blob: cac8b63c7eb508a2d3c17b9fd7b9e048cd9244b6 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +010038 # Only the complete word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmananac773182024-04-27 11:36:12 +020070 # Additional command after "class name"
71 lines =<< trim END
72 vim9script
73 class Something | var x = 10
74 endclass
75 END
76 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
77
78 # Additional command after "object variable"
79 lines =<< trim END
80 vim9script
81 class Something
82 var l: list<number> = [] | var y = 10
83 endclass
84 END
85 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
86
87 # Additional command after "class variable"
88 lines =<< trim END
89 vim9script
90 class Something
91 static var d = {a: 10} | var y = 10
92 endclass
93 END
94 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
95
96 # Additional command after "object method"
97 lines =<< trim END
98 vim9script
99 class Something
100 def Foo() | var y = 10
101 enddef
102 endclass
103 END
104 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
105
Yegappan Lakshmananfe55c312024-04-28 09:54:09 +0200106 # Comments are allowed after an inline block
107 lines =<< trim END
108 vim9script
109 class Foo
110 static const bar = { # {{{
111 baz: 'qux'
112 } # }}}
113 endclass
114 assert_equal({baz: 'qux'}, Foo.bar)
115 END
116 v9.CheckSourceSuccess(lines)
117
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +0100118 # Try to define a class with the same name as an existing variable
119 lines =<< trim END
120 vim9script
121 var Something: list<number> = [1]
122 class Thing
123 endclass
124 interface Api
125 endinterface
126 class Something extends Thing implements Api
127 var v1: string = ''
128 def Foo()
129 enddef
130 endclass
131 END
132 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 7)
133
zeertzjqe7102202024-02-13 20:32:04 +0100134 # Use old "this." prefixed member variable declaration syntax (without initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100135 lines =<< trim END
136 vim9script
137 class Something
138 this.count: number
139 endclass
140 END
141 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
142
zeertzjqe7102202024-02-13 20:32:04 +0100143 # Use old "this." prefixed member variable declaration syntax (with initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100144 lines =<< trim END
145 vim9script
146 class Something
147 this.count: number = 42
148 endclass
149 END
150 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
151
152 # Use old "this." prefixed member variable declaration syntax (type inferred)
153 lines =<< trim END
154 vim9script
155 class Something
156 this.count = 42
157 endclass
158 END
159 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
160
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200161 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000162 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 vim9script
164 class Something
165 this
166 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000167 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100168 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000169
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200170 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000171 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200172 vim9script
173 class Something
174 this.
175 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000176 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100177 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000178
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200179 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000180 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200181 vim9script
182 class Something
183 this .count
184 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000185 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100186 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000187
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200188 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000189 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200190 vim9script
191 class Something
192 this. count
193 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000194 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100195 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000196
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200197 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000198 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200199 vim9script
200 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100201 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200202 that.count
203 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200205 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000206
Doug Kearns74da0ee2023-12-14 20:26:26 +0100207 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000208 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200209 vim9script
210 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100211 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000213 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100214 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
215
216 # Use "variable" instead of "var" for member variable declaration (with initialization)
217 lines =<< trim END
218 vim9script
219 class Something
220 variable count: number = 42
221 endclass
222 END
223 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
224
225 # Use "variable" instead of "var" for member variable declaration (type inferred)
226 lines =<< trim END
227 vim9script
228 class Something
229 variable count = 42
230 endclass
231 END
232 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000233
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200234 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000235 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200236 vim9script
237 class Something
238 def new()
239 this.state = 0
240 enddef
241 endclass
242 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000243 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200244 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000245
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200246 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000247 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200248 vim9script
249 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100250 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200251 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000252 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200253 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000254
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200255 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000256 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200257 vim9script
258 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100259 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200260 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000261 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200262 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000263
Doug Kearns74da0ee2023-12-14 20:26:26 +0100264 # Missing ":var" in a "var" member variable declaration (without initialization)
265 lines =<< trim END
266 vim9script
267 class Something
268 var: number
269 endclass
270 END
271 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
272
273 # Missing ":var" in a "var" member variable declaration (with initialization)
274 lines =<< trim END
275 vim9script
276 class Something
277 var: number = 42
278 endclass
279 END
280 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
281
282 # Missing ":var" in a "var" member variable declaration (type inferred)
283 lines =<< trim END
284 vim9script
285 class Something
286 var = 42
287 endclass
288 END
289 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
290
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200291 # Test for unsupported comment specifier
292 lines =<< trim END
293 vim9script
294 class Something
295 # comment
296 #{
297 endclass
298 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200299 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200300
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200301 # Test for using class as a bool
302 lines =<< trim END
303 vim9script
304 class A
305 endclass
306 if A
307 endif
308 END
Ernie Raele75fde62023-12-21 17:18:54 +0100309 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200310
311 # Test for using object as a bool
312 lines =<< trim END
313 vim9script
314 class A
315 endclass
316 var a = A.new()
317 if a
318 endif
319 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200320 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200321
322 # Test for using class as a float
323 lines =<< trim END
324 vim9script
325 class A
326 endclass
327 sort([1.1, A], 'f')
328 END
Ernie Raelfa831102023-12-14 20:06:39 +0100329 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200330
331 # Test for using object as a float
332 lines =<< trim END
333 vim9script
334 class A
335 endclass
336 var a = A.new()
337 sort([1.1, a], 'f')
338 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200339 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200340
341 # Test for using class as a string
342 lines =<< trim END
343 vim9script
344 class A
345 endclass
346 :exe 'call ' .. A
347 END
Ernie Raele75fde62023-12-21 17:18:54 +0100348 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200349
350 # Test for using object as a string
351 lines =<< trim END
352 vim9script
353 class A
354 endclass
355 var a = A.new()
356 :exe 'call ' .. a
357 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200358 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200359
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200360 # Test creating a class with member variables and methods, calling a object
361 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000362 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200363 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000364
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200365 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100366 var lnum: number
367 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000368
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200369 # make a nicely formatted string
370 def ToString(): string
371 return $'({this.lnum}, {this.col})'
372 enddef
373 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000374
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200375 # use the automatically generated new() method
376 var pos = TextPosition.new(2, 12)
377 assert_equal(2, pos.lnum)
378 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000379
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200380 # call an object method
381 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000382
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200383 assert_equal(v:t_class, type(TextPosition))
384 assert_equal(v:t_object, type(pos))
385 assert_equal('class<TextPosition>', typename(TextPosition))
386 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000387 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200388 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200389
390 # When referencing object methods, space cannot be used after a "."
391 lines =<< trim END
392 vim9script
393 class A
394 def Foo(): number
395 return 10
396 enddef
397 endclass
398 var a = A.new()
399 var v = a. Foo()
400 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200401 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200402
403 # Using an object without specifying a method or a member variable
404 lines =<< trim END
405 vim9script
406 class A
407 def Foo(): number
408 return 10
409 enddef
410 endclass
411 var a = A.new()
412 var v = a.
413 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200414 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200415
416 # Error when parsing the arguments of an object method.
417 lines =<< trim END
418 vim9script
419 class A
420 def Foo()
421 enddef
422 endclass
423 var a = A.new()
424 var v = a.Foo(,)
425 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200426 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200427
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200428 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200429 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200430 vim9script
431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100432 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200433 X: 1
434 }
435 endclass
436 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200437 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200438 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000439enddef
440
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200441" Tests for object/class methods in a class
442def Test_class_def_method()
443 # Using the "public" keyword when defining an object method
444 var lines =<< trim END
445 vim9script
446 class A
447 public def Foo()
448 enddef
449 endclass
450 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200451 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200452
453 # Using the "public" keyword when defining a class method
454 lines =<< trim END
455 vim9script
456 class A
457 public static def Foo()
458 enddef
459 endclass
460 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200461 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200462
Ernie Rael03042a22023-11-11 08:53:32 +0100463 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200464 lines =<< trim END
465 vim9script
466 class A
467 public def _Foo()
468 enddef
469 endclass
470 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200471 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200472
Ernie Rael03042a22023-11-11 08:53:32 +0100473 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200474 lines =<< trim END
475 vim9script
476 class A
477 public static def _Foo()
478 enddef
479 endclass
480 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200481 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200482
483 # Using a "def" keyword without an object method name
484 lines =<< trim END
485 vim9script
486 class A
487 def
488 enddef
489 endclass
490 END
491 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
492
493 # Using a "def" keyword without a class method name
494 lines =<< trim END
495 vim9script
496 class A
497 static def
498 enddef
499 endclass
500 END
501 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
502enddef
503
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000504def Test_class_defined_twice()
505 # class defined twice should fail
506 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200507 vim9script
508 class There
509 endclass
510 class There
511 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000512 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200513 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000514
515 # one class, reload same script twice is OK
516 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 vim9script
518 class There
519 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000520 END
521 writefile(lines, 'XclassTwice.vim', 'D')
522 source XclassTwice.vim
523 source XclassTwice.vim
524enddef
525
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000526def Test_returning_null_object()
527 # this was causing an internal error
528 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200529 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000530
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200531 class BufferList
532 def Current(): any
533 return null_object
534 enddef
535 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000536
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200537 var buffers = BufferList.new()
538 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000539 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200540 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000541enddef
542
Bram Moolenaard13dd302023-03-11 20:56:35 +0000543def Test_using_null_class()
544 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200545 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200547 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200548
549 # Test for using a null class as a value
550 lines =<< trim END
551 vim9script
552 echo empty(null_class)
553 END
554 v9.CheckSourceFailure(lines, 'E1405: Class "" cannot be used as a value', 2)
555
556 # Test for using a null class with string()
557 lines =<< trim END
558 vim9script
559 assert_equal('class [unknown]', string(null_class))
560 END
561 v9.CheckSourceSuccess(lines)
562
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +0200563 # Test for using a null class with type() and typename()
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200564 lines =<< trim END
565 vim9script
566 assert_equal(12, type(null_class))
567 assert_equal('class<Unknown>', typename(null_class))
568 END
569 v9.CheckSourceSuccess(lines)
570enddef
571
Bram Moolenaar657aea72023-01-27 13:16:19 +0000572def Test_class_interface_wrong_end()
573 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200574 vim9script
575 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100576 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200577 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200579 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000580
581 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200582 vim9script
583 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100584 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200585 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000586 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200587 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000588enddef
589
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000590def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200591 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000592 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200593 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000594
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200595 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100596 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200597 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200599 var state: State
600 var db = {'xyz': 789}
601 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200603 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000604
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200605 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000606 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200607 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000608
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200609 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100610 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200611 def Method1()
612 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000613 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200614 endclass
615
616 var obj: Class
617 def Func()
618 obj.Method1()
619 enddef
620 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000621 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200622 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000623
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200624 # Pass an uninitialized object variable to a "new" function and try to call an
625 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000626 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200627 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000628
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200629 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100630 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200631 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000632
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200633 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100634 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200636 def GetBackground(): string
637 return this._bg.background
638 enddef
639 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000640
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200641 var bg: Background # UNINITIALIZED
642 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200644 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000645
646 # TODO: this should not give an error but be handled at runtime
647 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200648 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000649
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200650 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100651 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200652 def Method1()
653 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000654 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200655 endclass
656
657 var obj = null_object
658 def Func()
659 obj.Method1()
660 enddef
661 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000662 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200663 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Ernie Raelbe828252024-07-26 18:37:02 +0200664
665 # Reference a object variable through a null class object which is stored in a
666 # variable of type "any".
667 lines =<< trim END
668 vim9script
669
670 def Z()
671 var o: any = null_object
672 o.v = 4
673 enddef
674 Z()
675 END
676 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
677
678 # Do "echom" of a null object variable.
679 lines =<< trim END
680 vim9script
681
682 def X()
683 var x = null_object
684 echom x
685 enddef
686 X()
687 END
688 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 2)
Ernie Rael94082b62024-07-26 19:40:29 +0200689
690 # Use a null object variable that vim wants to force to number.
691 lines =<< trim END
692 vim9script
693
694 def X()
695 var o = null_object
696 var l = [ 1, o]
697 sort(l, 'N')
698 enddef
699 X()
700 END
701 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 3)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000702enddef
703
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200704" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200705def Test_null_object_assign_compare()
706 var lines =<< trim END
707 vim9script
708
709 var nullo = null_object
710 def F(): any
711 return nullo
712 enddef
713 assert_equal('object<Unknown>', typename(F()))
714
715 var o0 = F()
716 assert_true(o0 == null_object)
717 assert_true(o0 == null)
718
719 var o1: any = nullo
720 assert_true(o1 == null_object)
721 assert_true(o1 == null)
722
723 def G()
724 var x = null_object
725 enddef
726
727 class C
728 endclass
729 var o2: C
730 assert_true(o2 == null_object)
731 assert_true(o2 == null)
732
733 o2 = null_object
734 assert_true(o2 == null)
735
736 o2 = C.new()
737 assert_true(o2 != null)
738
739 o2 = null_object
740 assert_true(o2 == null)
741 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200742 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200743enddef
744
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200745" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000746def Test_class_member_initializer()
747 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200748 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000749
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200750 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100751 var lnum: number = 1
752 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000753
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200754 # constructor with only the line number
755 def new(lnum: number)
756 this.lnum = lnum
757 enddef
758 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200760 var pos = TextPosition.new(3)
761 assert_equal(3, pos.lnum)
762 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000763
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200764 var instr = execute('disassemble TextPosition.new')
765 assert_match('new\_s*' ..
766 '0 NEW TextPosition size \d\+\_s*' ..
767 '\d PUSHNR 1\_s*' ..
768 '\d STORE_THIS 0\_s*' ..
769 '\d PUSHNR 1\_s*' ..
770 '\d STORE_THIS 1\_s*' ..
771 'this.lnum = lnum\_s*' ..
772 '\d LOAD arg\[-1]\_s*' ..
773 '\d PUSHNR 0\_s*' ..
774 '\d LOAD $0\_s*' ..
775 '\d\+ STOREINDEX object\_s*' ..
776 '\d\+ RETURN object.*',
777 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000778 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200779 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000780enddef
781
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000782def Test_member_any_used_as_object()
783 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200784 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000785
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200786 class Inner
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +0100787 public var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200788 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000789
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200790 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100791 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200792 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200794 def F(outer: Outer)
795 outer.inner.value = 1
796 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000797
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200798 var inner_obj = Inner.new(0)
799 var outer_obj = Outer.new(inner_obj)
800 F(outer_obj)
801 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000802 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200803 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000804
Ernie Rael03042a22023-11-11 08:53:32 +0100805 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200806 lines =<< trim END
807 vim9script
808
809 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100810 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200811 endclass
812
813 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100814 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200815 endclass
816
817 def F(outer: Outer)
818 outer.inner._value = 'b'
819 enddef
820
821 var inner_obj = Inner.new('a')
822 var outer_obj = Outer.new(inner_obj)
823 F(outer_obj)
824 END
Ernie Rael03042a22023-11-11 08:53:32 +0100825 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200826
827 # Try modifying a non-existing variable using an "any" object
828 lines =<< trim END
829 vim9script
830
831 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100832 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200833 endclass
834
835 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100836 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200837 endclass
838
839 def F(outer: Outer)
840 outer.inner.someval = 'b'
841 enddef
842
843 var inner_obj = Inner.new('a')
844 var outer_obj = Outer.new(inner_obj)
845 F(outer_obj)
846 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200847 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000848enddef
849
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200850" Nested assignment to a object variable which is of another class type
851def Test_assignment_nested_type()
852 var lines =<< trim END
853 vim9script
854
855 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100856 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200857 endclass
858
859 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100860 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200861 endclass
862
863 def F(outer: Outer)
864 outer.inner.value = 1
865 enddef
866
867 def Test_assign_to_nested_typed_member()
868 var inner = Inner.new(0)
869 var outer = Outer.new(inner)
870 F(outer)
871 assert_equal(1, inner.value)
872 enddef
873
874 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200875
876 var script_inner = Inner.new(0)
877 var script_outer = Outer.new(script_inner)
878 script_outer.inner.value = 1
879 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200880 END
881 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200882
883 # Assignment where target item is read only in :def
884 lines =<< trim END
885 vim9script
886
887 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100888 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200889 endclass
890
891 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100892 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200893 endclass
894
895 def F(outer: Outer)
896 outer.inner.value = 1
897 enddef
898
899 def Test_assign_to_nested_typed_member()
900 var inner = Inner.new(0)
901 var outer = Outer.new(inner)
902 F(outer)
903 assert_equal(1, inner.value)
904 enddef
905
906 Test_assign_to_nested_typed_member()
907 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200908 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200909
910 # Assignment where target item is read only script level
911 lines =<< trim END
912 vim9script
913
914 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100915 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200916 endclass
917
918 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100919 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200920 endclass
921
922 def F(outer: Outer)
923 outer.inner.value = 1
924 enddef
925
926 var script_inner = Inner.new(0)
927 var script_outer = Outer.new(script_inner)
928 script_outer.inner.value = 1
929 assert_equal(1, script_inner.value)
930 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200931 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200932enddef
933
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000934def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200935 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000936 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200937 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000938
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200939 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100940 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000941
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200942 def Add(n: number)
943 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100944 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200945 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100946
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200947 var f = Foo.new(3)
948 f.Add(17)
949 assert_equal(20, f.x)
950
951 def AddToFoo(obj: Foo)
952 obj.x += 3
953 enddef
954
955 AddToFoo(f)
956 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000957 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200958 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000959enddef
960
Bram Moolenaarf4508042023-01-15 16:54:57 +0000961def Test_list_of_objects()
962 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200963 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000964
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200965 class Foo
966 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000967 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200968 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000969
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200970 def ProcessList(fooList: list<Foo>)
971 for foo in fooList
972 foo.Add()
973 endfor
974 enddef
975
976 var l: list<Foo> = [Foo.new()]
977 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000978 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200979 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000980enddef
981
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000982def Test_expr_after_using_object()
983 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200984 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000985
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200986 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100987 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200988 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000989
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200990 def Foo(): Something
991 var v = Something.new()
992 echo 'in Foo(): ' .. typename(v)
993 return v
994 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000995
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200996 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000997 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200998 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000999enddef
1000
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001001def Test_class_default_new()
1002 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001003 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001004
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001005 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001006 var lnum: number = 1
1007 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001008 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001009
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001010 var pos = TextPosition.new()
1011 assert_equal(1, pos.lnum)
1012 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001013
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001014 pos = TextPosition.new(v:none, v:none)
1015 assert_equal(1, pos.lnum)
1016 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001017
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001018 pos = TextPosition.new(3, 22)
1019 assert_equal(3, pos.lnum)
1020 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001022 pos = TextPosition.new(v:none, 33)
1023 assert_equal(1, pos.lnum)
1024 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001025 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001026 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001027
1028 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001029 vim9script
1030 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001031 var name: string
1032 var age: number = 42
1033 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001034
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001035 def new(this.name, this.age = v:none, this.education = v:none)
1036 enddef
1037 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001038
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001039 var piet = Person.new("Piet")
1040 assert_equal("Piet", piet.name)
1041 assert_equal(42, piet.age)
1042 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001043
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001044 var chris = Person.new("Chris", 4, "none")
1045 assert_equal("Chris", chris.name)
1046 assert_equal(4, chris.age)
1047 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001048 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001049 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001050
1051 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001052 vim9script
1053 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001054 var name: string
1055 var age: number = 42
1056 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +00001057
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001058 def new(this.name, this.age = v:none, this.education = v:none)
1059 enddef
1060 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001061
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001062 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +00001063 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001064 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001065
1066 # Using a specific value to initialize an instance variable in the new()
1067 # method.
1068 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001069 vim9script
1070 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001071 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001072 def new(this.val = 'a')
1073 enddef
1074 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001075 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001076 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001077enddef
1078
h-east2261c892023-08-16 21:49:54 +09001079def Test_class_new_with_object_member()
1080 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001081 vim9script
h-east2261c892023-08-16 21:49:54 +09001082
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001083 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001084 var str: string
1085 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001086 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +09001087 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001088 def newVals(this.str, this.num)
1089 enddef
1090 endclass
h-east2261c892023-08-16 21:49:54 +09001091
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001092 def Check()
1093 try
1094 var c = C.new('cats', 2)
1095 assert_equal('cats', c.str)
1096 assert_equal(2, c.num)
1097
1098 c = C.newVals('dogs', 4)
1099 assert_equal('dogs', c.str)
1100 assert_equal(4, c.num)
1101 catch
1102 assert_report($'Unexpected exception was caught: {v:exception}')
1103 endtry
1104 enddef
1105
1106 Check()
h-east2261c892023-08-16 21:49:54 +09001107 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001108 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001109
1110 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001111 vim9script
1112
1113 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001114 var str: string
1115 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001116 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001117 enddef
1118 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001119
1120 def Check()
1121 try
1122 var c = C.new(1, 2)
1123 catch
1124 assert_report($'Unexpected exception was caught: {v:exception}')
1125 endtry
1126 enddef
1127
1128 Check()
h-eastdb385522023-09-28 22:18:19 +02001129 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001130 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001131
1132 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001133 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001134
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001135 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001136 var str: string
1137 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001138 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001139 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001140 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001141
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001142 def Check()
1143 try
1144 var c = C.newVals('dogs', 'apes')
1145 catch
1146 assert_report($'Unexpected exception was caught: {v:exception}')
1147 endtry
1148 enddef
1149
1150 Check()
1151 END
1152 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1153
1154 lines =<< trim END
1155 vim9script
1156
1157 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001158 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001159 def new(str: any)
1160 enddef
1161 endclass
1162
1163 def Check()
1164 try
1165 var c = C.new(1)
1166 catch
1167 assert_report($'Unexpected exception was caught: {v:exception}')
1168 endtry
1169 enddef
1170
1171 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001172 END
1173 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001174
1175 # Try using "this." argument in a class method
1176 lines =<< trim END
1177 vim9script
1178 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001179 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001180 static def Foo(this.val: number)
1181 enddef
1182 endclass
1183 END
1184 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1185
1186 # Try using "this." argument in an object method
1187 lines =<< trim END
1188 vim9script
1189 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001190 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001191 def Foo(this.val: number)
1192 enddef
1193 endclass
1194 END
1195 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001196enddef
1197
Bram Moolenaar74e12742022-12-13 21:14:28 +00001198def Test_class_object_member_inits()
1199 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001200 vim9script
1201 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001202 var lnum: number
1203 var col = 1
1204 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001205 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001206
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001207 var pos = TextPosition.new()
1208 assert_equal(0, pos.lnum)
1209 assert_equal(1, pos.col)
1210 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001211 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001212 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001213
1214 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001215 vim9script
1216 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001217 var lnum
1218 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001219 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001220 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001221 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001222
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001223 # If the type is not specified for a member, then it should be set during
1224 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001225 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001226 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001227
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001228 var init_count = 0
1229 def Init(): string
1230 init_count += 1
1231 return 'foo'
1232 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001233
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001234 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001235 var str1 = Init()
1236 var str2: string = Init()
1237 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001238 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001239
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001240 assert_equal(init_count, 0)
1241 var a = A.new()
1242 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001243 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001244 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001245
1246 # Test for initializing an object member with an unknown variable/type
1247 lines =<< trim END
1248 vim9script
1249 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001250 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001251 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001252 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001253 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001254 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001255
1256 # Test for initializing an object member with an special type
1257 lines =<< trim END
1258 vim9script
1259 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001260 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001261 endclass
1262 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001263 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001264enddef
1265
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001266" Test for instance variable access
1267def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001268 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001269 vim9script
1270 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001271 var _one = 1
1272 var two = 2
1273 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001274
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001275 def GetOne(): number
1276 return this._one
1277 enddef
1278 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001279
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001280 var trip = Triple.new()
1281 assert_equal(1, trip.GetOne())
1282 assert_equal(2, trip.two)
1283 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001284 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001285
Ernie Rael03042a22023-11-11 08:53:32 +01001286 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001287 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1288 trip.three = 33
1289 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001290
Ernie Raeld4802ec2023-10-20 11:59:00 +02001291 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001292 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001293 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001294
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001295 # Test for a public member variable name beginning with an underscore
1296 lines =<< trim END
1297 vim9script
1298 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001299 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001300 endclass
1301 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001302 v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001303
Bram Moolenaar590162c2022-12-24 21:24:06 +00001304 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001305 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001306
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001307 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001308 var make: string
1309 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001310
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001311 def new(make_arg: string)
1312 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001313 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001314
1315 def GetMake(): string
1316 return $"make = {this.make}"
1317 enddef
1318 def GetAge(): number
1319 return this.age
1320 enddef
1321 endclass
1322
1323 var c = MyCar.new("abc")
1324 assert_equal('make = abc', c.GetMake())
1325
1326 c = MyCar.new("def")
1327 assert_equal('make = def', c.GetMake())
1328
1329 var c2 = MyCar.new("123")
1330 assert_equal('make = 123', c2.GetMake())
1331
1332 def CheckCar()
1333 assert_equal("make = def", c.GetMake())
1334 assert_equal(5, c.GetAge())
1335 enddef
1336 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001337 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001338 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001339
1340 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001341 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001342
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001343 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001344 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001345
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001346 def new(make_arg: string)
1347 this.make = make_arg
1348 enddef
1349 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001350
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001351 var c = MyCar.new("abc")
1352 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001353 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001354 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001355
1356 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001357 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001359 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001360 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001361
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001362 def Add(n: number): any
1363 this.x->add(n)
1364 return this
1365 enddef
1366 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001367
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001368 echo Foo.new().Add(1).Add(2).x
1369 echo Foo.new().Add(1).Add(2)
1370 .x
1371 echo Foo.new().Add(1)
1372 .Add(2).x
1373 echo Foo.new()
1374 .Add(1).Add(2).x
1375 echo Foo.new()
1376 .Add(1)
1377 .Add(2)
1378 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001379 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001380 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001381
1382 # Test for "public" cannot be abbreviated
1383 lines =<< trim END
1384 vim9script
1385 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001386 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001387 endclass
1388 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001389 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001390
Doug Kearns74da0ee2023-12-14 20:26:26 +01001391 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001392 lines =<< trim END
1393 vim9script
1394 class Something
1395 public val = 1
1396 endclass
1397 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001398 v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001399
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001400 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001401 lines =<< trim END
1402 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001403 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001404 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001405 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001406 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001407 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001408 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001409
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001410 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001411 lines =<< trim END
1412 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001413 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001414 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001415 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001416 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001417 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001418 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001419
1420 # Modify a instance variable using the class name in a def function
1421 lines =<< trim END
1422 vim9script
1423 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001424 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001425 endclass
1426 def T()
1427 A.val = 1
1428 enddef
1429 T()
1430 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001431 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001432
1433 # Read a instance variable using the class name in a def function
1434 lines =<< trim END
1435 vim9script
1436 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001437 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001438 endclass
1439 def T()
1440 var i = A.val
1441 enddef
1442 T()
1443 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001444 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001445
1446 # Access from child class extending a class:
1447 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001448 vim9script
1449 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001450 var ro_obj_var = 10
1451 public var rw_obj_var = 20
1452 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001453 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001454
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001455 class B extends A
1456 def Foo()
1457 var x: number
1458 x = this.ro_obj_var
1459 this.ro_obj_var = 0
1460 x = this.rw_obj_var
1461 this.rw_obj_var = 0
1462 x = this._priv_obj_var
1463 this._priv_obj_var = 0
1464 enddef
1465 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001466
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001467 var b = B.new()
1468 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001469 END
1470 v9.CheckSourceSuccess(lines)
1471enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001472
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001473" Test for class variable access
1474def Test_class_variable_access()
1475 # Test for "static" cannot be abbreviated
1476 var lines =<< trim END
1477 vim9script
1478 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001479 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001480 endclass
1481 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001482 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001483
1484 # Test for "static" cannot be followed by "public".
1485 lines =<< trim END
1486 vim9script
1487 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001488 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001489 endclass
1490 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001491 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001492
1493 # A readonly class variable cannot be modified from a child class
1494 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001495 vim9script
1496 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001497 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001499
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001500 class B extends A
1501 def Foo()
1502 A.ro_class_var = 50
1503 enddef
1504 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001505
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001506 var b = B.new()
1507 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001508 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001509 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001510
Ernie Rael03042a22023-11-11 08:53:32 +01001511 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001512 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001513 vim9script
1514 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001515 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001516 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001517
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001518 class B extends A
1519 def Foo()
1520 var i = A._priv_class_var
1521 enddef
1522 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001523
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001524 var b = B.new()
1525 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001526 END
Ernie Rael03042a22023-11-11 08:53:32 +01001527 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001528
Ernie Rael03042a22023-11-11 08:53:32 +01001529 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001530 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001531 vim9script
1532 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001533 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001534 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001535
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001536 class B extends A
1537 def Foo()
1538 A._priv_class_var = 0
1539 enddef
1540 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001541
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001542 var b = B.new()
1543 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001544 END
Ernie Rael03042a22023-11-11 08:53:32 +01001545 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001546
1547 # Access from child class extending a class and from script context
1548 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001549 vim9script
1550 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001551 static var ro_class_var = 10
1552 public static var rw_class_var = 20
1553 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001554 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001555
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001556 class B extends A
1557 def Foo()
1558 var x: number
1559 x = A.ro_class_var
1560 assert_equal(10, x)
1561 x = A.rw_class_var
1562 assert_equal(25, x)
1563 A.rw_class_var = 20
1564 assert_equal(20, A.rw_class_var)
1565 enddef
1566 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001567
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001568 assert_equal(10, A.ro_class_var)
1569 assert_equal(20, A.rw_class_var)
1570 A.rw_class_var = 25
1571 assert_equal(25, A.rw_class_var)
1572 var b = B.new()
1573 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001574 END
1575 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001576enddef
1577
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001578def Test_class_object_compare()
1579 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001580 vim9script
1581 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001582 var nr = 0
1583 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001584 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001585 END
1586
1587 # used at the script level and in a compiled function
1588 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001589 var i1 = Item.new()
1590 assert_equal(i1, i1)
1591 assert_true(i1 is i1)
1592 var i2 = Item.new()
1593 assert_equal(i1, i2)
1594 assert_false(i1 is i2)
1595 var i3 = Item.new(0, 'xx')
1596 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001598 var io1 = Item.new(1, 'xx')
1599 assert_notequal(i1, io1)
1600 var io2 = Item.new(0, 'yy')
1601 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001602 END
1603
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001604 v9.CheckSourceSuccess(class_lines + test_lines)
1605 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001606 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001607
1608 for op in ['>', '>=', '<', '<=', '=~', '!~']
1609 var op_lines = [
1610 'var i1 = Item.new()',
1611 'var i2 = Item.new()',
1612 'echo i1 ' .. op .. ' i2',
1613 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001614 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001615 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001616 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001617 endfor
1618enddef
1619
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001620def Test_object_type()
1621 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001622 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001623
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001624 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001625 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001626 endclass
1627 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001628 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001629 endclass
1630 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001631 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001632 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001633
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001634 var o: One = One.new()
1635 var t: Two = Two.new()
1636 var m: TwoMore = TwoMore.new()
1637 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001638
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001639 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001640 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001641 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001642
1643 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001644 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001645
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001646 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001647 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001648 endclass
1649 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001650 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001651 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001652
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001653 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001654 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001655 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001656
1657 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001658 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001659
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001660 interface One
1661 def GetMember(): number
1662 endinterface
1663 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001664 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001665 def GetMember(): number
1666 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001667 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001668 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001669
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001670 var o: One = Two.new(5)
1671 assert_equal(5, o.GetMember())
1672 END
1673 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001674
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001675 lines =<< trim END
1676 vim9script
1677
1678 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001679 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001680 endclass
1681
1682 def Ref(name: string): func(Num): Num
1683 return (arg: Num): Num => {
1684 return eval(name)(arg)
1685 }
1686 enddef
1687
1688 const Fn = Ref('Double')
1689 var Double = (m: Num): Num => Num.new(m.n * 2)
1690
1691 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001692 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001693 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001694enddef
1695
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001696def Test_class_member()
1697 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001698 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001699 vim9script
1700 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001701 var lnum = 1
1702 var col = 1
1703 static var counter = 0
1704 static var _secret = 7
1705 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001706
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001707 static def AddToCounter(nr: number)
1708 counter += nr
1709 enddef
1710 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001711
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001712 assert_equal(0, TextPos.counter)
1713 TextPos.AddToCounter(3)
1714 assert_equal(3, TextPos.counter)
1715 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001716
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001717 def GetCounter(): number
1718 return TextPos.counter
1719 enddef
1720 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001722 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1723 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1724 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001725
Ernie Rael03042a22023-11-11 08:53:32 +01001726 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1727 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001728
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001729 assert_equal(42, TextPos.anybody)
1730 TextPos.anybody = 12
1731 assert_equal(12, TextPos.anybody)
1732 TextPos.anybody += 5
1733 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001734 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001735 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001736
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001737 # example in the help
1738 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001739 vim9script
1740 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001741 var size: number
1742 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001743
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001744 def new(this.size)
1745 totalSize += this.size
1746 enddef
1747 endclass
1748 assert_equal(0, OtherThing.totalSize)
1749 var to3 = OtherThing.new(3)
1750 assert_equal(3, OtherThing.totalSize)
1751 var to7 = OtherThing.new(7)
1752 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001753 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001754 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001755
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001756 # using static class member twice
1757 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001758 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001760 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001761 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001762
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001763 static def MacroSubstitute(s: string): string
1764 return substitute(s, '{{author}}', author, 'gi')
1765 enddef
1766 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001767
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001768 assert_equal('some text', HTML.MacroSubstitute('some text'))
1769 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001770 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001771 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001772
Ernie Rael03042a22023-11-11 08:53:32 +01001773 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001774 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001775 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001776
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001777 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001778 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001779
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001780 def Add(n: number): number
1781 const F = (): number => this._x + n
1782 return F()
1783 enddef
1784 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001785
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001786 var foo = Foo.new()
1787 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001789 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001790
Ernie Rael03042a22023-11-11 08:53:32 +01001791 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001792 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001793 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001794
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001795 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001796 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001797
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001798 def Add(n: number): number
1799 var Lam = () => {
1800 this._x = this._x + n
1801 }
1802 Lam()
1803 return this._x
1804 enddef
1805 endclass
h-east2bd6a092023-05-19 19:01:17 +01001806
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001807 var foo = Foo.new()
1808 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001809 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001810 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001811
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001812 # check shadowing
1813 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001814 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001815
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001816 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001817 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001818 def Method(count: number)
1819 echo count
1820 enddef
1821 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001822
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001823 var s = Some.new()
1824 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001825 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001826 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001827
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001828 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001829 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001830 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001831
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001832 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001833 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001834 def Method(arg: number)
1835 var count = 3
1836 echo arg count
1837 enddef
1838 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001839
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001840 var s = Some.new()
1841 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001842 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001843 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001844
1845 # Test for using an invalid type for a member variable
1846 lines =<< trim END
1847 vim9script
1848 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001849 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001850 endclass
1851 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001852 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001853
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001854 # Test for setting a member on a null object
1855 lines =<< trim END
1856 vim9script
1857 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001858 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001859 endclass
1860
1861 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001862 var obj: A
1863 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001864 enddef
1865 F()
1866 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001867 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001868
1869 # Test for accessing a member on a null object
1870 lines =<< trim END
1871 vim9script
1872 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001873 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001874 endclass
1875
1876 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001877 var obj: A
1878 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001879 enddef
1880 F()
1881 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001882 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001883
1884 # Test for setting a member on a null object, at script level
1885 lines =<< trim END
1886 vim9script
1887 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001888 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001889 endclass
1890
1891 var obj: A
1892 obj.val = ""
1893 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001894 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001895
1896 # Test for accessing a member on a null object, at script level
1897 lines =<< trim END
1898 vim9script
1899 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001900 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001901 endclass
1902
1903 var obj: A
1904 echo obj.val
1905 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001906 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001907
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001908 # Test for no space before or after the '=' when initializing a member
1909 # variable
1910 lines =<< trim END
1911 vim9script
1912 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001913 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001914 endclass
1915 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001916 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001917 lines =<< trim END
1918 vim9script
1919 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001920 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001921 endclass
1922 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001923 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001924
1925 # Access a non-existing member
1926 lines =<< trim END
1927 vim9script
1928 class A
1929 endclass
1930 var a = A.new()
1931 var v = a.bar
1932 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001933 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001934enddef
1935
Ernie Raele6c9aa52023-10-06 19:55:52 +02001936" These messages should show the defining class of the variable (base class),
1937" not the class that did the reference (super class)
1938def Test_defining_class_message()
1939 var lines =<< trim END
1940 vim9script
1941
1942 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001943 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001944 endclass
1945
1946 class Child extends Base
1947 endclass
1948
1949 var o = Child.new()
1950 var x = o._v1
1951 END
Ernie Rael03042a22023-11-11 08:53:32 +01001952 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001953 lines =<< trim END
1954 vim9script
1955
1956 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001957 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001958 endclass
1959
1960 class Child extends Base
1961 endclass
1962
1963 def F()
1964 var o = Child.new()
1965 var x = o._v1
1966 enddef
1967 F()
1968 END
Ernie Rael03042a22023-11-11 08:53:32 +01001969 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001970 lines =<< trim END
1971 vim9script
1972
1973 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001974 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001975 endclass
1976
1977 class Child extends Base
1978 endclass
1979
1980 var o = Child.new()
1981 o.v1 = []
1982 END
1983 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1984 lines =<< trim END
1985 vim9script
1986
1987 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001988 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001989 endclass
1990
1991 class Child extends Base
1992 endclass
1993
1994 def F()
1995 var o = Child.new()
1996 o.v1 = []
1997 enddef
1998 F()
1999 END
2000
Ernie Rael03042a22023-11-11 08:53:32 +01002001 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02002002 # of the class hierarchy.
2003 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
2004 lines =<< trim END
2005 vim9script
2006
2007 class Base0
2008 endclass
2009
2010 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01002011 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002012 endclass
2013
2014 class Child extends Base
2015 endclass
2016
2017 def F()
2018 var o = Child.new()
2019 var x = o._v1
2020 enddef
2021 F()
2022 END
Ernie Rael03042a22023-11-11 08:53:32 +01002023 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002024
Ernie Rael03042a22023-11-11 08:53:32 +01002025 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02002026 # of the class hierarchy.
2027 lines =<< trim END
2028 vim9script
2029
2030 class Base0
2031 endclass
2032
2033 class Base extends Base0
2034 endclass
2035
2036 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002037 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002038 endclass
2039
2040 def F()
2041 var o = Child.new()
2042 var x = o._v1
2043 enddef
2044 F()
2045 END
Ernie Rael03042a22023-11-11 08:53:32 +01002046 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002047enddef
2048
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002049func Test_class_garbagecollect()
2050 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002051 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002052
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002053 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002054 var p = [2, 3]
2055 static var pl = ['a', 'b']
2056 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002057 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002058
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002059 echo Point.pl Point.pd
2060 call test_garbagecollect_now()
2061 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002062 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002063 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002064
2065 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002066 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002067
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002068 interface View
2069 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002070
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002071 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01002072 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002073 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002074
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002075 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01002076 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002077
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002078 def new()
2079 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01002080 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002081 enddef
2082 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002083
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002084 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002085
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002086 # overwrite "view", will be garbage-collected next
2087 view = MyView.new()
2088 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002089 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002090 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002091endfunc
2092
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002093" Test interface garbage collection
2094func Test_interface_garbagecollect()
2095 let lines =<< trim END
2096 vim9script
2097
2098 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002099 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002100
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002101 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002102 endinterface
2103
2104 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002105 static var ro_class_var: number = 10
2106 public static var rw_class_var: number = 20
2107 static var _priv_class_var: number = 30
2108 var ro_obj_var: number = 40
2109 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002110
2111 static def _ClassBar(): number
2112 return _priv_class_var
2113 enddef
2114
2115 static def ClassFoo(): number
2116 return ro_class_var + rw_class_var + A._ClassBar()
2117 enddef
2118
2119 def _ObjBar(): number
2120 return this._priv_obj_var
2121 enddef
2122
2123 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002124 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002125 enddef
2126 endclass
2127
2128 assert_equal(60, A.ClassFoo())
2129 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002130 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002131 test_garbagecollect_now()
2132 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002133 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002134 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002135 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002136endfunc
2137
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002138def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002139 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002140 vim9script
2141 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002142 var value = 0
2143 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002144
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002145 def new(v: number)
2146 this.value = v
2147 ++objects
2148 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002149
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002150 static def GetCount(): number
2151 return objects
2152 enddef
2153 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002154
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002155 assert_equal(0, Value.GetCount())
2156 var v1 = Value.new(2)
2157 assert_equal(1, Value.GetCount())
2158 var v2 = Value.new(7)
2159 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002160 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002161 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002162
2163 # Test for cleaning up after a class definition failure when using class
2164 # functions.
2165 lines =<< trim END
2166 vim9script
2167 class A
2168 static def Foo()
2169 enddef
2170 aaa
2171 endclass
2172 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002173 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002174
2175 # Test for calling a class method from another class method without the class
2176 # name prefix.
2177 lines =<< trim END
2178 vim9script
2179 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002180 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002181 static def Foo(n: number)
2182 myList->add(n)
2183 enddef
2184 static def Bar()
2185 Foo(2)
2186 enddef
2187 def Baz()
2188 Foo(3)
2189 enddef
2190 endclass
2191 A.Bar()
2192 var a = A.new()
2193 a.Baz()
2194 assert_equal([1, 2, 3], A.myList)
2195 END
2196 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002197enddef
2198
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002199def Test_class_defcompile()
2200 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002201 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 class C
2204 def Fo(i: number): string
2205 return i
2206 enddef
2207 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002208
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002209 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002210 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002211 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002212
2213 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002214 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002215
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002216 class C
2217 static def Fc(): number
2218 return 'x'
2219 enddef
2220 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002221
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002222 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002223 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002224 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002225
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002226 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002227 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002228
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002229 class C
2230 static def new()
2231 enddef
2232 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002233
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002234 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002235 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002236 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002237
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002238 # Trying to compile a function using a non-existing class variable
2239 lines =<< trim END
2240 vim9script
2241 defcompile x.Foo()
2242 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002243 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002244
2245 # Trying to compile a function using a variable which is not a class
2246 lines =<< trim END
2247 vim9script
2248 var x: number
2249 defcompile x.Foo()
2250 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002251 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002252
2253 # Trying to compile a function without specifying the name
2254 lines =<< trim END
2255 vim9script
2256 class A
2257 endclass
2258 defcompile A.
2259 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002260 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002261
2262 # Trying to compile a non-existing class object member function
2263 lines =<< trim END
2264 vim9script
2265 class A
2266 endclass
2267 var a = A.new()
2268 defcompile a.Foo()
2269 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002270 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002271enddef
2272
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002273def Test_class_object_to_string()
2274 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002275 vim9script
2276 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002277 var lnum = 1
2278 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002279 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002280
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002281 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002282
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002283 var pos = TextPosition.new()
2284 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002285 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002286 v9.CheckSourceSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +02002287
2288 # check string() with object nesting
2289 lines =<< trim END
2290 vim9script
2291 class C
2292 var nest1: C
2293 var nest2: C
2294 def Init(n1: C, n2: C)
2295 this.nest1 = n1
2296 this.nest2 = n2
2297 enddef
2298 endclass
2299
2300 var o1 = C.new()
2301 var o2 = C.new()
2302 o1.Init(o1, o2)
2303 o2.Init(o2, o1)
2304
2305 # The following previously put's vim into an infinite loop.
2306
2307 var expect = "object of C {nest1: object of C {...}, nest2: object of C {nest1: object of C {...}, nest2: object of C {...}}}"
2308 assert_equal(expect, string(o1))
2309 END
2310 v9.CheckSourceSuccess(lines)
2311
2312 lines =<< trim END
2313 vim9script
2314
2315 class B
2316 endclass
2317
2318 class C
2319 var b: B
2320 var c: C
2321 endclass
2322
2323 var o1 = C.new(B.new(), C.new(B.new()))
2324 var expect = "object of C {b: object of B {}, c: object of C {b: object of B {}, c: object of [unknown]}}"
2325 assert_equal(expect, string(o1))
2326 END
2327 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002328enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002329
Bram Moolenaar554d0312023-01-05 19:59:18 +00002330def Test_interface_basics()
2331 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002332 vim9script
2333 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002334 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002335 def GetCount(): number
2336 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002337 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002338 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002339
2340 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002341 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002342 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002343 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002344 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002345 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002346
2347 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002348 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002349
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002350 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002351 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002352 def Method(value: number)
2353 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002354 END
h-east61378a12023-04-18 19:07:29 +01002355 # The argument name and the object member name are the same, but this is not a
2356 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002357 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002358
2359 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002360 vim9script
2361 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002362 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002363 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002364 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002365 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002366
2367 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002368 vim9script
2369 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002370 var value: string
2371 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002372 def GetCount(): number
2373 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002374 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002375 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002376
2377 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002378 vim9script
2379 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002380 var value: string
2381 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 def GetCount(): number
2383 return 5
2384 enddef
2385 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002386 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002387 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002388
h-eastaa979c72025-01-03 10:19:45 +01002389 # Test for "interface" cannot be abbreviated
2390 lines =<< trim END
2391 vim9script
2392 inte Something
2393 endinterface
2394 END
2395 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: inte Something', 2)
2396
2397 # Test for "endinterface" cannot be abbreviated
2398 lines =<< trim END
2399 vim9script
2400 interface Something
2401 endin
2402 END
2403 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endin', 3)
2404
Yegappan Lakshmananac773182024-04-27 11:36:12 +02002405 # Additional commands after "interface name"
2406 lines =<< trim END
2407 vim9script
2408 interface Something | var x = 10 | var y = 20
2409 endinterface
2410 END
2411 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
2412
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002413 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002414 vim9script
2415 export interface EnterExit
2416 def Enter(): void
2417 def Exit(): void
2418 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002419 END
2420 writefile(lines, 'XdefIntf.vim', 'D')
2421
2422 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002423 vim9script
2424 import './XdefIntf.vim' as defIntf
2425 export def With(ee: defIntf.EnterExit, F: func)
2426 ee.Enter()
2427 try
2428 F()
2429 finally
2430 ee.Exit()
2431 endtry
2432 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002433 END
2434 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002435
2436 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002437 vim9script
2438 export abstract class EnterExit
2439 def Enter(): void
2440 enddef
2441 def Exit(): void
2442 enddef
2443 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002444 END
2445 writefile(imported, 'XdefIntf2.vim', 'D')
2446
2447 lines[1] = " import './XdefIntf2.vim' as defIntf"
2448 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002449enddef
2450
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002451" Test for using string() with an interface
2452def Test_interface_to_string()
2453 var lines =<< trim END
2454 vim9script
2455 interface Intf
2456 def Method(nr: number)
2457 endinterface
2458 assert_equal("interface Intf", string(Intf))
2459 END
2460 v9.CheckSourceSuccess(lines)
2461enddef
2462
Bram Moolenaar94674f22023-01-06 18:42:20 +00002463def Test_class_implements_interface()
2464 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002465 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002466
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002467 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002468 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002469 def Method(nr: number)
2470 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002471
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002472 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002473 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002474 def Method(nr: number)
2475 echo nr
2476 enddef
2477 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002478
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002479 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002480 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002481 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002482
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002483 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002484 var member = 'abc'
2485 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002486 def Method(nr: number)
2487 echo nr
2488 enddef
2489 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002490 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002491 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002492
2493 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002494 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002495
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002496 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002497 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002498 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002499
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002500 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002501 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002502 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002503 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002504 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002505
2506 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002507 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002508
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002509 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002510 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002511 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002512
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002513 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002514 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002515 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002517 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002518
2519 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002520 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002521
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002522 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002523 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002524 def Method(nr: number)
2525 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002526
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002527 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002528 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002529 def Method(nr: number)
2530 echo nr
2531 enddef
2532 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002533 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002534 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002535
2536 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002537 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002538
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002539 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002540 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002541 def Methods(nr: number)
2542 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002543
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002544 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002545 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002546 def Method(nr: number)
2547 echo nr
2548 enddef
2549 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002550 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002551 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002552
2553 # Check different order of members in class and interface works.
2554 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002555 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002556
2557 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002558 var label: string
2559 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002560 endinterface
2561
2562 # order of members is opposite of interface
2563 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002564 public var lnum: number = 5
2565 var errpos: number = 42
2566 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002567 endclass
2568
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002569 def Test()
2570 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002571
2572 assert_equal('label', result.label)
2573 assert_equal(42, result.errpos)
2574 enddef
2575
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002576 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002577 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002578 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002579
2580 # Interface name after "extends" doesn't end in a space or NUL character
2581 lines =<< trim END
2582 vim9script
2583 interface A
2584 endinterface
2585 class B extends A"
2586 endclass
2587 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002588 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002589
2590 # Trailing characters after a class name
2591 lines =<< trim END
2592 vim9script
2593 class A bbb
2594 endclass
2595 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002596 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002597
2598 # using "implements" with a non-existing class
2599 lines =<< trim END
2600 vim9script
2601 class A implements B
2602 endclass
2603 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002604 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002605
2606 # using "implements" with a regular class
2607 lines =<< trim END
2608 vim9script
2609 class A
2610 endclass
2611 class B implements A
2612 endclass
2613 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002614 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002615
2616 # using "implements" with a variable
2617 lines =<< trim END
2618 vim9script
2619 var T: number = 10
2620 class A implements T
2621 endclass
2622 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002623 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002624
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002625 # implements should be followed by a white space
2626 lines =<< trim END
2627 vim9script
2628 interface A
2629 endinterface
2630 class B implements A;
2631 endclass
2632 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002633 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002634
LemonBoyc5d27442023-08-19 13:02:35 +02002635 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002636 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002637
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002638 interface One
2639 def IsEven(nr: number): bool
2640 endinterface
2641 class Two implements One
2642 def IsEven(nr: number): string
2643 enddef
2644 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002645 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002646 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002647
2648 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002649 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002650
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002651 interface One
2652 def IsEven(nr: number): bool
2653 endinterface
2654 class Two implements One
2655 def IsEven(nr: bool): bool
2656 enddef
2657 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002658 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002659 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002660
2661 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002662 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002663
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002664 interface One
2665 def IsEven(nr: number): bool
2666 endinterface
2667 class Two implements One
2668 def IsEven(nr: number, ...extra: list<number>): bool
2669 enddef
2670 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002671 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002672 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 +02002673
2674 # access superclass interface members from subclass, mix variable order
2675 lines =<< trim END
2676 vim9script
2677
2678 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002679 var mvar1: number
2680 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002681 endinterface
2682
2683 # NOTE: the order is swapped
2684 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002685 var mvar2: number
2686 var mvar1: number
2687 public static var svar2: number
2688 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002689 def new()
2690 svar1 = 11
2691 svar2 = 12
2692 this.mvar1 = 111
2693 this.mvar2 = 112
2694 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002695 endclass
2696
2697 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002698 def new()
2699 this.mvar1 = 121
2700 this.mvar2 = 122
2701 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002702 endclass
2703
2704 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002705 def new()
2706 this.mvar1 = 131
2707 this.mvar2 = 132
2708 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002709 endclass
2710
Ernie Raelcf138d42023-09-06 20:45:03 +02002711 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002712 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002713 enddef
2714
2715 var oa = A.new()
2716 var ob = B.new()
2717 var oc = C.new()
2718
Ernie Raelcf138d42023-09-06 20:45:03 +02002719 assert_equal([111, 112], F2(oa))
2720 assert_equal([121, 122], F2(ob))
2721 assert_equal([131, 132], F2(oc))
2722 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002723 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002724
2725 # Access superclass interface members from subclass, mix variable order.
2726 # Two interfaces, one on A, one on B; each has both kinds of variables
2727 lines =<< trim END
2728 vim9script
2729
2730 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002731 var mvar1: number
2732 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002733 endinterface
2734
2735 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002736 var mvar3: number
2737 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002738 endinterface
2739
2740 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002741 public static var svar1: number
2742 public static var svar2: number
2743 var mvar1: number
2744 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002745 def new()
2746 svar1 = 11
2747 svar2 = 12
2748 this.mvar1 = 111
2749 this.mvar2 = 112
2750 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002751 endclass
2752
2753 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002754 static var svar3: number
2755 static var svar4: number
2756 var mvar3: number
2757 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002758 def new()
2759 svar3 = 23
2760 svar4 = 24
2761 this.mvar1 = 121
2762 this.mvar2 = 122
2763 this.mvar3 = 123
2764 this.mvar4 = 124
2765 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002766 endclass
2767
2768 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002769 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002770 def new()
2771 svar5 = 1001
2772 this.mvar1 = 131
2773 this.mvar2 = 132
2774 this.mvar3 = 133
2775 this.mvar4 = 134
2776 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002777 endclass
2778
Ernie Raelcf138d42023-09-06 20:45:03 +02002779 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002780 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002781 enddef
2782
Ernie Raelcf138d42023-09-06 20:45:03 +02002783 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002784 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002785 enddef
2786
Ernie Raelcf138d42023-09-06 20:45:03 +02002787 var oa = A.new()
2788 var ob = B.new()
2789 var oc = C.new()
2790
Ernie Raelcf138d42023-09-06 20:45:03 +02002791 assert_equal([[111, 112]], [F2(oa)])
2792 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2793 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002794 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002795 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002796
2797 # Using two interface names without a space after the ","
2798 lines =<< trim END
2799 vim9script
2800 interface A
2801 endinterface
2802 interface B
2803 endinterface
2804 class C implements A,B
2805 endclass
2806 END
2807 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2808
2809 # No interface name after a comma
2810 lines =<< trim END
2811 vim9script
2812 interface A
2813 endinterface
2814 class B implements A,
2815 endclass
2816 END
2817 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2818
2819 # No interface name after implements
2820 lines =<< trim END
2821 vim9script
2822 class A implements
2823 endclass
2824 END
2825 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002826enddef
2827
Bram Moolenaard0200c82023-01-28 15:19:40 +00002828def Test_call_interface_method()
2829 var lines =<< trim END
2830 vim9script
2831 interface Base
2832 def Enter(): void
2833 endinterface
2834
2835 class Child implements Base
2836 def Enter(): void
2837 g:result ..= 'child'
2838 enddef
2839 endclass
2840
2841 def F(obj: Base)
2842 obj.Enter()
2843 enddef
2844
2845 g:result = ''
2846 F(Child.new())
2847 assert_equal('child', g:result)
2848 unlet g:result
2849 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002850 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002851
2852 lines =<< trim END
2853 vim9script
2854 class Base
2855 def Enter(): void
2856 g:result ..= 'base'
2857 enddef
2858 endclass
2859
2860 class Child extends Base
2861 def Enter(): void
2862 g:result ..= 'child'
2863 enddef
2864 endclass
2865
2866 def F(obj: Base)
2867 obj.Enter()
2868 enddef
2869
2870 g:result = ''
2871 F(Child.new())
2872 assert_equal('child', g:result)
2873 unlet g:result
2874 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002875 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002876
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002877 # method of interface returns a value
2878 lines =<< trim END
2879 vim9script
2880 interface Base
2881 def Enter(): string
2882 endinterface
2883
2884 class Child implements Base
2885 def Enter(): string
2886 g:result ..= 'child'
2887 return "/resource"
2888 enddef
2889 endclass
2890
2891 def F(obj: Base)
2892 var r = obj.Enter()
2893 g:result ..= r
2894 enddef
2895
2896 g:result = ''
2897 F(Child.new())
2898 assert_equal('child/resource', g:result)
2899 unlet g:result
2900 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002901 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002902
2903 lines =<< trim END
2904 vim9script
2905 class Base
2906 def Enter(): string
2907 return null_string
2908 enddef
2909 endclass
2910
2911 class Child extends Base
2912 def Enter(): string
2913 g:result ..= 'child'
2914 return "/resource"
2915 enddef
2916 endclass
2917
2918 def F(obj: Base)
2919 var r = obj.Enter()
2920 g:result ..= r
2921 enddef
2922
2923 g:result = ''
2924 F(Child.new())
2925 assert_equal('child/resource', g:result)
2926 unlet g:result
2927 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002928 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002929
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002930 # No class that implements the interface.
2931 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002932 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002933
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002934 interface IWithEE
2935 def Enter(): any
2936 def Exit(): void
2937 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002938
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002939 def With1(ee: IWithEE, F: func)
2940 var r = ee.Enter()
2941 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002942
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002943 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002944 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002945 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002946enddef
2947
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002948def Test_class_used_as_type()
2949 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002950 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002951
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002952 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002953 var x = 0
2954 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002955 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002956
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002957 var p: Point
2958 p = Point.new(2, 33)
2959 assert_equal(2, p.x)
2960 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002961 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002962 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002963
2964 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002965 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002966
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002967 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002968 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002969 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002970
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002971 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002972 var x = 0
2973 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002974 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002975
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002976 var p: Point
2977 p = Point.new(2, 33)
2978 var hx = p
2979 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002980 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002981 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002982
2983 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002984 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002985
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002986 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002987 var x = 0
2988 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002989 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002990
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002991 var p: Point
2992 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002993 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002994 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002995enddef
2996
Bram Moolenaar83677162023-01-08 19:54:10 +00002997def Test_class_extends()
2998 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002999 vim9script
3000 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003001 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003002 def GetOne(): number
3003 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00003004 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003005 endclass
3006 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003007 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003008 def GetTotal(): number
3009 return this.one + this.two
3010 enddef
3011 endclass
3012 var o = Child.new()
3013 assert_equal(1, o.one)
3014 assert_equal(2, o.two)
3015 assert_equal(1, o.GetOne())
3016 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00003017 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003018 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00003019
3020 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003021 vim9script
3022 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003023 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003024 endclass
3025 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003026 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003027 endclass
3028 var o = Child.new(3, 44)
3029 assert_equal(3, o.one)
3030 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00003031 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003032 v9.CheckSourceSuccess(lines)
3033
3034 lines =<< trim END
3035 vim9script
3036 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003037 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003038 endclass
3039 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003040 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003041 endclass
3042 END
3043 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
3044
3045 lines =<< trim END
3046 vim9script
3047 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01003048 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003049 endclass
3050 END
3051 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
3052
3053 lines =<< trim END
3054 vim9script
3055 var SomeVar = 99
3056 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01003057 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003058 endclass
3059 END
3060 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
3061
3062 lines =<< trim END
3063 vim9script
3064 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003065 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003066 def ToString(): string
3067 return this.name
3068 enddef
3069 endclass
3070
3071 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003072 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003073 def ToString(): string
3074 return super.ToString() .. ': ' .. this.age
3075 enddef
3076 endclass
3077
3078 var o = Child.new('John', 42)
3079 assert_equal('John: 42', o.ToString())
3080 END
3081 v9.CheckSourceSuccess(lines)
3082
3083 lines =<< trim END
3084 vim9script
3085 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003086 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003087 def ToString(): number
3088 return this.age
3089 enddef
3090 def ToString(): string
3091 return this.age
3092 enddef
3093 endclass
3094 END
3095 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
3096
3097 lines =<< trim END
3098 vim9script
3099 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003100 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003101 def ToString(): string
3102 return super .ToString() .. ': ' .. this.age
3103 enddef
3104 endclass
3105 var o = Child.new(42)
3106 echo o.ToString()
3107 END
3108 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
3109
3110 lines =<< trim END
3111 vim9script
3112 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003113 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003114 def ToString(): string
3115 return this.name
3116 enddef
3117 endclass
3118
3119 var age = 42
3120 def ToString(): string
3121 return super.ToString() .. ': ' .. age
3122 enddef
3123 echo ToString()
3124 END
3125 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
3126
3127 lines =<< trim END
3128 vim9script
3129 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003130 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003131 def ToString(): string
3132 return super.ToString() .. ': ' .. this.age
3133 enddef
3134 endclass
3135 var o = Child.new(42)
3136 echo o.ToString()
3137 END
3138 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
3139
3140 lines =<< trim END
3141 vim9script
3142 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003143 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003144 static def ToString(): string
3145 return 'Base class'
3146 enddef
3147 endclass
3148
3149 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003150 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003151 def ToString(): string
3152 return Base.ToString() .. ': ' .. this.age
3153 enddef
3154 endclass
3155
3156 var o = Child.new('John', 42)
3157 assert_equal('Base class: 42', o.ToString())
3158 END
3159 v9.CheckSourceSuccess(lines)
3160
3161 lines =<< trim END
3162 vim9script
3163 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003164 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003165 def new(init: number)
3166 this.value = number + 1
3167 enddef
3168 endclass
3169 class Child extends Base
3170 def new()
3171 this.new(3)
3172 enddef
3173 endclass
3174 var c = Child.new()
3175 END
3176 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003177
3178 # base class with more than one object member
3179 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003180 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003181
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003182 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003183 var success: bool
3184 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003185 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003186
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003187 class Success extends Result
3188 def new(this.value = v:none)
3189 this.success = true
3190 enddef
3191 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003192
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003193 var v = Success.new('asdf')
3194 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003195 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003196 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003197
3198 # class name after "extends" doesn't end in a space or NUL character
3199 lines =<< trim END
3200 vim9script
3201 class A
3202 endclass
3203 class B extends A"
3204 endclass
3205 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003206 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003207enddef
3208
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003209def Test_using_base_class()
3210 var lines =<< trim END
3211 vim9script
3212
3213 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003214 def Enter(): any
3215 return null
3216 enddef
3217 def Exit(resource: any): void
3218 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003219 endclass
3220
3221 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003222 def Enter(): any
3223 return 42
3224 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003225
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003226 def Exit(resource: number): void
3227 g:result ..= '/exit'
3228 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003229 endclass
3230
3231 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003232 var r = ee.Enter()
3233 try
3234 g:result ..= r
3235 finally
3236 g:result ..= '/finally'
3237 ee.Exit(r)
3238 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003239 enddef
3240
3241 g:result = ''
3242 With(ChildEE.new())
3243 assert_equal('42/finally/exit', g:result)
3244 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003245 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003246 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003247
3248 # Using super, Child invokes Base method which has optional arg. #12471
3249 lines =<< trim END
3250 vim9script
3251
3252 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003253 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003254 def Method(arg = 0)
3255 this.success = true
3256 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003257 endclass
3258
3259 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003260 def new()
3261 super.Method()
3262 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003263 endclass
3264
3265 var obj = Child.new()
3266 assert_equal(true, obj.success)
3267 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003268 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003269enddef
3270
Ernie Rael58c95792024-08-13 23:27:22 +02003271def Test_super_dispatch()
3272 # See #15448 and #15463
3273 var lines =<< trim END
3274 vim9script
3275
3276 class A
3277 def String(): string
3278 return 'A'
3279 enddef
3280 endclass
3281
3282 class B extends A
3283 def String(): string
3284 return super.String()
3285 enddef
3286 endclass
3287
3288 class C extends B
3289 endclass
3290
3291 assert_equal('A', C.new().String())
3292 END
3293 v9.CheckSourceSuccess(lines)
3294
3295 lines =<< trim END
3296 vim9script
3297
3298 class A
3299 def F(): string
3300 return 'AA'
3301 enddef
3302 endclass
3303
3304 class B extends A
3305 def F(): string
3306 return 'BB'
3307 enddef
3308 def S(): string
3309 return super.F()
3310 enddef
3311 def S0(): string
3312 return this.S()
3313 enddef
3314 endclass
3315
3316 class C extends B
3317 def F(): string
3318 return 'CC'
3319 enddef
3320 def ToB(): string
3321 return super.F()
3322 enddef
3323 endclass
3324
3325 assert_equal('AA', B.new().S())
3326 assert_equal('AA', C.new().S())
3327 assert_equal('AA', B.new().S0())
3328 assert_equal('AA', C.new().S0())
3329
3330 assert_equal('BB', C.new().ToB())
3331
3332 assert_equal('CC', C.new().F())
3333 assert_equal('BB', B.new().F())
3334 assert_equal('AA', A.new().F())
3335 END
3336 v9.CheckSourceSuccess(lines)
3337
3338 lines =<< trim END
3339 vim9script
3340
3341 var call_chain: list<string>
3342
3343 abstract class A
3344 abstract def _G(): string
3345
3346 def F(): string
3347 call_chain->add('A.F()')
3348 return this._G()
3349 enddef
3350 def _H(): string
3351 call_chain->add('A._H()')
3352 return this.F()
3353 enddef
3354 endclass
3355
3356 class B extends A
3357 def _G(): string
3358 call_chain->add('B.G()')
3359 return 'BBB'
3360 enddef
3361 def SF(): string
3362 call_chain->add('B.SF()')
3363 return super._H()
3364 enddef
3365 endclass
3366
3367 class C extends B
3368 endclass
3369
3370 class D extends C
3371 def SF(): string
3372 call_chain->add('D.SF()')
3373 return super.SF()
3374 enddef
3375 endclass
3376
3377 class E extends D
3378 def SF(): string
3379 call_chain->add('E.SF()')
3380 return super.SF()
3381 enddef
3382 endclass
3383
3384 class F extends E
3385 def _G(): string
3386 call_chain->add('F._G()')
3387 return 'FFF'
3388 enddef
3389 endclass
3390
3391 # E.new() -> A.F() -> B._G()
3392 call_chain = []
3393 var o1 = E.new()
3394 assert_equal('BBB', o1.F())
3395 assert_equal(['A.F()', 'B.G()'], call_chain)
3396
3397 # F.new() -> E.SF() -> D.SF() -> B.SF() -> A._H() -> A.F() -> F._G()
3398 call_chain = []
3399 var o2 = F.new()
3400 assert_equal('FFF', o2.SF())
3401 assert_equal(['E.SF()', 'D.SF()', 'B.SF()', 'A._H()', 'A.F()', 'F._G()'], call_chain)
3402 END
3403 v9.CheckSourceSuccess(lines)
3404enddef
3405
Bram Moolenaara86655a2023-01-12 17:06:27 +00003406def Test_class_import()
3407 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003408 vim9script
3409 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003410 var kind: string
3411 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003412 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003413 END
3414 writefile(lines, 'Xanimal.vim', 'D')
3415
3416 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003417 vim9script
3418 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003419
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003420 var a: animal.Animal
3421 a = animal.Animal.new('fish', 'Eric')
3422 assert_equal('fish', a.kind)
3423 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003424
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003425 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3426 assert_equal('cat', b.kind)
3427 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003428 END
3429 v9.CheckScriptSuccess(lines)
3430enddef
3431
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003432" Test for importing a class into a legacy script and calling the class method
3433def Test_class_method_from_legacy_script()
3434 var lines =<< trim END
3435 vim9script
3436 export class A
3437 static var name: string = 'a'
3438 static def SetName(n: string)
3439 name = n
3440 enddef
3441 endclass
3442 END
3443 writefile(lines, 'Xvim9export.vim', 'D')
3444
3445 lines =<< trim END
3446 import './Xvim9export.vim' as vim9
3447
3448 call s:vim9.A.SetName('b')
3449 call assert_equal('b', s:vim9.A.name)
3450 END
3451 v9.CheckScriptSuccess(lines)
3452enddef
3453
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003454" Test for implementing an imported interface
3455def Test_implement_imported_interface()
3456 var lines =<< trim END
3457 vim9script
3458 export interface Imp_Intf1
3459 def Fn1(): number
3460 endinterface
3461 export interface Imp_Intf2
3462 def Fn2(): number
3463 endinterface
3464 END
3465 writefile(lines, 'Ximportinterface.vim', 'D')
3466
3467 lines =<< trim END
3468 vim9script
3469 import './Ximportinterface.vim' as Xintf
3470
3471 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3472 def Fn1(): number
3473 return 10
3474 enddef
3475 def Fn2(): number
3476 return 20
3477 enddef
3478 endclass
3479 var a = A.new()
3480 assert_equal(10, a.Fn1())
3481 assert_equal(20, a.Fn2())
3482 END
3483 v9.CheckScriptSuccess(lines)
3484enddef
3485
3486" Test for extending an imported class
3487def Test_extend_imported_class()
3488 var lines =<< trim END
3489 vim9script
3490 export class Imp_C1
3491 def Fn1(): number
3492 return 5
3493 enddef
3494 endclass
3495 END
3496 writefile(lines, 'Xextendimportclass.vim', 'D')
3497
3498 lines =<< trim END
3499 vim9script
3500 import './Xextendimportclass.vim' as XClass
3501
3502 class A extends XClass.Imp_C1
3503 endclass
3504 var a = A.new()
3505 assert_equal(5, a.Fn1())
3506 END
3507 v9.CheckScriptSuccess(lines)
3508enddef
3509
Hirohito Higashi57f01192025-01-14 17:21:42 +01003510" Test for multi level import
3511def Test_multi_level_import_normal()
3512 var lines =<< trim END
3513 vim9script
3514 export class Property
3515 public var value: string
3516 endclass
3517 END
3518 writefile(lines, 'aa.vim', 'D')
3519
3520 lines =<< trim END
3521 vim9script
3522 import './aa.vim'
3523 export class View
3524 var content = aa.Property.new('')
3525 endclass
3526 END
3527 writefile(lines, 'bb.vim', 'D')
3528
3529 lines =<< trim END
3530 vim9script
3531 import './bb.vim'
3532 class MyView extends bb.View
3533 def new(value: string)
3534 this.content.value = value
3535 enddef
3536 endclass
3537 var myView = MyView.new('This should be ok')
3538 END
3539 v9.CheckScriptSuccess(lines)
3540enddef
3541
3542" Test for multi level import
3543def Test_multi_level_import_nest_over()
3544 var lines =<< trim END
3545 vim9script
3546 import './xbb.vim'
3547 export class Property
3548 public var value: string
3549 endclass
3550 END
3551 writefile(lines, 'xaa.vim', 'D')
3552
3553 lines =<< trim END
3554 vim9script
3555 import './xaa.vim'
3556 export class View
3557 var content = aa.Property.new('')
3558 endclass
3559 END
3560 writefile(lines, 'xbb.vim', 'D')
3561
3562 lines =<< trim END
3563 vim9script
3564 set maxfuncdepth=100
3565 import './xbb.vim'
3566 class MyView extends bb.View
3567 def new(value: string)
3568 this.content.value = value
3569 enddef
3570 endclass
3571 var myView = MyView.new('This should be ok')
3572 END
3573 v9.CheckSourceFailure(lines, 'E1045: Import nesting too deep', 3)
3574enddef
3575
3576def Test_abtstract_class()
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003577 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003578 vim9script
3579 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003580 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003581 endclass
3582 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003583 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003584 endclass
3585 var p: Base = Person.new('Peter', 42)
3586 assert_equal('Peter', p.name)
3587 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003588 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003589 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003590
3591 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003592 vim9script
3593 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003594 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003595 endclass
3596 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003597 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003598 endclass
3599 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003600 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003601 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003602
3603 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003604 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003605 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003606 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003607 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003608 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003609
h-eastaa979c72025-01-03 10:19:45 +01003610 # Test for "abstract" cannot be abbreviated
3611 lines =<< trim END
3612 vim9script
3613 abs class A
3614 endclass
3615 END
3616 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs class A', 2)
3617
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003618 # Additional commands after "abstract class"
3619 lines =<< trim END
3620 vim9script
3621 abstract class Something | var x = []
3622 endclass
3623 END
3624 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3625
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003626 # Abstract class cannot have a "new" function
3627 lines =<< trim END
3628 vim9script
3629 abstract class Base
3630 def new()
3631 enddef
3632 endclass
3633 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003634 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003635
3636 # extending an abstract class with class methods and variables
3637 lines =<< trim END
3638 vim9script
3639 abstract class A
3640 static var s: string = 'vim'
3641 static def Fn(): list<number>
3642 return [10]
3643 enddef
3644 endclass
3645 class B extends A
3646 endclass
3647 var b = B.new()
3648 assert_equal('vim', A.s)
3649 assert_equal([10], A.Fn())
3650 END
3651 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003652enddef
3653
Bram Moolenaar486fc252023-01-18 14:51:07 +00003654def Test_closure_in_class()
3655 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003656 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003657
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003658 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003659 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003660
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003661 def new()
3662 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3663 enddef
3664 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003665
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003666 Foo.new()
3667 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003668 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003669 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003670enddef
3671
Ernie Rael9ed53752023-12-11 17:40:46 +01003672def Test_construct_object_from_legacy()
3673 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003674 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003675 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003676
Ernie Rael9ed53752023-12-11 17:40:46 +01003677 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003678
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003679 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003680 def new(arg: string)
3681 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003682 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003683 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003684
Ernie Rael9ed53752023-12-11 17:40:46 +01003685 export def CreateA(...args: list<any>): A
3686 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003687 enddef
3688
Ernie Rael9ed53752023-12-11 17:40:46 +01003689 g:P = CreateA
3690 legacy call g:P('some_arg')
3691 assert_equal(true, newCalled)
3692 unlet g:P
3693 END
3694 v9.CheckSourceSuccess(lines)
3695
3696 lines =<< trim END
3697 vim9script
3698
3699 var newCalled = false
3700
3701 class A
3702 static def CreateA(options = {}): any
3703 return A.new()
3704 enddef
3705 def new()
3706 newCalled = true
3707 enddef
3708 endclass
3709
3710 g:P = A.CreateA
3711 legacy call g:P()
3712 assert_equal(true, newCalled)
3713 unlet g:P
3714 END
3715 v9.CheckSourceSuccess(lines)
3716
3717 # This also tests invoking "new()" with "call"
3718 lines =<< trim END
3719 vim9script
3720
3721 var createdObject: any
3722
3723 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003724 var val1: number
3725 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003726 static def CreateA(...args: list<any>): any
3727 createdObject = call(A.new, args)
3728 return createdObject
3729 enddef
3730 endclass
3731
3732 g:P = A.CreateA
3733 legacy call g:P(3, 5)
3734 assert_equal(3, createdObject.val1)
3735 assert_equal(5, createdObject.val2)
3736 legacy call g:P()
3737 assert_equal(0, createdObject.val1)
3738 assert_equal(0, createdObject.val2)
3739 legacy call g:P(7)
3740 assert_equal(7, createdObject.val1)
3741 assert_equal(0, createdObject.val2)
3742 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003743 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003744 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003745enddef
3746
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003747def Test_defer_with_object()
3748 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003749 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003750
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003751 class CWithEE
3752 def Enter()
3753 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003754 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003755 def Exit()
3756 g:result ..= "exited"
3757 enddef
3758 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003760 def With(ee: CWithEE, F: func)
3761 ee.Enter()
3762 defer ee.Exit()
3763 F()
3764 enddef
3765
3766 g:result = ''
3767 var obj = CWithEE.new()
3768 obj->With(() => {
3769 g:result ..= "called/"
3770 })
3771 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003772 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003773 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003774 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003775
3776 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003777 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003778
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003779 class BaseWithEE
3780 def Enter()
3781 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003782 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003783 def Exit()
3784 g:result ..= "exited-base"
3785 enddef
3786 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003787
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003788 class CWithEE extends BaseWithEE
3789 def Enter()
3790 g:result ..= "entered-child/"
3791 enddef
3792 def Exit()
3793 g:result ..= "exited-child"
3794 enddef
3795 endclass
3796
3797 def With(ee: BaseWithEE, F: func)
3798 ee.Enter()
3799 defer ee.Exit()
3800 F()
3801 enddef
3802
3803 g:result = ''
3804 var obj = CWithEE.new()
3805 obj->With(() => {
3806 g:result ..= "called/"
3807 })
3808 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003809 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003810 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003811 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003812enddef
3813
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003814" The following test used to crash Vim (Github issue #12676)
3815def Test_extends_method_crashes_vim()
3816 var lines =<< trim END
3817 vim9script
3818
3819 class Observer
3820 endclass
3821
3822 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003823 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003824
3825 def Set(v: any)
3826 if v != this.value
3827 this.value = v
3828 endif
3829 enddef
3830
3831 def Register(observer: Observer)
3832 enddef
3833 endclass
3834
3835 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003836 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003837 endclass
3838
3839 def Observe(obj: Property, who: Observer)
3840 obj.Register(who)
3841 enddef
3842
3843 var p = Bool.new(false)
3844 var myObserver = Observer.new()
3845
3846 Observe(p, myObserver)
3847
3848 p.Set(true)
3849 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003850 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003851enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003852
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003853" Test for calling a method in a class that is extended
3854def Test_call_method_in_extended_class()
3855 var lines =<< trim END
3856 vim9script
3857
3858 var prop_init_called = false
3859 var prop_register_called = false
3860
3861 class Property
3862 def Init()
3863 prop_init_called = true
3864 enddef
3865
3866 def Register()
3867 prop_register_called = true
3868 enddef
3869 endclass
3870
3871 class Bool extends Property
3872 endclass
3873
3874 def Observe(obj: Property)
3875 obj.Register()
3876 enddef
3877
3878 var p = Property.new()
3879 Observe(p)
3880
3881 p.Init()
3882 assert_true(prop_init_called)
3883 assert_true(prop_register_called)
3884 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003885 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003886enddef
3887
LemonBoyafe04662023-08-23 21:08:11 +02003888def Test_instanceof()
3889 var lines =<< trim END
3890 vim9script
3891
3892 class Base1
3893 endclass
3894
3895 class Base2 extends Base1
3896 endclass
3897
3898 interface Intf1
3899 endinterface
3900
3901 class Mix1 implements Intf1
3902 endclass
3903
3904 class Base3 extends Mix1
3905 endclass
3906
Ernie Rael2025af12023-12-12 16:58:00 +01003907 type AliasBase1 = Base1
3908 type AliasBase2 = Base2
3909 type AliasIntf1 = Intf1
3910 type AliasMix1 = Mix1
3911
LemonBoyafe04662023-08-23 21:08:11 +02003912 var b1 = Base1.new()
3913 var b2 = Base2.new()
3914 var b3 = Base3.new()
3915
3916 assert_true(instanceof(b1, Base1))
3917 assert_true(instanceof(b2, Base1))
3918 assert_false(instanceof(b1, Base2))
3919 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003920 assert_true(instanceof(b3, Base1, Base2, Intf1))
3921
3922 assert_true(instanceof(b1, AliasBase1))
3923 assert_true(instanceof(b2, AliasBase1))
3924 assert_false(instanceof(b1, AliasBase2))
3925 assert_true(instanceof(b3, AliasMix1))
3926 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003927
3928 def Foo()
3929 var a1 = Base1.new()
3930 var a2 = Base2.new()
3931 var a3 = Base3.new()
3932
3933 assert_true(instanceof(a1, Base1))
3934 assert_true(instanceof(a2, Base1))
3935 assert_false(instanceof(a1, Base2))
3936 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003937 assert_true(instanceof(a3, Base1, Base2, Intf1))
3938
3939 assert_true(instanceof(a1, AliasBase1))
3940 assert_true(instanceof(a2, AliasBase1))
3941 assert_false(instanceof(a1, AliasBase2))
3942 assert_true(instanceof(a3, AliasMix1))
3943 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003944 enddef
3945 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003946
3947 var o_null: Base1
3948 assert_false(instanceof(o_null, Base1))
3949
LemonBoyafe04662023-08-23 21:08:11 +02003950 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003951 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003952
3953 lines =<< trim END
3954 vim9script
3955
3956 class Base1
3957 endclass
3958 instanceof(Base1.new())
3959 END
3960 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3961
3962 lines =<< trim END
3963 vim9script
3964
3965 class Base1
3966 endclass
3967 def F()
3968 instanceof(Base1.new())
3969 enddef
3970 F()
3971 END
3972 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3973
3974 lines =<< trim END
3975 vim9script
3976
3977 class Base1
3978 endclass
3979
3980 class Base2
3981 endclass
3982
3983 var o = Base2.new()
3984 instanceof(o, Base1, Base2, 3)
3985 END
3986 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3987
3988 lines =<< trim END
3989 vim9script
3990
3991 class Base1
3992 endclass
3993
3994 class Base2
3995 endclass
3996
3997 def F()
3998 var o = Base2.new()
3999 instanceof(o, Base1, Base2, 3)
4000 enddef
4001 F()
4002 END
4003 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02004004enddef
4005
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02004006" Test for calling a method in the parent class that is extended partially.
4007" This used to fail with the 'E118: Too many arguments for function: Text' error
4008" message (Github issue #12524).
4009def Test_call_method_in_parent_class()
4010 var lines =<< trim END
4011 vim9script
4012
4013 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01004014 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02004015
4016 def SetY(lnum: number)
4017 this._lnum = lnum
4018 enddef
4019
4020 def Text(): string
4021 return ''
4022 enddef
4023 endclass
4024
4025 class Foo extends Widget
4026 def Text(): string
4027 return '<Foo>'
4028 enddef
4029 endclass
4030
4031 def Stack(w1: Widget, w2: Widget): list<Widget>
4032 w1.SetY(1)
4033 w2.SetY(2)
4034 return [w1, w2]
4035 enddef
4036
4037 var foo1 = Foo.new()
4038 var foo2 = Foo.new()
4039 var l = Stack(foo1, foo2)
4040 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004041 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02004042enddef
4043
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004044" Test for calling methods from three levels of classes
4045def Test_multi_level_method_call()
4046 var lines =<< trim END
4047 vim9script
4048
4049 var A_func1: number = 0
4050 var A_func2: number = 0
4051 var A_func3: number = 0
4052 var B_func2: number = 0
4053 var B_func3: number = 0
4054 var C_func3: number = 0
4055
4056 class A
4057 def Func1()
4058 A_func1 += 1
4059 enddef
4060
4061 def Func2()
4062 A_func2 += 1
4063 enddef
4064
4065 def Func3()
4066 A_func3 += 1
4067 enddef
4068 endclass
4069
4070 class B extends A
4071 def Func2()
4072 B_func2 += 1
4073 enddef
4074
4075 def Func3()
4076 B_func3 += 1
4077 enddef
4078 endclass
4079
4080 class C extends B
4081 def Func3()
4082 C_func3 += 1
4083 enddef
4084 endclass
4085
4086 def A_CallFuncs(a: A)
4087 a.Func1()
4088 a.Func2()
4089 a.Func3()
4090 enddef
4091
4092 def B_CallFuncs(b: B)
4093 b.Func1()
4094 b.Func2()
4095 b.Func3()
4096 enddef
4097
4098 def C_CallFuncs(c: C)
4099 c.Func1()
4100 c.Func2()
4101 c.Func3()
4102 enddef
4103
4104 var cobj = C.new()
4105 A_CallFuncs(cobj)
4106 B_CallFuncs(cobj)
4107 C_CallFuncs(cobj)
4108 assert_equal(3, A_func1)
4109 assert_equal(0, A_func2)
4110 assert_equal(0, A_func3)
4111 assert_equal(3, B_func2)
4112 assert_equal(0, B_func3)
4113 assert_equal(3, C_func3)
4114 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004115 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004116enddef
4117
4118" Test for using members from three levels of classes
4119def Test_multi_level_member_access()
4120 var lines =<< trim END
4121 vim9script
4122
4123 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01004124 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004125 endclass
4126
4127 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01004128 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004129 endclass
4130
4131 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01004132 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004133 endclass
4134
4135 def A_members(a: A)
4136 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004137 enddef
4138
4139 def B_members(b: B)
4140 b.val1 += 1
4141 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004142 enddef
4143
4144 def C_members(c: C)
4145 c.val1 += 1
4146 c.val2 += 1
4147 c.val3 += 1
4148 enddef
4149
4150 var cobj = C.new()
4151 A_members(cobj)
4152 B_members(cobj)
4153 C_members(cobj)
4154 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004155 assert_equal(2, cobj.val2)
4156 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004157 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004158 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004159enddef
4160
LemonBoy0ffc17a2023-08-20 18:09:11 +02004161" Test expansion of <stack> with class methods.
4162def Test_stack_expansion_with_methods()
4163 var lines =<< trim END
4164 vim9script
4165
4166 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004167 def M1()
4168 F0()
4169 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02004170 endclass
4171
4172 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02004173 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02004174 enddef
4175
4176 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004177 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02004178 enddef
4179
4180 F()
4181 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004182 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02004183enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004184
4185" Test the return type of the new() constructor
4186def Test_new_return_type()
4187 # new() uses the default return type and there is no return statement
4188 var lines =<< trim END
4189 vim9script
4190
4191 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004192 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004193
4194 def new(this._bufnr)
4195 if !bufexists(this._bufnr)
4196 this._bufnr = -1
4197 endif
4198 enddef
4199 endclass
4200
4201 var c = C.new(12345)
4202 assert_equal('object<C>', typename(c))
4203
4204 var v1: C
4205 v1 = C.new(12345)
4206 assert_equal('object<C>', typename(v1))
4207
4208 def F()
4209 var v2: C
4210 v2 = C.new(12345)
4211 assert_equal('object<C>', typename(v2))
4212 enddef
4213 F()
4214 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004215 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004216
4217 # new() uses the default return type and an empty 'return' statement
4218 lines =<< trim END
4219 vim9script
4220
4221 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004222 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004223
4224 def new(this._bufnr)
4225 if !bufexists(this._bufnr)
4226 this._bufnr = -1
4227 return
4228 endif
4229 enddef
4230 endclass
4231
4232 var c = C.new(12345)
4233 assert_equal('object<C>', typename(c))
4234
4235 var v1: C
4236 v1 = C.new(12345)
4237 assert_equal('object<C>', typename(v1))
4238
4239 def F()
4240 var v2: C
4241 v2 = C.new(12345)
4242 assert_equal('object<C>', typename(v2))
4243 enddef
4244 F()
4245 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004246 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004247
4248 # new() uses "any" return type and returns "this"
4249 lines =<< trim END
4250 vim9script
4251
4252 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004253 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004254
4255 def new(this._bufnr): any
4256 if !bufexists(this._bufnr)
4257 this._bufnr = -1
4258 return this
4259 endif
4260 enddef
4261 endclass
4262 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004263 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004264
4265 # new() uses 'Dict' return type and returns a Dict
4266 lines =<< trim END
4267 vim9script
4268
4269 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004270 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004271
4272 def new(): dict<any>
4273 this._state = {}
4274 return this._state
4275 enddef
4276 endclass
4277
4278 var c = C.new()
4279 assert_equal('object<C>', typename(c))
4280 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004281 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004282enddef
4283
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004284" Test for checking a member initialization type at run time.
4285def Test_runtime_type_check_for_member_init()
4286 var lines =<< trim END
4287 vim9script
4288
4289 var retnum: bool = false
4290
4291 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004292 retnum = !retnum
4293 if retnum
4294 return 1
4295 else
4296 return "hello"
4297 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004298 enddef
4299
4300 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004301 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004302 endclass
4303
4304 var c1 = C.new()
4305 var c2 = C.new()
4306 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004307 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004308enddef
4309
4310" Test for locking a variable referring to an object and reassigning to another
4311" object.
Ernie Raelee865f32023-09-29 19:53:55 +02004312def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004313 var lines =<< trim END
4314 vim9script
4315
4316 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004317 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004318 def new(this.val)
4319 enddef
4320 endclass
4321
4322 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
4323 lockvar 2 some_dict
4324
4325 var current: C
4326 current = some_dict['c']
4327 assert_equal(3, current.val)
4328 current = some_dict['b']
4329 assert_equal(2, current.val)
4330
4331 def F()
4332 current = some_dict['c']
4333 enddef
4334
4335 def G()
4336 current = some_dict['b']
4337 enddef
4338
4339 F()
4340 assert_equal(3, current.val)
4341 G()
4342 assert_equal(2, current.val)
4343 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004344 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004345enddef
4346
Ernie Raelee865f32023-09-29 19:53:55 +02004347" Test trying to lock an object variable from various places
4348def Test_lockvar_object_variable()
4349 # An object variable lockvar has several cases:
4350 # object method, scriptlevel, scriplevel from :def, :def arg
4351 # method arg, static method arg.
4352 # Also different depths
4353
Ernie Raelee865f32023-09-29 19:53:55 +02004354 #
4355 # lockvar of read-only object variable
4356 #
4357
4358 # read-only lockvar from object method
4359 var lines =<< trim END
4360 vim9script
4361
4362 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004363 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004364 def Lock()
4365 lockvar this.val1
4366 enddef
4367 endclass
4368 var o = C.new(3)
4369 o.Lock()
4370 END
Ernie Rael64885642023-10-04 20:16:22 +02004371 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004372
4373 # read-only lockvar from scriptlevel
4374 lines =<< trim END
4375 vim9script
4376
4377 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004378 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004379 endclass
4380 var o = C.new(3)
4381 lockvar o.val2
4382 END
4383 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4384
4385 # read-only lockvar of scriptlevel variable from def
4386 lines =<< trim END
4387 vim9script
4388
4389 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004390 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004391 endclass
4392 var o = C.new(3)
4393 def Lock()
4394 lockvar o.val3
4395 enddef
4396 Lock()
4397 END
4398 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4399
4400 # read-only lockvar of def argument variable
4401 lines =<< trim END
4402 vim9script
4403
4404 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004405 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004406 endclass
4407 def Lock(o: C)
4408 lockvar o.val4
4409 enddef
4410 Lock(C.new(3))
4411 END
4412 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4413
Ernie Raelee865f32023-09-29 19:53:55 +02004414 # read-only lockvar from object method arg
4415 lines =<< trim END
4416 vim9script
4417
4418 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004419 var val5: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004420 def Lock(c: C)
4421 lockvar c.val5
Ernie Raelee865f32023-09-29 19:53:55 +02004422 enddef
4423 endclass
4424 var o = C.new(3)
4425 o.Lock(C.new(5))
4426 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004427 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004428
4429 # read-only lockvar from class method arg
4430 lines =<< trim END
4431 vim9script
4432
4433 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004434 var val6: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004435 static def Lock(c: C)
4436 lockvar c.val6
Ernie Raelee865f32023-09-29 19:53:55 +02004437 enddef
4438 endclass
4439 var o = C.new(3)
4440 C.Lock(o)
4441 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004442 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004443
4444 #
4445 # lockvar of public object variable
4446 #
4447
4448 # lockvar from object method
4449 lines =<< trim END
4450 vim9script
4451
4452 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004453 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004454 def Lock()
4455 lockvar this.val1
4456 enddef
4457 endclass
4458 var o = C.new(3)
4459 o.Lock()
4460 END
4461 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4462
4463 # lockvar from scriptlevel
4464 lines =<< trim END
4465 vim9script
4466
4467 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004468 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004469 endclass
4470 var o = C.new(3)
4471 lockvar o.val2
4472 END
4473 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4474
4475 # lockvar of scriptlevel variable from def
4476 lines =<< trim END
4477 vim9script
4478
4479 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004480 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004481 endclass
4482 var o = C.new(3)
4483 def Lock()
4484 lockvar o.val3
4485 enddef
4486 Lock()
4487 END
4488 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4489
4490 # lockvar of def argument variable
4491 lines =<< trim END
4492 vim9script
4493
4494 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004495 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004496 endclass
4497 def Lock(o: C)
4498 lockvar o.val4
4499 enddef
4500 Lock(C.new(3))
4501 END
4502 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4503
4504 # lockvar from object method arg
4505 lines =<< trim END
4506 vim9script
4507
4508 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004509 public var val5: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004510 def Lock(c: C)
4511 lockvar c.val5
Ernie Raelee865f32023-09-29 19:53:55 +02004512 enddef
4513 endclass
4514 var o = C.new(3)
4515 o.Lock(C.new(5))
4516 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004517 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val5" in class "C"', 1)
Ernie Raelee865f32023-09-29 19:53:55 +02004518
4519 # lockvar from class method arg
4520 lines =<< trim END
4521 vim9script
4522
4523 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004524 public var val6: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004525 static def Lock(c: C)
4526 lockvar c.val6
Ernie Raelee865f32023-09-29 19:53:55 +02004527 enddef
4528 endclass
4529 var o = C.new(3)
4530 C.Lock(o)
4531 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004532 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val6" in class "C"', 1)
Ernie Raelee865f32023-09-29 19:53:55 +02004533enddef
4534
4535" Test trying to lock a class variable from various places
4536def Test_lockvar_class_variable()
4537
4538 # lockvar bare static from object method
4539 var lines =<< trim END
4540 vim9script
4541
4542 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004543 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004544 def Lock()
4545 lockvar sval1
4546 enddef
4547 endclass
4548 var o = C.new()
4549 o.Lock()
4550 END
4551 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4552
4553 # lockvar C.static from object method
4554 lines =<< trim END
4555 vim9script
4556
4557 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004558 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004559 def Lock()
4560 lockvar C.sval2
4561 enddef
4562 endclass
4563 var o = C.new()
4564 o.Lock()
4565 END
4566 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4567
4568 # lockvar bare static from class method
4569 lines =<< trim END
4570 vim9script
4571
4572 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004573 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004574 static def Lock()
4575 lockvar sval3
4576 enddef
4577 endclass
4578 C.Lock()
4579 END
4580 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4581
4582 # lockvar C.static from class method
4583 lines =<< trim END
4584 vim9script
4585
4586 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004587 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004588 static def Lock()
4589 lockvar C.sval4
4590 enddef
4591 endclass
4592 C.Lock()
4593 END
4594 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4595
4596 # lockvar C.static from script level
4597 lines =<< trim END
4598 vim9script
4599
4600 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004601 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004602 endclass
4603 lockvar C.sval5
4604 END
4605 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4606
4607 # lockvar o.static from script level
4608 lines =<< trim END
4609 vim9script
4610
4611 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004612 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004613 endclass
4614 var o = C.new()
4615 lockvar o.sval6
4616 END
4617 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4618enddef
4619
4620" Test locking an argument to :def
4621def Test_lockvar_argument()
4622 # Lockvar a function arg
4623 var lines =<< trim END
4624 vim9script
4625
4626 def Lock(val: any)
4627 lockvar val
4628 enddef
4629
4630 var d = {a: 1, b: 2}
4631 Lock(d)
4632
4633 d->extend({c: 3})
4634 END
4635 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4636
4637 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4638 # class member in "C". This tests lval_root_is_arg.
4639 lines =<< trim END
4640 vim9script
4641
4642 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004643 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004644 endclass
4645
4646 def Lock2(sval: any)
4647 lockvar sval
4648 enddef
4649
4650 var o = C.new()
4651 Lock2(o)
4652 END
4653 v9.CheckSourceSuccess(lines)
4654
4655 # Lock a class.
4656 lines =<< trim END
4657 vim9script
4658
4659 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004660 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004661 endclass
4662
4663 def Lock2(sval: any)
4664 lockvar sval
4665 enddef
4666
4667 Lock2(C)
4668 END
Ernie Raelb077b582023-12-14 20:11:44 +01004669 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004670
4671 # Lock an object.
4672 lines =<< trim END
4673 vim9script
4674
4675 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004676 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004677 endclass
4678
4679 def Lock2(sval: any)
4680 lockvar sval
4681 enddef
4682
4683 Lock2(C.new())
4684 END
4685 v9.CheckSourceSuccess(lines)
4686
4687 # In this case (unlike previous) "lockvar sval" is a class member.
4688 lines =<< trim END
4689 vim9script
4690
4691 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004692 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004693 def Lock2()
4694 lockvar sval
4695 enddef
4696 endclass
4697
4698
4699 var o = C.new()
4700 o.Lock2()
4701 END
4702 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4703enddef
4704
4705" Test that this can be locked without error
4706def Test_lockvar_this()
4707 # lockvar this
4708 var lines =<< trim END
4709 vim9script
4710 class C
4711 def TLock()
4712 lockvar this
4713 enddef
4714 endclass
4715 var o = C.new()
4716 o.TLock()
4717 END
4718 v9.CheckSourceSuccess(lines)
4719
4720 # lockvar four (four letter word, but not this)
4721 lines =<< trim END
4722 vim9script
4723 class C
4724 def TLock4()
4725 var four: number
4726 lockvar four
4727 enddef
4728 endclass
4729 var o = C.new()
4730 o.TLock4()
4731 END
4732 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4733
4734 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4735 lines =<< trim END
4736 vim9script
4737 class C
4738 def TLock5()
4739 var this5: number
4740 lockvar this5
4741 enddef
4742 endclass
4743 var o = C.new()
4744 o.TLock5()
4745 END
4746 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4747enddef
4748
4749" Test some general lockvar cases
4750def Test_lockvar_general()
4751 # lockvar an object and a class. It does nothing
4752 var lines =<< trim END
4753 vim9script
4754 class C
4755 endclass
4756 var o = C.new()
4757 lockvar o
4758 lockvar C
4759 END
4760 v9.CheckSourceSuccess(lines)
4761
4762 # Lock a list element that's nested in an object variable from a :def
4763 lines =<< trim END
4764 vim9script
4765
4766 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004767 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004768 endclass
4769 def Lock2(obj: any)
4770 lockvar obj.val[1]
4771 enddef
4772
4773 var o = C.new()
4774 Lock2(o)
4775 o.val[0] = [9]
4776 assert_equal([ [9], [2], [3] ], o.val)
4777 try
4778 o.val[1] = [999]
4779 call assert_false(true, 'assign should have failed')
4780 catch
4781 assert_exception('E741:')
4782 endtry
4783 o.val[2] = [8]
4784 assert_equal([ [9], [2], [8] ], o.val)
4785 END
4786 v9.CheckSourceSuccess(lines)
4787
4788 # Lock a list element that's nested in an object variable from scriptlevel
4789 lines =<< trim END
4790 vim9script
4791
4792 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004793 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004794 endclass
4795
4796 var o = C.new()
4797 lockvar o.val[1]
4798 o.val[0] = [9]
4799 assert_equal([ [9], [2], [3] ], o.val)
4800 try
4801 o.val[1] = [999]
4802 call assert_false(true, 'assign should have failed')
4803 catch
4804 assert_exception('E741:')
4805 endtry
4806 o.val[2] = [8]
4807 assert_equal([ [9], [2], [8] ], o.val)
4808 END
4809 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004810
4811 # lock a script level variable from an object method
4812 lines =<< trim END
4813 vim9script
4814
4815 class C
4816 def Lock()
4817 lockvar l
4818 enddef
4819 endclass
4820
4821 var l = [1]
4822 C.new().Lock()
4823 l[0] = 11
4824 END
4825 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4826
Ernie Rael03042a22023-11-11 08:53:32 +01004827 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004828 # in an object fetched via a script level list
4829 lines =<< trim END
4830 vim9script
4831
4832 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004833 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004834 def Lock()
4835 lockvar lc[0]._v1[1]
4836 enddef
4837 endclass
4838
4839 var l = [[1], [2], [3]]
4840 var o = C.new(l)
4841 var lc: list<C> = [ o ]
4842
4843 o.Lock()
4844 l[0] = [22]
4845 l[1] = [33]
4846 END
4847 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4848
4849 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004850 # in a class that does not own the protected variable.
4851 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004852 # the same name.
4853 lines =<< trim END
4854 vim9script
4855
4856 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004857 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004858 def Lock(obj: any)
4859 lockvar lc[0]._v1[1]
4860 enddef
4861 endclass
4862
4863 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004864 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004865 endclass
4866
4867 var l = [[1], [2], [3]]
4868 var o = C.new(l)
4869 var lc: list<C> = [ o ]
4870
4871 var o2 = C2.new()
4872 o2.Lock(o)
4873 END
Ernie Rael03042a22023-11-11 08:53:32 +01004874 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004875enddef
4876
Ernie Rael9771b2a2023-10-07 22:05:40 +02004877" Test builtin islocked()
4878def Test_lockvar_islocked()
4879 # Can't lock class/object variable
4880 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004881 # Lock item of variable's value (a list item)
4882 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004883 var lines =<< trim END
4884 vim9script
4885
4886 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004887 var o0: list<list<number>> = [ [0], [1], [2]]
4888 var o1: list<list<number>> = [[10], [11], [12]]
4889 static var c0: list<list<number>> = [[20], [21], [22]]
4890 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004891 endclass
4892
4893 def LockIt(arg: any)
4894 lockvar arg
4895 enddef
4896
4897 def UnlockIt(arg: any)
4898 unlockvar arg
4899 enddef
4900
4901 var obj = C.new()
4902 #lockvar obj.o1 # can't lock something you can't write to
4903
4904 try
4905 lockvar obj.o1 # can't lock something you can't write to
4906 call assert_false(1, '"lockvar obj.o1" should have failed')
4907 catch
4908 call assert_exception('E1335:')
4909 endtry
4910
4911 LockIt(obj.o1) # but can lock it's value
4912 assert_equal(1, islocked("obj.o1"))
4913 assert_equal(1, islocked("obj.o1[0]"))
4914 assert_equal(1, islocked("obj.o1[1]"))
4915 UnlockIt(obj.o1)
4916 assert_equal(0, islocked("obj.o1"))
4917 assert_equal(0, islocked("obj.o1[0]"))
4918
4919 lockvar obj.o1[0]
4920 assert_equal(0, islocked("obj.o1"))
4921 assert_equal(1, islocked("obj.o1[0]"))
4922 assert_equal(0, islocked("obj.o1[1]"))
4923 unlockvar obj.o1[0]
4924 assert_equal(0, islocked("obj.o1"))
4925 assert_equal(0, islocked("obj.o1[0]"))
4926
4927 # Same thing, but with a static
4928
4929 try
4930 lockvar C.c1 # can't lock something you can't write to
4931 call assert_false(1, '"lockvar C.c1" should have failed')
4932 catch
4933 call assert_exception('E1335:')
4934 endtry
4935
4936 LockIt(C.c1) # but can lock it's value
4937 assert_equal(1, islocked("C.c1"))
4938 assert_equal(1, islocked("C.c1[0]"))
4939 assert_equal(1, islocked("C.c1[1]"))
4940 UnlockIt(C.c1)
4941 assert_equal(0, islocked("C.c1"))
4942 assert_equal(0, islocked("C.c1[0]"))
4943
4944 lockvar C.c1[0]
4945 assert_equal(0, islocked("C.c1"))
4946 assert_equal(1, islocked("C.c1[0]"))
4947 assert_equal(0, islocked("C.c1[1]"))
4948 unlockvar C.c1[0]
4949 assert_equal(0, islocked("C.c1"))
4950 assert_equal(0, islocked("C.c1[0]"))
4951 END
4952 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004953
4954 # Do islocked() from an object method
4955 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004956 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004957 vim9script
4958
4959 var l0o0 = [ [0], [1], [2]]
4960 var l0o1 = [ [10], [11], [12]]
4961 var l0c0 = [[120], [121], [122]]
4962 var l0c1 = [[130], [131], [132]]
4963
4964 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004965 var o0: list<list<number>> = l0o0
4966 var o1: list<list<number>> = l0o1
4967 static var c0: list<list<number>> = l0c0
4968 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004969 def Islocked(arg: string): number
4970 return islocked(arg)
4971 enddef
4972 static def SIslocked(arg: string): number
4973 return islocked(arg)
4974 enddef
4975 endclass
4976
4977 var l2o0 = [[20000], [20001], [20002]]
4978 var l2o1 = [[20010], [20011], [20012]]
4979 var l2c0 = [[20120], [20121], [20122]]
4980 var l2c1 = [[20130], [20131], [20132]]
4981
4982 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004983 var o0: list<list<number>> = l2o0
4984 var o1: list<list<number>> = l2o1
4985 static var c0: list<list<number>> = l2c0
4986 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004987 def Islocked(arg: string): number
4988 return islocked(arg)
4989 enddef
4990 static def SIslocked(arg: string): number
4991 return islocked(arg)
4992 enddef
4993 endclass
4994
4995 var obj0 = C0.new()
4996 var obj2 = C2.new()
4997
4998 var l = [ obj0, null_object, obj2 ]
4999
5000 # lock list, object func access through script var expr
5001 assert_equal(0, obj0.Islocked("l[0].o0"))
5002 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
5003 lockvar l0o0
5004 assert_equal(1, obj0.Islocked("l[0].o0"))
5005 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
5006
5007 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
5008
5009 # lock list element, object func access through script var expr
5010 lockvar l0o1[1]
5011 assert_equal(0, obj0.Islocked("this.o1[0]"))
5012 assert_equal(1, obj0.Islocked("this.o1[1]"))
5013
5014 assert_equal(0, obj0.Islocked("this.o1"))
5015 lockvar l0o1
5016 assert_equal(1, obj0.Islocked("this.o1"))
5017 unlockvar l0o1
5018
5019 lockvar l0c1[1]
5020
5021 # static by class name member expr from same class
5022 assert_equal(0, obj0.Islocked("C0.c1[0]"))
5023 assert_equal(1, obj0.Islocked("C0.c1[1]"))
5024 # static by bare name member expr from same class
5025 assert_equal(0, obj0.Islocked("c1[0]"))
5026 assert_equal(1, obj0.Islocked("c1[1]"))
5027
5028 # static by class name member expr from other class
5029 assert_equal(0, obj2.Islocked("C0.c1[0]"))
5030 assert_equal(1, obj2.Islocked("C0.c1[1]"))
5031 # static by bare name member expr from other class
5032 assert_equal(0, obj2.Islocked("c1[0]"))
5033 assert_equal(0, obj2.Islocked("c1[1]"))
5034
5035
5036 # static by bare name in same class
5037 assert_equal(0, obj0.Islocked("c0"))
5038 lockvar l0c0
5039 assert_equal(1, obj0.Islocked("c0"))
5040
5041 #
5042 # similar stuff, but use static method
5043 #
5044
5045 unlockvar l0o0
5046
5047 # lock list, object func access through script var expr
5048 assert_equal(0, C0.SIslocked("l[0].o0"))
5049 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
5050 lockvar l0o0
5051 assert_equal(1, C0.SIslocked("l[0].o0"))
5052 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
5053
5054 unlockvar l0o1
5055
5056 # can't access "this" from class method
5057 try
5058 C0.SIslocked("this.o1[0]")
5059 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
5060 catch
5061 call assert_exception('E121: Undefined variable: this')
5062 endtry
5063
5064 lockvar l0c1[1]
5065
5066 # static by class name member expr from same class
5067 assert_equal(0, C0.SIslocked("C0.c1[0]"))
5068 assert_equal(1, C0.SIslocked("C0.c1[1]"))
5069 # static by bare name member expr from same class
5070 assert_equal(0, C0.SIslocked("c1[0]"))
5071 assert_equal(1, C0.SIslocked("c1[1]"))
5072
5073 # static by class name member expr from other class
5074 assert_equal(0, C2.SIslocked("C0.c1[0]"))
5075 assert_equal(1, C2.SIslocked("C0.c1[1]"))
5076 # static by bare name member expr from other class
5077 assert_equal(0, C2.SIslocked("c1[0]"))
5078 assert_equal(0, C2.SIslocked("c1[1]"))
5079
5080
5081 # static by bare name in same class
5082 unlockvar l0c0
5083 assert_equal(0, C0.SIslocked("c0"))
5084 lockvar l0c0
5085 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02005086 END
Ernie Rael4c8da022023-10-11 21:35:11 +02005087 v9.CheckSourceSuccess(lines)
5088
5089 # Check islocked class/object from various places.
5090 lines =<< trim END
5091 vim9script
5092
5093 class C
5094 def Islocked(arg: string): number
5095 return islocked(arg)
5096 enddef
5097 static def SIslocked(arg: string): number
5098 return islocked(arg)
5099 enddef
5100 endclass
5101 var obj = C.new()
5102
5103 # object method
5104 assert_equal(0, obj.Islocked("this"))
5105 assert_equal(0, obj.Islocked("C"))
5106
5107 # class method
5108 ### assert_equal(0, C.SIslocked("this"))
5109 assert_equal(0, C.SIslocked("C"))
5110
5111 #script level
5112 var v: number
5113 v = islocked("C")
5114 assert_equal(0, v)
5115 v = islocked("obj")
5116 assert_equal(0, v)
5117 END
5118 v9.CheckSourceSuccess(lines)
5119enddef
5120
5121def Test_lockvar_islocked_notfound()
5122 # Try non-existent things
5123 var lines =<< trim END
5124 vim9script
5125
5126 class C
5127 def Islocked(arg: string): number
5128 return islocked(arg)
5129 enddef
5130 static def SIslocked(arg: string): number
5131 return islocked(arg)
5132 enddef
5133 endclass
5134 var obj = C.new()
5135 assert_equal(-1, obj.Islocked("anywhere"))
5136 assert_equal(-1, C.SIslocked("notanywhere"))
5137 END
5138 v9.CheckSourceSuccess(lines)
5139
5140 # Something not found of the form "name1.name2" is an error
5141 lines =<< trim END
5142 vim9script
5143
5144 islocked("one.two")
5145 END
5146 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
5147
5148 lines =<< trim END
5149 vim9script
5150
5151 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005152 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02005153 def Islocked(arg: string): number
5154 return islocked(arg)
5155 enddef
5156 endclass
5157 var obj = C.new()
5158 obj.Islocked("this.val.not_there"))
5159 END
5160 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
5161
5162 lines =<< trim END
5163 vim9script
5164
5165 class C
5166 def Islocked(arg: string): number
5167 return islocked(arg)
5168 enddef
5169 endclass
5170 var obj = C.new()
5171 obj.Islocked("this.notobjmember")
5172 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005173 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02005174
5175 # access a script variable through methods
5176 lines =<< trim END
5177 vim9script
5178
5179 var l = [1]
5180 class C
5181 def Islocked(arg: string): number
5182 return islocked(arg)
5183 enddef
5184 static def SIslocked(arg: string): number
5185 return islocked(arg)
5186 enddef
5187 endclass
5188 var obj = C.new()
5189 assert_equal(0, obj.Islocked("l"))
5190 assert_equal(0, C.SIslocked("l"))
5191 lockvar l
5192 assert_equal(1, obj.Islocked("l"))
5193 assert_equal(1, C.SIslocked("l"))
5194 END
5195 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02005196enddef
5197
Ernie Rael03042a22023-11-11 08:53:32 +01005198" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005199def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005200 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005201 var lines =<< trim END
5202 vim9script
5203
5204 class A
5205 def _Foo(): number
5206 return 1234
5207 enddef
5208 endclass
5209 var a = A.new()
5210 a._Foo()
5211 END
Ernie Rael03042a22023-11-11 08:53:32 +01005212 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005213
Ernie Rael03042a22023-11-11 08:53:32 +01005214 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005215 lines =<< trim END
5216 vim9script
5217
5218 class A
5219 def _Foo(): number
5220 return 1234
5221 enddef
5222 endclass
5223 def T()
5224 var a = A.new()
5225 a._Foo()
5226 enddef
5227 T()
5228 END
Ernie Rael03042a22023-11-11 08:53:32 +01005229 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005230
Ernie Rael03042a22023-11-11 08:53:32 +01005231 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005232 lines =<< trim END
5233 vim9script
5234
5235 class A
5236 def _Foo(): number
5237 return 1234
5238 enddef
5239 def Bar(): number
5240 return this._Foo()
5241 enddef
5242 endclass
5243 var a = A.new()
5244 assert_equal(1234, a.Bar())
5245 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005246 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005247
Ernie Rael03042a22023-11-11 08:53:32 +01005248 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005249 lines =<< trim END
5250 vim9script
5251
5252 class A
5253 def _Foo(): number
5254 return 1234
5255 enddef
5256 def Bar(): number
5257 return this._Foo()
5258 enddef
5259 endclass
5260 def T()
5261 var a = A.new()
5262 assert_equal(1234, a.Bar())
5263 enddef
5264 T()
5265 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005266 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005267
Ernie Rael03042a22023-11-11 08:53:32 +01005268 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005269 lines =<< trim END
5270 vim9script
5271
5272 class A
5273 def _Foo(): number
5274 return 1234
5275 enddef
5276 def Bar(): number
5277 return _Foo()
5278 enddef
5279 endclass
5280 var a = A.new()
5281 a.Bar()
5282 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005283 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005284
Ernie Rael03042a22023-11-11 08:53:32 +01005285 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005286 lines =<< trim END
5287 vim9script
5288
5289 class A
5290 def _Foo(): number
5291 return 1234
5292 enddef
5293 endclass
5294 A._Foo()
5295 END
Ernie Rael03042a22023-11-11 08:53:32 +01005296 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005297
Ernie Rael03042a22023-11-11 08:53:32 +01005298 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005299 lines =<< trim END
5300 vim9script
5301
5302 class A
5303 def _Foo()
5304 enddef
5305 def _Foo()
5306 enddef
5307 endclass
5308 var a = A.new()
5309 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005310 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005311
Ernie Rael03042a22023-11-11 08:53:32 +01005312 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005313 lines =<< trim END
5314 vim9script
5315
5316 class A
5317 def _Foo()
5318 enddef
5319 def Foo()
5320 enddef
5321 endclass
5322 var a = A.new()
5323 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005324 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005325
Ernie Rael03042a22023-11-11 08:53:32 +01005326 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005327 lines =<< trim END
5328 vim9script
5329
5330 class A
5331 def Foo()
5332 enddef
5333 def _Foo()
5334 enddef
5335 endclass
5336 var a = A.new()
5337 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005338 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005339
Ernie Rael03042a22023-11-11 08:53:32 +01005340 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005341 lines =<< trim END
5342 vim9script
5343
5344 class A
5345 def Foo(): number
5346 return 100
5347 enddef
5348 def _Bar(): number
5349 return 200
5350 enddef
5351 def _Baz()
5352 assert_equal(100, this.Foo())
5353 assert_equal(200, this._Bar())
5354 enddef
5355 def T()
5356 this._Baz()
5357 enddef
5358 endclass
5359 var a = A.new()
5360 a.T()
5361 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005362 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005363
Ernie Rael03042a22023-11-11 08:53:32 +01005364 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005365 lines =<< trim END
5366 vim9script
5367
5368 class A
5369 def _Foo(): number
5370 return 100
5371 enddef
5372 endclass
5373 class B
5374 def Foo(): number
5375 var a = A.new()
5376 a._Foo()
5377 enddef
5378 endclass
5379 var b = B.new()
5380 b.Foo()
5381 END
Ernie Rael03042a22023-11-11 08:53:32 +01005382 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005383
Ernie Rael03042a22023-11-11 08:53:32 +01005384 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005385 lines =<< trim END
5386 vim9script
5387 class A
5388 def _Foo(): number
5389 return 1234
5390 enddef
5391 endclass
5392 class B extends A
5393 def Bar()
5394 enddef
5395 endclass
5396 class C extends B
5397 def Baz(): number
5398 return this._Foo()
5399 enddef
5400 endclass
5401 var c = C.new()
5402 assert_equal(1234, c.Baz())
5403 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005404 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005405
Ernie Rael03042a22023-11-11 08:53:32 +01005406 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005407 lines =<< trim END
5408 vim9script
5409 class A
5410 def _Foo(): number
5411 return 1234
5412 enddef
5413 endclass
5414 class B extends A
5415 def Bar()
5416 enddef
5417 endclass
5418 class C extends B
5419 def Baz(): number
5420 enddef
5421 endclass
5422 var c = C.new()
5423 assert_equal(1234, c._Foo())
5424 END
Ernie Rael03042a22023-11-11 08:53:32 +01005425 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005426
5427 # Using "_" prefix in a method name should fail outside of a class
5428 lines =<< trim END
5429 vim9script
5430 def _Foo(): number
5431 return 1234
5432 enddef
5433 var a = _Foo()
5434 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005435 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005436enddef
5437
Ernie Rael03042a22023-11-11 08:53:32 +01005438" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005439def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005440 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005441 var lines =<< trim END
5442 vim9script
5443
5444 class A
5445 static def _Foo(): number
5446 return 1234
5447 enddef
5448 endclass
5449 A._Foo()
5450 END
Ernie Rael03042a22023-11-11 08:53:32 +01005451 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005452
Ernie Rael03042a22023-11-11 08:53:32 +01005453 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005454 lines =<< trim END
5455 vim9script
5456
5457 class A
5458 static def _Foo(): number
5459 return 1234
5460 enddef
5461 endclass
5462 def T()
5463 A._Foo()
5464 enddef
5465 T()
5466 END
Ernie Rael03042a22023-11-11 08:53:32 +01005467 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005468
Ernie Rael03042a22023-11-11 08:53:32 +01005469 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005470 lines =<< trim END
5471 vim9script
5472
5473 class A
5474 static def _Foo(): number
5475 return 1234
5476 enddef
5477 endclass
5478 var a = A.new()
5479 a._Foo()
5480 END
Ernie Rael03042a22023-11-11 08:53:32 +01005481 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005482
Ernie Rael03042a22023-11-11 08:53:32 +01005483 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005484 lines =<< trim END
5485 vim9script
5486
5487 class A
5488 static def _Foo(): number
5489 return 1234
5490 enddef
5491 endclass
5492 def T()
5493 var a = A.new()
5494 a._Foo()
5495 enddef
5496 T()
5497 END
Ernie Rael03042a22023-11-11 08:53:32 +01005498 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005499
Ernie Rael03042a22023-11-11 08:53:32 +01005500 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005501 lines =<< trim END
5502 vim9script
5503
5504 class A
5505 static def _Foo(): number
5506 return 1234
5507 enddef
5508 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005509 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005510 enddef
5511 endclass
5512 var a = A.new()
5513 a.Bar()
5514 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005515 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005516
Ernie Rael03042a22023-11-11 08:53:32 +01005517 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005518 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005519 lines =<< trim END
5520 vim9script
5521
5522 class A
5523 static def _Foo1(): number
5524 return 1234
5525 enddef
5526 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005527 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005528 enddef
5529 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005530 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005531 enddef
5532 endclass
5533 var a = A.new()
5534 a.Bar()
5535 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005536 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005537
Ernie Rael03042a22023-11-11 08:53:32 +01005538 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005539 lines =<< trim END
5540 vim9script
5541
5542 class A
5543 static def _Foo()
5544 enddef
5545 static def Foo()
5546 enddef
5547 endclass
5548 var a = A.new()
5549 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005550 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005551
Ernie Rael03042a22023-11-11 08:53:32 +01005552 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005553 lines =<< trim END
5554 vim9script
5555
5556 class A
5557 static def _Foo(): number
5558 return 1234
5559 enddef
5560 endclass
5561 class B
5562 def Foo(): number
5563 return A._Foo()
5564 enddef
5565 endclass
5566 var b = B.new()
5567 assert_equal(1234, b.Foo())
5568 END
Ernie Rael03042a22023-11-11 08:53:32 +01005569 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005570
Ernie Rael03042a22023-11-11 08:53:32 +01005571 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005572 lines =<< trim END
5573 vim9script
5574 class A
5575 static def _Foo(): number
5576 return 1234
5577 enddef
5578 endclass
5579 class B extends A
5580 def Bar()
5581 enddef
5582 endclass
5583 class C extends B
5584 def Baz(): number
5585 return A._Foo()
5586 enddef
5587 endclass
5588 var c = C.new()
5589 assert_equal(1234, c.Baz())
5590 END
Ernie Rael03042a22023-11-11 08:53:32 +01005591 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005592
Ernie Rael03042a22023-11-11 08:53:32 +01005593 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005594 lines =<< trim END
5595 vim9script
5596 class A
5597 static def _Foo(): number
5598 return 1234
5599 enddef
5600 endclass
5601 class B extends A
5602 def Bar()
5603 enddef
5604 endclass
5605 class C extends B
5606 static def Baz(): number
5607 return A._Foo()
5608 enddef
5609 endclass
5610 assert_equal(1234, C.Baz())
5611 END
Ernie Rael03042a22023-11-11 08:53:32 +01005612 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005613
Ernie Rael03042a22023-11-11 08:53:32 +01005614 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005615 lines =<< trim END
5616 vim9script
5617 class A
5618 static def _Foo(): number
5619 return 1234
5620 enddef
5621 endclass
5622 class B extends A
5623 def Bar()
5624 enddef
5625 endclass
5626 class C extends B
5627 def Baz(): number
5628 enddef
5629 endclass
5630 var c = C.new()
5631 assert_equal(1234, C._Foo())
5632 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005633 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005634enddef
5635
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005636" Test for using the return value of a class/object method as a function
5637" argument.
5638def Test_objmethod_funcarg()
5639 var lines =<< trim END
5640 vim9script
5641
5642 class C
5643 def Foo(): string
5644 return 'foo'
5645 enddef
5646 endclass
5647
5648 def Bar(a: number, s: string): string
5649 return s
5650 enddef
5651
5652 def Baz(c: C)
5653 assert_equal('foo', Bar(10, c.Foo()))
5654 enddef
5655
5656 var t = C.new()
5657 Baz(t)
5658 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005659 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005660
5661 lines =<< trim END
5662 vim9script
5663
5664 class C
5665 static def Foo(): string
5666 return 'foo'
5667 enddef
5668 endclass
5669
5670 def Bar(a: number, s: string): string
5671 return s
5672 enddef
5673
5674 def Baz()
5675 assert_equal('foo', Bar(10, C.Foo()))
5676 enddef
5677
5678 Baz()
5679 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005680 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005681enddef
5682
Ernie Raelcf138d42023-09-06 20:45:03 +02005683def Test_static_inheritence()
5684 # subclasses get their own static copy
5685 var lines =<< trim END
5686 vim9script
5687
5688 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005689 static var _svar: number
5690 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005691 def new()
5692 _svar = 1
5693 this._mvar = 101
5694 enddef
5695 def AccessObject(): number
5696 return this._mvar
5697 enddef
5698 def AccessStaticThroughObject(): number
5699 return _svar
5700 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005701 endclass
5702
5703 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005704 def new()
5705 this._mvar = 102
5706 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005707 endclass
5708
5709 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005710 def new()
5711 this._mvar = 103
5712 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005713
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005714 def AccessPrivateStaticThroughClassName(): number
5715 assert_equal(1, A._svar)
5716 return 444
5717 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005718 endclass
5719
5720 var oa = A.new()
5721 var ob = B.new()
5722 var oc = C.new()
5723 assert_equal(101, oa.AccessObject())
5724 assert_equal(102, ob.AccessObject())
5725 assert_equal(103, oc.AccessObject())
5726
Ernie Rael03042a22023-11-11 08:53:32 +01005727 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005728
5729 # verify object properly resolves to correct static
5730 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005731 assert_equal(1, ob.AccessStaticThroughObject())
5732 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005733 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005734 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005735enddef
5736
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005737" Test for declaring duplicate object and class members
5738def Test_dup_member_variable()
5739 # Duplicate member variable
5740 var lines =<< trim END
5741 vim9script
5742 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005743 var val = 10
5744 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005745 endclass
5746 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005747 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005748
Ernie Rael03042a22023-11-11 08:53:32 +01005749 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005750 lines =<< trim END
5751 vim9script
5752 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005753 var _val = 10
5754 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005755 endclass
5756 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005757 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005758
5759 # Duplicate public member variable
5760 lines =<< trim END
5761 vim9script
5762 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005763 public var val = 10
5764 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005765 endclass
5766 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005767 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005768
Ernie Rael03042a22023-11-11 08:53:32 +01005769 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005770 lines =<< trim END
5771 vim9script
5772 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005773 var val = 10
5774 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005775 endclass
5776 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005777 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005778
Ernie Rael03042a22023-11-11 08:53:32 +01005779 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005780 lines =<< trim END
5781 vim9script
5782 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005783 var _val = 20
5784 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005785 endclass
5786 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005787 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005788
5789 # Duplicate class member variable
5790 lines =<< trim END
5791 vim9script
5792 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005793 static var s: string = "abc"
5794 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005795 endclass
5796 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005797 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005798
Ernie Rael03042a22023-11-11 08:53:32 +01005799 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005800 lines =<< trim END
5801 vim9script
5802 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005803 public static var s: string = "abc"
5804 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005805 endclass
5806 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005807 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005808
5809 # Duplicate class and object member variable
5810 lines =<< trim END
5811 vim9script
5812 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005813 static var val = 10
5814 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005815 def new()
5816 enddef
5817 endclass
5818 var c = C.new()
5819 assert_equal(10, C.val)
5820 assert_equal(20, c.val)
5821 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005822 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005823
5824 # Duplicate object member variable in a derived class
5825 lines =<< trim END
5826 vim9script
5827 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005828 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005829 endclass
5830 class B extends A
5831 endclass
5832 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005833 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005834 endclass
5835 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005836 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005837
Ernie Rael03042a22023-11-11 08:53:32 +01005838 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005839 lines =<< trim END
5840 vim9script
5841 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005842 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005843 endclass
5844 class B extends A
5845 endclass
5846 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005847 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005848 endclass
5849 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005850 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005851
Ernie Rael03042a22023-11-11 08:53:32 +01005852 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005853 lines =<< trim END
5854 vim9script
5855 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005856 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005857 endclass
5858 class B extends A
5859 endclass
5860 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005861 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005862 endclass
5863 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005864 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005865
5866 # Duplicate object member variable in a derived class
5867 lines =<< trim END
5868 vim9script
5869 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005870 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005871 endclass
5872 class B extends A
5873 endclass
5874 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005875 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005876 endclass
5877 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005878 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005879
5880 # Two member variables with a common prefix
5881 lines =<< trim END
5882 vim9script
5883 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005884 public static var svar2: number
5885 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005886 endclass
5887 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005888 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005889enddef
5890
Ernie Rael03042a22023-11-11 08:53:32 +01005891" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005892def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005893 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005894 var lines =<< trim END
5895 vim9script
5896 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005897 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005898 def GetVal(): number
5899 return this._val
5900 enddef
5901 endclass
5902 def T()
5903 var a = A.new()
5904 a._val = 20
5905 enddef
5906 T()
5907 END
Ernie Rael03042a22023-11-11 08:53:32 +01005908 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005909
Ernie Rael03042a22023-11-11 08:53:32 +01005910 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005911 lines =<< trim END
5912 vim9script
5913 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005914 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005915 endclass
5916 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005917 var a = A.new()
5918 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005919 enddef
5920 T()
5921 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005922 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005923
Ernie Rael03042a22023-11-11 08:53:32 +01005924 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005925 lines =<< trim END
5926 vim9script
5927 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005928 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005929 endclass
5930 def T()
5931 var a = A.new()
5932 var x = a._val
5933 enddef
5934 T()
5935 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005936 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005937
Ernie Rael03042a22023-11-11 08:53:32 +01005938 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005939 lines =<< trim END
5940 vim9script
5941 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005942 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005943 endclass
5944 def T()
5945 var a = A.new()
5946 a._val = 3
5947 enddef
5948 T()
5949 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005950 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005951
Ernie Rael03042a22023-11-11 08:53:32 +01005952 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005953 lines =<< trim END
5954 vim9script
5955 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005956 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005957 endclass
5958 def T()
5959 var x = A._val
5960 enddef
5961 T()
5962 END
Ernie Rael03042a22023-11-11 08:53:32 +01005963 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005964
Ernie Rael03042a22023-11-11 08:53:32 +01005965 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005966 lines =<< trim END
5967 vim9script
5968 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005969 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005970 endclass
5971 def T()
5972 A._val = 3
5973 enddef
5974 T()
5975 END
Ernie Rael03042a22023-11-11 08:53:32 +01005976 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005977enddef
5978
5979" Test for changing the member access of an interface in a implementation class
5980def Test_change_interface_member_access()
5981 var lines =<< trim END
5982 vim9script
5983 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005984 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005985 endinterface
5986 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005987 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005988 endclass
5989 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005990 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005991
5992 lines =<< trim END
5993 vim9script
5994 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005995 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005996 endinterface
5997 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005998 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005999 endclass
6000 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006001 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02006002enddef
6003
6004" Test for trying to change a readonly member from a def function
6005def Test_readonly_member_change_in_def_func()
6006 var lines =<< trim END
6007 vim9script
6008 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006009 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02006010 endclass
6011 def T()
6012 var a = A.new()
6013 a.val = 20
6014 enddef
6015 T()
6016 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006017 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02006018enddef
6019
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02006020" Test for reading and writing a class member from a def function
6021def Test_modify_class_member_from_def_function()
6022 var lines =<< trim END
6023 vim9script
6024 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006025 var var1: number = 10
6026 public static var var2: list<number> = [1, 2]
6027 public static var var3: dict<number> = {a: 1, b: 2}
6028 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02006029 endclass
6030 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02006031 assert_equal([1, 2], A.var2)
6032 assert_equal({a: 1, b: 2}, A.var3)
6033 A.var2 = [3, 4]
6034 A.var3 = {c: 3, d: 4}
6035 assert_equal([3, 4], A.var2)
6036 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01006037 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02006038 enddef
6039 T()
6040 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006041 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02006042enddef
6043
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006044" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006045def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006046 var lines =<< trim END
6047 vim9script
6048 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006049 public static var svar1: list<number> = [1]
6050 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006051 endclass
6052
6053 A.svar1->add(3)
6054 A.svar2->add(4)
6055 assert_equal([1, 3], A.svar1)
6056 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006057
6058 def Foo()
6059 A.svar1->add(7)
6060 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006061 assert_equal([1, 3, 7], A.svar1)
6062 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006063 enddef
6064 Foo()
6065 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006066 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006067
6068 # Cannot read from a class variable using an object in script context
6069 lines =<< trim END
6070 vim9script
6071 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006072 public var var1: number
6073 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006074 endclass
6075
6076 var a = A.new()
6077 echo a.svar2
6078 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006079 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006080
6081 # Cannot write to a class variable using an object in script context
6082 lines =<< trim END
6083 vim9script
6084 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006085 public var var1: number
6086 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006087 endclass
6088
6089 var a = A.new()
6090 a.svar2 = [2]
6091 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006092 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006093
6094 # Cannot read from a class variable using an object in def method context
6095 lines =<< trim END
6096 vim9script
6097 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006098 public var var1: number
6099 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006100 endclass
6101
6102 def T()
6103 var a = A.new()
6104 echo a.svar2
6105 enddef
6106 T()
6107 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006108 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006109
6110 # Cannot write to a class variable using an object in def method context
6111 lines =<< trim END
6112 vim9script
6113 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006114 public var var1: number
6115 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006116 endclass
6117
6118 def T()
6119 var a = A.new()
6120 a.svar2 = [2]
6121 enddef
6122 T()
6123 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006124 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006125enddef
6126
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006127" Test for using a interface method using a child object
6128def Test_interface_method_from_child()
6129 var lines =<< trim END
6130 vim9script
6131
6132 interface A
6133 def Foo(): string
6134 endinterface
6135
6136 class B implements A
6137 def Foo(): string
6138 return 'foo'
6139 enddef
6140 endclass
6141
6142 class C extends B
6143 def Bar(): string
6144 return 'bar'
6145 enddef
6146 endclass
6147
6148 def T1(a: A)
6149 assert_equal('foo', a.Foo())
6150 enddef
6151
6152 def T2(b: B)
6153 assert_equal('foo', b.Foo())
6154 enddef
6155
6156 var c = C.new()
6157 T1(c)
6158 T2(c)
6159 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006160 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006161enddef
6162
6163" Test for using an interface method using a child object when it is overridden
6164" by the child class.
Yegappan Lakshmanan8e92db42025-01-13 07:30:11 +01006165def Test_interface_overridden_method_from_child()
6166 var lines =<< trim END
6167 vim9script
6168
6169 interface A
6170 def Foo(): string
6171 endinterface
6172
6173 class B implements A
6174 def Foo(): string
6175 return 'b-foo'
6176 enddef
6177 endclass
6178
6179 class C extends B
6180 def Bar(): string
6181 return 'bar'
6182 enddef
6183 def Foo(): string
6184 return 'c-foo'
6185 enddef
6186 endclass
6187
6188 def T1(a: A)
6189 assert_equal('c-foo', a.Foo())
6190 enddef
6191
6192 def T2(b: B)
6193 assert_equal('c-foo', b.Foo())
6194 enddef
6195
6196 var c = C.new()
6197 T1(c)
6198 T2(c)
6199 END
6200 v9.CheckSourceSuccess(lines)
6201enddef
6202
6203" Test for interface inheritance
6204def Test_interface_inheritance()
6205 var lines =<< trim END
6206 vim9script
6207
6208 interface A
6209 def A_Fn(): string
6210 endinterface
6211
6212 interface B
6213 def B_Fn(): string
6214 endinterface
6215
6216 interface C
6217 def C_Fn(): string
6218 endinterface
6219
6220 class C1 implements A
6221 def A_Fn(): string
6222 return 'c1-a'
6223 enddef
6224 endclass
6225
6226 class C2 extends C1 implements B
6227 def B_Fn(): string
6228 return 'c2-b'
6229 enddef
6230 def A_Fn(): string
6231 return 'c2-a'
6232 enddef
6233 endclass
6234
6235 class C3 extends C2 implements C
6236 def C_Fn(): string
6237 return 'c3-c'
6238 enddef
6239 def A_Fn(): string
6240 return 'c3-a'
6241 enddef
6242 def B_Fn(): string
6243 return 'c3-b'
6244 enddef
6245 endclass
6246
6247 def T1(a: A, s: string)
6248 assert_equal(s, a.A_Fn())
6249 enddef
6250
6251 def T2(b: B, s: string)
6252 assert_equal(s, b.B_Fn())
6253 enddef
6254
6255 def T3(c: C, s: string)
6256 assert_equal(s, c.C_Fn())
6257 enddef
6258
6259 def T4(c1: C1)
6260 T1(c1, 'c3-a')
6261 enddef
6262
6263 def T5(c2: C2)
6264 T1(c2, 'c3-a')
6265 T2(c2, 'c3-b')
6266 enddef
6267
6268 def T6(c3: C3)
6269 T1(c3, 'c3-a')
6270 T2(c3, 'c3-b')
6271 T3(c3, 'c3-c')
6272 enddef
6273
6274 var o3 = C3.new()
6275 T4(o3)
6276 T5(o3)
6277 T6(o3)
6278 END
6279 v9.CheckSourceSuccess(lines)
6280
6281 # Both the parent and child classes implement the same interface
6282 lines =<< trim END
6283 vim9script
6284
6285 interface I
6286 def Foo(): string
6287 endinterface
6288
6289 class A implements I
6290 def Foo(): string
6291 return 'A-foo'
6292 enddef
6293 endclass
6294
6295 class B implements I
6296 def Foo(): string
6297 return 'B-foo'
6298 enddef
6299 endclass
6300
6301 def Bar(i1: I): string
6302 return i1.Foo()
6303 enddef
6304
6305 var b = B.new()
6306 assert_equal('B-foo', Bar(b))
6307 END
6308 v9.CheckSourceSuccess(lines)
6309enddef
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006310
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006311" Test for abstract methods
6312def Test_abstract_method()
6313 # Use two abstract methods
6314 var lines =<< trim END
6315 vim9script
6316 abstract class A
6317 def M1(): number
6318 return 10
6319 enddef
6320 abstract def M2(): number
6321 abstract def M3(): number
6322 endclass
6323 class B extends A
6324 def M2(): number
6325 return 20
6326 enddef
6327 def M3(): number
6328 return 30
6329 enddef
6330 endclass
6331 var b = B.new()
6332 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
6333 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006334 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006335
6336 # Don't define an abstract method
6337 lines =<< trim END
6338 vim9script
6339 abstract class A
6340 abstract def Foo()
6341 endclass
6342 class B extends A
6343 endclass
6344 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006345 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006346
6347 # Use abstract method in a concrete class
6348 lines =<< trim END
6349 vim9script
6350 class A
6351 abstract def Foo()
6352 endclass
6353 class B extends A
6354 endclass
6355 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006356 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006357
6358 # Use abstract method in an interface
6359 lines =<< trim END
6360 vim9script
6361 interface A
6362 abstract def Foo()
6363 endinterface
6364 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006365 def Foo()
6366 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006367 endclass
6368 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01006369 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6370
6371 # Use abstract static method in an interface
6372 lines =<< trim END
6373 vim9script
6374 interface A
6375 abstract static def Foo()
6376 enddef
6377 endinterface
6378 END
6379 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6380
6381 # Use abstract static variable in an interface
6382 lines =<< trim END
6383 vim9script
6384 interface A
6385 abstract static foo: number = 10
6386 endinterface
6387 END
6388 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006389
6390 # Abbreviate the "abstract" keyword
6391 lines =<< trim END
6392 vim9script
6393 class A
6394 abs def Foo()
6395 endclass
6396 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006397 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006398
6399 # Use "abstract" with a member variable
6400 lines =<< trim END
6401 vim9script
6402 abstract class A
6403 abstract this.val = 10
6404 endclass
6405 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006406 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006407
6408 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01006409 lines =<< trim END
6410 vim9script
6411 abstract class A
6412 abstract static def Foo(): number
6413 endclass
6414 END
6415 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006416
6417 # Type mismatch between abstract method and concrete method
6418 lines =<< trim END
6419 vim9script
6420 abstract class A
6421 abstract def Foo(a: string, b: number): list<number>
6422 endclass
6423 class B extends A
6424 def Foo(a: number, b: string): list<string>
6425 return []
6426 enddef
6427 endclass
6428 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006429 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 +02006430
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006431 # Invoke an abstract method from a def function
6432 lines =<< trim END
6433 vim9script
6434 abstract class A
6435 abstract def Foo(): list<number>
6436 endclass
6437 class B extends A
6438 def Foo(): list<number>
6439 return [3, 5]
6440 enddef
6441 endclass
6442 def Bar(c: B)
6443 assert_equal([3, 5], c.Foo())
6444 enddef
6445 var b = B.new()
6446 Bar(b)
6447 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006448 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006449
6450 # Use a static method in an abstract class
6451 lines =<< trim END
6452 vim9script
6453 abstract class A
6454 static def Foo(): string
6455 return 'foo'
6456 enddef
6457 endclass
6458 assert_equal('foo', A.Foo())
6459 END
6460 v9.CheckSourceSuccess(lines)
Ernie Rael7c92e882025-01-18 17:26:39 +01006461
6462 # Invoke method returning a value through the abstract class. See #15432.
6463 lines =<< trim END
6464 vim9script
6465
6466 abstract class A
6467 abstract def String(): string
6468 endclass
6469
6470 class B extends A
6471 def String(): string
6472 return 'B'
6473 enddef
6474 endclass
6475
6476 def F(o: A)
6477 assert_equal('B', o.String())
6478 enddef
6479 F(B.new())
6480 END
6481 v9.CheckSourceSuccess(lines)
6482
6483 # Invoke abstract method returning a value does not compile
6484 lines =<< trim END
6485 vim9script
6486
6487 abstract class A
6488 abstract def String(): string
6489 return 'X'
6490 enddef
6491 endclass
6492 END
6493 v9.CheckScriptFailure(lines, "E1318: Not a valid command in a class: return 'X'")
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006494enddef
6495
6496" Test for calling a class method from a subclass
6497def Test_class_method_call_from_subclass()
6498 # class method call from a subclass
6499 var lines =<< trim END
6500 vim9script
6501
6502 class A
6503 static def Foo()
6504 echo "foo"
6505 enddef
6506 endclass
6507
6508 class B extends A
6509 def Bar()
6510 Foo()
6511 enddef
6512 endclass
6513
6514 var b = B.new()
6515 b.Bar()
6516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006517 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006518enddef
6519
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006520" Test for calling a class method using an object in a def function context and
6521" script context.
6522def Test_class_method_call_using_object()
6523 # script context
6524 var lines =<< trim END
6525 vim9script
6526 class A
6527 static def Foo(): list<string>
6528 return ['a', 'b']
6529 enddef
6530 def Bar()
6531 assert_equal(['a', 'b'], A.Foo())
6532 assert_equal(['a', 'b'], Foo())
6533 enddef
6534 endclass
6535
6536 def T()
6537 assert_equal(['a', 'b'], A.Foo())
6538 var t_a = A.new()
6539 t_a.Bar()
6540 enddef
6541
6542 assert_equal(['a', 'b'], A.Foo())
6543 var a = A.new()
6544 a.Bar()
6545 T()
6546 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006547 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006548
6549 # script context
6550 lines =<< trim END
6551 vim9script
6552 class A
6553 static def Foo(): string
6554 return 'foo'
6555 enddef
6556 endclass
6557
6558 var a = A.new()
6559 assert_equal('foo', a.Foo())
6560 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006561 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006562
6563 # def function context
6564 lines =<< trim END
6565 vim9script
6566 class A
6567 static def Foo(): string
6568 return 'foo'
6569 enddef
6570 endclass
6571
6572 def T()
6573 var a = A.new()
6574 assert_equal('foo', a.Foo())
6575 enddef
6576 T()
6577 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006578 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006579enddef
6580
6581def Test_class_variable()
6582 var lines =<< trim END
6583 vim9script
6584
6585 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006586 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006587 static def ClassFunc()
6588 assert_equal(10, val)
6589 enddef
6590 def ObjFunc()
6591 assert_equal(10, val)
6592 enddef
6593 endclass
6594
6595 class B extends A
6596 endclass
6597
6598 assert_equal(10, A.val)
6599 A.ClassFunc()
6600 var a = A.new()
6601 a.ObjFunc()
6602 var b = B.new()
6603 b.ObjFunc()
6604
6605 def T1(a1: A)
6606 a1.ObjFunc()
6607 A.ClassFunc()
6608 enddef
6609 T1(b)
6610
6611 A.val = 20
6612 assert_equal(20, A.val)
6613 END
6614 v9.CheckSourceSuccess(lines)
6615
6616 # Modifying a parent class variable from a child class method
6617 lines =<< trim END
6618 vim9script
6619
6620 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006621 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006622 endclass
6623
6624 class B extends A
6625 static def ClassFunc()
6626 val = 20
6627 enddef
6628 endclass
6629 B.ClassFunc()
6630 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006631 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006632
6633 # Reading a parent class variable from a child class method
6634 lines =<< trim END
6635 vim9script
6636
6637 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006638 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006639 endclass
6640
6641 class B extends A
6642 static def ClassFunc()
6643 var i = val
6644 enddef
6645 endclass
6646 B.ClassFunc()
6647 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006648 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006649
6650 # Modifying a parent class variable from a child object method
6651 lines =<< trim END
6652 vim9script
6653
6654 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006655 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006656 endclass
6657
6658 class B extends A
6659 def ObjFunc()
6660 val = 20
6661 enddef
6662 endclass
6663 var b = B.new()
6664 b.ObjFunc()
6665 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006666 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006667
6668 # Reading a parent class variable from a child object method
6669 lines =<< trim END
6670 vim9script
6671
6672 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006673 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006674 endclass
6675
6676 class B extends A
6677 def ObjFunc()
6678 var i = val
6679 enddef
6680 endclass
6681 var b = B.new()
6682 b.ObjFunc()
6683 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006684 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006685
6686 # Modifying a class variable using an object at script level
6687 lines =<< trim END
6688 vim9script
6689
6690 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006691 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006692 endclass
6693 var a = A.new()
6694 a.val = 20
6695 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006696 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006697
6698 # Reading a class variable using an object at script level
6699 lines =<< trim END
6700 vim9script
6701
6702 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006703 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006704 endclass
6705 var a = A.new()
6706 var i = a.val
6707 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006708 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006709
6710 # Modifying a class variable using an object at function level
6711 lines =<< trim END
6712 vim9script
6713
6714 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006715 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006716 endclass
6717
6718 def T()
6719 var a = A.new()
6720 a.val = 20
6721 enddef
6722 T()
6723 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006724 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006725
6726 # Reading a class variable using an object at function level
6727 lines =<< trim END
6728 vim9script
6729
6730 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006731 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006732 endclass
6733 def T()
6734 var a = A.new()
6735 var i = a.val
6736 enddef
6737 T()
6738 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006739 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006740
6741 # Use old implicit var declaration syntax (without initialization)
6742 lines =<< trim END
6743 vim9script
6744
6745 class A
6746 static val: number
6747 endclass
6748 END
6749 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6750
6751 # Use old implicit var declaration syntax (with initialization)
6752 lines =<< trim END
6753 vim9script
6754
6755 class A
6756 static val: number = 10
6757 endclass
6758 END
6759 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6760
6761 # Use old implicit var declaration syntax (type inferred)
6762 lines =<< trim END
6763 vim9script
6764
6765 class A
6766 static val = 10
6767 endclass
6768 END
6769 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6770
6771 # Missing ":var" in "var" class variable declaration (without initialization)
6772 lines =<< trim END
6773 vim9script
6774
6775 class A
6776 static var: number
6777 endclass
6778 END
6779 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6780
6781 # Missing ":var" in "var" class variable declaration (with initialization)
6782 lines =<< trim END
6783 vim9script
6784
6785 class A
6786 static var: number = 10
6787 endclass
6788 END
6789 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6790
6791 # Missing ":var" in "var" class variable declaration (type inferred)
6792 lines =<< trim END
6793 vim9script
6794
6795 class A
6796 static var = 10
6797 endclass
6798 END
6799 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6800
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006801enddef
6802
6803" Test for using a duplicate class method and class variable in a child class
6804def Test_dup_class_member()
6805 # duplicate class variable, class method and overridden object method
6806 var lines =<< trim END
6807 vim9script
6808 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006809 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006810 static def Check()
6811 assert_equal(100, sval)
6812 enddef
6813 def GetVal(): number
6814 return sval
6815 enddef
6816 endclass
6817
6818 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006819 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006820 static def Check()
6821 assert_equal(200, sval)
6822 enddef
6823 def GetVal(): number
6824 return sval
6825 enddef
6826 endclass
6827
6828 def T1(aa: A): number
6829 return aa.GetVal()
6830 enddef
6831
6832 def T2(bb: B): number
6833 return bb.GetVal()
6834 enddef
6835
6836 assert_equal(100, A.sval)
6837 assert_equal(200, B.sval)
6838 var a = A.new()
6839 assert_equal(100, a.GetVal())
6840 var b = B.new()
6841 assert_equal(200, b.GetVal())
6842 assert_equal(200, T1(b))
6843 assert_equal(200, T2(b))
6844 END
6845 v9.CheckSourceSuccess(lines)
6846
6847 # duplicate class variable and class method
6848 lines =<< trim END
6849 vim9script
6850 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006851 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006852 static def Check()
6853 assert_equal(100, sval)
6854 enddef
6855 def GetVal(): number
6856 return sval
6857 enddef
6858 endclass
6859
6860 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006861 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006862 static def Check()
6863 assert_equal(200, sval)
6864 enddef
6865 endclass
6866
6867 def T1(aa: A): number
6868 return aa.GetVal()
6869 enddef
6870
6871 def T2(bb: B): number
6872 return bb.GetVal()
6873 enddef
6874
6875 assert_equal(100, A.sval)
6876 assert_equal(200, B.sval)
6877 var a = A.new()
6878 assert_equal(100, a.GetVal())
6879 var b = B.new()
6880 assert_equal(100, b.GetVal())
6881 assert_equal(100, T1(b))
6882 assert_equal(100, T2(b))
6883 END
6884 v9.CheckSourceSuccess(lines)
6885enddef
6886
6887" Test for calling an instance method using the class
6888def Test_instance_method_call_using_class()
6889 # Invoke an object method using a class in script context
6890 var lines =<< trim END
6891 vim9script
6892 class A
6893 def Foo()
6894 echo "foo"
6895 enddef
6896 endclass
6897 A.Foo()
6898 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006899 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006900
6901 # Invoke an object method using a class in def function context
6902 lines =<< trim END
6903 vim9script
6904 class A
6905 def Foo()
6906 echo "foo"
6907 enddef
6908 endclass
6909 def T()
6910 A.Foo()
6911 enddef
6912 T()
6913 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006914 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006915enddef
6916
6917" Test for duplicate class method and instance method
6918def Test_dup_classmethod_objmethod()
6919 # Duplicate instance method
6920 var lines =<< trim END
6921 vim9script
6922 class A
6923 static def Foo()
6924 enddef
6925 def Foo()
6926 enddef
6927 endclass
6928 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006929 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006930
Ernie Rael03042a22023-11-11 08:53:32 +01006931 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006932 lines =<< trim END
6933 vim9script
6934 class A
6935 static def Foo()
6936 enddef
6937 def _Foo()
6938 enddef
6939 endclass
6940 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006941 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006942
6943 # Duplicate class method
6944 lines =<< trim END
6945 vim9script
6946 class A
6947 def Foo()
6948 enddef
6949 static def Foo()
6950 enddef
6951 endclass
6952 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006953 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006954
Ernie Rael03042a22023-11-11 08:53:32 +01006955 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006956 lines =<< trim END
6957 vim9script
6958 class A
6959 def Foo()
6960 enddef
6961 static def _Foo()
6962 enddef
6963 endclass
6964 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006965 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006966
Ernie Rael03042a22023-11-11 08:53:32 +01006967 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006968 lines =<< trim END
6969 vim9script
6970 class A
6971 def _Foo()
6972 enddef
6973 static def _Foo()
6974 enddef
6975 endclass
6976 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006977 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006978enddef
6979
6980" Test for an instance method access level comparison with parent instance
6981" methods.
6982def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006983 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006984 var lines =<< trim END
6985 vim9script
6986 class A
6987 def Foo()
6988 enddef
6989 endclass
6990 class B extends A
6991 endclass
6992 class C extends B
6993 def _Foo()
6994 enddef
6995 endclass
6996 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006997 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006998
6999 # Public method in subclass
7000 lines =<< trim END
7001 vim9script
7002 class A
7003 def _Foo()
7004 enddef
7005 endclass
7006 class B extends A
7007 endclass
7008 class C extends B
7009 def Foo()
7010 enddef
7011 endclass
7012 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007013 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02007014enddef
7015
7016def Test_extend_empty_class()
7017 var lines =<< trim END
7018 vim9script
7019 class A
7020 endclass
7021 class B extends A
7022 endclass
7023 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007024 public static var rw_class_var = 1
7025 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02007026 static def ClassMethod(): number
7027 return 3
7028 enddef
7029 def ObjMethod(): number
7030 return 4
7031 enddef
7032 endclass
7033 assert_equal(1, C.rw_class_var)
7034 assert_equal(3, C.ClassMethod())
7035 var c = C.new()
7036 assert_equal(2, c.rw_obj_var)
7037 assert_equal(4, c.ObjMethod())
7038 END
7039 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02007040enddef
7041
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007042" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01007043" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007044def Test_interface_with_unsupported_members()
7045 var lines =<< trim END
7046 vim9script
7047 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007048 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007049 endinterface
7050 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007051 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007052
7053 lines =<< trim END
7054 vim9script
7055 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007056 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007057 endinterface
7058 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007059 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007060
7061 lines =<< trim END
7062 vim9script
7063 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007064 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007065 endinterface
7066 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02007067 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007068
7069 lines =<< trim END
7070 vim9script
7071 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007072 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02007073 endinterface
7074 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02007075 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02007076
7077 lines =<< trim END
7078 vim9script
7079 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007080 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007081 endinterface
7082 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007083 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007084
7085 lines =<< trim END
7086 vim9script
7087 interface A
7088 static def Foo(d: dict<any>): list<string>
7089 endinterface
7090 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007091 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007092
7093 lines =<< trim END
7094 vim9script
7095 interface A
7096 static def _Foo(d: dict<any>): list<string>
7097 endinterface
7098 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007099 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007100
7101 lines =<< trim END
7102 vim9script
7103 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007104 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007105 endinterface
7106 END
Ernie Rael03042a22023-11-11 08:53:32 +01007107 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007108
7109 lines =<< trim END
7110 vim9script
7111 interface A
7112 def _Foo(d: dict<any>): list<string>
7113 endinterface
7114 END
Ernie Rael03042a22023-11-11 08:53:32 +01007115 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007116enddef
7117
7118" Test for extending an interface
7119def Test_extend_interface()
7120 var lines =<< trim END
7121 vim9script
7122 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007123 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007124 def Foo()
7125 endinterface
7126 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007127 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007128 def Bar()
7129 endinterface
7130 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007131 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007132 def Foo()
7133 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007134 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007135 def Bar()
7136 enddef
7137 endclass
7138 END
7139 v9.CheckSourceSuccess(lines)
7140
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007141 # extending empty interface
7142 lines =<< trim END
7143 vim9script
7144 interface A
7145 endinterface
7146 interface B extends A
7147 endinterface
7148 class C implements B
7149 endclass
7150 END
7151 v9.CheckSourceSuccess(lines)
7152
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007153 lines =<< trim END
7154 vim9script
7155 interface A
7156 def Foo()
7157 endinterface
7158 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007159 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007160 endinterface
7161 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007162 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007163 endclass
7164 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007165 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007166
7167 lines =<< trim END
7168 vim9script
7169 interface A
7170 def Foo()
7171 endinterface
7172 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007173 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007174 endinterface
7175 class C implements A, B
7176 def Foo()
7177 enddef
7178 endclass
7179 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007180 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007181
7182 # interface cannot extend a class
7183 lines =<< trim END
7184 vim9script
7185 class A
7186 endclass
7187 interface B extends A
7188 endinterface
7189 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007190 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007191
7192 # class cannot extend an interface
7193 lines =<< trim END
7194 vim9script
7195 interface A
7196 endinterface
7197 class B extends A
7198 endclass
7199 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007200 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007201
7202 # interface cannot implement another interface
7203 lines =<< trim END
7204 vim9script
7205 interface A
7206 endinterface
7207 interface B implements A
7208 endinterface
7209 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007210 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007211
7212 # interface cannot extend multiple interfaces
7213 lines =<< trim END
7214 vim9script
7215 interface A
7216 endinterface
7217 interface B
7218 endinterface
7219 interface C extends A, B
7220 endinterface
7221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007222 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007223
7224 # Variable type in an extended interface is of different type
7225 lines =<< trim END
7226 vim9script
7227 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007228 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007229 endinterface
7230 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007231 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007232 endinterface
7233 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007234 var val1: string
7235 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007236 endinterface
7237 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007238 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007239enddef
7240
7241" Test for a child class implementing an interface when some of the methods are
7242" defined in the parent class.
7243def Test_child_class_implements_interface()
7244 var lines =<< trim END
7245 vim9script
7246
7247 interface Intf
7248 def F1(): list<list<number>>
7249 def F2(): list<list<number>>
7250 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01007251 var var1: list<dict<number>>
7252 var var2: list<dict<number>>
7253 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007254 endinterface
7255
7256 class A
7257 def A1()
7258 enddef
7259 def F3(): list<list<number>>
7260 return [[3]]
7261 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007262 var v1: list<list<number>> = [[0]]
7263 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007264 endclass
7265
7266 class B extends A
7267 def B1()
7268 enddef
7269 def F2(): list<list<number>>
7270 return [[2]]
7271 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007272 var v2: list<list<number>> = [[0]]
7273 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007274 endclass
7275
7276 class C extends B implements Intf
7277 def C1()
7278 enddef
7279 def F1(): list<list<number>>
7280 return [[1]]
7281 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007282 var v3: list<list<number>> = [[0]]
7283 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007284 endclass
7285
7286 def T(if: Intf)
7287 assert_equal([[1]], if.F1())
7288 assert_equal([[2]], if.F2())
7289 assert_equal([[3]], if.F3())
7290 assert_equal([{a: 10}], if.var1)
7291 assert_equal([{b: 20}], if.var2)
7292 assert_equal([{c: 30}], if.var3)
7293 enddef
7294
7295 var c = C.new()
7296 T(c)
7297 assert_equal([[1]], c.F1())
7298 assert_equal([[2]], c.F2())
7299 assert_equal([[3]], c.F3())
7300 assert_equal([{a: 10}], c.var1)
7301 assert_equal([{b: 20}], c.var2)
7302 assert_equal([{c: 30}], c.var3)
7303 END
7304 v9.CheckSourceSuccess(lines)
7305
7306 # One of the interface methods is not found
7307 lines =<< trim END
7308 vim9script
7309
7310 interface Intf
7311 def F1()
7312 def F2()
7313 def F3()
7314 endinterface
7315
7316 class A
7317 def A1()
7318 enddef
7319 endclass
7320
7321 class B extends A
7322 def B1()
7323 enddef
7324 def F2()
7325 enddef
7326 endclass
7327
7328 class C extends B implements Intf
7329 def C1()
7330 enddef
7331 def F1()
7332 enddef
7333 endclass
7334 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007335 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007336
7337 # One of the interface methods is of different type
7338 lines =<< trim END
7339 vim9script
7340
7341 interface Intf
7342 def F1()
7343 def F2()
7344 def F3()
7345 endinterface
7346
7347 class A
7348 def F3(): number
7349 return 0
7350 enddef
7351 def A1()
7352 enddef
7353 endclass
7354
7355 class B extends A
7356 def B1()
7357 enddef
7358 def F2()
7359 enddef
7360 endclass
7361
7362 class C extends B implements Intf
7363 def C1()
7364 enddef
7365 def F1()
7366 enddef
7367 endclass
7368 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007369 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007370
7371 # One of the interface variables is not present
7372 lines =<< trim END
7373 vim9script
7374
7375 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007376 var var1: list<dict<number>>
7377 var var2: list<dict<number>>
7378 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007379 endinterface
7380
7381 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007382 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007383 endclass
7384
7385 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007386 var v2: list<list<number>> = [[0]]
7387 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007388 endclass
7389
7390 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007391 var v3: list<list<number>> = [[0]]
7392 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007393 endclass
7394 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007395 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007396
7397 # One of the interface variables is of different type
7398 lines =<< trim END
7399 vim9script
7400
7401 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007402 var var1: list<dict<number>>
7403 var var2: list<dict<number>>
7404 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007405 endinterface
7406
7407 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007408 var v1: list<list<number>> = [[0]]
7409 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007410 endclass
7411
7412 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007413 var v2: list<list<number>> = [[0]]
7414 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007415 endclass
7416
7417 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007418 var v3: list<list<number>> = [[0]]
7419 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007420 endclass
7421 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007422 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 +02007423enddef
7424
7425" Test for extending an interface with duplicate variables and methods
7426def Test_interface_extends_with_dup_members()
7427 var lines =<< trim END
7428 vim9script
7429 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007430 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007431 def Foo1(): number
7432 endinterface
7433 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007434 var n2: number
7435 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007436 def Foo2(): number
7437 def Foo1(): number
7438 endinterface
7439 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007440 var n1 = 10
7441 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007442 def Foo1(): number
7443 return 30
7444 enddef
7445 def Foo2(): number
7446 return 40
7447 enddef
7448 endclass
7449 def T1(a: A)
7450 assert_equal(10, a.n1)
7451 assert_equal(30, a.Foo1())
7452 enddef
7453 def T2(b: B)
7454 assert_equal(10, b.n1)
7455 assert_equal(20, b.n2)
7456 assert_equal(30, b.Foo1())
7457 assert_equal(40, b.Foo2())
7458 enddef
7459 var c = C.new()
7460 T1(c)
7461 T2(c)
7462 END
7463 v9.CheckSourceSuccess(lines)
7464enddef
7465
Yegappan Lakshmananc10342d2025-01-11 09:39:01 +01007466" Test for implementing an interface with different ordering for the interface
7467" member variables.
7468def Test_implement_interface_with_different_variable_order()
7469 var lines =<< trim END
7470 vim9script
7471
7472 interface IX
7473 var F: func(): string
7474 endinterface
7475
7476 class X implements IX
7477 var x: number
7478 var F: func(): string = () => 'ok'
7479 endclass
7480
7481 def Foo(ix: IX): string
7482 return ix.F()
7483 enddef
7484
7485 var x0 = X.new(0)
7486 assert_equal('ok', Foo(x0))
7487 END
7488 v9.CheckSourceSuccess(lines)
7489enddef
7490
Yegappan Lakshmanan8e92db42025-01-13 07:30:11 +01007491" Test for inheriting interfaces from an imported super class
7492def Test_interface_inheritance_with_imported_super()
7493 var lines =<< trim END
7494 vim9script
7495
7496 export interface I
7497 def F(): string
7498 endinterface
7499
7500 export class A implements I
7501 def F(): string
7502 return 'A'
7503 enddef
7504 endclass
7505 END
7506 writefile(lines, 'Xinheritintfimportclass.vim', 'D')
7507
7508 lines =<< trim END
7509 vim9script
7510
7511 import './Xinheritintfimportclass.vim' as i_imp
7512
7513 # class C extends i_imp.A
7514 class C extends i_imp.A implements i_imp.I
7515 def F(): string
7516 return 'C'
7517 enddef
7518 endclass
7519
7520 def TestI(i: i_imp.I): string
7521 return i.F()
7522 enddef
7523
7524 assert_equal('C', TestI(C.new()))
7525 END
7526 v9.CheckSourceSuccess(lines)
7527enddef
7528
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007529" Test for using "any" type for a variable in a sub-class while it has a
7530" concrete type in the interface
7531def Test_implements_using_var_type_any()
7532 var lines =<< trim END
7533 vim9script
7534 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007535 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007536 endinterface
7537 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007538 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007539 endclass
7540 var b = B.new()
7541 assert_equal([{a: '1'}, {b: '2'}], b.val)
7542 END
7543 v9.CheckSourceSuccess(lines)
7544
7545 # initialize instance variable using a different type
7546 lines =<< trim END
7547 vim9script
7548 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007549 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007550 endinterface
7551 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007552 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007553 endclass
7554 var b = B.new()
7555 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007556 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007557enddef
7558
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007559" Test for assigning to a member variable in a nested class
7560def Test_nested_object_assignment()
7561 var lines =<< trim END
7562 vim9script
7563
7564 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007565 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007566 endclass
7567
7568 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007569 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007570 endclass
7571
7572 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007573 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007574 endclass
7575
7576 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007577 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007578 endclass
7579
7580 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007581 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007582 enddef
7583
7584 var d = D.new()
7585 T(d)
7586 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007587 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007588enddef
7589
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007590" Test for calling methods using a null object
7591def Test_null_object_method_call()
7592 # Calling a object method using a null object in script context
7593 var lines =<< trim END
7594 vim9script
7595
7596 class C
7597 def Foo()
7598 assert_report('This method should not be executed')
7599 enddef
7600 endclass
7601
7602 var o: C
7603 o.Foo()
7604 END
7605 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7606
7607 # Calling a object method using a null object in def function context
7608 lines =<< trim END
7609 vim9script
7610
7611 class C
7612 def Foo()
7613 assert_report('This method should not be executed')
7614 enddef
7615 endclass
7616
7617 def T()
7618 var o: C
7619 o.Foo()
7620 enddef
7621 T()
7622 END
7623 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7624
7625 # Calling a object method through another class method using a null object in
7626 # script context
7627 lines =<< trim END
7628 vim9script
7629
7630 class C
7631 def Foo()
7632 assert_report('This method should not be executed')
7633 enddef
7634
7635 static def Bar(o_any: any)
7636 var o_typed: C = o_any
7637 o_typed.Foo()
7638 enddef
7639 endclass
7640
7641 var o: C
7642 C.Bar(o)
7643 END
7644 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7645
7646 # Calling a object method through another class method using a null object in
7647 # def function context
7648 lines =<< trim END
7649 vim9script
7650
7651 class C
7652 def Foo()
7653 assert_report('This method should not be executed')
7654 enddef
7655
7656 static def Bar(o_any: any)
7657 var o_typed: C = o_any
7658 o_typed.Foo()
7659 enddef
7660 endclass
7661
7662 def T()
7663 var o: C
7664 C.Bar(o)
7665 enddef
7666 T()
7667 END
7668 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Ernie Raelbe828252024-07-26 18:37:02 +02007669
7670 # Calling an object method defined in a class that is extended. This differs
7671 # from the previous by invoking ISN_METHODCALL instead of ISN_DCALL.
7672 lines =<< trim END
7673 vim9script
7674
7675 class C0
7676 def F()
7677 enddef
7678 endclass
7679
7680 class C extends C0
7681 endclass
7682
7683 def X()
7684 var o: C0 = null_object
7685 o.F()
7686 enddef
7687 X()
7688 END
7689 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7690
7691 # Getting a function ref an object method.
7692 lines =<< trim END
7693 vim9script
7694
7695 class C0
7696 def F()
7697 enddef
7698 endclass
7699
7700 class C extends C0
7701 endclass
7702
7703 def X()
7704 var o: C0 = null_object
7705 var XXX = o.F
7706 enddef
7707 X()
7708 END
7709 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007710enddef
7711
7712" Test for using a dict as an object member
7713def Test_dict_object_member()
7714 var lines =<< trim END
7715 vim9script
7716
7717 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007718 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007719 def GetState(): dict<number>
7720 return this.state
7721 enddef
7722 endclass
7723
7724 var ctx = Context.new()
7725 ctx.state->extend({a: 1})
7726 ctx.state['b'] = 2
7727 assert_equal({a: 1, b: 2}, ctx.GetState())
7728
7729 def F()
7730 ctx.state['c'] = 3
7731 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7732 enddef
7733 F()
7734 assert_equal(3, ctx.state.c)
7735 ctx.state.c = 4
7736 assert_equal(4, ctx.state.c)
7737 END
7738 v9.CheckSourceSuccess(lines)
7739enddef
7740
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007741" The following test was failing after 9.0.1914. This was caused by using a
7742" freed object from a previous method call.
7743def Test_freed_object_from_previous_method_call()
7744 var lines =<< trim END
7745 vim9script
7746
7747 class Context
7748 endclass
7749
7750 class Result
7751 endclass
7752
7753 def Failure(): Result
7754 return Result.new()
7755 enddef
7756
7757 def GetResult(ctx: Context): Result
7758 return Failure()
7759 enddef
7760
7761 def Test_GetResult()
7762 var ctx = Context.new()
7763 var result = GetResult(ctx)
7764 enddef
7765
7766 Test_GetResult()
7767 END
7768 v9.CheckSourceSuccess(lines)
7769enddef
7770
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007771" Test for duplicate object and class variable
7772def Test_duplicate_variable()
7773 # Object variable name is same as the class variable name
7774 var lines =<< trim END
7775 vim9script
7776 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007777 public static var sval: number
7778 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007779 endclass
7780 var a = A.new()
7781 END
7782 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7783
7784 # Duplicate variable name and calling a class method
7785 lines =<< trim END
7786 vim9script
7787 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007788 public static var sval: number
7789 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007790 def F1()
7791 echo this.sval
7792 enddef
7793 static def F2()
7794 echo sval
7795 enddef
7796 endclass
7797 A.F2()
7798 END
7799 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7800
7801 # Duplicate variable with an empty constructor
7802 lines =<< trim END
7803 vim9script
7804 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007805 public static var sval: number
7806 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007807 def new()
7808 enddef
7809 endclass
7810 var a = A.new()
7811 END
7812 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7813enddef
7814
7815" Test for using a reserved keyword as a variable name
7816def Test_reserved_varname()
7817 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7818 'null_function', 'null_list', 'null_partial', 'null_string',
7819 'null_channel', 'null_job', 'super', 'this']
7820
7821 var lines =<< trim eval END
7822 vim9script
7823 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007824 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007825 endclass
7826 var o = C.new()
7827 END
7828 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7829
7830 lines =<< trim eval END
7831 vim9script
7832 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007833 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007834 def new()
7835 enddef
7836 endclass
7837 var o = C.new()
7838 END
7839 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7840
7841 lines =<< trim eval END
7842 vim9script
7843 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007844 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007845 def new()
7846 enddef
7847 def F()
7848 echo this.{kword}
7849 enddef
7850 endclass
7851 var o = C.new()
7852 o.F()
7853 END
7854 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007855
7856 # class variable name
7857 if kword != 'this'
7858 lines =<< trim eval END
7859 vim9script
7860 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007861 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007862 endclass
7863 END
7864 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7865 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007866 endfor
7867enddef
7868
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007869" Test for checking the type of the arguments and the return value of a object
7870" method in an extended class.
7871def Test_extended_obj_method_type_check()
7872 var lines =<< trim END
7873 vim9script
7874
7875 class A
7876 endclass
7877 class B extends A
7878 endclass
7879 class C extends B
7880 endclass
7881
7882 class Foo
7883 def Doit(p: B): B
7884 return B.new()
7885 enddef
7886 endclass
7887
7888 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007889 def Doit(p: C): B
7890 return B.new()
7891 enddef
7892 endclass
7893 END
7894 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7895
7896 lines =<< trim END
7897 vim9script
7898
7899 class A
7900 endclass
7901 class B extends A
7902 endclass
7903 class C extends B
7904 endclass
7905
7906 class Foo
7907 def Doit(p: B): B
7908 return B.new()
7909 enddef
7910 endclass
7911
7912 class Bar extends Foo
7913 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007914 return C.new()
7915 enddef
7916 endclass
7917 END
7918 v9.CheckSourceSuccess(lines)
7919
7920 lines =<< trim END
7921 vim9script
7922
7923 class A
7924 endclass
7925 class B extends A
7926 endclass
7927 class C extends B
7928 endclass
7929
7930 class Foo
7931 def Doit(p: B): B
7932 return B.new()
7933 enddef
7934 endclass
7935
7936 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007937 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007938 return B.new()
7939 enddef
7940 endclass
7941 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007942 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<A>): object<B>', 20)
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007943
7944 lines =<< trim END
7945 vim9script
7946
7947 class A
7948 endclass
7949 class B extends A
7950 endclass
7951 class C extends B
7952 endclass
7953
7954 class Foo
7955 def Doit(p: B): B
7956 return B.new()
7957 enddef
7958 endclass
7959
7960 class Bar extends Foo
7961 def Doit(p: B): A
7962 return A.new()
7963 enddef
7964 endclass
7965 END
7966 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<B>): object<A>', 20)
Ernie Rael96952b22023-10-17 18:15:01 +02007967
7968 # check varargs type mismatch
7969 lines =<< trim END
7970 vim9script
7971
7972 class B
7973 def F(...xxx: list<any>)
7974 enddef
7975 endclass
7976 class C extends B
7977 def F(xxx: list<any>)
7978 enddef
7979 endclass
7980 END
7981 v9.CheckSourceFailure(lines, 'E1383: Method "F": type mismatch, expected func(...list<any>) but got func(list<any>)', 10)
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007982enddef
7983
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007984" Test type checking for class variable in assignments
7985func Test_class_variable_complex_type_check()
7986 " class variable with a specific type. Try assigning a different type at
7987 " script level.
7988 let lines =<< trim END
7989 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007990 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007991 return {}
7992 enddef
7993 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007994 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007995 endclass
7996 test_garbagecollect_now()
7997 A.Fn = "abc"
7998 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007999 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 9)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008000
8001 " class variable with a specific type. Try assigning a different type at
8002 " class def method level.
8003 let lines =<< trim END
8004 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008005 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008006 return {}
8007 enddef
8008 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008009 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008010 def Bar()
8011 Fn = "abc"
8012 enddef
8013 endclass
8014 var a = A.new()
8015 test_garbagecollect_now()
8016 a.Bar()
8017 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008018 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008019
8020 " class variable with a specific type. Try assigning a different type at
8021 " script def method level.
8022 let lines =<< trim END
8023 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008024 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008025 return {}
8026 enddef
8027 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008028 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008029 endclass
8030 def Bar()
8031 A.Fn = "abc"
8032 enddef
8033 test_garbagecollect_now()
8034 Bar()
8035 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008036 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008037
8038 " class variable without any type. Should be set to the initialization
8039 " expression type. Try assigning a different type from script level.
8040 let lines =<< trim END
8041 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008042 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008043 return {}
8044 enddef
8045 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008046 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008047 endclass
8048 test_garbagecollect_now()
8049 A.Fn = "abc"
8050 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008051 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 9)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008052
8053 " class variable without any type. Should be set to the initialization
8054 " expression type. Try assigning a different type at class def level.
8055 let lines =<< trim END
8056 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008057 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008058 return {}
8059 enddef
8060 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008061 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008062 def Bar()
8063 Fn = "abc"
8064 enddef
8065 endclass
8066 var a = A.new()
8067 test_garbagecollect_now()
8068 a.Bar()
8069 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008070 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008071
8072 " class variable without any type. Should be set to the initialization
8073 " expression type. Try assigning a different type at script def level.
8074 let lines =<< trim END
8075 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008076 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008077 return {}
8078 enddef
8079 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008080 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008081 endclass
8082 def Bar()
8083 A.Fn = "abc"
8084 enddef
8085 test_garbagecollect_now()
8086 Bar()
8087 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008088 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008089
8090 " class variable with 'any" type. Can be assigned different types.
8091 let lines =<< trim END
8092 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008093 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008094 return {}
8095 enddef
8096 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008097 public static var Fn: any = Foo
8098 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008099 endclass
8100 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008101 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008102 A.Fn = "abc"
8103 test_garbagecollect_now()
8104 assert_equal('string', typename(A.Fn))
8105 A.Fn2 = Foo
8106 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008107 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008108 A.Fn2 = "xyz"
8109 test_garbagecollect_now()
8110 assert_equal('string', typename(A.Fn2))
8111 END
8112 call v9.CheckSourceSuccess(lines)
8113
8114 " class variable with 'any" type. Can be assigned different types.
8115 let lines =<< trim END
8116 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008117 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008118 return {}
8119 enddef
8120 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008121 public static var Fn: any = Foo
8122 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008123
8124 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008125 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008126 Fn = "abc"
8127 assert_equal('string', typename(Fn))
8128 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008129 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008130 Fn2 = "xyz"
8131 assert_equal('string', typename(Fn2))
8132 enddef
8133 endclass
8134 var a = A.new()
8135 test_garbagecollect_now()
8136 a.Bar()
8137 test_garbagecollect_now()
8138 A.Fn = Foo
8139 a.Bar()
8140 END
8141 call v9.CheckSourceSuccess(lines)
8142
8143 " class variable with 'any" type. Can be assigned different types.
8144 let lines =<< trim END
8145 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008146 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008147 return {}
8148 enddef
8149 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008150 public static var Fn: any = Foo
8151 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008152 endclass
8153
8154 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008155 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008156 A.Fn = "abc"
8157 assert_equal('string', typename(A.Fn))
8158 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008159 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008160 A.Fn2 = "xyz"
8161 assert_equal('string', typename(A.Fn2))
8162 enddef
8163 Bar()
8164 test_garbagecollect_now()
8165 A.Fn = Foo
8166 Bar()
8167 END
8168 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008169
8170 let lines =<< trim END
8171 vim9script
8172 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008173 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008174 endclass
8175 assert_equal([0z10, 0z20], A.foo)
8176 A.foo = [0z30]
8177 assert_equal([0z30], A.foo)
8178 var a = A.foo
8179 assert_equal([0z30], a)
8180 END
8181 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008182endfunc
8183
8184" Test type checking for object variable in assignments
8185func Test_object_variable_complex_type_check()
8186 " object variable with a specific type. Try assigning a different type at
8187 " script level.
8188 let lines =<< trim END
8189 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008190 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008191 return {}
8192 enddef
8193 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008194 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008195 endclass
8196 var a = A.new()
8197 test_garbagecollect_now()
8198 a.Fn = "abc"
8199 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008200 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 10)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008201
8202 " object variable with a specific type. Try assigning a different type at
8203 " object def method level.
8204 let lines =<< trim END
8205 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008206 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008207 return {}
8208 enddef
8209 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008210 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008211 def Bar()
8212 this.Fn = "abc"
8213 this.Fn = Foo
8214 enddef
8215 endclass
8216 var a = A.new()
8217 test_garbagecollect_now()
8218 a.Bar()
8219 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008220 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008221
8222 " object variable with a specific type. Try assigning a different type at
8223 " script def method level.
8224 let lines =<< trim END
8225 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008226 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008227 return {}
8228 enddef
8229 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008230 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008231 endclass
8232 def Bar()
8233 var a = A.new()
8234 a.Fn = "abc"
8235 a.Fn = Foo
8236 enddef
8237 test_garbagecollect_now()
8238 Bar()
8239 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008240 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 2)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008241
8242 " object variable without any type. Should be set to the initialization
8243 " expression type. Try assigning a different type from script level.
8244 let lines =<< trim END
8245 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008246 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008247 return {}
8248 enddef
8249 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008250 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008251 endclass
8252 var a = A.new()
8253 test_garbagecollect_now()
8254 a.Fn = "abc"
8255 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008256 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 10)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008257
8258 " object variable without any type. Should be set to the initialization
8259 " expression type. Try assigning a different type at object def level.
8260 let lines =<< trim END
8261 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008262 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008263 return {}
8264 enddef
8265 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008266 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008267 def Bar()
8268 this.Fn = "abc"
8269 this.Fn = Foo
8270 enddef
8271 endclass
8272 var a = A.new()
8273 test_garbagecollect_now()
8274 a.Bar()
8275 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008276 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008277
8278 " object variable without any type. Should be set to the initialization
8279 " expression type. Try assigning a different type at script def level.
8280 let lines =<< trim END
8281 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008282 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008283 return {}
8284 enddef
8285 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008286 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008287 endclass
8288 def Bar()
8289 var a = A.new()
8290 a.Fn = "abc"
8291 a.Fn = Foo
8292 enddef
8293 test_garbagecollect_now()
8294 Bar()
8295 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008296 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 2)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008297
8298 " object variable with 'any" type. Can be assigned different types.
8299 let lines =<< trim END
8300 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008301 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008302 return {}
8303 enddef
8304 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008305 public var Fn: any = Foo
8306 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008307 endclass
8308
8309 var a = A.new()
8310 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008311 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008312 a.Fn = "abc"
8313 test_garbagecollect_now()
8314 assert_equal('string', typename(a.Fn))
8315 a.Fn2 = Foo
8316 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008317 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008318 a.Fn2 = "xyz"
8319 test_garbagecollect_now()
8320 assert_equal('string', typename(a.Fn2))
8321 END
8322 call v9.CheckSourceSuccess(lines)
8323
8324 " object variable with 'any" type. Can be assigned different types.
8325 let lines =<< trim END
8326 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008327 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008328 return {}
8329 enddef
8330 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008331 public var Fn: any = Foo
8332 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008333
8334 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008335 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008336 this.Fn = "abc"
8337 assert_equal('string', typename(this.Fn))
8338 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008339 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008340 this.Fn2 = "xyz"
8341 assert_equal('string', typename(this.Fn2))
8342 enddef
8343 endclass
8344
8345 var a = A.new()
8346 test_garbagecollect_now()
8347 a.Bar()
8348 test_garbagecollect_now()
8349 a.Fn = Foo
8350 a.Bar()
8351 END
8352 call v9.CheckSourceSuccess(lines)
8353
8354 " object variable with 'any" type. Can be assigned different types.
8355 let lines =<< trim END
8356 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008357 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008358 return {}
8359 enddef
8360 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008361 public var Fn: any = Foo
8362 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008363 endclass
8364
8365 def Bar()
8366 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008367 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008368 a.Fn = "abc"
8369 assert_equal('string', typename(a.Fn))
8370 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008371 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008372 a.Fn2 = "xyz"
8373 assert_equal('string', typename(a.Fn2))
8374 enddef
8375 test_garbagecollect_now()
8376 Bar()
8377 test_garbagecollect_now()
8378 Bar()
8379 END
8380 call v9.CheckSourceSuccess(lines)
8381endfunc
8382
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008383" Test for recursively calling an object method. This used to cause an
8384" use-after-free error.
8385def Test_recursive_object_method_call()
8386 var lines =<< trim END
8387 vim9script
8388 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008389 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008390 def Foo(): number
8391 if this.val >= 90
8392 return this.val
8393 endif
8394 this.val += 1
8395 return this.Foo()
8396 enddef
8397 endclass
8398 var a = A.new()
8399 assert_equal(90, a.Foo())
8400 END
8401 v9.CheckSourceSuccess(lines)
8402enddef
8403
8404" Test for recursively calling a class method.
8405def Test_recursive_class_method_call()
8406 var lines =<< trim END
8407 vim9script
8408 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008409 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008410 static def Foo(): number
8411 if val >= 90
8412 return val
8413 endif
8414 val += 1
8415 return Foo()
8416 enddef
8417 endclass
8418 assert_equal(90, A.Foo())
8419 END
8420 v9.CheckSourceSuccess(lines)
8421enddef
8422
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02008423" Test for checking the argument types and the return type when assigning a
8424" funcref to make sure the invariant class type is used.
8425def Test_funcref_argtype_returntype_check()
8426 var lines =<< trim END
8427 vim9script
8428 class A
8429 endclass
8430 class B extends A
8431 endclass
8432
8433 def Foo(p: B): B
8434 return B.new()
8435 enddef
8436
8437 var Bar: func(A): A = Foo
8438 END
8439 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
8440
8441 lines =<< trim END
8442 vim9script
8443 class A
8444 endclass
8445 class B extends A
8446 endclass
8447
8448 def Foo(p: B): B
8449 return B.new()
8450 enddef
8451
8452 def Baz()
8453 var Bar: func(A): A = Foo
8454 enddef
8455 Baz()
8456 END
8457 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
8458enddef
8459
Ernie Rael96952b22023-10-17 18:15:01 +02008460def Test_funcref_argtype_invariance_check()
8461 var lines =<< trim END
8462 vim9script
8463
8464 class A
8465 endclass
8466 class B extends A
8467 endclass
8468 class C extends B
8469 endclass
8470
8471 var Func: func(B): number
8472 Func = (o: B): number => 3
8473 assert_equal(3, Func(B.new()))
8474 END
8475 v9.CheckSourceSuccess(lines)
8476
8477 lines =<< trim END
8478 vim9script
8479
8480 class A
8481 endclass
8482 class B extends A
8483 endclass
8484 class C extends B
8485 endclass
8486
8487 var Func: func(B): number
8488 Func = (o: A): number => 3
8489 END
8490 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
8491
8492 lines =<< trim END
8493 vim9script
8494
8495 class A
8496 endclass
8497 class B extends A
8498 endclass
8499 class C extends B
8500 endclass
8501
8502 var Func: func(B): number
8503 Func = (o: C): number => 3
8504 END
8505 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
8506enddef
8507
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008508" Test for using an operator (e.g. +) with an assignment
8509def Test_op_and_assignment()
8510 # Using += with a class variable
8511 var lines =<< trim END
8512 vim9script
8513 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008514 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008515 static def Foo(): list<number>
8516 val += [1]
8517 return val
8518 enddef
8519 endclass
8520 def Bar(): list<number>
8521 A.val += [2]
8522 return A.val
8523 enddef
8524 assert_equal([1], A.Foo())
8525 assert_equal([1, 2], Bar())
8526 A.val += [3]
8527 assert_equal([1, 2, 3], A.val)
8528 END
8529 v9.CheckSourceSuccess(lines)
8530
8531 # Using += with an object variable
8532 lines =<< trim END
8533 vim9script
8534 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008535 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008536 def Foo(): list<number>
8537 this.val += [1]
8538 return this.val
8539 enddef
8540 endclass
8541 def Bar(bar_a: A): list<number>
8542 bar_a.val += [2]
8543 return bar_a.val
8544 enddef
8545 var a = A.new()
8546 assert_equal([1], a.Foo())
8547 assert_equal([1, 2], Bar(a))
8548 a.val += [3]
8549 assert_equal([1, 2, 3], a.val)
8550 END
8551 v9.CheckSourceSuccess(lines)
8552enddef
8553
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008554" Test for using an object method as a funcref
8555def Test_object_funcref()
8556 # Using object method funcref from a def function
8557 var lines =<< trim END
8558 vim9script
8559 class A
8560 def Foo(): list<number>
8561 return [3, 2, 1]
8562 enddef
8563 endclass
8564 def Bar()
8565 var a = A.new()
8566 var Fn = a.Foo
8567 assert_equal([3, 2, 1], Fn())
8568 enddef
8569 Bar()
8570 END
8571 v9.CheckSourceSuccess(lines)
8572
8573 # Using object method funcref at the script level
8574 lines =<< trim END
8575 vim9script
8576 class A
8577 def Foo(): dict<number>
8578 return {a: 1, b: 2}
8579 enddef
8580 endclass
8581 var a = A.new()
8582 var Fn = a.Foo
8583 assert_equal({a: 1, b: 2}, Fn())
8584 END
8585 v9.CheckSourceSuccess(lines)
8586
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008587 # Using object method funcref at the script level
8588 lines =<< trim END
8589 vim9script
8590 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008591 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008592 def Foo(): number
8593 return this.val
8594 enddef
8595 endclass
8596 var a = A.new(345)
8597 var Fn = a.Foo
8598 assert_equal(345, Fn())
8599 END
8600 v9.CheckSourceSuccess(lines)
8601
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008602 # Using object method funcref from another object method
8603 lines =<< trim END
8604 vim9script
8605 class A
8606 def Foo(): list<number>
8607 return [3, 2, 1]
8608 enddef
8609 def Bar()
8610 var Fn = this.Foo
8611 assert_equal([3, 2, 1], Fn())
8612 enddef
8613 endclass
8614 var a = A.new()
8615 a.Bar()
8616 END
8617 v9.CheckSourceSuccess(lines)
8618
8619 # Using function() to get a object method funcref
8620 lines =<< trim END
8621 vim9script
8622 class A
8623 def Foo(l: list<any>): list<any>
8624 return l
8625 enddef
8626 endclass
8627 var a = A.new()
8628 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8629 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8630 END
8631 v9.CheckSourceSuccess(lines)
8632
8633 # Use an object method with a function returning a funcref and then call the
8634 # funcref.
8635 lines =<< trim END
8636 vim9script
8637
8638 def Map(F: func(number): number): func(number): number
8639 return (n: number) => F(n)
8640 enddef
8641
8642 class Math
8643 def Double(n: number): number
8644 return 2 * n
8645 enddef
8646 endclass
8647
8648 const math = Math.new()
8649 assert_equal(48, Map(math.Double)(24))
8650 END
8651 v9.CheckSourceSuccess(lines)
8652
Ernie Rael03042a22023-11-11 08:53:32 +01008653 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008654 lines =<< trim END
8655 vim9script
8656 class A
8657 def _Foo()
8658 enddef
8659 endclass
8660 def Bar()
8661 var a = A.new()
8662 var Fn = a._Foo
8663 enddef
8664 Bar()
8665 END
Ernie Rael03042a22023-11-11 08:53:32 +01008666 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008667
Ernie Rael03042a22023-11-11 08:53:32 +01008668 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008669 lines =<< trim END
8670 vim9script
8671 class A
8672 def _Foo()
8673 enddef
8674 endclass
8675 var a = A.new()
8676 var Fn = a._Foo
8677 END
Ernie Rael03042a22023-11-11 08:53:32 +01008678 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008679
Ernie Rael03042a22023-11-11 08:53:32 +01008680 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008681 lines =<< trim END
8682 vim9script
8683 class A
8684 def _Foo(): list<number>
8685 return [3, 2, 1]
8686 enddef
8687 def Bar()
8688 var Fn = this._Foo
8689 assert_equal([3, 2, 1], Fn())
8690 enddef
8691 endclass
8692 var a = A.new()
8693 a.Bar()
8694 END
8695 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008696
8697 # Using object method funcref using call()
8698 lines =<< trim END
8699 vim9script
8700 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008701 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008702 def Foo(): number
8703 return this.val
8704 enddef
8705 endclass
8706
8707 def Bar(obj: A)
8708 assert_equal(123, call(obj.Foo, []))
8709 enddef
8710
8711 var a = A.new(123)
8712 Bar(a)
8713 assert_equal(123, call(a.Foo, []))
8714 END
8715 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008716enddef
8717
8718" Test for using a class method as a funcref
8719def Test_class_funcref()
8720 # Using class method funcref in a def function
8721 var lines =<< trim END
8722 vim9script
8723 class A
8724 static def Foo(): list<number>
8725 return [3, 2, 1]
8726 enddef
8727 endclass
8728 def Bar()
8729 var Fn = A.Foo
8730 assert_equal([3, 2, 1], Fn())
8731 enddef
8732 Bar()
8733 END
8734 v9.CheckSourceSuccess(lines)
8735
8736 # Using class method funcref at script level
8737 lines =<< trim END
8738 vim9script
8739 class A
8740 static def Foo(): dict<number>
8741 return {a: 1, b: 2}
8742 enddef
8743 endclass
8744 var Fn = A.Foo
8745 assert_equal({a: 1, b: 2}, Fn())
8746 END
8747 v9.CheckSourceSuccess(lines)
8748
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008749 # Using class method funcref at the script level
8750 lines =<< trim END
8751 vim9script
8752 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008753 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008754 static def Foo(): number
8755 return val
8756 enddef
8757 endclass
8758 A.val = 567
8759 var Fn = A.Foo
8760 assert_equal(567, Fn())
8761 END
8762 v9.CheckSourceSuccess(lines)
8763
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008764 # Using function() to get a class method funcref
8765 lines =<< trim END
8766 vim9script
8767 class A
8768 static def Foo(l: list<any>): list<any>
8769 return l
8770 enddef
8771 endclass
8772 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8773 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8774 END
8775 v9.CheckSourceSuccess(lines)
8776
8777 # Using a class method funcref from another class method
8778 lines =<< trim END
8779 vim9script
8780 class A
8781 static def Foo(): list<number>
8782 return [3, 2, 1]
8783 enddef
8784 static def Bar()
8785 var Fn = Foo
8786 assert_equal([3, 2, 1], Fn())
8787 enddef
8788 endclass
8789 A.Bar()
8790 END
8791 v9.CheckSourceSuccess(lines)
8792
8793 # Use a class method with a function returning a funcref and then call the
8794 # funcref.
8795 lines =<< trim END
8796 vim9script
8797
8798 def Map(F: func(number): number): func(number): number
8799 return (n: number) => F(n)
8800 enddef
8801
8802 class Math
8803 static def StaticDouble(n: number): number
8804 return 2 * n
8805 enddef
8806 endclass
8807
8808 assert_equal(48, Map(Math.StaticDouble)(24))
8809 END
8810 v9.CheckSourceSuccess(lines)
8811
Ernie Rael03042a22023-11-11 08:53:32 +01008812 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008813 lines =<< trim END
8814 vim9script
8815 class A
8816 static def _Foo()
8817 enddef
8818 endclass
8819 def Bar()
8820 var Fn = A._Foo
8821 enddef
8822 Bar()
8823 END
Ernie Rael03042a22023-11-11 08:53:32 +01008824 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008825
Ernie Rael03042a22023-11-11 08:53:32 +01008826 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008827 lines =<< trim END
8828 vim9script
8829 class A
8830 static def _Foo()
8831 enddef
8832 endclass
8833 var Fn = A._Foo
8834 END
Ernie Rael03042a22023-11-11 08:53:32 +01008835 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008836
Ernie Rael03042a22023-11-11 08:53:32 +01008837 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008838 lines =<< trim END
8839 vim9script
8840 class A
8841 static def _Foo(): list<number>
8842 return [3, 2, 1]
8843 enddef
8844 static def Bar()
8845 var Fn = _Foo
8846 assert_equal([3, 2, 1], Fn())
8847 enddef
8848 endclass
8849 A.Bar()
8850 END
8851 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008852
8853 # Using class method funcref using call()
8854 lines =<< trim END
8855 vim9script
8856 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008857 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008858 static def Foo(): number
8859 return val
8860 enddef
8861 endclass
8862
8863 def Bar()
8864 A.val = 468
8865 assert_equal(468, call(A.Foo, []))
8866 enddef
8867 Bar()
8868 assert_equal(468, call(A.Foo, []))
8869 END
8870 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008871enddef
8872
8873" Test for using an object member as a funcref
8874def Test_object_member_funcref()
8875 # Using a funcref object variable in an object method
8876 var lines =<< trim END
8877 vim9script
8878 def Foo(n: number): number
8879 return n * 10
8880 enddef
8881
8882 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008883 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008884 def Bar()
8885 assert_equal(200, this.Cb(20))
8886 enddef
8887 endclass
8888
8889 var a = A.new()
8890 a.Bar()
8891 END
8892 v9.CheckSourceSuccess(lines)
8893
8894 # Using a funcref object variable in a def method
8895 lines =<< trim END
8896 vim9script
8897 def Foo(n: number): number
8898 return n * 10
8899 enddef
8900
8901 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008902 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008903 endclass
8904
8905 def Bar()
8906 var a = A.new()
8907 assert_equal(200, a.Cb(20))
8908 enddef
8909 Bar()
8910 END
8911 v9.CheckSourceSuccess(lines)
8912
8913 # Using a funcref object variable at script level
8914 lines =<< trim END
8915 vim9script
8916 def Foo(n: number): number
8917 return n * 10
8918 enddef
8919
8920 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008921 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008922 endclass
8923
8924 var a = A.new()
8925 assert_equal(200, a.Cb(20))
8926 END
8927 v9.CheckSourceSuccess(lines)
8928
8929 # Using a funcref object variable pointing to an object method in an object
8930 # method.
8931 lines =<< trim END
8932 vim9script
8933 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008934 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008935 def Foo(n: number): number
8936 return n * 10
8937 enddef
8938 def Bar()
8939 assert_equal(200, this.Cb(20))
8940 enddef
8941 endclass
8942
8943 var a = A.new()
8944 a.Bar()
8945 END
8946 v9.CheckSourceSuccess(lines)
8947
8948 # Using a funcref object variable pointing to an object method in a def
8949 # method.
8950 lines =<< trim END
8951 vim9script
8952 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008953 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008954 def Foo(n: number): number
8955 return n * 10
8956 enddef
8957 endclass
8958
8959 def Bar()
8960 var a = A.new()
8961 assert_equal(200, a.Cb(20))
8962 enddef
8963 Bar()
8964 END
8965 v9.CheckSourceSuccess(lines)
8966
8967 # Using a funcref object variable pointing to an object method at script
8968 # level.
8969 lines =<< trim END
8970 vim9script
8971 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008972 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008973 def Foo(n: number): number
8974 return n * 10
8975 enddef
8976 endclass
8977
8978 var a = A.new()
8979 assert_equal(200, a.Cb(20))
8980 END
8981 v9.CheckSourceSuccess(lines)
8982enddef
8983
8984" Test for using a class member as a funcref
8985def Test_class_member_funcref()
8986 # Using a funcref class variable in a class method
8987 var lines =<< trim END
8988 vim9script
8989 def Foo(n: number): number
8990 return n * 10
8991 enddef
8992
8993 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008994 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008995 static def Bar()
8996 assert_equal(200, Cb(20))
8997 enddef
8998 endclass
8999
9000 A.Bar()
9001 END
9002 v9.CheckSourceSuccess(lines)
9003
9004 # Using a funcref class variable in a def method
9005 lines =<< trim END
9006 vim9script
9007 def Foo(n: number): number
9008 return n * 10
9009 enddef
9010
9011 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009012 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02009013 endclass
9014
9015 def Bar()
9016 assert_equal(200, A.Cb(20))
9017 enddef
9018 Bar()
9019 END
9020 v9.CheckSourceSuccess(lines)
9021
9022 # Using a funcref class variable at script level
9023 lines =<< trim END
9024 vim9script
9025 def Foo(n: number): number
9026 return n * 10
9027 enddef
9028
9029 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009030 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02009031 endclass
9032
9033 assert_equal(200, A.Cb(20))
9034 END
9035 v9.CheckSourceSuccess(lines)
9036
9037 # Using a funcref class variable pointing to a class method in a class
9038 # method.
9039 lines =<< trim END
9040 vim9script
9041 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009042 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02009043 static def Foo(n: number): number
9044 return n * 10
9045 enddef
9046 static def Init()
9047 Cb = Foo
9048 enddef
9049 static def Bar()
9050 assert_equal(200, Cb(20))
9051 enddef
9052 endclass
9053
9054 A.Init()
9055 A.Bar()
9056 END
9057 v9.CheckSourceSuccess(lines)
9058
9059 # Using a funcref class variable pointing to a class method in a def method.
9060 lines =<< trim END
9061 vim9script
9062 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009063 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02009064 static def Foo(n: number): number
9065 return n * 10
9066 enddef
9067 static def Init()
9068 Cb = Foo
9069 enddef
9070 endclass
9071
9072 def Bar()
9073 A.Init()
9074 assert_equal(200, A.Cb(20))
9075 enddef
9076 Bar()
9077 END
9078 v9.CheckSourceSuccess(lines)
9079
9080 # Using a funcref class variable pointing to a class method at script level.
9081 lines =<< trim END
9082 vim9script
9083 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009084 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02009085 static def Foo(n: number): number
9086 return n * 10
9087 enddef
9088 static def Init()
9089 Cb = Foo
9090 enddef
9091 endclass
9092
9093 A.Init()
9094 assert_equal(200, A.Cb(20))
9095 END
9096 v9.CheckSourceSuccess(lines)
9097enddef
9098
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009099" Test for using object methods as popup callback functions
9100def Test_objmethod_popup_callback()
9101 # Use the popup from the script level
9102 var lines =<< trim END
9103 vim9script
9104
9105 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009106 var selection: number = -1
9107 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009108
9109 def PopupFilter(id: number, key: string): bool
9110 add(this.filterkeys, key)
9111 return popup_filter_yesno(id, key)
9112 enddef
9113
9114 def PopupCb(id: number, result: number)
9115 this.selection = result ? 100 : 200
9116 enddef
9117 endclass
9118
9119 var a = A.new()
9120 feedkeys('', 'xt')
9121 var winid = popup_create('Y/N?',
9122 {filter: a.PopupFilter, callback: a.PopupCb})
9123 feedkeys('y', 'xt')
9124 popup_close(winid)
9125 assert_equal(100, a.selection)
9126 assert_equal(['y'], a.filterkeys)
9127 feedkeys('', 'xt')
9128 winid = popup_create('Y/N?',
9129 {filter: a.PopupFilter, callback: a.PopupCb})
9130 feedkeys('n', 'xt')
9131 popup_close(winid)
9132 assert_equal(200, a.selection)
9133 assert_equal(['y', 'n'], a.filterkeys)
9134 END
9135 v9.CheckSourceSuccess(lines)
9136
9137 # Use the popup from a def function
9138 lines =<< trim END
9139 vim9script
9140
9141 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009142 var selection: number = -1
9143 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009144
9145 def PopupFilter(id: number, key: string): bool
9146 add(this.filterkeys, key)
9147 return popup_filter_yesno(id, key)
9148 enddef
9149
9150 def PopupCb(id: number, result: number)
9151 this.selection = result ? 100 : 200
9152 enddef
9153 endclass
9154
9155 def Foo()
9156 var a = A.new()
9157 feedkeys('', 'xt')
9158 var winid = popup_create('Y/N?',
9159 {filter: a.PopupFilter, callback: a.PopupCb})
9160 feedkeys('y', 'xt')
9161 popup_close(winid)
9162 assert_equal(100, a.selection)
9163 assert_equal(['y'], a.filterkeys)
9164 feedkeys('', 'xt')
9165 winid = popup_create('Y/N?',
9166 {filter: a.PopupFilter, callback: a.PopupCb})
9167 feedkeys('n', 'xt')
9168 popup_close(winid)
9169 assert_equal(200, a.selection)
9170 assert_equal(['y', 'n'], a.filterkeys)
9171 enddef
9172 Foo()
9173 END
9174 v9.CheckSourceSuccess(lines)
9175enddef
9176
9177" Test for using class methods as popup callback functions
9178def Test_classmethod_popup_callback()
9179 # Use the popup from the script level
9180 var lines =<< trim END
9181 vim9script
9182
9183 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009184 static var selection: number = -1
9185 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009186
9187 static def PopupFilter(id: number, key: string): bool
9188 add(filterkeys, key)
9189 return popup_filter_yesno(id, key)
9190 enddef
9191
9192 static def PopupCb(id: number, result: number)
9193 selection = result ? 100 : 200
9194 enddef
9195 endclass
9196
9197 feedkeys('', 'xt')
9198 var winid = popup_create('Y/N?',
9199 {filter: A.PopupFilter, callback: A.PopupCb})
9200 feedkeys('y', 'xt')
9201 popup_close(winid)
9202 assert_equal(100, A.selection)
9203 assert_equal(['y'], A.filterkeys)
9204 feedkeys('', 'xt')
9205 winid = popup_create('Y/N?',
9206 {filter: A.PopupFilter, callback: A.PopupCb})
9207 feedkeys('n', 'xt')
9208 popup_close(winid)
9209 assert_equal(200, A.selection)
9210 assert_equal(['y', 'n'], A.filterkeys)
9211 END
9212 v9.CheckSourceSuccess(lines)
9213
9214 # Use the popup from a def function
9215 lines =<< trim END
9216 vim9script
9217
9218 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009219 static var selection: number = -1
9220 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009221
9222 static def PopupFilter(id: number, key: string): bool
9223 add(filterkeys, key)
9224 return popup_filter_yesno(id, key)
9225 enddef
9226
9227 static def PopupCb(id: number, result: number)
9228 selection = result ? 100 : 200
9229 enddef
9230 endclass
9231
9232 def Foo()
9233 feedkeys('', 'xt')
9234 var winid = popup_create('Y/N?',
9235 {filter: A.PopupFilter, callback: A.PopupCb})
9236 feedkeys('y', 'xt')
9237 popup_close(winid)
9238 assert_equal(100, A.selection)
9239 assert_equal(['y'], A.filterkeys)
9240 feedkeys('', 'xt')
9241 winid = popup_create('Y/N?',
9242 {filter: A.PopupFilter, callback: A.PopupCb})
9243 feedkeys('n', 'xt')
9244 popup_close(winid)
9245 assert_equal(200, A.selection)
9246 assert_equal(['y', 'n'], A.filterkeys)
9247 enddef
9248 Foo()
9249 END
9250 v9.CheckSourceSuccess(lines)
9251enddef
9252
9253" Test for using an object method as a timer callback function
9254def Test_objmethod_timer_callback()
9255 # Use the timer callback from script level
9256 var lines =<< trim END
9257 vim9script
9258
9259 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009260 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009261 def TimerCb(timerID: number)
9262 this.timerTick = 6
9263 enddef
9264 endclass
9265
9266 var a = A.new()
9267 timer_start(0, a.TimerCb)
9268 var maxWait = 5
9269 while maxWait > 0 && a.timerTick == -1
9270 :sleep 10m
9271 maxWait -= 1
9272 endwhile
9273 assert_equal(6, a.timerTick)
9274 END
9275 v9.CheckSourceSuccess(lines)
9276
9277 # Use the timer callback from a def function
9278 lines =<< trim END
9279 vim9script
9280
9281 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009282 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009283 def TimerCb(timerID: number)
9284 this.timerTick = 6
9285 enddef
9286 endclass
9287
9288 def Foo()
9289 var a = A.new()
9290 timer_start(0, a.TimerCb)
9291 var maxWait = 5
9292 while maxWait > 0 && a.timerTick == -1
9293 :sleep 10m
9294 maxWait -= 1
9295 endwhile
9296 assert_equal(6, a.timerTick)
9297 enddef
9298 Foo()
9299 END
9300 v9.CheckSourceSuccess(lines)
9301enddef
9302
9303" Test for using a class method as a timer callback function
9304def Test_classmethod_timer_callback()
9305 # Use the timer callback from script level
9306 var lines =<< trim END
9307 vim9script
9308
9309 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009310 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009311 static def TimerCb(timerID: number)
9312 timerTick = 6
9313 enddef
9314 endclass
9315
9316 timer_start(0, A.TimerCb)
9317 var maxWait = 5
9318 while maxWait > 0 && A.timerTick == -1
9319 :sleep 10m
9320 maxWait -= 1
9321 endwhile
9322 assert_equal(6, A.timerTick)
9323 END
9324 v9.CheckSourceSuccess(lines)
9325
9326 # Use the timer callback from a def function
9327 lines =<< trim END
9328 vim9script
9329
9330 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009331 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009332 static def TimerCb(timerID: number)
9333 timerTick = 6
9334 enddef
9335 endclass
9336
9337 def Foo()
9338 timer_start(0, A.TimerCb)
9339 var maxWait = 5
9340 while maxWait > 0 && A.timerTick == -1
9341 :sleep 10m
9342 maxWait -= 1
9343 endwhile
9344 assert_equal(6, A.timerTick)
9345 enddef
9346 Foo()
9347 END
9348 v9.CheckSourceSuccess(lines)
9349enddef
9350
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009351" Test for using a class variable as the first and/or second operand of a binary
9352" operator.
9353def Test_class_variable_as_operands()
9354 var lines =<< trim END
9355 vim9script
9356 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01009357 static var truthy: bool = true
9358 public static var TruthyFn: func
9359 static var list: list<any> = []
9360 static var four: number = 4
9361 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009362
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009363 static def Str(): string
9364 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009365 enddef
9366
9367 static def Four(): number
9368 return four
9369 enddef
9370
9371 static def List(): list<any>
9372 return list
9373 enddef
9374
9375 static def Truthy(): bool
9376 return truthy
9377 enddef
9378
9379 def TestOps()
9380 assert_true(Tests.truthy == truthy)
9381 assert_true(truthy == Tests.truthy)
9382 assert_true(Tests.list isnot [])
9383 assert_true([] isnot Tests.list)
9384 assert_equal(2, Tests.four >> 1)
9385 assert_equal(16, 1 << Tests.four)
9386 assert_equal(8, Tests.four + four)
9387 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009388 assert_equal('hellohello', Tests.str .. str)
9389 assert_equal('hellohello', str .. Tests.str)
9390
9391 # Using class variable for list indexing
9392 var l = range(10)
9393 assert_equal(4, l[Tests.four])
9394 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9395
9396 # Using class variable for Dict key
9397 var d = {hello: 'abc'}
9398 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009399 enddef
9400 endclass
9401
9402 def TestOps2()
9403 assert_true(Tests.truthy == Tests.Truthy())
9404 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009405 assert_true(Tests.truthy == Tests.TruthyFn())
9406 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009407 assert_true(Tests.list is Tests.List())
9408 assert_true(Tests.List() is Tests.list)
9409 assert_equal(2, Tests.four >> 1)
9410 assert_equal(16, 1 << Tests.four)
9411 assert_equal(8, Tests.four + Tests.Four())
9412 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009413 assert_equal('hellohello', Tests.str .. Tests.Str())
9414 assert_equal('hellohello', Tests.Str() .. Tests.str)
9415
9416 # Using class variable for list indexing
9417 var l = range(10)
9418 assert_equal(4, l[Tests.four])
9419 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9420
9421 # Using class variable for Dict key
9422 var d = {hello: 'abc'}
9423 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009424 enddef
9425
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009426 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009427 var t = Tests.new()
9428 t.TestOps()
9429 TestOps2()
9430
9431 assert_true(Tests.truthy == Tests.Truthy())
9432 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009433 assert_true(Tests.truthy == Tests.TruthyFn())
9434 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009435 assert_true(Tests.list is Tests.List())
9436 assert_true(Tests.List() is Tests.list)
9437 assert_equal(2, Tests.four >> 1)
9438 assert_equal(16, 1 << Tests.four)
9439 assert_equal(8, Tests.four + Tests.Four())
9440 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009441 assert_equal('hellohello', Tests.str .. Tests.Str())
9442 assert_equal('hellohello', Tests.Str() .. Tests.str)
9443
9444 # Using class variable for list indexing
9445 var l = range(10)
9446 assert_equal(4, l[Tests.four])
9447 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9448
9449 # Using class variable for Dict key
9450 var d = {hello: 'abc'}
9451 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009452 END
9453 v9.CheckSourceSuccess(lines)
9454enddef
9455
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009456" Test for checking the type of the key used to access an object dict member.
9457def Test_dict_member_key_type_check()
9458 var lines =<< trim END
9459 vim9script
9460
9461 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01009462 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009463 endclass
9464
9465 class Test extends State
9466 def ObjMethodTests()
9467 var cursor: number = 0
9468 var z: number = 0
9469 [this.numbers[cursor]] = ['zero.1']
9470 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9471 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9472 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9473 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9474 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9475 [this.numbers[cursor], z] = ['zero.4', 1]
9476 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9477 [z, this.numbers[cursor]] = [1, 'zero.5']
9478 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9479 enddef
9480
9481 static def ClassMethodTests(that: State)
9482 var cursor: number = 0
9483 var z: number = 0
9484 [that.numbers[cursor]] = ['zero.1']
9485 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9486 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9487 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9488 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9489 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9490 [that.numbers[cursor], z] = ['zero.4', 1]
9491 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9492 [z, that.numbers[cursor]] = [1, 'zero.5']
9493 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9494 enddef
9495
9496 def new()
9497 enddef
9498
9499 def newMethodTests()
9500 var cursor: number = 0
9501 var z: number
9502 [this.numbers[cursor]] = ['zero.1']
9503 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9504 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9505 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9506 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9507 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9508 [this.numbers[cursor], z] = ['zero.4', 1]
9509 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9510 [z, this.numbers[cursor]] = [1, 'zero.5']
9511 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9512 enddef
9513 endclass
9514
9515 def DefFuncTests(that: Test)
9516 var cursor: number = 0
9517 var z: number
9518 [that.numbers[cursor]] = ['zero.1']
9519 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9520 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9521 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9522 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9523 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9524 [that.numbers[cursor], z] = ['zero.4', 1]
9525 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9526 [z, that.numbers[cursor]] = [1, 'zero.5']
9527 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9528 enddef
9529
9530 Test.newMethodTests()
9531 Test.new().ObjMethodTests()
9532 Test.ClassMethodTests(Test.new())
9533 DefFuncTests(Test.new())
9534
9535 const test: Test = Test.new()
9536 var cursor: number = 0
9537 [test.numbers[cursor], cursor] = ['zero', 1]
9538 [cursor, test.numbers[cursor]] = [1, 'one']
9539 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
9540 END
9541 v9.CheckSourceSuccess(lines)
9542
9543 lines =<< trim END
9544 vim9script
9545
9546 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009547 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009548
9549 def new()
9550 enddef
9551
9552 def Foo()
9553 var z: number
9554 [this.numbers.a, z] = [{}, 10]
9555 enddef
9556 endclass
9557
9558 var a = A.new()
9559 a.Foo()
9560 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009561 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009562
9563 lines =<< trim END
9564 vim9script
9565
9566 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009567 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009568
9569 def new()
9570 enddef
9571
9572 def Foo()
9573 var x: string = 'a'
9574 var y: number
9575 [this.numbers[x], y] = [{}, 10]
9576 enddef
9577 endclass
9578
9579 var a = A.new()
9580 a.Foo()
9581 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009582 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009583enddef
9584
mityua5550692023-11-25 15:41:20 +01009585def Test_compile_many_def_functions_in_funcref_instr()
9586 # This used to crash Vim. This is reproducible only when run on new instance
9587 # of Vim.
9588 var lines =<< trim END
9589 vim9script
9590
9591 class A
9592 def new()
9593 this.TakeFunc(this.F00)
9594 enddef
9595
9596 def TakeFunc(F: func)
9597 enddef
9598
9599 def F00()
9600 this.F01()
9601 this.F02()
9602 this.F03()
9603 this.F04()
9604 this.F05()
9605 this.F06()
9606 this.F07()
9607 this.F08()
9608 this.F09()
9609 this.F10()
9610 this.F11()
9611 this.F12()
9612 this.F13()
9613 this.F14()
9614 this.F15()
9615 this.F16()
9616 this.F17()
9617 this.F18()
9618 this.F19()
9619 this.F20()
9620 this.F21()
9621 this.F22()
9622 this.F23()
9623 this.F24()
9624 this.F25()
9625 this.F26()
9626 this.F27()
9627 this.F28()
9628 this.F29()
9629 this.F30()
9630 this.F31()
9631 this.F32()
9632 this.F33()
9633 this.F34()
9634 this.F35()
9635 this.F36()
9636 this.F37()
9637 this.F38()
9638 this.F39()
9639 this.F40()
9640 this.F41()
9641 this.F42()
9642 this.F43()
9643 this.F44()
9644 this.F45()
9645 this.F46()
9646 this.F47()
9647 enddef
9648
9649 def F01()
9650 enddef
9651 def F02()
9652 enddef
9653 def F03()
9654 enddef
9655 def F04()
9656 enddef
9657 def F05()
9658 enddef
9659 def F06()
9660 enddef
9661 def F07()
9662 enddef
9663 def F08()
9664 enddef
9665 def F09()
9666 enddef
9667 def F10()
9668 enddef
9669 def F11()
9670 enddef
9671 def F12()
9672 enddef
9673 def F13()
9674 enddef
9675 def F14()
9676 enddef
9677 def F15()
9678 enddef
9679 def F16()
9680 enddef
9681 def F17()
9682 enddef
9683 def F18()
9684 enddef
9685 def F19()
9686 enddef
9687 def F20()
9688 enddef
9689 def F21()
9690 enddef
9691 def F22()
9692 enddef
9693 def F23()
9694 enddef
9695 def F24()
9696 enddef
9697 def F25()
9698 enddef
9699 def F26()
9700 enddef
9701 def F27()
9702 enddef
9703 def F28()
9704 enddef
9705 def F29()
9706 enddef
9707 def F30()
9708 enddef
9709 def F31()
9710 enddef
9711 def F32()
9712 enddef
9713 def F33()
9714 enddef
9715 def F34()
9716 enddef
9717 def F35()
9718 enddef
9719 def F36()
9720 enddef
9721 def F37()
9722 enddef
9723 def F38()
9724 enddef
9725 def F39()
9726 enddef
9727 def F40()
9728 enddef
9729 def F41()
9730 enddef
9731 def F42()
9732 enddef
9733 def F43()
9734 enddef
9735 def F44()
9736 enddef
9737 def F45()
9738 enddef
9739 def F46()
9740 enddef
9741 def F47()
9742 enddef
9743 endclass
9744
9745 A.new()
9746 END
9747 writefile(lines, 'Xscript', 'D')
9748 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9749 assert_equal(0, v:shell_error)
9750enddef
9751
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009752" Test for 'final' class and object variables
9753def Test_final_class_object_variable()
9754 # Test for changing a final object variable from an object function
9755 var lines =<< trim END
9756 vim9script
9757 class A
9758 final foo: string = "abc"
9759 def Foo()
9760 this.foo = "def"
9761 enddef
9762 endclass
9763 defcompile A.Foo
9764 END
9765 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9766
9767 # Test for changing a final object variable from the 'new' function
9768 lines =<< trim END
9769 vim9script
9770 class A
9771 final s1: string
9772 final s2: string
9773 def new(this.s1)
9774 this.s2 = 'def'
9775 enddef
9776 endclass
9777 var a = A.new('abc')
9778 assert_equal('abc', a.s1)
9779 assert_equal('def', a.s2)
9780 END
9781 v9.CheckSourceSuccess(lines)
9782
9783 # Test for a final class variable
9784 lines =<< trim END
9785 vim9script
9786 class A
9787 static final s1: string = "abc"
9788 endclass
9789 assert_equal('abc', A.s1)
9790 END
9791 v9.CheckSourceSuccess(lines)
9792
9793 # Test for changing a final class variable from a class function
9794 lines =<< trim END
9795 vim9script
9796 class A
9797 static final s1: string = "abc"
9798 static def Foo()
9799 s1 = "def"
9800 enddef
9801 endclass
9802 A.Foo()
9803 END
9804 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9805
9806 # Test for changing a public final class variable at script level
9807 lines =<< trim END
9808 vim9script
9809 class A
9810 public static final s1: string = "abc"
9811 endclass
9812 assert_equal('abc', A.s1)
9813 A.s1 = 'def'
9814 END
9815 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9816
9817 # Test for changing a public final class variable from a class function
9818 lines =<< trim END
9819 vim9script
9820 class A
9821 public static final s1: string = "abc"
9822 static def Foo()
9823 s1 = "def"
9824 enddef
9825 endclass
9826 A.Foo()
9827 END
9828 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9829
9830 # Test for changing a public final class variable from a function
9831 lines =<< trim END
9832 vim9script
9833 class A
9834 public static final s1: string = "abc"
9835 endclass
9836 def Foo()
9837 A.s1 = 'def'
9838 enddef
9839 defcompile
9840 END
9841 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9842
9843 # Test for using a final variable of composite type
9844 lines =<< trim END
9845 vim9script
9846 class A
9847 public final l: list<number>
9848 def new()
9849 this.l = [1, 2]
9850 enddef
9851 def Foo()
9852 this.l[0] = 3
9853 this.l->add(4)
9854 enddef
9855 endclass
9856 var a = A.new()
9857 assert_equal([1, 2], a.l)
9858 a.Foo()
9859 assert_equal([3, 2, 4], a.l)
9860 END
9861 v9.CheckSourceSuccess(lines)
9862
9863 # Test for changing a final variable of composite type from another object
9864 # function
9865 lines =<< trim END
9866 vim9script
9867 class A
9868 public final l: list<number> = [1, 2]
9869 def Foo()
9870 this.l = [3, 4]
9871 enddef
9872 endclass
9873 var a = A.new()
9874 a.Foo()
9875 END
9876 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9877
9878 # Test for modifying a final variable of composite type at script level
9879 lines =<< trim END
9880 vim9script
9881 class A
9882 public final l: list<number> = [1, 2]
9883 endclass
9884 var a = A.new()
9885 a.l[0] = 3
9886 a.l->add(4)
9887 assert_equal([3, 2, 4], a.l)
9888 END
9889 v9.CheckSourceSuccess(lines)
9890
9891 # Test for modifying a final variable of composite type from a function
9892 lines =<< trim END
9893 vim9script
9894 class A
9895 public final l: list<number> = [1, 2]
9896 endclass
9897 def Foo()
9898 var a = A.new()
9899 a.l[0] = 3
9900 a.l->add(4)
9901 assert_equal([3, 2, 4], a.l)
9902 enddef
9903 Foo()
9904 END
9905 v9.CheckSourceSuccess(lines)
9906
9907 # Test for modifying a final variable of composite type from another object
9908 # function
9909 lines =<< trim END
9910 vim9script
9911 class A
9912 public final l: list<number> = [1, 2]
9913 def Foo()
9914 this.l[0] = 3
9915 this.l->add(4)
9916 enddef
9917 endclass
9918 var a = A.new()
9919 a.Foo()
9920 assert_equal([3, 2, 4], a.l)
9921 END
9922 v9.CheckSourceSuccess(lines)
9923
9924 # Test for assigning a new value to a final variable of composite type at
9925 # script level
9926 lines =<< trim END
9927 vim9script
9928 class A
9929 public final l: list<number> = [1, 2]
9930 endclass
9931 var a = A.new()
9932 a.l = [3, 4]
9933 END
9934 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9935
9936 # Test for assigning a new value to a final variable of composite type from
9937 # another object function
9938 lines =<< trim END
9939 vim9script
9940 class A
9941 public final l: list<number> = [1, 2]
9942 def Foo()
9943 this.l = [3, 4]
9944 enddef
9945 endclass
9946 var a = A.new()
9947 a.Foo()
9948 END
9949 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9950
9951 # Test for assigning a new value to a final variable of composite type from
9952 # another function
9953 lines =<< trim END
9954 vim9script
9955 class A
9956 public final l: list<number> = [1, 2]
9957 endclass
9958 def Foo()
9959 var a = A.new()
9960 a.l = [3, 4]
9961 enddef
9962 Foo()
9963 END
9964 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9965
9966 # Error case: Use 'final' with just a variable name
9967 lines =<< trim END
9968 vim9script
9969 class A
9970 final foo
9971 endclass
9972 var a = A.new()
9973 END
9974 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9975
9976 # Error case: Use 'final' followed by 'public'
9977 lines =<< trim END
9978 vim9script
9979 class A
9980 final public foo: number
9981 endclass
9982 var a = A.new()
9983 END
9984 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9985
9986 # Error case: Use 'final' followed by 'static'
9987 lines =<< trim END
9988 vim9script
9989 class A
9990 final static foo: number
9991 endclass
9992 var a = A.new()
9993 END
9994 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9995
9996 # Error case: 'final' cannot be used in an interface
9997 lines =<< trim END
9998 vim9script
9999 interface A
10000 final foo: number = 10
10001 endinterface
10002 END
10003 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
10004
10005 # Error case: 'final' not supported for an object method
10006 lines =<< trim END
10007 vim9script
10008 class A
10009 final def Foo()
10010 enddef
10011 endclass
10012 END
10013 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10014
10015 # Error case: 'final' not supported for a class method
10016 lines =<< trim END
10017 vim9script
10018 class A
10019 static final def Foo()
10020 enddef
10021 endclass
10022 END
10023 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10024enddef
10025
10026" Test for 'const' class and object variables
10027def Test_const_class_object_variable()
10028 # Test for changing a const object variable from an object function
10029 var lines =<< trim END
10030 vim9script
10031 class A
10032 const foo: string = "abc"
10033 def Foo()
10034 this.foo = "def"
10035 enddef
10036 endclass
10037 defcompile A.Foo
10038 END
10039 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
10040
10041 # Test for changing a const object variable from the 'new' function
10042 lines =<< trim END
10043 vim9script
10044 class A
10045 const s1: string
10046 const s2: string
10047 def new(this.s1)
10048 this.s2 = 'def'
10049 enddef
10050 endclass
10051 var a = A.new('abc')
10052 assert_equal('abc', a.s1)
10053 assert_equal('def', a.s2)
10054 END
10055 v9.CheckSourceSuccess(lines)
10056
10057 # Test for changing a const object variable from an object method called from
10058 # the 'new' function
10059 lines =<< trim END
10060 vim9script
10061 class A
10062 const s1: string = 'abc'
10063 def new()
10064 this.ChangeStr()
10065 enddef
10066 def ChangeStr()
10067 this.s1 = 'def'
10068 enddef
10069 endclass
10070 var a = A.new()
10071 END
10072 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
10073
10074 # Test for a const class variable
10075 lines =<< trim END
10076 vim9script
10077 class A
10078 static const s1: string = "abc"
10079 endclass
10080 assert_equal('abc', A.s1)
10081 END
10082 v9.CheckSourceSuccess(lines)
10083
10084 # Test for changing a const class variable from a class function
10085 lines =<< trim END
10086 vim9script
10087 class A
10088 static const s1: string = "abc"
10089 static def Foo()
10090 s1 = "def"
10091 enddef
10092 endclass
10093 A.Foo()
10094 END
10095 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
10096
10097 # Test for changing a public const class variable at script level
10098 lines =<< trim END
10099 vim9script
10100 class A
10101 public static const s1: string = "abc"
10102 endclass
10103 assert_equal('abc', A.s1)
10104 A.s1 = 'def'
10105 END
10106 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
10107
10108 # Test for changing a public const class variable from a class function
10109 lines =<< trim END
10110 vim9script
10111 class A
10112 public static const s1: string = "abc"
10113 static def Foo()
10114 s1 = "def"
10115 enddef
10116 endclass
10117 A.Foo()
10118 END
10119 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
10120
10121 # Test for changing a public const class variable from a function
10122 lines =<< trim END
10123 vim9script
10124 class A
10125 public static const s1: string = "abc"
10126 endclass
10127 def Foo()
10128 A.s1 = 'def'
10129 enddef
10130 defcompile
10131 END
10132 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
10133
10134 # Test for changing a const List item from an object function
10135 lines =<< trim END
10136 vim9script
10137 class A
10138 public const l: list<number>
10139 def new()
10140 this.l = [1, 2]
10141 enddef
10142 def Foo()
10143 this.l[0] = 3
10144 enddef
10145 endclass
10146 var a = A.new()
10147 assert_equal([1, 2], a.l)
10148 a.Foo()
10149 END
10150 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
10151
10152 # Test for adding a value to a const List from an object function
10153 lines =<< trim END
10154 vim9script
10155 class A
10156 public const l: list<number>
10157 def new()
10158 this.l = [1, 2]
10159 enddef
10160 def Foo()
10161 this.l->add(3)
10162 enddef
10163 endclass
10164 var a = A.new()
10165 a.Foo()
10166 END
10167 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
10168
10169 # Test for reassigning a const List from an object function
10170 lines =<< trim END
10171 vim9script
10172 class A
10173 public const l: list<number> = [1, 2]
10174 def Foo()
10175 this.l = [3, 4]
10176 enddef
10177 endclass
10178 var a = A.new()
10179 a.Foo()
10180 END
10181 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
10182
10183 # Test for changing a const List item at script level
10184 lines =<< trim END
10185 vim9script
10186 class A
10187 public const l: list<number> = [1, 2]
10188 endclass
10189 var a = A.new()
10190 a.l[0] = 3
10191 END
10192 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
10193
10194 # Test for adding a value to a const List item at script level
10195 lines =<< trim END
10196 vim9script
10197 class A
10198 public const l: list<number> = [1, 2]
10199 endclass
10200 var a = A.new()
10201 a.l->add(4)
10202 END
10203 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
10204
10205 # Test for changing a const List item from a function
10206 lines =<< trim END
10207 vim9script
10208 class A
10209 public const l: list<number> = [1, 2]
10210 endclass
10211 def Foo()
10212 var a = A.new()
10213 a.l[0] = 3
10214 enddef
10215 Foo()
10216 END
10217 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
10218
10219 # Test for adding a value to a const List item from a function
10220 lines =<< trim END
10221 vim9script
10222 class A
10223 public const l: list<number> = [1, 2]
10224 endclass
10225 def Foo()
10226 var a = A.new()
10227 a.l->add(4)
10228 enddef
10229 Foo()
10230 END
10231 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
10232
10233 # Test for changing a const List item from an object method
10234 lines =<< trim END
10235 vim9script
10236 class A
10237 public const l: list<number> = [1, 2]
10238 def Foo()
10239 this.l[0] = 3
10240 enddef
10241 endclass
10242 var a = A.new()
10243 a.Foo()
10244 END
10245 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
10246
10247 # Test for adding a value to a const List item from an object method
10248 lines =<< trim END
10249 vim9script
10250 class A
10251 public const l: list<number> = [1, 2]
10252 def Foo()
10253 this.l->add(4)
10254 enddef
10255 endclass
10256 var a = A.new()
10257 a.Foo()
10258 END
10259 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
10260
10261 # Test for reassigning a const List object variable at script level
10262 lines =<< trim END
10263 vim9script
10264 class A
10265 public const l: list<number> = [1, 2]
10266 endclass
10267 var a = A.new()
10268 a.l = [3, 4]
10269 END
10270 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
10271
10272 # Test for reassigning a const List object variable from an object method
10273 lines =<< trim END
10274 vim9script
10275 class A
10276 public const l: list<number> = [1, 2]
10277 def Foo()
10278 this.l = [3, 4]
10279 enddef
10280 endclass
10281 var a = A.new()
10282 a.Foo()
10283 END
10284 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
10285
10286 # Test for reassigning a const List object variable from another function
10287 lines =<< trim END
10288 vim9script
10289 class A
10290 public const l: list<number> = [1, 2]
10291 endclass
10292 def Foo()
10293 var a = A.new()
10294 a.l = [3, 4]
10295 enddef
10296 Foo()
10297 END
10298 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
10299
10300 # Error case: Use 'const' with just a variable name
10301 lines =<< trim END
10302 vim9script
10303 class A
10304 const foo
10305 endclass
10306 var a = A.new()
10307 END
10308 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10309
10310 # Error case: Use 'const' followed by 'public'
10311 lines =<< trim END
10312 vim9script
10313 class A
10314 const public foo: number
10315 endclass
10316 var a = A.new()
10317 END
10318 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10319
10320 # Error case: Use 'const' followed by 'static'
10321 lines =<< trim END
10322 vim9script
10323 class A
10324 const static foo: number
10325 endclass
10326 var a = A.new()
10327 END
10328 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10329
10330 # Error case: 'const' cannot be used in an interface
10331 lines =<< trim END
10332 vim9script
10333 interface A
10334 const foo: number = 10
10335 endinterface
10336 END
10337 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
10338
10339 # Error case: 'const' not supported for an object method
10340 lines =<< trim END
10341 vim9script
10342 class A
10343 const def Foo()
10344 enddef
10345 endclass
10346 END
10347 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10348
10349 # Error case: 'const' not supported for a class method
10350 lines =<< trim END
10351 vim9script
10352 class A
10353 static const def Foo()
10354 enddef
10355 endclass
10356 END
10357 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10358enddef
10359
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +010010360" Test for compiling class/object methods using :defcompile
10361def Test_defcompile_class()
10362 # defcompile all the classes in the current script
10363 var lines =<< trim END
10364 vim9script
10365 class A
10366 def Foo()
10367 var i = 10
10368 enddef
10369 endclass
10370 class B
10371 def Bar()
10372 var i = 20
10373 xxx
10374 enddef
10375 endclass
10376 defcompile
10377 END
10378 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
10379
10380 # defcompile a specific class
10381 lines =<< trim END
10382 vim9script
10383 class A
10384 def Foo()
10385 xxx
10386 enddef
10387 endclass
10388 class B
10389 def Bar()
10390 yyy
10391 enddef
10392 endclass
10393 defcompile B
10394 END
10395 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
10396
10397 # defcompile a non-class
10398 lines =<< trim END
10399 vim9script
10400 class A
10401 def Foo()
10402 enddef
10403 endclass
10404 var X: list<number> = []
10405 defcompile X
10406 END
10407 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
10408
10409 # defcompile a class twice
10410 lines =<< trim END
10411 vim9script
10412 class A
10413 def new()
10414 enddef
10415 endclass
10416 defcompile A
10417 defcompile A
10418 assert_equal('Function A.new does not need compiling', v:statusmsg)
10419 END
10420 v9.CheckSourceSuccess(lines)
10421
10422 # defcompile should not compile an imported class
10423 lines =<< trim END
10424 vim9script
10425 export class A
10426 def Foo()
10427 xxx
10428 enddef
10429 endclass
10430 END
10431 writefile(lines, 'Xdefcompileimport.vim', 'D')
10432 lines =<< trim END
10433 vim9script
10434
10435 import './Xdefcompileimport.vim'
10436 class B
10437 endclass
10438 defcompile
10439 END
10440 v9.CheckScriptSuccess(lines)
10441enddef
10442
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +010010443" Test for cases common to all the object builtin methods
10444def Test_object_builtin_method()
10445 var lines =<< trim END
10446 vim9script
10447 class A
10448 def abc()
10449 enddef
10450 endclass
10451 END
10452 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
10453
10454 for funcname in ["len", "string", "empty"]
10455 lines =<< trim eval END
10456 vim9script
10457 class A
10458 static def {funcname}(): number
10459 enddef
10460 endclass
10461 END
10462 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
10463 endfor
10464enddef
10465
10466" Test for using the empty() builtin method with an object
10467" This is a legacy function to use the test_garbagecollect_now() function.
10468func Test_object_empty()
10469 let lines =<< trim END
10470 vim9script
10471 class A
10472 def empty(): bool
10473 return true
10474 enddef
10475 endclass
10476
10477 def Foo()
10478 var afoo = A.new()
10479 assert_equal(true, empty(afoo))
10480 assert_equal(true, afoo->empty())
10481 enddef
10482
10483 var a = A.new()
10484 assert_equal(1, empty(a))
10485 assert_equal(1, a->empty())
10486 test_garbagecollect_now()
10487 assert_equal(1, empty(a))
10488 Foo()
10489 test_garbagecollect_now()
10490 Foo()
10491 END
10492 call v9.CheckSourceSuccess(lines)
10493
10494 " empty() should return 1 without a builtin method
10495 let lines =<< trim END
10496 vim9script
10497 class A
10498 endclass
10499
10500 def Foo()
10501 var afoo = A.new()
10502 assert_equal(1, empty(afoo))
10503 enddef
10504
10505 var a = A.new()
10506 assert_equal(1, empty(a))
10507 Foo()
10508 END
10509 call v9.CheckSourceSuccess(lines)
10510
10511 " Unsupported signature for the empty() method
10512 let lines =<< trim END
10513 vim9script
10514 class A
10515 def empty()
10516 enddef
10517 endclass
10518 END
10519 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
10520
10521 " Error when calling the empty() method
10522 let lines =<< trim END
10523 vim9script
10524 class A
10525 def empty(): bool
10526 throw "Failed to check emptiness"
10527 enddef
10528 endclass
10529
10530 def Foo()
10531 var afoo = A.new()
10532 var i = empty(afoo)
10533 enddef
10534
10535 var a = A.new()
10536 assert_fails('empty(a)', 'Failed to check emptiness')
10537 assert_fails('Foo()', 'Failed to check emptiness')
10538 END
10539 call v9.CheckSourceSuccess(lines)
10540
10541 " call empty() using an object from a script
10542 let lines =<< trim END
10543 vim9script
10544 class A
10545 def empty(): bool
10546 return true
10547 enddef
10548 endclass
10549 var afoo = A.new()
10550 assert_equal(true, afoo.empty())
10551 END
10552 call v9.CheckSourceSuccess(lines)
10553
10554 " call empty() using an object from a method
10555 let lines =<< trim END
10556 vim9script
10557 class A
10558 def empty(): bool
10559 return true
10560 enddef
10561 endclass
10562 def Foo()
10563 var afoo = A.new()
10564 assert_equal(true, afoo.empty())
10565 enddef
10566 Foo()
10567 END
10568 call v9.CheckSourceSuccess(lines)
10569
10570 " call empty() using "this" from an object method
10571 let lines =<< trim END
10572 vim9script
10573 class A
10574 def empty(): bool
10575 return true
10576 enddef
10577 def Foo(): bool
10578 return this.empty()
10579 enddef
10580 endclass
10581 def Bar()
10582 var abar = A.new()
10583 assert_equal(true, abar.Foo())
10584 enddef
10585 Bar()
10586 END
10587 call v9.CheckSourceSuccess(lines)
10588
10589 " Call empty() from a derived object
10590 let lines =<< trim END
10591 vim9script
10592 class A
10593 def empty(): bool
10594 return false
10595 enddef
10596 endclass
10597 class B extends A
10598 def empty(): bool
10599 return true
10600 enddef
10601 endclass
10602 def Foo(afoo: A)
10603 assert_equal(true, empty(afoo))
10604 var bfoo = B.new()
10605 assert_equal(true, empty(bfoo))
10606 enddef
10607 var b = B.new()
10608 assert_equal(1, empty(b))
10609 Foo(b)
10610 END
10611 call v9.CheckSourceSuccess(lines)
10612
10613 " Invoking empty method using an interface
10614 let lines =<< trim END
10615 vim9script
10616 interface A
10617 def empty(): bool
10618 endinterface
10619 class B implements A
10620 def empty(): bool
10621 return false
10622 enddef
10623 endclass
10624 def Foo(a: A)
10625 assert_equal(false, empty(a))
10626 enddef
10627 var b = B.new()
10628 Foo(b)
10629 END
10630 call v9.CheckSourceSuccess(lines)
10631endfunc
10632
10633" Test for using the len() builtin method with an object
10634" This is a legacy function to use the test_garbagecollect_now() function.
10635func Test_object_length()
10636 let lines =<< trim END
10637 vim9script
10638 class A
10639 var mylen: number = 0
10640 def new(n: number)
10641 this.mylen = n
10642 enddef
10643 def len(): number
10644 return this.mylen
10645 enddef
10646 endclass
10647
10648 def Foo()
10649 var afoo = A.new(12)
10650 assert_equal(12, len(afoo))
10651 assert_equal(12, afoo->len())
10652 enddef
10653
10654 var a = A.new(22)
10655 assert_equal(22, len(a))
10656 assert_equal(22, a->len())
10657 test_garbagecollect_now()
10658 assert_equal(22, len(a))
10659 Foo()
10660 test_garbagecollect_now()
10661 Foo()
10662 END
10663 call v9.CheckSourceSuccess(lines)
10664
10665 " len() should return 0 without a builtin method
10666 let lines =<< trim END
10667 vim9script
10668 class A
10669 endclass
10670
10671 def Foo()
10672 var afoo = A.new()
10673 assert_equal(0, len(afoo))
10674 enddef
10675
10676 var a = A.new()
10677 assert_equal(0, len(a))
10678 Foo()
10679 END
10680 call v9.CheckSourceSuccess(lines)
10681
10682 " Unsupported signature for the len() method
10683 let lines =<< trim END
10684 vim9script
10685 class A
10686 def len()
10687 enddef
10688 endclass
10689 END
10690 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10691
10692 " Error when calling the len() method
10693 let lines =<< trim END
10694 vim9script
10695 class A
10696 def len(): number
10697 throw "Failed to compute length"
10698 enddef
10699 endclass
10700
10701 def Foo()
10702 var afoo = A.new()
10703 var i = len(afoo)
10704 enddef
10705
10706 var a = A.new()
10707 assert_fails('len(a)', 'Failed to compute length')
10708 assert_fails('Foo()', 'Failed to compute length')
10709 END
10710 call v9.CheckSourceSuccess(lines)
10711
10712 " call len() using an object from a script
10713 let lines =<< trim END
10714 vim9script
10715 class A
10716 def len(): number
10717 return 5
10718 enddef
10719 endclass
10720 var afoo = A.new()
10721 assert_equal(5, afoo.len())
10722 END
10723 call v9.CheckSourceSuccess(lines)
10724
10725 " call len() using an object from a method
10726 let lines =<< trim END
10727 vim9script
10728 class A
10729 def len(): number
10730 return 5
10731 enddef
10732 endclass
10733 def Foo()
10734 var afoo = A.new()
10735 assert_equal(5, afoo.len())
10736 enddef
10737 Foo()
10738 END
10739 call v9.CheckSourceSuccess(lines)
10740
10741 " call len() using "this" from an object method
10742 let lines =<< trim END
10743 vim9script
10744 class A
10745 def len(): number
10746 return 8
10747 enddef
10748 def Foo(): number
10749 return this.len()
10750 enddef
10751 endclass
10752 def Bar()
10753 var abar = A.new()
10754 assert_equal(8, abar.Foo())
10755 enddef
10756 Bar()
10757 END
10758 call v9.CheckSourceSuccess(lines)
10759
10760 " Call len() from a derived object
10761 let lines =<< trim END
10762 vim9script
10763 class A
10764 def len(): number
10765 return 10
10766 enddef
10767 endclass
10768 class B extends A
10769 def len(): number
10770 return 20
10771 enddef
10772 endclass
10773 def Foo(afoo: A)
10774 assert_equal(20, len(afoo))
10775 var bfoo = B.new()
10776 assert_equal(20, len(bfoo))
10777 enddef
10778 var b = B.new()
10779 assert_equal(20, len(b))
10780 Foo(b)
10781 END
10782 call v9.CheckSourceSuccess(lines)
10783
10784 " Invoking len method using an interface
10785 let lines =<< trim END
10786 vim9script
10787 interface A
10788 def len(): number
10789 endinterface
10790 class B implements A
10791 def len(): number
10792 return 123
10793 enddef
10794 endclass
10795 def Foo(a: A)
10796 assert_equal(123, len(a))
10797 enddef
10798 var b = B.new()
10799 Foo(b)
10800 END
10801 call v9.CheckSourceSuccess(lines)
10802endfunc
10803
10804" Test for using the string() builtin method with an object
10805" This is a legacy function to use the test_garbagecollect_now() function.
10806func Test_object_string()
10807 let lines =<< trim END
10808 vim9script
10809 class A
10810 var name: string
10811 def string(): string
10812 return this.name
10813 enddef
10814 endclass
10815
10816 def Foo()
10817 var afoo = A.new("foo-A")
10818 assert_equal('foo-A', string(afoo))
10819 assert_equal('foo-A', afoo->string())
10820 enddef
10821
10822 var a = A.new("script-A")
10823 assert_equal('script-A', string(a))
10824 assert_equal('script-A', a->string())
10825 assert_equal(['script-A'], execute('echo a')->split("\n"))
10826 test_garbagecollect_now()
10827 assert_equal('script-A', string(a))
10828 Foo()
10829 test_garbagecollect_now()
10830 Foo()
10831 END
10832 call v9.CheckSourceSuccess(lines)
10833
10834 " string() should return "object of A {}" without a builtin method
10835 let lines =<< trim END
10836 vim9script
10837 class A
10838 endclass
10839
10840 def Foo()
10841 var afoo = A.new()
10842 assert_equal('object of A {}', string(afoo))
10843 enddef
10844
10845 var a = A.new()
10846 assert_equal('object of A {}', string(a))
10847 Foo()
10848 END
10849 call v9.CheckSourceSuccess(lines)
10850
10851 " Unsupported signature for the string() method
10852 let lines =<< trim END
10853 vim9script
10854 class A
10855 def string()
10856 enddef
10857 endclass
10858 END
10859 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10860
10861 " Error when calling the string() method
10862 let lines =<< trim END
10863 vim9script
10864 class A
10865 def string(): string
10866 throw "Failed to get text"
10867 enddef
10868 endclass
10869
10870 def Foo()
10871 var afoo = A.new()
10872 var i = string(afoo)
10873 enddef
10874
10875 var a = A.new()
10876 assert_fails('string(a)', 'Failed to get text')
10877 assert_fails('Foo()', 'Failed to get text')
10878 END
10879 call v9.CheckSourceSuccess(lines)
10880
10881 " call string() using an object from a script
10882 let lines =<< trim END
10883 vim9script
10884 class A
10885 def string(): string
10886 return 'A'
10887 enddef
10888 endclass
10889 var afoo = A.new()
10890 assert_equal('A', afoo.string())
10891 END
10892 call v9.CheckSourceSuccess(lines)
10893
10894 " call string() using an object from a method
10895 let lines =<< trim END
10896 vim9script
10897 class A
10898 def string(): string
10899 return 'A'
10900 enddef
10901 endclass
10902 def Foo()
10903 var afoo = A.new()
10904 assert_equal('A', afoo.string())
10905 enddef
10906 Foo()
10907 END
10908 call v9.CheckSourceSuccess(lines)
10909
10910 " call string() using "this" from an object method
10911 let lines =<< trim END
10912 vim9script
10913 class A
10914 def string(): string
10915 return 'A'
10916 enddef
10917 def Foo(): string
10918 return this.string()
10919 enddef
10920 endclass
10921 def Bar()
10922 var abar = A.new()
10923 assert_equal('A', abar.string())
10924 enddef
10925 Bar()
10926 END
10927 call v9.CheckSourceSuccess(lines)
10928
10929 " Call string() from a derived object
10930 let lines =<< trim END
10931 vim9script
10932 class A
10933 def string(): string
10934 return 'A'
10935 enddef
10936 endclass
10937 class B extends A
10938 def string(): string
10939 return 'B'
10940 enddef
10941 endclass
10942 def Foo(afoo: A)
10943 assert_equal('B', string(afoo))
10944 var bfoo = B.new()
10945 assert_equal('B', string(bfoo))
10946 enddef
10947 var b = B.new()
10948 assert_equal('B', string(b))
10949 Foo(b)
10950 END
10951 call v9.CheckSourceSuccess(lines)
10952
10953 " Invoking string method using an interface
10954 let lines =<< trim END
10955 vim9script
10956 interface A
10957 def string(): string
10958 endinterface
10959 class B implements A
10960 def string(): string
10961 return 'B'
10962 enddef
10963 endclass
10964 def Foo(a: A)
10965 assert_equal('B', string(a))
10966 enddef
10967 var b = B.new()
10968 Foo(b)
10969 END
10970 call v9.CheckSourceSuccess(lines)
10971endfunc
10972
Ernie Rael9d779c52024-07-07 20:41:44 +020010973" Test for using the string() builtin method with an object's method
10974def Test_method_string()
10975 var lines =<< trim END
10976 vim9script
10977 class A
10978 def F()
10979 enddef
10980 endclass
10981 assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F))
10982 END
10983 v9.CheckScriptSuccess(lines)
10984enddef
10985
10986
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010987" Test for using a class in the class definition
10988def Test_Ref_Class_Within_Same_Class()
10989 var lines =<< trim END
10990 vim9script
10991 class A
10992 var n: number = 0
10993 def Equals(other: A): bool
10994 return this.n == other.n
10995 enddef
10996 endclass
10997
10998 var a1 = A.new(10)
10999 var a2 = A.new(10)
11000 var a3 = A.new(20)
11001 assert_equal(true, a1.Equals(a2))
11002 assert_equal(false, a2.Equals(a3))
11003 END
11004 v9.CheckScriptSuccess(lines)
11005
11006 lines =<< trim END
11007 vim9script
11008
11009 class Foo
11010 var num: number
11011 def Clone(): Foo
11012 return Foo.new(this.num)
11013 enddef
11014 endclass
11015
11016 var f1 = Foo.new(1)
11017
11018 def F()
11019 var f2: Foo = f1.Clone()
11020 assert_equal(false, f2 is f1)
11021 assert_equal(true, f2.num == f1.num)
11022 enddef
11023 F()
11024
11025 var f3: Foo = f1.Clone()
11026 assert_equal(false, f3 is f1)
11027 assert_equal(true, f3.num == f1.num)
11028 END
11029 v9.CheckScriptSuccess(lines)
11030
11031 # Test for trying to use a class to extend when defining the same class
11032 lines =<< trim END
11033 vim9script
11034 class A extends A
11035 endclass
11036 END
11037 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
11038
11039 # Test for trying to use a class to implement when defining the same class
11040 lines =<< trim END
11041 vim9script
11042 class A implements A
11043 endclass
11044 END
11045 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
11046enddef
11047
Ernie Raelf0e69142024-06-22 11:12:00 +020011048" Test for comparing a class referencing itself
11049def Test_Object_Compare_With_Recursive_Class_Ref()
11050 var lines =<< trim END
11051 vim9script
11052
11053 class C
11054 public var nest: C
11055 endclass
11056
11057 var o1 = C.new()
11058 o1.nest = o1
11059
11060 var result = o1 == o1
11061 assert_equal(true, result)
11062 END
11063 v9.CheckScriptSuccess(lines)
Ernie Rael86257142024-06-23 09:54:45 +020011064
11065 lines =<< trim END
11066 vim9script
11067
11068 class C
11069 public var nest: C
11070 endclass
11071 var o1 = C.new()
11072 var o2 = C.new(C.new())
11073
11074 var result = o1 == o2
11075 assert_equal(false, result)
11076 END
11077 v9.CheckScriptSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +020011078
11079 lines =<< trim END
11080 vim9script
11081 class C
11082 var nest1: C
11083 var nest2: C
11084 def Init(n1: C, n2: C)
11085 this.nest1 = n1
11086 this.nest2 = n2
11087 enddef
11088 endclass
11089
11090 var o1 = C.new()
11091 var o2 = C.new()
11092 o1.Init(o1, o2)
11093 o2.Init(o2, o1)
11094
11095 var result = o1 == o2
11096 assert_equal(true, result)
11097 END
11098 v9.CheckScriptSuccess(lines)
Ernie Raelf0e69142024-06-22 11:12:00 +020011099enddef
11100
Ernie Raelf3975492024-07-06 11:44:37 +020011101" Test for comparing a class with nesting objects
11102def Test_Object_Compare_With_Nesting_Objects()
11103 # On a compare, after vim equal recurses 1000 times, not finding an unequal,
11104 # return the compare is equal.
11105 # Test that limit
11106
11107 var lines =<< trim END
11108 vim9script
11109 class C
11110 public var n: number
11111 public var nest: C
11112
11113 # Create a "C" that chains/nests to indicated depth.
11114 # return {head: firstC, tail: lastC}
11115 static def CreateNested(depth: number): dict<C>
11116 var first = C.new(1, null_object)
11117 var last = first
11118 for i in range(2, depth)
11119 last.nest = C.new(i, null_object)
11120 last = last.nest
11121 endfor
11122 return {head: first, tail: last}
11123 enddef
11124
11125 # Return pointer to nth item in chain.
11126 def GetLink(depth: number): C
11127 var count = 1
11128 var p: C = this
11129 while count < depth
11130 p = p.nest
11131 if p == null
11132 throw "too deep"
11133 endif
11134 count += 1
11135 endwhile
11136 return p
11137 enddef
11138
11139 # Return the length of the chain
11140 def len(): number
11141 var count = 1
11142 var p: C = this
11143 while p.nest != null
11144 p = p.nest
11145 count += 1
11146 endwhile
11147 return count
11148 enddef
11149 endclass
11150
11151 var chain = C.CreateNested(3)
11152 var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}"
11153 assert_equal(s, string(chain.head))
11154 assert_equal(3, chain.head->len())
11155
11156 var chain1 = C.CreateNested(100)
11157 var chain2 = C.CreateNested(100)
11158 assert_true(chain1.head == chain2.head)
11159
11160 # modify the tail of chain2, compare not equal
11161 chain2.tail.n = 123456
11162 assert_true(chain1.head != chain2.head)
11163
11164 # a tail of a different length compares not equal
11165 chain2 = C.CreateNested(101)
11166 assert_true(chain1.head != chain2.head)
11167
11168 chain1 = C.CreateNested(1000)
11169 chain2 = C.CreateNested(1000)
11170 assert_true(chain1.head == chain2.head)
11171
11172 # modify the tail of chain2, compare not equal
11173 chain2.tail.n = 123456
11174 assert_true(chain1.head != chain2.head)
11175
11176 # try a chain longer that the limit
11177 chain1 = C.CreateNested(1001)
11178 chain2 = C.CreateNested(1001)
11179 assert_true(chain1.head == chain2.head)
11180
11181 # modify the tail, but still equal
11182 chain2.tail.n = 123456
11183 assert_true(chain1.head == chain2.head)
11184
11185 # remove 2 items from front, shorten the chain by two.
11186 chain1.head = chain1.head.GetLink(3)
11187 chain2.head = chain2.head.GetLink(3)
11188 assert_equal(3, chain1.head.n)
11189 assert_equal(3, chain2.head.n)
11190 assert_equal(999, chain1.head->len())
11191 assert_equal(999, chain2.head->len())
11192 # Now less than the limit, compare not equal
11193 assert_true(chain1.head != chain2.head)
11194 END
11195 v9.CheckScriptSuccess(lines)
11196enddef
11197
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010011198" Test for using a compound operator from a lambda function in an object method
11199def Test_compound_op_in_objmethod_lambda()
11200 # Test using the "+=" operator
11201 var lines =<< trim END
11202 vim9script
11203 class A
11204 var n: number = 10
11205 def Foo()
11206 var Fn = () => {
11207 this.n += 1
11208 }
11209 Fn()
11210 enddef
11211 endclass
11212
11213 var a = A.new()
11214 a.Foo()
11215 assert_equal(11, a.n)
11216 END
11217 v9.CheckScriptSuccess(lines)
11218
11219 # Test using the "..=" operator
11220 lines =<< trim END
11221 vim9script
11222 class A
11223 var s: string = "a"
11224 def Foo()
11225 var Fn = () => {
11226 this.s ..= "a"
11227 }
11228 Fn()
11229 enddef
11230 endclass
11231
11232 var a = A.new()
11233 a.Foo()
11234 a.Foo()
11235 assert_equal("aaa", a.s)
11236 END
11237 v9.CheckScriptSuccess(lines)
11238enddef
11239
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010011240" Test for using test_refcount() with a class and an object
11241def Test_class_object_refcount()
11242 var lines =<< trim END
11243 vim9script
11244 class A
11245 endclass
11246 var a: A = A.new()
11247 assert_equal(2, test_refcount(A))
11248 assert_equal(1, test_refcount(a))
11249 var b = a
11250 assert_equal(2, test_refcount(A))
11251 assert_equal(2, test_refcount(a))
11252 assert_equal(2, test_refcount(b))
11253 END
11254 v9.CheckScriptSuccess(lines)
11255enddef
11256
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010011257" call a lambda function in one object from another object
11258def Test_lambda_invocation_across_classes()
11259 var lines =<< trim END
11260 vim9script
11261 class A
11262 var s: string = "foo"
11263 def GetFn(): func
11264 var Fn = (): string => {
11265 return this.s
11266 }
11267 return Fn
11268 enddef
11269 endclass
11270
11271 class B
11272 var s: string = "bar"
11273 def GetFn(): func
11274 var a = A.new()
11275 return a.GetFn()
11276 enddef
11277 endclass
11278
11279 var b = B.new()
11280 var Fn = b.GetFn()
11281 assert_equal("foo", Fn())
11282 END
11283 v9.CheckScriptSuccess(lines)
11284enddef
11285
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010011286" Test for using a class member which is an object of the current class
11287def Test_current_class_object_class_member()
11288 var lines =<< trim END
11289 vim9script
11290 class A
11291 public static var obj1: A = A.new(10)
11292 var n: number
11293 endclass
11294 defcompile
11295 assert_equal(10, A.obj1.n)
11296 END
11297 v9.CheckScriptSuccess(lines)
11298enddef
11299
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020011300" Test for updating a base class variable from a base class method without the
11301" class name. This used to crash Vim (Github issue #14352).
11302def Test_use_base_class_variable_from_base_class_method()
11303 var lines =<< trim END
11304 vim9script
11305
11306 class DictKeyClass
11307 static var _obj_id_count = 1
11308 def _GenerateKey()
11309 _obj_id_count += 1
11310 enddef
11311 static def GetIdCount(): number
11312 return _obj_id_count
11313 enddef
11314 endclass
11315
11316 class C extends DictKeyClass
11317 def F()
11318 this._GenerateKey()
11319 enddef
11320 endclass
11321
11322 C.new().F()
11323 assert_equal(2, DictKeyClass.GetIdCount())
11324 END
11325 v9.CheckScriptSuccess(lines)
11326enddef
11327
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020011328" Test for accessing protected funcref object and class variables
11329def Test_protected_funcref()
11330 # protected funcref object variable
11331 var lines =<< trim END
11332 vim9script
11333 class Test1
11334 const _Id: func(any): any = (v) => v
11335 endclass
11336 var n = Test1.new()._Id(1)
11337 END
11338 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
11339
11340 # protected funcref class variable
11341 lines =<< trim END
11342 vim9script
11343 class Test2
11344 static const _Id: func(any): any = (v) => v
11345 endclass
11346 var n = Test2._Id(2)
11347 END
11348 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
11349enddef
11350
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020011351" Test for using lambda block in classes
11352def Test_lambda_block_in_class()
11353 # This used to crash Vim
11354 var lines =<< trim END
11355 vim9script
11356 class IdClass1
11357 const Id: func(number): number = (num: number): number => {
11358 # Return a ID
11359 return num * 10
11360 }
11361 endclass
11362 var id = IdClass1.new()
11363 assert_equal(20, id.Id(2))
11364 END
11365 v9.CheckScriptSuccess(lines)
11366
11367 # This used to crash Vim
11368 lines =<< trim END
11369 vim9script
11370 class IdClass2
11371 static const Id: func(number): number = (num: number): number => {
11372 # Return a ID
11373 return num * 2
11374 }
11375 endclass
11376 assert_equal(16, IdClass2.Id(8))
11377 END
11378 v9.CheckScriptSuccess(lines)
11379enddef
11380
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020011381" Test for defcompiling an abstract method
11382def Test_abstract_method_defcompile()
11383 # Compile an abstract class with abstract object methods
11384 var lines =<< trim END
11385 vim9script
11386 abstract class A
11387 abstract def Foo(): string
11388 abstract def Bar(): list<string>
11389 endclass
11390 defcompile
11391 END
11392 v9.CheckScriptSuccess(lines)
11393
11394 # Compile a concrete object method in an abstract class
11395 lines =<< trim END
11396 vim9script
11397 abstract class A
11398 abstract def Foo(): string
11399 abstract def Bar(): list<string>
11400 def Baz(): string
11401 pass
11402 enddef
11403 endclass
11404 defcompile
11405 END
11406 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
11407
11408 # Compile a concrete class method in an abstract class
11409 lines =<< trim END
11410 vim9script
11411 abstract class A
11412 abstract def Foo(): string
11413 abstract def Bar(): list<string>
11414 static def Baz(): string
11415 pass
11416 enddef
11417 endclass
11418 defcompile
11419 END
11420 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
11421enddef
11422
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020011423" Test for defining a class in a function
11424def Test_class_definition_in_a_function()
11425 var lines =<< trim END
11426 vim9script
11427 def Foo()
11428 class A
11429 endclass
11430 enddef
11431 defcompile
11432 END
11433 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
11434enddef
11435
Yegappan Lakshmanandbac0da2024-05-25 20:23:54 +020011436" Test for using [] with a class and an object
11437def Test_class_object_index()
11438 var lines =<< trim END
11439 vim9script
11440 class A
11441 endclass
11442 A[10] = 1
11443 END
11444 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a class: A[10] = 1', 4)
11445
11446 lines =<< trim END
11447 vim9script
11448 class A
11449 endclass
11450 var a = A.new()
11451 a[10] = 1
11452 END
11453 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5)
11454enddef
11455
LemonBoyf4af3312024-07-04 13:43:12 +020011456def Test_class_member_init_typecheck()
11457 # Ensure the class member is assigned its declared type.
11458 var lines =<< trim END
11459 vim9script
11460 class S
11461 static var l: list<string> = []
11462 endclass
11463 S.l->add(123)
11464 END
11465 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5)
11466
11467 # Ensure the initializer value and the declared type match.
11468 lines =<< trim END
11469 vim9script
11470 class S
11471 var l: list<string> = [1, 2, 3]
11472 endclass
11473 var o = S.new()
11474 END
11475 v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>')
11476
11477 # Ensure the class member is assigned its declared type.
11478 lines =<< trim END
11479 vim9script
11480 class S
11481 var l: list<string> = []
11482 endclass
11483 var o = S.new()
11484 o.l->add(123)
11485 END
11486 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6)
11487enddef
11488
LemonBoy50d48542024-07-04 17:03:17 +020011489def Test_class_cast()
11490 var lines =<< trim END
11491 vim9script
11492 class A
11493 endclass
11494 class B extends A
11495 var mylen: number
11496 endclass
11497 def F(o: A): number
11498 return (<B>o).mylen
11499 enddef
11500
11501 defcompile F
11502 END
11503 v9.CheckScriptSuccess(lines)
11504enddef
11505
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011506" Test for using a variable of type "any" with an object
11507def Test_any_obj_var_type()
11508 var lines =<< trim END
11509 vim9script
11510 class A
11511 var name: string = "foobar"
11512 def Foo(): string
11513 return "func foo"
11514 enddef
11515 endclass
11516
11517 def CheckVals(x: any)
11518 assert_equal("foobar", x.name)
11519 assert_equal("func foo", x.Foo())
11520 enddef
11521
11522 var a = A.new()
11523 CheckVals(a)
11524 END
11525 v9.CheckScriptSuccess(lines)
11526
11527 # Try to set a non-existing variable
11528 lines =<< trim END
11529 vim9script
11530 class A
11531 var name: string = "foobar"
11532 endclass
11533
11534 def SetNonExistingVar(x: any)
11535 x.bar = [1, 2, 3]
11536 enddef
11537
11538 var a = A.new()
11539 SetNonExistingVar(a)
11540 END
11541 v9.CheckScriptFailure(lines, 'E1326: Variable "bar" not found in object "A"', 1)
11542
11543 # Try to read a non-existing variable
11544 lines =<< trim END
11545 vim9script
11546 class A
11547 var name: string = "foobar"
11548 endclass
11549
11550 def GetNonExistingVar(x: any)
11551 var i: dict<any> = x.bar
11552 enddef
11553
11554 var a = A.new()
11555 GetNonExistingVar(a)
11556 END
11557 v9.CheckScriptFailure(lines, 'E1326: Variable "bar" not found in object "A"', 1)
11558
11559 # Try to invoke a non-existing method
11560 lines =<< trim END
11561 vim9script
11562 class A
11563 def Foo(): number
11564 return 10
11565 enddef
11566 endclass
11567
11568 def CallNonExistingMethod(x: any)
11569 var i: number = x.Bar()
11570 enddef
11571
11572 var a = A.new()
11573 CallNonExistingMethod(a)
11574 END
11575 v9.CheckScriptFailure(lines, 'E1326: Variable "Bar" not found in object "A"', 1)
11576
11577 # Use an object which is a Dict value
11578 lines =<< trim END
11579 vim9script
11580 class Foo
11581 def Bar(): number
11582 return 369
11583 enddef
11584 endclass
11585
11586 def GetValue(FooDict: dict<any>): number
11587 var n: number = 0
11588 for foo in values(FooDict)
11589 n += foo.Bar()
11590 endfor
11591 return n
11592 enddef
11593
11594 var d = {'x': Foo.new()}
11595 assert_equal(369, GetValue(d))
11596 END
11597 v9.CheckScriptSuccess(lines)
11598
zeertzjqd32bf0a2024-12-17 20:55:13 +010011599 # Nested data. Object containing a Dict containing another Object.
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011600 lines =<< trim END
11601 vim9script
11602 class Context
11603 public var state: dict<any> = {}
11604 endclass
11605
11606 class Metadata
11607 public var value = 0
11608 endclass
11609
11610 var ctx = Context.new()
11611 ctx.state["meta"] = Metadata.new(2468)
11612
11613 const foo = ctx.state.meta.value
11614
11615 def F(): number
11616 const bar = ctx.state.meta.value
11617 return bar
11618 enddef
11619
11620 assert_equal(2468, F())
11621 END
11622 v9.CheckScriptSuccess(lines)
11623
11624 # Accessing an object from a method inside the class using any type
11625 lines =<< trim END
11626 vim9script
11627 class C
11628 def _G(): string
11629 return '_G'
11630 enddef
11631 static def S(o_any: any): string
11632 return o_any._G()
11633 enddef
11634 endclass
11635
11636 var o1 = C.new()
11637 assert_equal('_G', C.S(o1))
11638 END
11639 v9.CheckScriptSuccess(lines)
11640
11641 # Modifying an object private variable from a method in another class using
11642 # any type
11643 lines =<< trim END
11644 vim9script
11645
11646 class A
11647 var num = 10
11648 endclass
11649
11650 class B
11651 def SetVal(x: any)
11652 x.num = 20
11653 enddef
11654 endclass
11655
11656 var a = A.new()
11657 var b = B.new()
11658 b.SetVal(a)
11659 END
11660 v9.CheckScriptFailure(lines, 'E1335: Variable "num" in class "A" is not writable', 1)
11661
11662 # Accessing a object protected variable from a method in another class using
11663 # any type
11664 lines =<< trim END
11665 vim9script
11666
11667 class A
11668 var _num = 10
11669 endclass
11670
11671 class B
11672 def GetVal(x: any): number
11673 return x._num
11674 enddef
11675 endclass
11676
11677 var a = A.new()
11678 var b = B.new()
11679 var i = b.GetVal(a)
11680 END
11681 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_num" in class "A"', 1)
11682
11683 # Accessing an object returned from an imported function and class
11684 lines =<< trim END
11685 vim9script
11686 export class Foo
11687 public var name: string
11688 endclass
11689
11690 export def ReturnFooObject(): Foo
11691 var r = Foo.new('star')
11692 return r
11693 enddef
11694 END
11695 writefile(lines, 'Xanyvar1.vim', 'D')
11696
11697 lines =<< trim END
11698 vim9script
11699
11700 import './Xanyvar1.vim'
11701
11702 def GetName(): string
11703 var whatever = Xanyvar1.ReturnFooObject()
11704 return whatever.name
11705 enddef
11706
11707 assert_equal('star', GetName())
11708 END
11709 v9.CheckScriptSuccess(lines)
11710
11711 # Try to modify a private object variable using a variable of type "any"
11712 lines =<< trim END
11713 vim9script
11714
11715 class Foo
11716 var n: number = 10
11717 endclass
11718 def Fn(x: any)
11719 x.n = 20
11720 enddef
11721 var a = Foo.new()
11722 Fn(a)
11723 END
11724 v9.CheckScriptFailure(lines, 'E1335: Variable "n" in class "Foo" is not writable', 1)
11725
11726 # Try to read a protected object variable using a variable of type "any"
11727 lines =<< trim END
11728 vim9script
11729
11730 class Foo
11731 var _n: number = 10
11732 endclass
11733 def Fn(x: any): number
11734 return x._n
11735 enddef
11736
11737 var a = Foo.new()
11738 Fn(a)
11739 END
11740 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_n" in class "Foo"', 1)
11741
11742 # Read a protected object variable using a variable of type "any" in an object
11743 # method
11744 lines =<< trim END
11745 vim9script
11746
11747 class Foo
11748 var _n: number = 10
11749 def Fn(x: any): number
11750 return x._n
11751 enddef
11752 endclass
11753
11754 var a = Foo.new()
11755 assert_equal(10, a.Fn(a))
11756 END
11757 v9.CheckScriptSuccess(lines)
11758
11759 # Try to call a protected object method using a "any" type variable
11760 lines =<< trim END
11761 vim9script
11762
11763 class Foo
11764 def _GetVal(): number
11765 return 234
11766 enddef
11767 endclass
11768 def Fn(x: any): number
11769 return x._GetVal()
11770 enddef
11771
11772 var a = Foo.new()
11773 Fn(a)
11774 END
11775 v9.CheckScriptFailure(lines, 'E1366: Cannot access protected method: _GetVal', 1)
11776
11777 # Call a protected object method using a "any" type variable from another
11778 # object method
11779 lines =<< trim END
11780 vim9script
11781
11782 class Foo
11783 def _GetVal(): number
11784 return 234
11785 enddef
11786 def FooVal(x: any): number
11787 return x._GetVal()
11788 enddef
11789 endclass
11790
11791 var a = Foo.new()
11792 assert_equal(234, a.FooVal(a))
11793 END
11794 v9.CheckScriptSuccess(lines)
11795
11796 # Method chaining
11797 lines =<< trim END
11798 vim9script
11799
11800 export class T
11801 var id: number = 268
11802 def F(): any
11803 return this
11804 enddef
11805 endclass
11806
11807 def H()
11808 var a = T.new().F().F()
11809 assert_equal(268, a.id)
11810 enddef
11811 H()
11812
11813 var b: T = T.new().F().F()
11814 assert_equal(268, b.id)
11815 END
11816 v9.CheckScriptSuccess(lines)
11817
11818 # Using a null object to access a member variable
11819 lines =<< trim END
11820 vim9script
11821 def Fn(x: any): number
11822 return x.num
11823 enddef
11824
11825 Fn(null_object)
11826 END
11827 v9.CheckScriptFailure(lines, 'E1360: Using a null object', 1)
11828
11829 # Using a null object to invoke a method
11830 lines =<< trim END
11831 vim9script
11832 def Fn(x: any)
11833 x.Foo()
11834 enddef
11835
11836 Fn(null_object)
11837 END
11838 v9.CheckScriptFailure(lines, 'E1360: Using a null object', 1)
Yegappan Lakshmanane7984462024-11-12 21:03:00 +010011839
11840 # Try to change a const object variable using a "any" variable
11841 lines =<< trim END
11842 vim9script
11843 class A
11844 public const v1: number = 123
11845 endclass
11846
11847 def Fn(o: any)
11848 o.v1 = 321
11849 enddef
11850
11851 var a = A.new()
11852 Fn(a)
11853 END
11854 v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
11855
11856 # Try to change a final object variable using a "any" variable
11857 lines =<< trim END
11858 vim9script
11859 class A
11860 public final v1: number = 123
11861 endclass
11862
11863 def Fn(o: any)
11864 o.v1 = 321
11865 enddef
11866
11867 var a = A.new()
11868 Fn(a)
11869 END
11870 v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
11871
11872 # Assign a different type of value to an "any" type object variable
11873 lines =<< trim END
11874 vim9script
11875 class A
11876 public var v1: list<any> = [1, 2]
11877 endclass
11878
11879 def Fn(o: A)
11880 o.v1 = 'abc'
11881 enddef
11882
11883 var a = A.new()
11884 Fn(a)
11885 END
11886 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected list<any> but got string', 1)
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011887enddef
11888
Yegappan Lakshmanan481992c2024-12-06 18:35:12 +010011889" Test for using an object method with mapnew()
11890def Test_mapnew_with_instance_method()
11891 var lines =<< trim END
11892 vim9script
11893
11894 class Foo
11895 var str: string
11896 var nums: list<number> = [1, 2, 3]
11897
11898 def InstanceMethod(n: number): string
11899 return this.str .. n
11900 enddef
11901
11902 def MapperMethod(idx: number, elem: number): string
11903 return elem->this.InstanceMethod()
11904 enddef
11905
11906 def MapTest()
11907 this.str = "foo"
11908 var l = ['foo1', 'foo2', 'foo3']
11909 assert_equal(l, this.nums->mapnew(this.MapperMethod))
11910 enddef
11911 endclass
11912
11913 Foo.new().MapTest()
11914 END
11915 v9.CheckSourceSuccess(lines)
11916
11917 # Error in the mapnew() function
11918 lines =<< trim END
11919 vim9script
11920
11921 class Foo
11922 var str: string
11923 var nums: list<number> = [1, 2, 3]
11924
11925 def InstanceMethod(n: number): string
11926 throw "InstanceMethod failed"
11927 enddef
11928
11929 def MapperMethod(idx: number, elem: number): string
11930 return elem->this.InstanceMethod()
11931 enddef
11932
11933 def MapTest()
11934 this.str = "foo"
11935 var caught_exception: bool = false
11936 try
11937 this.nums->mapnew(this.MapperMethod)
11938 catch /InstanceMethod failed/
11939 caught_exception = true
11940 endtry
11941 assert_true(caught_exception)
11942 enddef
11943 endclass
11944
11945 Foo.new().MapTest()
11946 END
11947 v9.CheckSourceSuccess(lines)
11948enddef
11949
Yegappan Lakshmananb0206e92024-12-30 09:52:16 +010011950" Test for using an object method in a method call.
11951def Test_use_object_method_in_a_method_call()
11952 var lines =<< trim END
11953 vim9script
11954
11955 class Foo
11956 def Cost(nums: list<number>): number
11957 return nums[0] * nums[1]
11958 enddef
11959
11960 def ShowCost(): string
11961 var g = [4, 5]
11962 return $"Cost is: {g->this.Cost()}"
11963 enddef
11964 endclass
11965
11966 var d = Foo.new()
11967 assert_equal('Cost is: 20', d.ShowCost())
11968 END
11969 v9.CheckSourceSuccess(lines)
11970
11971 # Test for using a non-existing object method in string interpolation
11972 lines =<< trim END
11973 vim9script
11974
11975 class Foo
11976 def Cost(nums: list<number>): number
11977 return nums[0] * nums[1]
11978 enddef
11979
11980 def ShowCost(): string
11981 var g = [4, 5]
11982 echo $"Cost is: {g->this.NewCost()}"
11983 enddef
11984 endclass
11985
11986 var d = Foo.new()
11987 d.ShowCost()
11988 END
11989 v9.CheckSourceFailure(lines, 'E1326: Variable "NewCost" not found in object "Foo"')
11990enddef
11991
Yegappan Lakshmananb04af4c2025-01-03 10:50:08 +010011992" Test for referencing an object variable which is not yet initialized
11993def Test_uninitialized_object_var()
11994 var lines =<< trim END
11995 vim9script
11996 class Foo
11997 const two: number = Foo.Two(this)
11998 const one: number = 1
11999
12000 static def Two(that: Foo): number
12001 return that.one + 2
12002 enddef
12003 endclass
12004
12005 echo Foo.Two(Foo.new())
12006 END
12007 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'one' referenced")
12008
12009 lines =<< trim END
12010 vim9script
12011 class Foo
12012 const one: number = Foo.One(this)
12013
12014 static def One(that: Foo): number
12015 return 1
12016 enddef
12017 endclass
12018
12019 assert_equal(1, Foo.One(Foo.new()))
12020 END
12021 v9.CheckSourceSuccess(lines)
12022
12023 lines =<< trim END
12024 vim9script
12025 class Foo
12026 const one: number = 1
12027 const two: number = Foo.Two(this)
12028
12029 static def Two(that: Foo): number
12030 return that.one + 1
12031 enddef
12032 endclass
12033
12034 assert_equal(2, Foo.Two(Foo.new()))
12035 END
12036 v9.CheckSourceSuccess(lines)
12037
12038 lines =<< trim END
12039 vim9script
12040 class Foo
12041 const Id: func(any): any = ((_) => (v) => v)(this)
12042
12043 static def Id(that: Foo): func(any): any
12044 return that.Id
12045 enddef
12046 endclass
12047
12048 assert_equal(5, Foo.Id(Foo.new())(5))
12049 assert_equal(7, Foo.new().Id(7))
12050 END
12051 v9.CheckSourceSuccess(lines)
12052
12053 lines =<< trim END
12054 vim9script
12055 class Foo
12056 const Id: func(any): any = ((that) => (_) => that)(this)
12057
12058 static def Id(that: Foo): func(any): any
12059 return that.Id
12060 enddef
12061 endclass
12062
12063 const Id0: func(any): any = Foo.Id(Foo.new())
12064 const Id1: func(any): any = Foo.new().Id
12065 END
12066 v9.CheckSourceSuccess(lines)
12067
12068 lines =<< trim END
12069 vim9script
12070 class Foo
12071 const Id: any = Foo.Id(this)
12072
12073 static def Id(that: Foo): any
12074 return that.Id
12075 enddef
12076 endclass
12077
12078 const Id2: any = Foo.Id(Foo.new())
12079 const Id3: any = Foo.new().Id
12080 END
12081 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'Id' referenced")
12082
12083 lines =<< trim END
12084 vim9script
12085
12086 class Foo
12087 var x: string = ''
12088 var Y: func(): string = () => this.x
12089 endclass
12090
12091 var foo = Foo.new('ok')
12092 assert_equal('ok', foo.Y())
12093 END
12094 v9.CheckSourceSuccess(lines)
12095
12096 lines =<< trim END
12097 vim9script
12098
12099 class Foo
12100 var x: string = this.x
12101 endclass
12102
12103 var foo = Foo.new('ok')
12104 END
12105 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'x' referenced")
12106enddef
12107
Yegappan Lakshmanan2050dcc2025-01-06 18:34:49 +010012108" Test for initializing member variables of compound type in the constructor
12109def Test_constructor_init_compound_member_var()
12110 var lines =<< trim END
12111 vim9script
12112
12113 class Foo
12114 var v1: string = "aaa"
12115 var v2: list<number> = [1, 2]
12116 var v3: dict<string> = {a: 'a', b: 'b'}
12117 endclass
12118
12119 class Bar
12120 var v4: string = "bbb"
12121 var v5: Foo = Foo.new()
12122 var v6: list<number> = [1, 2]
12123 endclass
12124
12125 var b: Bar = Bar.new()
12126 assert_equal("aaa", b.v5.v1)
12127 assert_equal([1, 2], b.v5.v2)
12128 assert_equal({a: 'a', b: 'b'}, b.v5.v3)
12129 assert_equal("bbb", b.v4)
12130 assert_equal([1, 2], b.v6)
12131 END
12132 v9.CheckSourceSuccess(lines)
12133enddef
12134
Bram Moolenaar00b28d62022-12-08 15:32:33 +000012135" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker