blob: 799230a98b00c22c75f2199c9615cdfd20ce1792 [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
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003510def Test_abstract_class()
3511 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003512 vim9script
3513 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003514 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003515 endclass
3516 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003517 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003518 endclass
3519 var p: Base = Person.new('Peter', 42)
3520 assert_equal('Peter', p.name)
3521 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003522 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003523 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003524
3525 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003526 vim9script
3527 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003528 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003529 endclass
3530 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003531 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003532 endclass
3533 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003534 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003535 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003536
3537 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003538 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003539 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003540 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003541 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003542 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003543
h-eastaa979c72025-01-03 10:19:45 +01003544 # Test for "abstract" cannot be abbreviated
3545 lines =<< trim END
3546 vim9script
3547 abs class A
3548 endclass
3549 END
3550 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs class A', 2)
3551
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003552 # Additional commands after "abstract class"
3553 lines =<< trim END
3554 vim9script
3555 abstract class Something | var x = []
3556 endclass
3557 END
3558 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3559
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003560 # Abstract class cannot have a "new" function
3561 lines =<< trim END
3562 vim9script
3563 abstract class Base
3564 def new()
3565 enddef
3566 endclass
3567 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003568 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003569
3570 # extending an abstract class with class methods and variables
3571 lines =<< trim END
3572 vim9script
3573 abstract class A
3574 static var s: string = 'vim'
3575 static def Fn(): list<number>
3576 return [10]
3577 enddef
3578 endclass
3579 class B extends A
3580 endclass
3581 var b = B.new()
3582 assert_equal('vim', A.s)
3583 assert_equal([10], A.Fn())
3584 END
3585 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003586enddef
3587
Bram Moolenaar486fc252023-01-18 14:51:07 +00003588def Test_closure_in_class()
3589 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003590 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003591
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003592 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003593 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003594
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003595 def new()
3596 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3597 enddef
3598 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003599
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003600 Foo.new()
3601 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003602 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003603 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003604enddef
3605
Ernie Rael9ed53752023-12-11 17:40:46 +01003606def Test_construct_object_from_legacy()
3607 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003608 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003609 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003610
Ernie Rael9ed53752023-12-11 17:40:46 +01003611 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003612
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003613 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003614 def new(arg: string)
3615 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003616 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003617 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003618
Ernie Rael9ed53752023-12-11 17:40:46 +01003619 export def CreateA(...args: list<any>): A
3620 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003621 enddef
3622
Ernie Rael9ed53752023-12-11 17:40:46 +01003623 g:P = CreateA
3624 legacy call g:P('some_arg')
3625 assert_equal(true, newCalled)
3626 unlet g:P
3627 END
3628 v9.CheckSourceSuccess(lines)
3629
3630 lines =<< trim END
3631 vim9script
3632
3633 var newCalled = false
3634
3635 class A
3636 static def CreateA(options = {}): any
3637 return A.new()
3638 enddef
3639 def new()
3640 newCalled = true
3641 enddef
3642 endclass
3643
3644 g:P = A.CreateA
3645 legacy call g:P()
3646 assert_equal(true, newCalled)
3647 unlet g:P
3648 END
3649 v9.CheckSourceSuccess(lines)
3650
3651 # This also tests invoking "new()" with "call"
3652 lines =<< trim END
3653 vim9script
3654
3655 var createdObject: any
3656
3657 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003658 var val1: number
3659 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003660 static def CreateA(...args: list<any>): any
3661 createdObject = call(A.new, args)
3662 return createdObject
3663 enddef
3664 endclass
3665
3666 g:P = A.CreateA
3667 legacy call g:P(3, 5)
3668 assert_equal(3, createdObject.val1)
3669 assert_equal(5, createdObject.val2)
3670 legacy call g:P()
3671 assert_equal(0, createdObject.val1)
3672 assert_equal(0, createdObject.val2)
3673 legacy call g:P(7)
3674 assert_equal(7, createdObject.val1)
3675 assert_equal(0, createdObject.val2)
3676 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003677 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003678 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003679enddef
3680
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003681def Test_defer_with_object()
3682 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003683 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003684
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003685 class CWithEE
3686 def Enter()
3687 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003688 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003689 def Exit()
3690 g:result ..= "exited"
3691 enddef
3692 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003693
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003694 def With(ee: CWithEE, F: func)
3695 ee.Enter()
3696 defer ee.Exit()
3697 F()
3698 enddef
3699
3700 g:result = ''
3701 var obj = CWithEE.new()
3702 obj->With(() => {
3703 g:result ..= "called/"
3704 })
3705 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003706 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003707 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003708 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003709
3710 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003711 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003712
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003713 class BaseWithEE
3714 def Enter()
3715 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003716 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003717 def Exit()
3718 g:result ..= "exited-base"
3719 enddef
3720 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003722 class CWithEE extends BaseWithEE
3723 def Enter()
3724 g:result ..= "entered-child/"
3725 enddef
3726 def Exit()
3727 g:result ..= "exited-child"
3728 enddef
3729 endclass
3730
3731 def With(ee: BaseWithEE, F: func)
3732 ee.Enter()
3733 defer ee.Exit()
3734 F()
3735 enddef
3736
3737 g:result = ''
3738 var obj = CWithEE.new()
3739 obj->With(() => {
3740 g:result ..= "called/"
3741 })
3742 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003743 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003744 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003745 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003746enddef
3747
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003748" The following test used to crash Vim (Github issue #12676)
3749def Test_extends_method_crashes_vim()
3750 var lines =<< trim END
3751 vim9script
3752
3753 class Observer
3754 endclass
3755
3756 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003757 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003758
3759 def Set(v: any)
3760 if v != this.value
3761 this.value = v
3762 endif
3763 enddef
3764
3765 def Register(observer: Observer)
3766 enddef
3767 endclass
3768
3769 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003770 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003771 endclass
3772
3773 def Observe(obj: Property, who: Observer)
3774 obj.Register(who)
3775 enddef
3776
3777 var p = Bool.new(false)
3778 var myObserver = Observer.new()
3779
3780 Observe(p, myObserver)
3781
3782 p.Set(true)
3783 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003784 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003785enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003786
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003787" Test for calling a method in a class that is extended
3788def Test_call_method_in_extended_class()
3789 var lines =<< trim END
3790 vim9script
3791
3792 var prop_init_called = false
3793 var prop_register_called = false
3794
3795 class Property
3796 def Init()
3797 prop_init_called = true
3798 enddef
3799
3800 def Register()
3801 prop_register_called = true
3802 enddef
3803 endclass
3804
3805 class Bool extends Property
3806 endclass
3807
3808 def Observe(obj: Property)
3809 obj.Register()
3810 enddef
3811
3812 var p = Property.new()
3813 Observe(p)
3814
3815 p.Init()
3816 assert_true(prop_init_called)
3817 assert_true(prop_register_called)
3818 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003819 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003820enddef
3821
LemonBoyafe04662023-08-23 21:08:11 +02003822def Test_instanceof()
3823 var lines =<< trim END
3824 vim9script
3825
3826 class Base1
3827 endclass
3828
3829 class Base2 extends Base1
3830 endclass
3831
3832 interface Intf1
3833 endinterface
3834
3835 class Mix1 implements Intf1
3836 endclass
3837
3838 class Base3 extends Mix1
3839 endclass
3840
Ernie Rael2025af12023-12-12 16:58:00 +01003841 type AliasBase1 = Base1
3842 type AliasBase2 = Base2
3843 type AliasIntf1 = Intf1
3844 type AliasMix1 = Mix1
3845
LemonBoyafe04662023-08-23 21:08:11 +02003846 var b1 = Base1.new()
3847 var b2 = Base2.new()
3848 var b3 = Base3.new()
3849
3850 assert_true(instanceof(b1, Base1))
3851 assert_true(instanceof(b2, Base1))
3852 assert_false(instanceof(b1, Base2))
3853 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003854 assert_true(instanceof(b3, Base1, Base2, Intf1))
3855
3856 assert_true(instanceof(b1, AliasBase1))
3857 assert_true(instanceof(b2, AliasBase1))
3858 assert_false(instanceof(b1, AliasBase2))
3859 assert_true(instanceof(b3, AliasMix1))
3860 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003861
3862 def Foo()
3863 var a1 = Base1.new()
3864 var a2 = Base2.new()
3865 var a3 = Base3.new()
3866
3867 assert_true(instanceof(a1, Base1))
3868 assert_true(instanceof(a2, Base1))
3869 assert_false(instanceof(a1, Base2))
3870 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003871 assert_true(instanceof(a3, Base1, Base2, Intf1))
3872
3873 assert_true(instanceof(a1, AliasBase1))
3874 assert_true(instanceof(a2, AliasBase1))
3875 assert_false(instanceof(a1, AliasBase2))
3876 assert_true(instanceof(a3, AliasMix1))
3877 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003878 enddef
3879 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003880
3881 var o_null: Base1
3882 assert_false(instanceof(o_null, Base1))
3883
LemonBoyafe04662023-08-23 21:08:11 +02003884 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003885 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003886
3887 lines =<< trim END
3888 vim9script
3889
3890 class Base1
3891 endclass
3892 instanceof(Base1.new())
3893 END
3894 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3895
3896 lines =<< trim END
3897 vim9script
3898
3899 class Base1
3900 endclass
3901 def F()
3902 instanceof(Base1.new())
3903 enddef
3904 F()
3905 END
3906 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3907
3908 lines =<< trim END
3909 vim9script
3910
3911 class Base1
3912 endclass
3913
3914 class Base2
3915 endclass
3916
3917 var o = Base2.new()
3918 instanceof(o, Base1, Base2, 3)
3919 END
3920 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3921
3922 lines =<< trim END
3923 vim9script
3924
3925 class Base1
3926 endclass
3927
3928 class Base2
3929 endclass
3930
3931 def F()
3932 var o = Base2.new()
3933 instanceof(o, Base1, Base2, 3)
3934 enddef
3935 F()
3936 END
3937 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003938enddef
3939
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003940" Test for calling a method in the parent class that is extended partially.
3941" This used to fail with the 'E118: Too many arguments for function: Text' error
3942" message (Github issue #12524).
3943def Test_call_method_in_parent_class()
3944 var lines =<< trim END
3945 vim9script
3946
3947 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003948 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003949
3950 def SetY(lnum: number)
3951 this._lnum = lnum
3952 enddef
3953
3954 def Text(): string
3955 return ''
3956 enddef
3957 endclass
3958
3959 class Foo extends Widget
3960 def Text(): string
3961 return '<Foo>'
3962 enddef
3963 endclass
3964
3965 def Stack(w1: Widget, w2: Widget): list<Widget>
3966 w1.SetY(1)
3967 w2.SetY(2)
3968 return [w1, w2]
3969 enddef
3970
3971 var foo1 = Foo.new()
3972 var foo2 = Foo.new()
3973 var l = Stack(foo1, foo2)
3974 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003975 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003976enddef
3977
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003978" Test for calling methods from three levels of classes
3979def Test_multi_level_method_call()
3980 var lines =<< trim END
3981 vim9script
3982
3983 var A_func1: number = 0
3984 var A_func2: number = 0
3985 var A_func3: number = 0
3986 var B_func2: number = 0
3987 var B_func3: number = 0
3988 var C_func3: number = 0
3989
3990 class A
3991 def Func1()
3992 A_func1 += 1
3993 enddef
3994
3995 def Func2()
3996 A_func2 += 1
3997 enddef
3998
3999 def Func3()
4000 A_func3 += 1
4001 enddef
4002 endclass
4003
4004 class B extends A
4005 def Func2()
4006 B_func2 += 1
4007 enddef
4008
4009 def Func3()
4010 B_func3 += 1
4011 enddef
4012 endclass
4013
4014 class C extends B
4015 def Func3()
4016 C_func3 += 1
4017 enddef
4018 endclass
4019
4020 def A_CallFuncs(a: A)
4021 a.Func1()
4022 a.Func2()
4023 a.Func3()
4024 enddef
4025
4026 def B_CallFuncs(b: B)
4027 b.Func1()
4028 b.Func2()
4029 b.Func3()
4030 enddef
4031
4032 def C_CallFuncs(c: C)
4033 c.Func1()
4034 c.Func2()
4035 c.Func3()
4036 enddef
4037
4038 var cobj = C.new()
4039 A_CallFuncs(cobj)
4040 B_CallFuncs(cobj)
4041 C_CallFuncs(cobj)
4042 assert_equal(3, A_func1)
4043 assert_equal(0, A_func2)
4044 assert_equal(0, A_func3)
4045 assert_equal(3, B_func2)
4046 assert_equal(0, B_func3)
4047 assert_equal(3, C_func3)
4048 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004049 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004050enddef
4051
4052" Test for using members from three levels of classes
4053def Test_multi_level_member_access()
4054 var lines =<< trim END
4055 vim9script
4056
4057 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01004058 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004059 endclass
4060
4061 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01004062 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004063 endclass
4064
4065 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01004066 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004067 endclass
4068
4069 def A_members(a: A)
4070 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004071 enddef
4072
4073 def B_members(b: B)
4074 b.val1 += 1
4075 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004076 enddef
4077
4078 def C_members(c: C)
4079 c.val1 += 1
4080 c.val2 += 1
4081 c.val3 += 1
4082 enddef
4083
4084 var cobj = C.new()
4085 A_members(cobj)
4086 B_members(cobj)
4087 C_members(cobj)
4088 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004089 assert_equal(2, cobj.val2)
4090 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004091 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004092 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004093enddef
4094
LemonBoy0ffc17a2023-08-20 18:09:11 +02004095" Test expansion of <stack> with class methods.
4096def Test_stack_expansion_with_methods()
4097 var lines =<< trim END
4098 vim9script
4099
4100 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004101 def M1()
4102 F0()
4103 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02004104 endclass
4105
4106 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02004107 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02004108 enddef
4109
4110 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004111 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02004112 enddef
4113
4114 F()
4115 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004116 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02004117enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004118
4119" Test the return type of the new() constructor
4120def Test_new_return_type()
4121 # new() uses the default return type and there is no return statement
4122 var lines =<< trim END
4123 vim9script
4124
4125 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004126 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004127
4128 def new(this._bufnr)
4129 if !bufexists(this._bufnr)
4130 this._bufnr = -1
4131 endif
4132 enddef
4133 endclass
4134
4135 var c = C.new(12345)
4136 assert_equal('object<C>', typename(c))
4137
4138 var v1: C
4139 v1 = C.new(12345)
4140 assert_equal('object<C>', typename(v1))
4141
4142 def F()
4143 var v2: C
4144 v2 = C.new(12345)
4145 assert_equal('object<C>', typename(v2))
4146 enddef
4147 F()
4148 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004149 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004150
4151 # new() uses the default return type and an empty 'return' statement
4152 lines =<< trim END
4153 vim9script
4154
4155 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004156 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004157
4158 def new(this._bufnr)
4159 if !bufexists(this._bufnr)
4160 this._bufnr = -1
4161 return
4162 endif
4163 enddef
4164 endclass
4165
4166 var c = C.new(12345)
4167 assert_equal('object<C>', typename(c))
4168
4169 var v1: C
4170 v1 = C.new(12345)
4171 assert_equal('object<C>', typename(v1))
4172
4173 def F()
4174 var v2: C
4175 v2 = C.new(12345)
4176 assert_equal('object<C>', typename(v2))
4177 enddef
4178 F()
4179 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004180 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004181
4182 # new() uses "any" return type and returns "this"
4183 lines =<< trim END
4184 vim9script
4185
4186 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004187 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004188
4189 def new(this._bufnr): any
4190 if !bufexists(this._bufnr)
4191 this._bufnr = -1
4192 return this
4193 endif
4194 enddef
4195 endclass
4196 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004197 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004198
4199 # new() uses 'Dict' return type and returns a Dict
4200 lines =<< trim END
4201 vim9script
4202
4203 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004204 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004205
4206 def new(): dict<any>
4207 this._state = {}
4208 return this._state
4209 enddef
4210 endclass
4211
4212 var c = C.new()
4213 assert_equal('object<C>', typename(c))
4214 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004215 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004216enddef
4217
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004218" Test for checking a member initialization type at run time.
4219def Test_runtime_type_check_for_member_init()
4220 var lines =<< trim END
4221 vim9script
4222
4223 var retnum: bool = false
4224
4225 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004226 retnum = !retnum
4227 if retnum
4228 return 1
4229 else
4230 return "hello"
4231 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004232 enddef
4233
4234 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004235 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004236 endclass
4237
4238 var c1 = C.new()
4239 var c2 = C.new()
4240 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004241 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004242enddef
4243
4244" Test for locking a variable referring to an object and reassigning to another
4245" object.
Ernie Raelee865f32023-09-29 19:53:55 +02004246def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004247 var lines =<< trim END
4248 vim9script
4249
4250 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004251 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004252 def new(this.val)
4253 enddef
4254 endclass
4255
4256 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
4257 lockvar 2 some_dict
4258
4259 var current: C
4260 current = some_dict['c']
4261 assert_equal(3, current.val)
4262 current = some_dict['b']
4263 assert_equal(2, current.val)
4264
4265 def F()
4266 current = some_dict['c']
4267 enddef
4268
4269 def G()
4270 current = some_dict['b']
4271 enddef
4272
4273 F()
4274 assert_equal(3, current.val)
4275 G()
4276 assert_equal(2, current.val)
4277 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004278 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004279enddef
4280
Ernie Raelee865f32023-09-29 19:53:55 +02004281" Test trying to lock an object variable from various places
4282def Test_lockvar_object_variable()
4283 # An object variable lockvar has several cases:
4284 # object method, scriptlevel, scriplevel from :def, :def arg
4285 # method arg, static method arg.
4286 # Also different depths
4287
Ernie Raelee865f32023-09-29 19:53:55 +02004288 #
4289 # lockvar of read-only object variable
4290 #
4291
4292 # read-only lockvar from object method
4293 var lines =<< trim END
4294 vim9script
4295
4296 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004297 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004298 def Lock()
4299 lockvar this.val1
4300 enddef
4301 endclass
4302 var o = C.new(3)
4303 o.Lock()
4304 END
Ernie Rael64885642023-10-04 20:16:22 +02004305 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004306
4307 # read-only lockvar from scriptlevel
4308 lines =<< trim END
4309 vim9script
4310
4311 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004312 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004313 endclass
4314 var o = C.new(3)
4315 lockvar o.val2
4316 END
4317 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4318
4319 # read-only lockvar of scriptlevel variable from def
4320 lines =<< trim END
4321 vim9script
4322
4323 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004324 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004325 endclass
4326 var o = C.new(3)
4327 def Lock()
4328 lockvar o.val3
4329 enddef
4330 Lock()
4331 END
4332 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4333
4334 # read-only lockvar of def argument variable
4335 lines =<< trim END
4336 vim9script
4337
4338 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004339 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004340 endclass
4341 def Lock(o: C)
4342 lockvar o.val4
4343 enddef
4344 Lock(C.new(3))
4345 END
4346 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4347
Ernie Raelee865f32023-09-29 19:53:55 +02004348 # read-only lockvar from object method arg
4349 lines =<< trim END
4350 vim9script
4351
4352 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004353 var val5: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004354 def Lock(c: C)
4355 lockvar c.val5
Ernie Raelee865f32023-09-29 19:53:55 +02004356 enddef
4357 endclass
4358 var o = C.new(3)
4359 o.Lock(C.new(5))
4360 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004361 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004362
4363 # read-only lockvar from class method arg
4364 lines =<< trim END
4365 vim9script
4366
4367 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004368 var val6: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004369 static def Lock(c: C)
4370 lockvar c.val6
Ernie Raelee865f32023-09-29 19:53:55 +02004371 enddef
4372 endclass
4373 var o = C.new(3)
4374 C.Lock(o)
4375 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004376 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004377
4378 #
4379 # lockvar of public object variable
4380 #
4381
4382 # lockvar from object method
4383 lines =<< trim END
4384 vim9script
4385
4386 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004387 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004388 def Lock()
4389 lockvar this.val1
4390 enddef
4391 endclass
4392 var o = C.new(3)
4393 o.Lock()
4394 END
4395 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4396
4397 # lockvar from scriptlevel
4398 lines =<< trim END
4399 vim9script
4400
4401 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004402 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004403 endclass
4404 var o = C.new(3)
4405 lockvar o.val2
4406 END
4407 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4408
4409 # lockvar of scriptlevel variable from def
4410 lines =<< trim END
4411 vim9script
4412
4413 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004414 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004415 endclass
4416 var o = C.new(3)
4417 def Lock()
4418 lockvar o.val3
4419 enddef
4420 Lock()
4421 END
4422 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4423
4424 # lockvar of def argument variable
4425 lines =<< trim END
4426 vim9script
4427
4428 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004429 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004430 endclass
4431 def Lock(o: C)
4432 lockvar o.val4
4433 enddef
4434 Lock(C.new(3))
4435 END
4436 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4437
4438 # lockvar from object method arg
4439 lines =<< trim END
4440 vim9script
4441
4442 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004443 public var val5: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004444 def Lock(c: C)
4445 lockvar c.val5
Ernie Raelee865f32023-09-29 19:53:55 +02004446 enddef
4447 endclass
4448 var o = C.new(3)
4449 o.Lock(C.new(5))
4450 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004451 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val5" in class "C"', 1)
Ernie Raelee865f32023-09-29 19:53:55 +02004452
4453 # lockvar from class method arg
4454 lines =<< trim END
4455 vim9script
4456
4457 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004458 public var val6: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004459 static def Lock(c: C)
4460 lockvar c.val6
Ernie Raelee865f32023-09-29 19:53:55 +02004461 enddef
4462 endclass
4463 var o = C.new(3)
4464 C.Lock(o)
4465 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004466 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val6" in class "C"', 1)
Ernie Raelee865f32023-09-29 19:53:55 +02004467enddef
4468
4469" Test trying to lock a class variable from various places
4470def Test_lockvar_class_variable()
4471
4472 # lockvar bare static from object method
4473 var lines =<< trim END
4474 vim9script
4475
4476 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004477 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004478 def Lock()
4479 lockvar sval1
4480 enddef
4481 endclass
4482 var o = C.new()
4483 o.Lock()
4484 END
4485 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4486
4487 # lockvar C.static from object method
4488 lines =<< trim END
4489 vim9script
4490
4491 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004492 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004493 def Lock()
4494 lockvar C.sval2
4495 enddef
4496 endclass
4497 var o = C.new()
4498 o.Lock()
4499 END
4500 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4501
4502 # lockvar bare static from class method
4503 lines =<< trim END
4504 vim9script
4505
4506 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004507 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004508 static def Lock()
4509 lockvar sval3
4510 enddef
4511 endclass
4512 C.Lock()
4513 END
4514 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4515
4516 # lockvar C.static from class method
4517 lines =<< trim END
4518 vim9script
4519
4520 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004521 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004522 static def Lock()
4523 lockvar C.sval4
4524 enddef
4525 endclass
4526 C.Lock()
4527 END
4528 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4529
4530 # lockvar C.static from script level
4531 lines =<< trim END
4532 vim9script
4533
4534 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004535 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004536 endclass
4537 lockvar C.sval5
4538 END
4539 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4540
4541 # lockvar o.static from script level
4542 lines =<< trim END
4543 vim9script
4544
4545 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004546 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004547 endclass
4548 var o = C.new()
4549 lockvar o.sval6
4550 END
4551 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4552enddef
4553
4554" Test locking an argument to :def
4555def Test_lockvar_argument()
4556 # Lockvar a function arg
4557 var lines =<< trim END
4558 vim9script
4559
4560 def Lock(val: any)
4561 lockvar val
4562 enddef
4563
4564 var d = {a: 1, b: 2}
4565 Lock(d)
4566
4567 d->extend({c: 3})
4568 END
4569 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4570
4571 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4572 # class member in "C". This tests lval_root_is_arg.
4573 lines =<< trim END
4574 vim9script
4575
4576 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004577 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004578 endclass
4579
4580 def Lock2(sval: any)
4581 lockvar sval
4582 enddef
4583
4584 var o = C.new()
4585 Lock2(o)
4586 END
4587 v9.CheckSourceSuccess(lines)
4588
4589 # Lock a class.
4590 lines =<< trim END
4591 vim9script
4592
4593 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004594 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004595 endclass
4596
4597 def Lock2(sval: any)
4598 lockvar sval
4599 enddef
4600
4601 Lock2(C)
4602 END
Ernie Raelb077b582023-12-14 20:11:44 +01004603 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004604
4605 # Lock an object.
4606 lines =<< trim END
4607 vim9script
4608
4609 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004610 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004611 endclass
4612
4613 def Lock2(sval: any)
4614 lockvar sval
4615 enddef
4616
4617 Lock2(C.new())
4618 END
4619 v9.CheckSourceSuccess(lines)
4620
4621 # In this case (unlike previous) "lockvar sval" is a class member.
4622 lines =<< trim END
4623 vim9script
4624
4625 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004626 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004627 def Lock2()
4628 lockvar sval
4629 enddef
4630 endclass
4631
4632
4633 var o = C.new()
4634 o.Lock2()
4635 END
4636 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4637enddef
4638
4639" Test that this can be locked without error
4640def Test_lockvar_this()
4641 # lockvar this
4642 var lines =<< trim END
4643 vim9script
4644 class C
4645 def TLock()
4646 lockvar this
4647 enddef
4648 endclass
4649 var o = C.new()
4650 o.TLock()
4651 END
4652 v9.CheckSourceSuccess(lines)
4653
4654 # lockvar four (four letter word, but not this)
4655 lines =<< trim END
4656 vim9script
4657 class C
4658 def TLock4()
4659 var four: number
4660 lockvar four
4661 enddef
4662 endclass
4663 var o = C.new()
4664 o.TLock4()
4665 END
4666 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4667
4668 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4669 lines =<< trim END
4670 vim9script
4671 class C
4672 def TLock5()
4673 var this5: number
4674 lockvar this5
4675 enddef
4676 endclass
4677 var o = C.new()
4678 o.TLock5()
4679 END
4680 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4681enddef
4682
4683" Test some general lockvar cases
4684def Test_lockvar_general()
4685 # lockvar an object and a class. It does nothing
4686 var lines =<< trim END
4687 vim9script
4688 class C
4689 endclass
4690 var o = C.new()
4691 lockvar o
4692 lockvar C
4693 END
4694 v9.CheckSourceSuccess(lines)
4695
4696 # Lock a list element that's nested in an object variable from a :def
4697 lines =<< trim END
4698 vim9script
4699
4700 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004701 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004702 endclass
4703 def Lock2(obj: any)
4704 lockvar obj.val[1]
4705 enddef
4706
4707 var o = C.new()
4708 Lock2(o)
4709 o.val[0] = [9]
4710 assert_equal([ [9], [2], [3] ], o.val)
4711 try
4712 o.val[1] = [999]
4713 call assert_false(true, 'assign should have failed')
4714 catch
4715 assert_exception('E741:')
4716 endtry
4717 o.val[2] = [8]
4718 assert_equal([ [9], [2], [8] ], o.val)
4719 END
4720 v9.CheckSourceSuccess(lines)
4721
4722 # Lock a list element that's nested in an object variable from scriptlevel
4723 lines =<< trim END
4724 vim9script
4725
4726 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004727 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004728 endclass
4729
4730 var o = C.new()
4731 lockvar o.val[1]
4732 o.val[0] = [9]
4733 assert_equal([ [9], [2], [3] ], o.val)
4734 try
4735 o.val[1] = [999]
4736 call assert_false(true, 'assign should have failed')
4737 catch
4738 assert_exception('E741:')
4739 endtry
4740 o.val[2] = [8]
4741 assert_equal([ [9], [2], [8] ], o.val)
4742 END
4743 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004744
4745 # lock a script level variable from an object method
4746 lines =<< trim END
4747 vim9script
4748
4749 class C
4750 def Lock()
4751 lockvar l
4752 enddef
4753 endclass
4754
4755 var l = [1]
4756 C.new().Lock()
4757 l[0] = 11
4758 END
4759 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4760
Ernie Rael03042a22023-11-11 08:53:32 +01004761 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004762 # in an object fetched via a script level list
4763 lines =<< trim END
4764 vim9script
4765
4766 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004767 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004768 def Lock()
4769 lockvar lc[0]._v1[1]
4770 enddef
4771 endclass
4772
4773 var l = [[1], [2], [3]]
4774 var o = C.new(l)
4775 var lc: list<C> = [ o ]
4776
4777 o.Lock()
4778 l[0] = [22]
4779 l[1] = [33]
4780 END
4781 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4782
4783 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004784 # in a class that does not own the protected variable.
4785 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004786 # the same name.
4787 lines =<< trim END
4788 vim9script
4789
4790 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004791 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004792 def Lock(obj: any)
4793 lockvar lc[0]._v1[1]
4794 enddef
4795 endclass
4796
4797 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004798 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004799 endclass
4800
4801 var l = [[1], [2], [3]]
4802 var o = C.new(l)
4803 var lc: list<C> = [ o ]
4804
4805 var o2 = C2.new()
4806 o2.Lock(o)
4807 END
Ernie Rael03042a22023-11-11 08:53:32 +01004808 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004809enddef
4810
Ernie Rael9771b2a2023-10-07 22:05:40 +02004811" Test builtin islocked()
4812def Test_lockvar_islocked()
4813 # Can't lock class/object variable
4814 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004815 # Lock item of variable's value (a list item)
4816 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004817 var lines =<< trim END
4818 vim9script
4819
4820 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004821 var o0: list<list<number>> = [ [0], [1], [2]]
4822 var o1: list<list<number>> = [[10], [11], [12]]
4823 static var c0: list<list<number>> = [[20], [21], [22]]
4824 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004825 endclass
4826
4827 def LockIt(arg: any)
4828 lockvar arg
4829 enddef
4830
4831 def UnlockIt(arg: any)
4832 unlockvar arg
4833 enddef
4834
4835 var obj = C.new()
4836 #lockvar obj.o1 # can't lock something you can't write to
4837
4838 try
4839 lockvar obj.o1 # can't lock something you can't write to
4840 call assert_false(1, '"lockvar obj.o1" should have failed')
4841 catch
4842 call assert_exception('E1335:')
4843 endtry
4844
4845 LockIt(obj.o1) # but can lock it's value
4846 assert_equal(1, islocked("obj.o1"))
4847 assert_equal(1, islocked("obj.o1[0]"))
4848 assert_equal(1, islocked("obj.o1[1]"))
4849 UnlockIt(obj.o1)
4850 assert_equal(0, islocked("obj.o1"))
4851 assert_equal(0, islocked("obj.o1[0]"))
4852
4853 lockvar obj.o1[0]
4854 assert_equal(0, islocked("obj.o1"))
4855 assert_equal(1, islocked("obj.o1[0]"))
4856 assert_equal(0, islocked("obj.o1[1]"))
4857 unlockvar obj.o1[0]
4858 assert_equal(0, islocked("obj.o1"))
4859 assert_equal(0, islocked("obj.o1[0]"))
4860
4861 # Same thing, but with a static
4862
4863 try
4864 lockvar C.c1 # can't lock something you can't write to
4865 call assert_false(1, '"lockvar C.c1" should have failed')
4866 catch
4867 call assert_exception('E1335:')
4868 endtry
4869
4870 LockIt(C.c1) # but can lock it's value
4871 assert_equal(1, islocked("C.c1"))
4872 assert_equal(1, islocked("C.c1[0]"))
4873 assert_equal(1, islocked("C.c1[1]"))
4874 UnlockIt(C.c1)
4875 assert_equal(0, islocked("C.c1"))
4876 assert_equal(0, islocked("C.c1[0]"))
4877
4878 lockvar C.c1[0]
4879 assert_equal(0, islocked("C.c1"))
4880 assert_equal(1, islocked("C.c1[0]"))
4881 assert_equal(0, islocked("C.c1[1]"))
4882 unlockvar C.c1[0]
4883 assert_equal(0, islocked("C.c1"))
4884 assert_equal(0, islocked("C.c1[0]"))
4885 END
4886 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004887
4888 # Do islocked() from an object method
4889 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004890 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004891 vim9script
4892
4893 var l0o0 = [ [0], [1], [2]]
4894 var l0o1 = [ [10], [11], [12]]
4895 var l0c0 = [[120], [121], [122]]
4896 var l0c1 = [[130], [131], [132]]
4897
4898 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004899 var o0: list<list<number>> = l0o0
4900 var o1: list<list<number>> = l0o1
4901 static var c0: list<list<number>> = l0c0
4902 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004903 def Islocked(arg: string): number
4904 return islocked(arg)
4905 enddef
4906 static def SIslocked(arg: string): number
4907 return islocked(arg)
4908 enddef
4909 endclass
4910
4911 var l2o0 = [[20000], [20001], [20002]]
4912 var l2o1 = [[20010], [20011], [20012]]
4913 var l2c0 = [[20120], [20121], [20122]]
4914 var l2c1 = [[20130], [20131], [20132]]
4915
4916 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004917 var o0: list<list<number>> = l2o0
4918 var o1: list<list<number>> = l2o1
4919 static var c0: list<list<number>> = l2c0
4920 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004921 def Islocked(arg: string): number
4922 return islocked(arg)
4923 enddef
4924 static def SIslocked(arg: string): number
4925 return islocked(arg)
4926 enddef
4927 endclass
4928
4929 var obj0 = C0.new()
4930 var obj2 = C2.new()
4931
4932 var l = [ obj0, null_object, obj2 ]
4933
4934 # lock list, object func access through script var expr
4935 assert_equal(0, obj0.Islocked("l[0].o0"))
4936 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4937 lockvar l0o0
4938 assert_equal(1, obj0.Islocked("l[0].o0"))
4939 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4940
4941 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4942
4943 # lock list element, object func access through script var expr
4944 lockvar l0o1[1]
4945 assert_equal(0, obj0.Islocked("this.o1[0]"))
4946 assert_equal(1, obj0.Islocked("this.o1[1]"))
4947
4948 assert_equal(0, obj0.Islocked("this.o1"))
4949 lockvar l0o1
4950 assert_equal(1, obj0.Islocked("this.o1"))
4951 unlockvar l0o1
4952
4953 lockvar l0c1[1]
4954
4955 # static by class name member expr from same class
4956 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4957 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4958 # static by bare name member expr from same class
4959 assert_equal(0, obj0.Islocked("c1[0]"))
4960 assert_equal(1, obj0.Islocked("c1[1]"))
4961
4962 # static by class name member expr from other class
4963 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4964 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4965 # static by bare name member expr from other class
4966 assert_equal(0, obj2.Islocked("c1[0]"))
4967 assert_equal(0, obj2.Islocked("c1[1]"))
4968
4969
4970 # static by bare name in same class
4971 assert_equal(0, obj0.Islocked("c0"))
4972 lockvar l0c0
4973 assert_equal(1, obj0.Islocked("c0"))
4974
4975 #
4976 # similar stuff, but use static method
4977 #
4978
4979 unlockvar l0o0
4980
4981 # lock list, object func access through script var expr
4982 assert_equal(0, C0.SIslocked("l[0].o0"))
4983 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4984 lockvar l0o0
4985 assert_equal(1, C0.SIslocked("l[0].o0"))
4986 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4987
4988 unlockvar l0o1
4989
4990 # can't access "this" from class method
4991 try
4992 C0.SIslocked("this.o1[0]")
4993 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4994 catch
4995 call assert_exception('E121: Undefined variable: this')
4996 endtry
4997
4998 lockvar l0c1[1]
4999
5000 # static by class name member expr from same class
5001 assert_equal(0, C0.SIslocked("C0.c1[0]"))
5002 assert_equal(1, C0.SIslocked("C0.c1[1]"))
5003 # static by bare name member expr from same class
5004 assert_equal(0, C0.SIslocked("c1[0]"))
5005 assert_equal(1, C0.SIslocked("c1[1]"))
5006
5007 # static by class name member expr from other class
5008 assert_equal(0, C2.SIslocked("C0.c1[0]"))
5009 assert_equal(1, C2.SIslocked("C0.c1[1]"))
5010 # static by bare name member expr from other class
5011 assert_equal(0, C2.SIslocked("c1[0]"))
5012 assert_equal(0, C2.SIslocked("c1[1]"))
5013
5014
5015 # static by bare name in same class
5016 unlockvar l0c0
5017 assert_equal(0, C0.SIslocked("c0"))
5018 lockvar l0c0
5019 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02005020 END
Ernie Rael4c8da022023-10-11 21:35:11 +02005021 v9.CheckSourceSuccess(lines)
5022
5023 # Check islocked class/object from various places.
5024 lines =<< trim END
5025 vim9script
5026
5027 class C
5028 def Islocked(arg: string): number
5029 return islocked(arg)
5030 enddef
5031 static def SIslocked(arg: string): number
5032 return islocked(arg)
5033 enddef
5034 endclass
5035 var obj = C.new()
5036
5037 # object method
5038 assert_equal(0, obj.Islocked("this"))
5039 assert_equal(0, obj.Islocked("C"))
5040
5041 # class method
5042 ### assert_equal(0, C.SIslocked("this"))
5043 assert_equal(0, C.SIslocked("C"))
5044
5045 #script level
5046 var v: number
5047 v = islocked("C")
5048 assert_equal(0, v)
5049 v = islocked("obj")
5050 assert_equal(0, v)
5051 END
5052 v9.CheckSourceSuccess(lines)
5053enddef
5054
5055def Test_lockvar_islocked_notfound()
5056 # Try non-existent things
5057 var lines =<< trim END
5058 vim9script
5059
5060 class C
5061 def Islocked(arg: string): number
5062 return islocked(arg)
5063 enddef
5064 static def SIslocked(arg: string): number
5065 return islocked(arg)
5066 enddef
5067 endclass
5068 var obj = C.new()
5069 assert_equal(-1, obj.Islocked("anywhere"))
5070 assert_equal(-1, C.SIslocked("notanywhere"))
5071 END
5072 v9.CheckSourceSuccess(lines)
5073
5074 # Something not found of the form "name1.name2" is an error
5075 lines =<< trim END
5076 vim9script
5077
5078 islocked("one.two")
5079 END
5080 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
5081
5082 lines =<< trim END
5083 vim9script
5084
5085 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005086 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02005087 def Islocked(arg: string): number
5088 return islocked(arg)
5089 enddef
5090 endclass
5091 var obj = C.new()
5092 obj.Islocked("this.val.not_there"))
5093 END
5094 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
5095
5096 lines =<< trim END
5097 vim9script
5098
5099 class C
5100 def Islocked(arg: string): number
5101 return islocked(arg)
5102 enddef
5103 endclass
5104 var obj = C.new()
5105 obj.Islocked("this.notobjmember")
5106 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005107 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02005108
5109 # access a script variable through methods
5110 lines =<< trim END
5111 vim9script
5112
5113 var l = [1]
5114 class C
5115 def Islocked(arg: string): number
5116 return islocked(arg)
5117 enddef
5118 static def SIslocked(arg: string): number
5119 return islocked(arg)
5120 enddef
5121 endclass
5122 var obj = C.new()
5123 assert_equal(0, obj.Islocked("l"))
5124 assert_equal(0, C.SIslocked("l"))
5125 lockvar l
5126 assert_equal(1, obj.Islocked("l"))
5127 assert_equal(1, C.SIslocked("l"))
5128 END
5129 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02005130enddef
5131
Ernie Rael03042a22023-11-11 08:53:32 +01005132" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005133def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005134 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005135 var lines =<< trim END
5136 vim9script
5137
5138 class A
5139 def _Foo(): number
5140 return 1234
5141 enddef
5142 endclass
5143 var a = A.new()
5144 a._Foo()
5145 END
Ernie Rael03042a22023-11-11 08:53:32 +01005146 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005147
Ernie Rael03042a22023-11-11 08:53:32 +01005148 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005149 lines =<< trim END
5150 vim9script
5151
5152 class A
5153 def _Foo(): number
5154 return 1234
5155 enddef
5156 endclass
5157 def T()
5158 var a = A.new()
5159 a._Foo()
5160 enddef
5161 T()
5162 END
Ernie Rael03042a22023-11-11 08:53:32 +01005163 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005164
Ernie Rael03042a22023-11-11 08:53:32 +01005165 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005166 lines =<< trim END
5167 vim9script
5168
5169 class A
5170 def _Foo(): number
5171 return 1234
5172 enddef
5173 def Bar(): number
5174 return this._Foo()
5175 enddef
5176 endclass
5177 var a = A.new()
5178 assert_equal(1234, a.Bar())
5179 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005180 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005181
Ernie Rael03042a22023-11-11 08:53:32 +01005182 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005183 lines =<< trim END
5184 vim9script
5185
5186 class A
5187 def _Foo(): number
5188 return 1234
5189 enddef
5190 def Bar(): number
5191 return this._Foo()
5192 enddef
5193 endclass
5194 def T()
5195 var a = A.new()
5196 assert_equal(1234, a.Bar())
5197 enddef
5198 T()
5199 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005200 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005201
Ernie Rael03042a22023-11-11 08:53:32 +01005202 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005203 lines =<< trim END
5204 vim9script
5205
5206 class A
5207 def _Foo(): number
5208 return 1234
5209 enddef
5210 def Bar(): number
5211 return _Foo()
5212 enddef
5213 endclass
5214 var a = A.new()
5215 a.Bar()
5216 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005217 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005218
Ernie Rael03042a22023-11-11 08:53:32 +01005219 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005220 lines =<< trim END
5221 vim9script
5222
5223 class A
5224 def _Foo(): number
5225 return 1234
5226 enddef
5227 endclass
5228 A._Foo()
5229 END
Ernie Rael03042a22023-11-11 08:53:32 +01005230 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005231
Ernie Rael03042a22023-11-11 08:53:32 +01005232 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005233 lines =<< trim END
5234 vim9script
5235
5236 class A
5237 def _Foo()
5238 enddef
5239 def _Foo()
5240 enddef
5241 endclass
5242 var a = A.new()
5243 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005244 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005245
Ernie Rael03042a22023-11-11 08:53:32 +01005246 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005247 lines =<< trim END
5248 vim9script
5249
5250 class A
5251 def _Foo()
5252 enddef
5253 def Foo()
5254 enddef
5255 endclass
5256 var a = A.new()
5257 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005258 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005259
Ernie Rael03042a22023-11-11 08:53:32 +01005260 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005261 lines =<< trim END
5262 vim9script
5263
5264 class A
5265 def Foo()
5266 enddef
5267 def _Foo()
5268 enddef
5269 endclass
5270 var a = A.new()
5271 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005272 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005273
Ernie Rael03042a22023-11-11 08:53:32 +01005274 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005275 lines =<< trim END
5276 vim9script
5277
5278 class A
5279 def Foo(): number
5280 return 100
5281 enddef
5282 def _Bar(): number
5283 return 200
5284 enddef
5285 def _Baz()
5286 assert_equal(100, this.Foo())
5287 assert_equal(200, this._Bar())
5288 enddef
5289 def T()
5290 this._Baz()
5291 enddef
5292 endclass
5293 var a = A.new()
5294 a.T()
5295 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005296 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005297
Ernie Rael03042a22023-11-11 08:53:32 +01005298 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005299 lines =<< trim END
5300 vim9script
5301
5302 class A
5303 def _Foo(): number
5304 return 100
5305 enddef
5306 endclass
5307 class B
5308 def Foo(): number
5309 var a = A.new()
5310 a._Foo()
5311 enddef
5312 endclass
5313 var b = B.new()
5314 b.Foo()
5315 END
Ernie Rael03042a22023-11-11 08:53:32 +01005316 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005317
Ernie Rael03042a22023-11-11 08:53:32 +01005318 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005319 lines =<< trim END
5320 vim9script
5321 class A
5322 def _Foo(): number
5323 return 1234
5324 enddef
5325 endclass
5326 class B extends A
5327 def Bar()
5328 enddef
5329 endclass
5330 class C extends B
5331 def Baz(): number
5332 return this._Foo()
5333 enddef
5334 endclass
5335 var c = C.new()
5336 assert_equal(1234, c.Baz())
5337 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005338 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005339
Ernie Rael03042a22023-11-11 08:53:32 +01005340 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005341 lines =<< trim END
5342 vim9script
5343 class A
5344 def _Foo(): number
5345 return 1234
5346 enddef
5347 endclass
5348 class B extends A
5349 def Bar()
5350 enddef
5351 endclass
5352 class C extends B
5353 def Baz(): number
5354 enddef
5355 endclass
5356 var c = C.new()
5357 assert_equal(1234, c._Foo())
5358 END
Ernie Rael03042a22023-11-11 08:53:32 +01005359 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005360
5361 # Using "_" prefix in a method name should fail outside of a class
5362 lines =<< trim END
5363 vim9script
5364 def _Foo(): number
5365 return 1234
5366 enddef
5367 var a = _Foo()
5368 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005369 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005370enddef
5371
Ernie Rael03042a22023-11-11 08:53:32 +01005372" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005373def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005374 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005375 var lines =<< trim END
5376 vim9script
5377
5378 class A
5379 static def _Foo(): number
5380 return 1234
5381 enddef
5382 endclass
5383 A._Foo()
5384 END
Ernie Rael03042a22023-11-11 08:53:32 +01005385 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005386
Ernie Rael03042a22023-11-11 08:53:32 +01005387 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005388 lines =<< trim END
5389 vim9script
5390
5391 class A
5392 static def _Foo(): number
5393 return 1234
5394 enddef
5395 endclass
5396 def T()
5397 A._Foo()
5398 enddef
5399 T()
5400 END
Ernie Rael03042a22023-11-11 08:53:32 +01005401 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005402
Ernie Rael03042a22023-11-11 08:53:32 +01005403 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005404 lines =<< trim END
5405 vim9script
5406
5407 class A
5408 static def _Foo(): number
5409 return 1234
5410 enddef
5411 endclass
5412 var a = A.new()
5413 a._Foo()
5414 END
Ernie Rael03042a22023-11-11 08:53:32 +01005415 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005416
Ernie Rael03042a22023-11-11 08:53:32 +01005417 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005418 lines =<< trim END
5419 vim9script
5420
5421 class A
5422 static def _Foo(): number
5423 return 1234
5424 enddef
5425 endclass
5426 def T()
5427 var a = A.new()
5428 a._Foo()
5429 enddef
5430 T()
5431 END
Ernie Rael03042a22023-11-11 08:53:32 +01005432 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005433
Ernie Rael03042a22023-11-11 08:53:32 +01005434 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005435 lines =<< trim END
5436 vim9script
5437
5438 class A
5439 static def _Foo(): number
5440 return 1234
5441 enddef
5442 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005443 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005444 enddef
5445 endclass
5446 var a = A.new()
5447 a.Bar()
5448 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005449 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005450
Ernie Rael03042a22023-11-11 08:53:32 +01005451 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005452 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005453 lines =<< trim END
5454 vim9script
5455
5456 class A
5457 static def _Foo1(): number
5458 return 1234
5459 enddef
5460 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005461 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005462 enddef
5463 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005464 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005465 enddef
5466 endclass
5467 var a = A.new()
5468 a.Bar()
5469 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005470 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005471
Ernie Rael03042a22023-11-11 08:53:32 +01005472 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005473 lines =<< trim END
5474 vim9script
5475
5476 class A
5477 static def _Foo()
5478 enddef
5479 static def Foo()
5480 enddef
5481 endclass
5482 var a = A.new()
5483 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005484 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005485
Ernie Rael03042a22023-11-11 08:53:32 +01005486 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005487 lines =<< trim END
5488 vim9script
5489
5490 class A
5491 static def _Foo(): number
5492 return 1234
5493 enddef
5494 endclass
5495 class B
5496 def Foo(): number
5497 return A._Foo()
5498 enddef
5499 endclass
5500 var b = B.new()
5501 assert_equal(1234, b.Foo())
5502 END
Ernie Rael03042a22023-11-11 08:53:32 +01005503 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005504
Ernie Rael03042a22023-11-11 08:53:32 +01005505 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005506 lines =<< trim END
5507 vim9script
5508 class A
5509 static def _Foo(): number
5510 return 1234
5511 enddef
5512 endclass
5513 class B extends A
5514 def Bar()
5515 enddef
5516 endclass
5517 class C extends B
5518 def Baz(): number
5519 return A._Foo()
5520 enddef
5521 endclass
5522 var c = C.new()
5523 assert_equal(1234, c.Baz())
5524 END
Ernie Rael03042a22023-11-11 08:53:32 +01005525 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005526
Ernie Rael03042a22023-11-11 08:53:32 +01005527 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005528 lines =<< trim END
5529 vim9script
5530 class A
5531 static def _Foo(): number
5532 return 1234
5533 enddef
5534 endclass
5535 class B extends A
5536 def Bar()
5537 enddef
5538 endclass
5539 class C extends B
5540 static def Baz(): number
5541 return A._Foo()
5542 enddef
5543 endclass
5544 assert_equal(1234, C.Baz())
5545 END
Ernie Rael03042a22023-11-11 08:53:32 +01005546 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005547
Ernie Rael03042a22023-11-11 08:53:32 +01005548 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005549 lines =<< trim END
5550 vim9script
5551 class A
5552 static def _Foo(): number
5553 return 1234
5554 enddef
5555 endclass
5556 class B extends A
5557 def Bar()
5558 enddef
5559 endclass
5560 class C extends B
5561 def Baz(): number
5562 enddef
5563 endclass
5564 var c = C.new()
5565 assert_equal(1234, C._Foo())
5566 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005567 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005568enddef
5569
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005570" Test for using the return value of a class/object method as a function
5571" argument.
5572def Test_objmethod_funcarg()
5573 var lines =<< trim END
5574 vim9script
5575
5576 class C
5577 def Foo(): string
5578 return 'foo'
5579 enddef
5580 endclass
5581
5582 def Bar(a: number, s: string): string
5583 return s
5584 enddef
5585
5586 def Baz(c: C)
5587 assert_equal('foo', Bar(10, c.Foo()))
5588 enddef
5589
5590 var t = C.new()
5591 Baz(t)
5592 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005593 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005594
5595 lines =<< trim END
5596 vim9script
5597
5598 class C
5599 static def Foo(): string
5600 return 'foo'
5601 enddef
5602 endclass
5603
5604 def Bar(a: number, s: string): string
5605 return s
5606 enddef
5607
5608 def Baz()
5609 assert_equal('foo', Bar(10, C.Foo()))
5610 enddef
5611
5612 Baz()
5613 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005614 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005615enddef
5616
Ernie Raelcf138d42023-09-06 20:45:03 +02005617def Test_static_inheritence()
5618 # subclasses get their own static copy
5619 var lines =<< trim END
5620 vim9script
5621
5622 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005623 static var _svar: number
5624 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005625 def new()
5626 _svar = 1
5627 this._mvar = 101
5628 enddef
5629 def AccessObject(): number
5630 return this._mvar
5631 enddef
5632 def AccessStaticThroughObject(): number
5633 return _svar
5634 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005635 endclass
5636
5637 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005638 def new()
5639 this._mvar = 102
5640 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005641 endclass
5642
5643 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005644 def new()
5645 this._mvar = 103
5646 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005647
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005648 def AccessPrivateStaticThroughClassName(): number
5649 assert_equal(1, A._svar)
5650 return 444
5651 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005652 endclass
5653
5654 var oa = A.new()
5655 var ob = B.new()
5656 var oc = C.new()
5657 assert_equal(101, oa.AccessObject())
5658 assert_equal(102, ob.AccessObject())
5659 assert_equal(103, oc.AccessObject())
5660
Ernie Rael03042a22023-11-11 08:53:32 +01005661 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005662
5663 # verify object properly resolves to correct static
5664 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005665 assert_equal(1, ob.AccessStaticThroughObject())
5666 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005667 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005668 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005669enddef
5670
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005671" Test for declaring duplicate object and class members
5672def Test_dup_member_variable()
5673 # Duplicate member variable
5674 var lines =<< trim END
5675 vim9script
5676 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005677 var val = 10
5678 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005679 endclass
5680 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005681 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005682
Ernie Rael03042a22023-11-11 08:53:32 +01005683 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005684 lines =<< trim END
5685 vim9script
5686 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005687 var _val = 10
5688 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005689 endclass
5690 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005691 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005692
5693 # Duplicate public member variable
5694 lines =<< trim END
5695 vim9script
5696 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005697 public var val = 10
5698 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005699 endclass
5700 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005701 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005702
Ernie Rael03042a22023-11-11 08:53:32 +01005703 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005704 lines =<< trim END
5705 vim9script
5706 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005707 var val = 10
5708 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005709 endclass
5710 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005711 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005712
Ernie Rael03042a22023-11-11 08:53:32 +01005713 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005714 lines =<< trim END
5715 vim9script
5716 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005717 var _val = 20
5718 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005719 endclass
5720 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005721 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005722
5723 # Duplicate class member variable
5724 lines =<< trim END
5725 vim9script
5726 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005727 static var s: string = "abc"
5728 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005729 endclass
5730 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005731 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005732
Ernie Rael03042a22023-11-11 08:53:32 +01005733 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005734 lines =<< trim END
5735 vim9script
5736 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005737 public static var s: string = "abc"
5738 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005739 endclass
5740 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005741 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005742
5743 # Duplicate class and object member variable
5744 lines =<< trim END
5745 vim9script
5746 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005747 static var val = 10
5748 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005749 def new()
5750 enddef
5751 endclass
5752 var c = C.new()
5753 assert_equal(10, C.val)
5754 assert_equal(20, c.val)
5755 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005756 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005757
5758 # Duplicate object member variable in a derived class
5759 lines =<< trim END
5760 vim9script
5761 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005762 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005763 endclass
5764 class B extends A
5765 endclass
5766 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005767 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005768 endclass
5769 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005770 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005771
Ernie Rael03042a22023-11-11 08:53:32 +01005772 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005773 lines =<< trim END
5774 vim9script
5775 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005776 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005777 endclass
5778 class B extends A
5779 endclass
5780 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005781 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005782 endclass
5783 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005784 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005785
Ernie Rael03042a22023-11-11 08:53:32 +01005786 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005787 lines =<< trim END
5788 vim9script
5789 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005790 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005791 endclass
5792 class B extends A
5793 endclass
5794 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005795 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005796 endclass
5797 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005798 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005799
5800 # Duplicate object member variable in a derived class
5801 lines =<< trim END
5802 vim9script
5803 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005804 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005805 endclass
5806 class B extends A
5807 endclass
5808 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005809 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005810 endclass
5811 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005812 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005813
5814 # Two member variables with a common prefix
5815 lines =<< trim END
5816 vim9script
5817 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005818 public static var svar2: number
5819 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005820 endclass
5821 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005822 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005823enddef
5824
Ernie Rael03042a22023-11-11 08:53:32 +01005825" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005826def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005827 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005828 var lines =<< trim END
5829 vim9script
5830 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005831 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005832 def GetVal(): number
5833 return this._val
5834 enddef
5835 endclass
5836 def T()
5837 var a = A.new()
5838 a._val = 20
5839 enddef
5840 T()
5841 END
Ernie Rael03042a22023-11-11 08:53:32 +01005842 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005843
Ernie Rael03042a22023-11-11 08:53:32 +01005844 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005845 lines =<< trim END
5846 vim9script
5847 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005848 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005849 endclass
5850 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005851 var a = A.new()
5852 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005853 enddef
5854 T()
5855 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005856 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005857
Ernie Rael03042a22023-11-11 08:53:32 +01005858 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005859 lines =<< trim END
5860 vim9script
5861 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005862 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005863 endclass
5864 def T()
5865 var a = A.new()
5866 var x = a._val
5867 enddef
5868 T()
5869 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005870 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005871
Ernie Rael03042a22023-11-11 08:53:32 +01005872 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005873 lines =<< trim END
5874 vim9script
5875 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005876 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005877 endclass
5878 def T()
5879 var a = A.new()
5880 a._val = 3
5881 enddef
5882 T()
5883 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005884 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005885
Ernie Rael03042a22023-11-11 08:53:32 +01005886 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005887 lines =<< trim END
5888 vim9script
5889 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005890 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005891 endclass
5892 def T()
5893 var x = A._val
5894 enddef
5895 T()
5896 END
Ernie Rael03042a22023-11-11 08:53:32 +01005897 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005898
Ernie Rael03042a22023-11-11 08:53:32 +01005899 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005900 lines =<< trim END
5901 vim9script
5902 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005903 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005904 endclass
5905 def T()
5906 A._val = 3
5907 enddef
5908 T()
5909 END
Ernie Rael03042a22023-11-11 08:53:32 +01005910 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005911enddef
5912
5913" Test for changing the member access of an interface in a implementation class
5914def Test_change_interface_member_access()
5915 var lines =<< trim END
5916 vim9script
5917 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005918 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005919 endinterface
5920 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005921 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005922 endclass
5923 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005924 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005925
5926 lines =<< trim END
5927 vim9script
5928 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005929 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005930 endinterface
5931 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005932 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005933 endclass
5934 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005935 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005936enddef
5937
5938" Test for trying to change a readonly member from a def function
5939def Test_readonly_member_change_in_def_func()
5940 var lines =<< trim END
5941 vim9script
5942 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005943 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005944 endclass
5945 def T()
5946 var a = A.new()
5947 a.val = 20
5948 enddef
5949 T()
5950 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005951 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005952enddef
5953
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005954" Test for reading and writing a class member from a def function
5955def Test_modify_class_member_from_def_function()
5956 var lines =<< trim END
5957 vim9script
5958 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005959 var var1: number = 10
5960 public static var var2: list<number> = [1, 2]
5961 public static var var3: dict<number> = {a: 1, b: 2}
5962 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005963 endclass
5964 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005965 assert_equal([1, 2], A.var2)
5966 assert_equal({a: 1, b: 2}, A.var3)
5967 A.var2 = [3, 4]
5968 A.var3 = {c: 3, d: 4}
5969 assert_equal([3, 4], A.var2)
5970 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005971 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005972 enddef
5973 T()
5974 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005975 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005976enddef
5977
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005978" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005979def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005980 var lines =<< trim END
5981 vim9script
5982 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005983 public static var svar1: list<number> = [1]
5984 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005985 endclass
5986
5987 A.svar1->add(3)
5988 A.svar2->add(4)
5989 assert_equal([1, 3], A.svar1)
5990 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005991
5992 def Foo()
5993 A.svar1->add(7)
5994 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005995 assert_equal([1, 3, 7], A.svar1)
5996 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005997 enddef
5998 Foo()
5999 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006000 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006001
6002 # Cannot read from a class variable using an object in script context
6003 lines =<< trim END
6004 vim9script
6005 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006006 public var var1: number
6007 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006008 endclass
6009
6010 var a = A.new()
6011 echo a.svar2
6012 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006013 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006014
6015 # Cannot write to a class variable using an object in script context
6016 lines =<< trim END
6017 vim9script
6018 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006019 public var var1: number
6020 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006021 endclass
6022
6023 var a = A.new()
6024 a.svar2 = [2]
6025 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006026 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006027
6028 # Cannot read from a class variable using an object in def method context
6029 lines =<< trim END
6030 vim9script
6031 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006032 public var var1: number
6033 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006034 endclass
6035
6036 def T()
6037 var a = A.new()
6038 echo a.svar2
6039 enddef
6040 T()
6041 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006042 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006043
6044 # Cannot write to a class variable using an object in def method context
6045 lines =<< trim END
6046 vim9script
6047 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006048 public var var1: number
6049 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006050 endclass
6051
6052 def T()
6053 var a = A.new()
6054 a.svar2 = [2]
6055 enddef
6056 T()
6057 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006058 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006059enddef
6060
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006061" Test for using a interface method using a child object
6062def Test_interface_method_from_child()
6063 var lines =<< trim END
6064 vim9script
6065
6066 interface A
6067 def Foo(): string
6068 endinterface
6069
6070 class B implements A
6071 def Foo(): string
6072 return 'foo'
6073 enddef
6074 endclass
6075
6076 class C extends B
6077 def Bar(): string
6078 return 'bar'
6079 enddef
6080 endclass
6081
6082 def T1(a: A)
6083 assert_equal('foo', a.Foo())
6084 enddef
6085
6086 def T2(b: B)
6087 assert_equal('foo', b.Foo())
6088 enddef
6089
6090 var c = C.new()
6091 T1(c)
6092 T2(c)
6093 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006094 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006095enddef
6096
6097" Test for using an interface method using a child object when it is overridden
6098" by the child class.
6099" FIXME: This test fails.
6100" def Test_interface_overridden_method_from_child()
6101" var lines =<< trim END
6102" vim9script
6103"
6104" interface A
6105" def Foo(): string
6106" endinterface
6107"
6108" class B implements A
6109" def Foo(): string
6110" return 'b-foo'
6111" enddef
6112" endclass
6113"
6114" class C extends B
6115" def Bar(): string
6116" return 'bar'
6117" enddef
6118" def Foo(): string
6119" return 'c-foo'
6120" enddef
6121" endclass
6122"
6123" def T1(a: A)
6124" assert_equal('c-foo', a.Foo())
6125" enddef
6126"
6127" def T2(b: B)
6128" assert_equal('c-foo', b.Foo())
6129" enddef
6130"
6131" var c = C.new()
6132" T1(c)
6133" T2(c)
6134" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006135" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006136" enddef
6137
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006138" Test for abstract methods
6139def Test_abstract_method()
6140 # Use two abstract methods
6141 var lines =<< trim END
6142 vim9script
6143 abstract class A
6144 def M1(): number
6145 return 10
6146 enddef
6147 abstract def M2(): number
6148 abstract def M3(): number
6149 endclass
6150 class B extends A
6151 def M2(): number
6152 return 20
6153 enddef
6154 def M3(): number
6155 return 30
6156 enddef
6157 endclass
6158 var b = B.new()
6159 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
6160 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006161 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006162
6163 # Don't define an abstract method
6164 lines =<< trim END
6165 vim9script
6166 abstract class A
6167 abstract def Foo()
6168 endclass
6169 class B extends A
6170 endclass
6171 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006172 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006173
6174 # Use abstract method in a concrete class
6175 lines =<< trim END
6176 vim9script
6177 class A
6178 abstract def Foo()
6179 endclass
6180 class B extends A
6181 endclass
6182 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006183 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006184
6185 # Use abstract method in an interface
6186 lines =<< trim END
6187 vim9script
6188 interface A
6189 abstract def Foo()
6190 endinterface
6191 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006192 def Foo()
6193 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006194 endclass
6195 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01006196 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6197
6198 # Use abstract static method in an interface
6199 lines =<< trim END
6200 vim9script
6201 interface A
6202 abstract static def Foo()
6203 enddef
6204 endinterface
6205 END
6206 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6207
6208 # Use abstract static variable in an interface
6209 lines =<< trim END
6210 vim9script
6211 interface A
6212 abstract static foo: number = 10
6213 endinterface
6214 END
6215 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006216
6217 # Abbreviate the "abstract" keyword
6218 lines =<< trim END
6219 vim9script
6220 class A
6221 abs def Foo()
6222 endclass
6223 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006224 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006225
6226 # Use "abstract" with a member variable
6227 lines =<< trim END
6228 vim9script
6229 abstract class A
6230 abstract this.val = 10
6231 endclass
6232 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006233 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006234
6235 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01006236 lines =<< trim END
6237 vim9script
6238 abstract class A
6239 abstract static def Foo(): number
6240 endclass
6241 END
6242 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006243
6244 # Type mismatch between abstract method and concrete method
6245 lines =<< trim END
6246 vim9script
6247 abstract class A
6248 abstract def Foo(a: string, b: number): list<number>
6249 endclass
6250 class B extends A
6251 def Foo(a: number, b: string): list<string>
6252 return []
6253 enddef
6254 endclass
6255 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006256 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 +02006257
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006258 # Invoke an abstract method from a def function
6259 lines =<< trim END
6260 vim9script
6261 abstract class A
6262 abstract def Foo(): list<number>
6263 endclass
6264 class B extends A
6265 def Foo(): list<number>
6266 return [3, 5]
6267 enddef
6268 endclass
6269 def Bar(c: B)
6270 assert_equal([3, 5], c.Foo())
6271 enddef
6272 var b = B.new()
6273 Bar(b)
6274 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006275 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006276
6277 # Use a static method in an abstract class
6278 lines =<< trim END
6279 vim9script
6280 abstract class A
6281 static def Foo(): string
6282 return 'foo'
6283 enddef
6284 endclass
6285 assert_equal('foo', A.Foo())
6286 END
6287 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006288enddef
6289
6290" Test for calling a class method from a subclass
6291def Test_class_method_call_from_subclass()
6292 # class method call from a subclass
6293 var lines =<< trim END
6294 vim9script
6295
6296 class A
6297 static def Foo()
6298 echo "foo"
6299 enddef
6300 endclass
6301
6302 class B extends A
6303 def Bar()
6304 Foo()
6305 enddef
6306 endclass
6307
6308 var b = B.new()
6309 b.Bar()
6310 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006311 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006312enddef
6313
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006314" Test for calling a class method using an object in a def function context and
6315" script context.
6316def Test_class_method_call_using_object()
6317 # script context
6318 var lines =<< trim END
6319 vim9script
6320 class A
6321 static def Foo(): list<string>
6322 return ['a', 'b']
6323 enddef
6324 def Bar()
6325 assert_equal(['a', 'b'], A.Foo())
6326 assert_equal(['a', 'b'], Foo())
6327 enddef
6328 endclass
6329
6330 def T()
6331 assert_equal(['a', 'b'], A.Foo())
6332 var t_a = A.new()
6333 t_a.Bar()
6334 enddef
6335
6336 assert_equal(['a', 'b'], A.Foo())
6337 var a = A.new()
6338 a.Bar()
6339 T()
6340 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006341 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006342
6343 # script context
6344 lines =<< trim END
6345 vim9script
6346 class A
6347 static def Foo(): string
6348 return 'foo'
6349 enddef
6350 endclass
6351
6352 var a = A.new()
6353 assert_equal('foo', a.Foo())
6354 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006355 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006356
6357 # def function context
6358 lines =<< trim END
6359 vim9script
6360 class A
6361 static def Foo(): string
6362 return 'foo'
6363 enddef
6364 endclass
6365
6366 def T()
6367 var a = A.new()
6368 assert_equal('foo', a.Foo())
6369 enddef
6370 T()
6371 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006372 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006373enddef
6374
6375def Test_class_variable()
6376 var lines =<< trim END
6377 vim9script
6378
6379 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006380 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006381 static def ClassFunc()
6382 assert_equal(10, val)
6383 enddef
6384 def ObjFunc()
6385 assert_equal(10, val)
6386 enddef
6387 endclass
6388
6389 class B extends A
6390 endclass
6391
6392 assert_equal(10, A.val)
6393 A.ClassFunc()
6394 var a = A.new()
6395 a.ObjFunc()
6396 var b = B.new()
6397 b.ObjFunc()
6398
6399 def T1(a1: A)
6400 a1.ObjFunc()
6401 A.ClassFunc()
6402 enddef
6403 T1(b)
6404
6405 A.val = 20
6406 assert_equal(20, A.val)
6407 END
6408 v9.CheckSourceSuccess(lines)
6409
6410 # Modifying a parent class variable from a child class method
6411 lines =<< trim END
6412 vim9script
6413
6414 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006415 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006416 endclass
6417
6418 class B extends A
6419 static def ClassFunc()
6420 val = 20
6421 enddef
6422 endclass
6423 B.ClassFunc()
6424 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006425 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006426
6427 # Reading a parent class variable from a child class method
6428 lines =<< trim END
6429 vim9script
6430
6431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006432 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006433 endclass
6434
6435 class B extends A
6436 static def ClassFunc()
6437 var i = val
6438 enddef
6439 endclass
6440 B.ClassFunc()
6441 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006442 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006443
6444 # Modifying a parent class variable from a child object method
6445 lines =<< trim END
6446 vim9script
6447
6448 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006449 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006450 endclass
6451
6452 class B extends A
6453 def ObjFunc()
6454 val = 20
6455 enddef
6456 endclass
6457 var b = B.new()
6458 b.ObjFunc()
6459 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006460 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006461
6462 # Reading a parent class variable from a child object method
6463 lines =<< trim END
6464 vim9script
6465
6466 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006467 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006468 endclass
6469
6470 class B extends A
6471 def ObjFunc()
6472 var i = val
6473 enddef
6474 endclass
6475 var b = B.new()
6476 b.ObjFunc()
6477 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006478 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006479
6480 # Modifying a class variable using an object at script level
6481 lines =<< trim END
6482 vim9script
6483
6484 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006485 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006486 endclass
6487 var a = A.new()
6488 a.val = 20
6489 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006490 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006491
6492 # Reading a class variable using an object at script level
6493 lines =<< trim END
6494 vim9script
6495
6496 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006497 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006498 endclass
6499 var a = A.new()
6500 var i = a.val
6501 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006502 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006503
6504 # Modifying a class variable using an object at function level
6505 lines =<< trim END
6506 vim9script
6507
6508 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006509 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006510 endclass
6511
6512 def T()
6513 var a = A.new()
6514 a.val = 20
6515 enddef
6516 T()
6517 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006518 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006519
6520 # Reading a class variable using an object at function level
6521 lines =<< trim END
6522 vim9script
6523
6524 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006525 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006526 endclass
6527 def T()
6528 var a = A.new()
6529 var i = a.val
6530 enddef
6531 T()
6532 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006533 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006534
6535 # Use old implicit var declaration syntax (without initialization)
6536 lines =<< trim END
6537 vim9script
6538
6539 class A
6540 static val: number
6541 endclass
6542 END
6543 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6544
6545 # Use old implicit var declaration syntax (with initialization)
6546 lines =<< trim END
6547 vim9script
6548
6549 class A
6550 static val: number = 10
6551 endclass
6552 END
6553 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6554
6555 # Use old implicit var declaration syntax (type inferred)
6556 lines =<< trim END
6557 vim9script
6558
6559 class A
6560 static val = 10
6561 endclass
6562 END
6563 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6564
6565 # Missing ":var" in "var" class variable declaration (without initialization)
6566 lines =<< trim END
6567 vim9script
6568
6569 class A
6570 static var: number
6571 endclass
6572 END
6573 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6574
6575 # Missing ":var" in "var" class variable declaration (with initialization)
6576 lines =<< trim END
6577 vim9script
6578
6579 class A
6580 static var: number = 10
6581 endclass
6582 END
6583 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6584
6585 # Missing ":var" in "var" class variable declaration (type inferred)
6586 lines =<< trim END
6587 vim9script
6588
6589 class A
6590 static var = 10
6591 endclass
6592 END
6593 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6594
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006595enddef
6596
6597" Test for using a duplicate class method and class variable in a child class
6598def Test_dup_class_member()
6599 # duplicate class variable, class method and overridden object method
6600 var lines =<< trim END
6601 vim9script
6602 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006603 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006604 static def Check()
6605 assert_equal(100, sval)
6606 enddef
6607 def GetVal(): number
6608 return sval
6609 enddef
6610 endclass
6611
6612 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006613 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006614 static def Check()
6615 assert_equal(200, sval)
6616 enddef
6617 def GetVal(): number
6618 return sval
6619 enddef
6620 endclass
6621
6622 def T1(aa: A): number
6623 return aa.GetVal()
6624 enddef
6625
6626 def T2(bb: B): number
6627 return bb.GetVal()
6628 enddef
6629
6630 assert_equal(100, A.sval)
6631 assert_equal(200, B.sval)
6632 var a = A.new()
6633 assert_equal(100, a.GetVal())
6634 var b = B.new()
6635 assert_equal(200, b.GetVal())
6636 assert_equal(200, T1(b))
6637 assert_equal(200, T2(b))
6638 END
6639 v9.CheckSourceSuccess(lines)
6640
6641 # duplicate class variable and class method
6642 lines =<< trim END
6643 vim9script
6644 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006645 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006646 static def Check()
6647 assert_equal(100, sval)
6648 enddef
6649 def GetVal(): number
6650 return sval
6651 enddef
6652 endclass
6653
6654 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006655 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006656 static def Check()
6657 assert_equal(200, sval)
6658 enddef
6659 endclass
6660
6661 def T1(aa: A): number
6662 return aa.GetVal()
6663 enddef
6664
6665 def T2(bb: B): number
6666 return bb.GetVal()
6667 enddef
6668
6669 assert_equal(100, A.sval)
6670 assert_equal(200, B.sval)
6671 var a = A.new()
6672 assert_equal(100, a.GetVal())
6673 var b = B.new()
6674 assert_equal(100, b.GetVal())
6675 assert_equal(100, T1(b))
6676 assert_equal(100, T2(b))
6677 END
6678 v9.CheckSourceSuccess(lines)
6679enddef
6680
6681" Test for calling an instance method using the class
6682def Test_instance_method_call_using_class()
6683 # Invoke an object method using a class in script context
6684 var lines =<< trim END
6685 vim9script
6686 class A
6687 def Foo()
6688 echo "foo"
6689 enddef
6690 endclass
6691 A.Foo()
6692 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006693 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006694
6695 # Invoke an object method using a class in def function context
6696 lines =<< trim END
6697 vim9script
6698 class A
6699 def Foo()
6700 echo "foo"
6701 enddef
6702 endclass
6703 def T()
6704 A.Foo()
6705 enddef
6706 T()
6707 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006708 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006709enddef
6710
6711" Test for duplicate class method and instance method
6712def Test_dup_classmethod_objmethod()
6713 # Duplicate instance method
6714 var lines =<< trim END
6715 vim9script
6716 class A
6717 static def Foo()
6718 enddef
6719 def Foo()
6720 enddef
6721 endclass
6722 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006723 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006724
Ernie Rael03042a22023-11-11 08:53:32 +01006725 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006726 lines =<< trim END
6727 vim9script
6728 class A
6729 static def Foo()
6730 enddef
6731 def _Foo()
6732 enddef
6733 endclass
6734 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006735 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006736
6737 # Duplicate class method
6738 lines =<< trim END
6739 vim9script
6740 class A
6741 def Foo()
6742 enddef
6743 static def Foo()
6744 enddef
6745 endclass
6746 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006747 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006748
Ernie Rael03042a22023-11-11 08:53:32 +01006749 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006750 lines =<< trim END
6751 vim9script
6752 class A
6753 def Foo()
6754 enddef
6755 static def _Foo()
6756 enddef
6757 endclass
6758 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006759 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006760
Ernie Rael03042a22023-11-11 08:53:32 +01006761 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006762 lines =<< trim END
6763 vim9script
6764 class A
6765 def _Foo()
6766 enddef
6767 static def _Foo()
6768 enddef
6769 endclass
6770 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006771 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006772enddef
6773
6774" Test for an instance method access level comparison with parent instance
6775" methods.
6776def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006777 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006778 var lines =<< trim END
6779 vim9script
6780 class A
6781 def Foo()
6782 enddef
6783 endclass
6784 class B extends A
6785 endclass
6786 class C extends B
6787 def _Foo()
6788 enddef
6789 endclass
6790 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006791 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006792
6793 # Public method in subclass
6794 lines =<< trim END
6795 vim9script
6796 class A
6797 def _Foo()
6798 enddef
6799 endclass
6800 class B extends A
6801 endclass
6802 class C extends B
6803 def Foo()
6804 enddef
6805 endclass
6806 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006807 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006808enddef
6809
6810def Test_extend_empty_class()
6811 var lines =<< trim END
6812 vim9script
6813 class A
6814 endclass
6815 class B extends A
6816 endclass
6817 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006818 public static var rw_class_var = 1
6819 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006820 static def ClassMethod(): number
6821 return 3
6822 enddef
6823 def ObjMethod(): number
6824 return 4
6825 enddef
6826 endclass
6827 assert_equal(1, C.rw_class_var)
6828 assert_equal(3, C.ClassMethod())
6829 var c = C.new()
6830 assert_equal(2, c.rw_obj_var)
6831 assert_equal(4, c.ObjMethod())
6832 END
6833 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006834enddef
6835
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006836" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006837" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006838def Test_interface_with_unsupported_members()
6839 var lines =<< trim END
6840 vim9script
6841 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006842 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006843 endinterface
6844 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006845 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006846
6847 lines =<< trim END
6848 vim9script
6849 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006850 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006851 endinterface
6852 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006853 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006854
6855 lines =<< trim END
6856 vim9script
6857 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006858 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006859 endinterface
6860 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006861 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006862
6863 lines =<< trim END
6864 vim9script
6865 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006866 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006867 endinterface
6868 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006869 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006870
6871 lines =<< trim END
6872 vim9script
6873 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006874 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006875 endinterface
6876 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006877 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006878
6879 lines =<< trim END
6880 vim9script
6881 interface A
6882 static def Foo(d: dict<any>): list<string>
6883 endinterface
6884 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006885 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006886
6887 lines =<< trim END
6888 vim9script
6889 interface A
6890 static def _Foo(d: dict<any>): list<string>
6891 endinterface
6892 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006893 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006894
6895 lines =<< trim END
6896 vim9script
6897 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006898 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006899 endinterface
6900 END
Ernie Rael03042a22023-11-11 08:53:32 +01006901 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006902
6903 lines =<< trim END
6904 vim9script
6905 interface A
6906 def _Foo(d: dict<any>): list<string>
6907 endinterface
6908 END
Ernie Rael03042a22023-11-11 08:53:32 +01006909 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006910enddef
6911
6912" Test for extending an interface
6913def Test_extend_interface()
6914 var lines =<< trim END
6915 vim9script
6916 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006917 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006918 def Foo()
6919 endinterface
6920 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006921 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006922 def Bar()
6923 endinterface
6924 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006925 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006926 def Foo()
6927 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006928 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006929 def Bar()
6930 enddef
6931 endclass
6932 END
6933 v9.CheckSourceSuccess(lines)
6934
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006935 # extending empty interface
6936 lines =<< trim END
6937 vim9script
6938 interface A
6939 endinterface
6940 interface B extends A
6941 endinterface
6942 class C implements B
6943 endclass
6944 END
6945 v9.CheckSourceSuccess(lines)
6946
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006947 lines =<< trim END
6948 vim9script
6949 interface A
6950 def Foo()
6951 endinterface
6952 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006953 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006954 endinterface
6955 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006956 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006957 endclass
6958 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006959 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006960
6961 lines =<< trim END
6962 vim9script
6963 interface A
6964 def Foo()
6965 endinterface
6966 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006967 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006968 endinterface
6969 class C implements A, B
6970 def Foo()
6971 enddef
6972 endclass
6973 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006974 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006975
6976 # interface cannot extend a class
6977 lines =<< trim END
6978 vim9script
6979 class A
6980 endclass
6981 interface B extends A
6982 endinterface
6983 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006984 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006985
6986 # class cannot extend an interface
6987 lines =<< trim END
6988 vim9script
6989 interface A
6990 endinterface
6991 class B extends A
6992 endclass
6993 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006994 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006995
6996 # interface cannot implement another interface
6997 lines =<< trim END
6998 vim9script
6999 interface A
7000 endinterface
7001 interface B implements A
7002 endinterface
7003 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007004 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007005
7006 # interface cannot extend multiple interfaces
7007 lines =<< trim END
7008 vim9script
7009 interface A
7010 endinterface
7011 interface B
7012 endinterface
7013 interface C extends A, B
7014 endinterface
7015 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007016 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007017
7018 # Variable type in an extended interface is of different type
7019 lines =<< trim END
7020 vim9script
7021 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007022 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007023 endinterface
7024 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007025 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007026 endinterface
7027 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007028 var val1: string
7029 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007030 endinterface
7031 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007032 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007033enddef
7034
7035" Test for a child class implementing an interface when some of the methods are
7036" defined in the parent class.
7037def Test_child_class_implements_interface()
7038 var lines =<< trim END
7039 vim9script
7040
7041 interface Intf
7042 def F1(): list<list<number>>
7043 def F2(): list<list<number>>
7044 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01007045 var var1: list<dict<number>>
7046 var var2: list<dict<number>>
7047 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007048 endinterface
7049
7050 class A
7051 def A1()
7052 enddef
7053 def F3(): list<list<number>>
7054 return [[3]]
7055 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007056 var v1: list<list<number>> = [[0]]
7057 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007058 endclass
7059
7060 class B extends A
7061 def B1()
7062 enddef
7063 def F2(): list<list<number>>
7064 return [[2]]
7065 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007066 var v2: list<list<number>> = [[0]]
7067 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007068 endclass
7069
7070 class C extends B implements Intf
7071 def C1()
7072 enddef
7073 def F1(): list<list<number>>
7074 return [[1]]
7075 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007076 var v3: list<list<number>> = [[0]]
7077 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007078 endclass
7079
7080 def T(if: Intf)
7081 assert_equal([[1]], if.F1())
7082 assert_equal([[2]], if.F2())
7083 assert_equal([[3]], if.F3())
7084 assert_equal([{a: 10}], if.var1)
7085 assert_equal([{b: 20}], if.var2)
7086 assert_equal([{c: 30}], if.var3)
7087 enddef
7088
7089 var c = C.new()
7090 T(c)
7091 assert_equal([[1]], c.F1())
7092 assert_equal([[2]], c.F2())
7093 assert_equal([[3]], c.F3())
7094 assert_equal([{a: 10}], c.var1)
7095 assert_equal([{b: 20}], c.var2)
7096 assert_equal([{c: 30}], c.var3)
7097 END
7098 v9.CheckSourceSuccess(lines)
7099
7100 # One of the interface methods is not found
7101 lines =<< trim END
7102 vim9script
7103
7104 interface Intf
7105 def F1()
7106 def F2()
7107 def F3()
7108 endinterface
7109
7110 class A
7111 def A1()
7112 enddef
7113 endclass
7114
7115 class B extends A
7116 def B1()
7117 enddef
7118 def F2()
7119 enddef
7120 endclass
7121
7122 class C extends B implements Intf
7123 def C1()
7124 enddef
7125 def F1()
7126 enddef
7127 endclass
7128 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007129 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007130
7131 # One of the interface methods is of different type
7132 lines =<< trim END
7133 vim9script
7134
7135 interface Intf
7136 def F1()
7137 def F2()
7138 def F3()
7139 endinterface
7140
7141 class A
7142 def F3(): number
7143 return 0
7144 enddef
7145 def A1()
7146 enddef
7147 endclass
7148
7149 class B extends A
7150 def B1()
7151 enddef
7152 def F2()
7153 enddef
7154 endclass
7155
7156 class C extends B implements Intf
7157 def C1()
7158 enddef
7159 def F1()
7160 enddef
7161 endclass
7162 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007163 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007164
7165 # One of the interface variables is not present
7166 lines =<< trim END
7167 vim9script
7168
7169 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007170 var var1: list<dict<number>>
7171 var var2: list<dict<number>>
7172 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007173 endinterface
7174
7175 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007176 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007177 endclass
7178
7179 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007180 var v2: list<list<number>> = [[0]]
7181 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007182 endclass
7183
7184 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007185 var v3: list<list<number>> = [[0]]
7186 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007187 endclass
7188 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007189 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007190
7191 # One of the interface variables is of different type
7192 lines =<< trim END
7193 vim9script
7194
7195 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007196 var var1: list<dict<number>>
7197 var var2: list<dict<number>>
7198 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007199 endinterface
7200
7201 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007202 var v1: list<list<number>> = [[0]]
7203 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007204 endclass
7205
7206 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007207 var v2: list<list<number>> = [[0]]
7208 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007209 endclass
7210
7211 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007212 var v3: list<list<number>> = [[0]]
7213 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007214 endclass
7215 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007216 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 +02007217enddef
7218
7219" Test for extending an interface with duplicate variables and methods
7220def Test_interface_extends_with_dup_members()
7221 var lines =<< trim END
7222 vim9script
7223 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007224 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007225 def Foo1(): number
7226 endinterface
7227 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007228 var n2: number
7229 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007230 def Foo2(): number
7231 def Foo1(): number
7232 endinterface
7233 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007234 var n1 = 10
7235 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007236 def Foo1(): number
7237 return 30
7238 enddef
7239 def Foo2(): number
7240 return 40
7241 enddef
7242 endclass
7243 def T1(a: A)
7244 assert_equal(10, a.n1)
7245 assert_equal(30, a.Foo1())
7246 enddef
7247 def T2(b: B)
7248 assert_equal(10, b.n1)
7249 assert_equal(20, b.n2)
7250 assert_equal(30, b.Foo1())
7251 assert_equal(40, b.Foo2())
7252 enddef
7253 var c = C.new()
7254 T1(c)
7255 T2(c)
7256 END
7257 v9.CheckSourceSuccess(lines)
7258enddef
7259
7260" Test for using "any" type for a variable in a sub-class while it has a
7261" concrete type in the interface
7262def Test_implements_using_var_type_any()
7263 var lines =<< trim END
7264 vim9script
7265 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007266 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007267 endinterface
7268 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007269 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007270 endclass
7271 var b = B.new()
7272 assert_equal([{a: '1'}, {b: '2'}], b.val)
7273 END
7274 v9.CheckSourceSuccess(lines)
7275
7276 # initialize instance variable using a different type
7277 lines =<< trim END
7278 vim9script
7279 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007280 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007281 endinterface
7282 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007283 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007284 endclass
7285 var b = B.new()
7286 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007287 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007288enddef
7289
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007290" Test for assigning to a member variable in a nested class
7291def Test_nested_object_assignment()
7292 var lines =<< trim END
7293 vim9script
7294
7295 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007296 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007297 endclass
7298
7299 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007300 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007301 endclass
7302
7303 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007304 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007305 endclass
7306
7307 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007308 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007309 endclass
7310
7311 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007312 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007313 enddef
7314
7315 var d = D.new()
7316 T(d)
7317 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007318 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007319enddef
7320
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007321" Test for calling methods using a null object
7322def Test_null_object_method_call()
7323 # Calling a object method using a null object in script context
7324 var lines =<< trim END
7325 vim9script
7326
7327 class C
7328 def Foo()
7329 assert_report('This method should not be executed')
7330 enddef
7331 endclass
7332
7333 var o: C
7334 o.Foo()
7335 END
7336 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7337
7338 # Calling a object method using a null object in def function context
7339 lines =<< trim END
7340 vim9script
7341
7342 class C
7343 def Foo()
7344 assert_report('This method should not be executed')
7345 enddef
7346 endclass
7347
7348 def T()
7349 var o: C
7350 o.Foo()
7351 enddef
7352 T()
7353 END
7354 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7355
7356 # Calling a object method through another class method using a null object in
7357 # script context
7358 lines =<< trim END
7359 vim9script
7360
7361 class C
7362 def Foo()
7363 assert_report('This method should not be executed')
7364 enddef
7365
7366 static def Bar(o_any: any)
7367 var o_typed: C = o_any
7368 o_typed.Foo()
7369 enddef
7370 endclass
7371
7372 var o: C
7373 C.Bar(o)
7374 END
7375 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7376
7377 # Calling a object method through another class method using a null object in
7378 # def function context
7379 lines =<< trim END
7380 vim9script
7381
7382 class C
7383 def Foo()
7384 assert_report('This method should not be executed')
7385 enddef
7386
7387 static def Bar(o_any: any)
7388 var o_typed: C = o_any
7389 o_typed.Foo()
7390 enddef
7391 endclass
7392
7393 def T()
7394 var o: C
7395 C.Bar(o)
7396 enddef
7397 T()
7398 END
7399 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Ernie Raelbe828252024-07-26 18:37:02 +02007400
7401 # Calling an object method defined in a class that is extended. This differs
7402 # from the previous by invoking ISN_METHODCALL instead of ISN_DCALL.
7403 lines =<< trim END
7404 vim9script
7405
7406 class C0
7407 def F()
7408 enddef
7409 endclass
7410
7411 class C extends C0
7412 endclass
7413
7414 def X()
7415 var o: C0 = null_object
7416 o.F()
7417 enddef
7418 X()
7419 END
7420 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7421
7422 # Getting a function ref an object method.
7423 lines =<< trim END
7424 vim9script
7425
7426 class C0
7427 def F()
7428 enddef
7429 endclass
7430
7431 class C extends C0
7432 endclass
7433
7434 def X()
7435 var o: C0 = null_object
7436 var XXX = o.F
7437 enddef
7438 X()
7439 END
7440 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007441enddef
7442
7443" Test for using a dict as an object member
7444def Test_dict_object_member()
7445 var lines =<< trim END
7446 vim9script
7447
7448 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007449 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007450 def GetState(): dict<number>
7451 return this.state
7452 enddef
7453 endclass
7454
7455 var ctx = Context.new()
7456 ctx.state->extend({a: 1})
7457 ctx.state['b'] = 2
7458 assert_equal({a: 1, b: 2}, ctx.GetState())
7459
7460 def F()
7461 ctx.state['c'] = 3
7462 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7463 enddef
7464 F()
7465 assert_equal(3, ctx.state.c)
7466 ctx.state.c = 4
7467 assert_equal(4, ctx.state.c)
7468 END
7469 v9.CheckSourceSuccess(lines)
7470enddef
7471
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007472" The following test was failing after 9.0.1914. This was caused by using a
7473" freed object from a previous method call.
7474def Test_freed_object_from_previous_method_call()
7475 var lines =<< trim END
7476 vim9script
7477
7478 class Context
7479 endclass
7480
7481 class Result
7482 endclass
7483
7484 def Failure(): Result
7485 return Result.new()
7486 enddef
7487
7488 def GetResult(ctx: Context): Result
7489 return Failure()
7490 enddef
7491
7492 def Test_GetResult()
7493 var ctx = Context.new()
7494 var result = GetResult(ctx)
7495 enddef
7496
7497 Test_GetResult()
7498 END
7499 v9.CheckSourceSuccess(lines)
7500enddef
7501
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007502" Test for duplicate object and class variable
7503def Test_duplicate_variable()
7504 # Object variable name is same as the class variable name
7505 var lines =<< trim END
7506 vim9script
7507 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007508 public static var sval: number
7509 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007510 endclass
7511 var a = A.new()
7512 END
7513 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7514
7515 # Duplicate variable name and calling a class method
7516 lines =<< trim END
7517 vim9script
7518 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007519 public static var sval: number
7520 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007521 def F1()
7522 echo this.sval
7523 enddef
7524 static def F2()
7525 echo sval
7526 enddef
7527 endclass
7528 A.F2()
7529 END
7530 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7531
7532 # Duplicate variable with an empty constructor
7533 lines =<< trim END
7534 vim9script
7535 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007536 public static var sval: number
7537 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007538 def new()
7539 enddef
7540 endclass
7541 var a = A.new()
7542 END
7543 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7544enddef
7545
7546" Test for using a reserved keyword as a variable name
7547def Test_reserved_varname()
7548 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7549 'null_function', 'null_list', 'null_partial', 'null_string',
7550 'null_channel', 'null_job', 'super', 'this']
7551
7552 var lines =<< trim eval END
7553 vim9script
7554 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007555 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007556 endclass
7557 var o = C.new()
7558 END
7559 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7560
7561 lines =<< trim eval END
7562 vim9script
7563 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007564 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007565 def new()
7566 enddef
7567 endclass
7568 var o = C.new()
7569 END
7570 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7571
7572 lines =<< trim eval END
7573 vim9script
7574 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007575 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007576 def new()
7577 enddef
7578 def F()
7579 echo this.{kword}
7580 enddef
7581 endclass
7582 var o = C.new()
7583 o.F()
7584 END
7585 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007586
7587 # class variable name
7588 if kword != 'this'
7589 lines =<< trim eval END
7590 vim9script
7591 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007592 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007593 endclass
7594 END
7595 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7596 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007597 endfor
7598enddef
7599
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007600" Test for checking the type of the arguments and the return value of a object
7601" method in an extended class.
7602def Test_extended_obj_method_type_check()
7603 var lines =<< trim END
7604 vim9script
7605
7606 class A
7607 endclass
7608 class B extends A
7609 endclass
7610 class C extends B
7611 endclass
7612
7613 class Foo
7614 def Doit(p: B): B
7615 return B.new()
7616 enddef
7617 endclass
7618
7619 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007620 def Doit(p: C): B
7621 return B.new()
7622 enddef
7623 endclass
7624 END
7625 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7626
7627 lines =<< trim END
7628 vim9script
7629
7630 class A
7631 endclass
7632 class B extends A
7633 endclass
7634 class C extends B
7635 endclass
7636
7637 class Foo
7638 def Doit(p: B): B
7639 return B.new()
7640 enddef
7641 endclass
7642
7643 class Bar extends Foo
7644 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007645 return C.new()
7646 enddef
7647 endclass
7648 END
7649 v9.CheckSourceSuccess(lines)
7650
7651 lines =<< trim END
7652 vim9script
7653
7654 class A
7655 endclass
7656 class B extends A
7657 endclass
7658 class C extends B
7659 endclass
7660
7661 class Foo
7662 def Doit(p: B): B
7663 return B.new()
7664 enddef
7665 endclass
7666
7667 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007668 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007669 return B.new()
7670 enddef
7671 endclass
7672 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007673 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 +02007674
7675 lines =<< trim END
7676 vim9script
7677
7678 class A
7679 endclass
7680 class B extends A
7681 endclass
7682 class C extends B
7683 endclass
7684
7685 class Foo
7686 def Doit(p: B): B
7687 return B.new()
7688 enddef
7689 endclass
7690
7691 class Bar extends Foo
7692 def Doit(p: B): A
7693 return A.new()
7694 enddef
7695 endclass
7696 END
7697 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 +02007698
7699 # check varargs type mismatch
7700 lines =<< trim END
7701 vim9script
7702
7703 class B
7704 def F(...xxx: list<any>)
7705 enddef
7706 endclass
7707 class C extends B
7708 def F(xxx: list<any>)
7709 enddef
7710 endclass
7711 END
7712 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 +02007713enddef
7714
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007715" Test type checking for class variable in assignments
7716func Test_class_variable_complex_type_check()
7717 " class variable with a specific type. Try assigning a different type at
7718 " script level.
7719 let lines =<< trim END
7720 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007721 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007722 return {}
7723 enddef
7724 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007725 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007726 endclass
7727 test_garbagecollect_now()
7728 A.Fn = "abc"
7729 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007730 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 +02007731
7732 " class variable with a specific type. Try assigning a different type at
7733 " class def method level.
7734 let lines =<< trim END
7735 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007736 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007737 return {}
7738 enddef
7739 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007740 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007741 def Bar()
7742 Fn = "abc"
7743 enddef
7744 endclass
7745 var a = A.new()
7746 test_garbagecollect_now()
7747 a.Bar()
7748 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007749 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 +02007750
7751 " class variable with a specific type. Try assigning a different type at
7752 " script def method level.
7753 let lines =<< trim END
7754 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007755 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007756 return {}
7757 enddef
7758 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007759 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007760 endclass
7761 def Bar()
7762 A.Fn = "abc"
7763 enddef
7764 test_garbagecollect_now()
7765 Bar()
7766 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007767 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 +02007768
7769 " class variable without any type. Should be set to the initialization
7770 " expression type. Try assigning a different type from script level.
7771 let lines =<< trim END
7772 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007773 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007774 return {}
7775 enddef
7776 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007777 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007778 endclass
7779 test_garbagecollect_now()
7780 A.Fn = "abc"
7781 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007782 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 +02007783
7784 " class variable without any type. Should be set to the initialization
7785 " expression type. Try assigning a different type at class def level.
7786 let lines =<< trim END
7787 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007788 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007789 return {}
7790 enddef
7791 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007792 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007793 def Bar()
7794 Fn = "abc"
7795 enddef
7796 endclass
7797 var a = A.new()
7798 test_garbagecollect_now()
7799 a.Bar()
7800 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007801 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 +02007802
7803 " class variable without any type. Should be set to the initialization
7804 " expression type. Try assigning a different type at script def level.
7805 let lines =<< trim END
7806 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007807 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007808 return {}
7809 enddef
7810 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007811 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007812 endclass
7813 def Bar()
7814 A.Fn = "abc"
7815 enddef
7816 test_garbagecollect_now()
7817 Bar()
7818 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007819 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 +02007820
7821 " class variable with 'any" type. Can be assigned different types.
7822 let lines =<< trim END
7823 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007824 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007825 return {}
7826 enddef
7827 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007828 public static var Fn: any = Foo
7829 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007830 endclass
7831 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007832 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007833 A.Fn = "abc"
7834 test_garbagecollect_now()
7835 assert_equal('string', typename(A.Fn))
7836 A.Fn2 = Foo
7837 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007838 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007839 A.Fn2 = "xyz"
7840 test_garbagecollect_now()
7841 assert_equal('string', typename(A.Fn2))
7842 END
7843 call v9.CheckSourceSuccess(lines)
7844
7845 " class variable with 'any" type. Can be assigned different types.
7846 let lines =<< trim END
7847 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007848 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007849 return {}
7850 enddef
7851 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007852 public static var Fn: any = Foo
7853 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007854
7855 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007856 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007857 Fn = "abc"
7858 assert_equal('string', typename(Fn))
7859 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007860 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007861 Fn2 = "xyz"
7862 assert_equal('string', typename(Fn2))
7863 enddef
7864 endclass
7865 var a = A.new()
7866 test_garbagecollect_now()
7867 a.Bar()
7868 test_garbagecollect_now()
7869 A.Fn = Foo
7870 a.Bar()
7871 END
7872 call v9.CheckSourceSuccess(lines)
7873
7874 " class variable with 'any" type. Can be assigned different types.
7875 let lines =<< trim END
7876 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007877 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007878 return {}
7879 enddef
7880 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007881 public static var Fn: any = Foo
7882 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007883 endclass
7884
7885 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007886 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007887 A.Fn = "abc"
7888 assert_equal('string', typename(A.Fn))
7889 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007890 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007891 A.Fn2 = "xyz"
7892 assert_equal('string', typename(A.Fn2))
7893 enddef
7894 Bar()
7895 test_garbagecollect_now()
7896 A.Fn = Foo
7897 Bar()
7898 END
7899 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007900
7901 let lines =<< trim END
7902 vim9script
7903 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007904 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007905 endclass
7906 assert_equal([0z10, 0z20], A.foo)
7907 A.foo = [0z30]
7908 assert_equal([0z30], A.foo)
7909 var a = A.foo
7910 assert_equal([0z30], a)
7911 END
7912 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007913endfunc
7914
7915" Test type checking for object variable in assignments
7916func Test_object_variable_complex_type_check()
7917 " object variable with a specific type. Try assigning a different type at
7918 " script level.
7919 let lines =<< trim END
7920 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007921 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007922 return {}
7923 enddef
7924 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007925 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007926 endclass
7927 var a = A.new()
7928 test_garbagecollect_now()
7929 a.Fn = "abc"
7930 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007931 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 +02007932
7933 " object variable with a specific type. Try assigning a different type at
7934 " object def method level.
7935 let lines =<< trim END
7936 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007937 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007938 return {}
7939 enddef
7940 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007941 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007942 def Bar()
7943 this.Fn = "abc"
7944 this.Fn = Foo
7945 enddef
7946 endclass
7947 var a = A.new()
7948 test_garbagecollect_now()
7949 a.Bar()
7950 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007951 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 +02007952
7953 " object variable with a specific type. Try assigning a different type at
7954 " script def method level.
7955 let lines =<< trim END
7956 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007957 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007958 return {}
7959 enddef
7960 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007961 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007962 endclass
7963 def Bar()
7964 var a = A.new()
7965 a.Fn = "abc"
7966 a.Fn = Foo
7967 enddef
7968 test_garbagecollect_now()
7969 Bar()
7970 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007971 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 +02007972
7973 " object variable without any type. Should be set to the initialization
7974 " expression type. Try assigning a different type from script level.
7975 let lines =<< trim END
7976 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007977 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007978 return {}
7979 enddef
7980 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007981 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007982 endclass
7983 var a = A.new()
7984 test_garbagecollect_now()
7985 a.Fn = "abc"
7986 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007987 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 +02007988
7989 " object variable without any type. Should be set to the initialization
7990 " expression type. Try assigning a different type at object def level.
7991 let lines =<< trim END
7992 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007993 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007994 return {}
7995 enddef
7996 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007997 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007998 def Bar()
7999 this.Fn = "abc"
8000 this.Fn = Foo
8001 enddef
8002 endclass
8003 var a = A.new()
8004 test_garbagecollect_now()
8005 a.Bar()
8006 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008007 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 +02008008
8009 " object variable without any type. Should be set to the initialization
8010 " expression type. Try assigning a different type at script def level.
8011 let lines =<< trim END
8012 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008013 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008014 return {}
8015 enddef
8016 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008017 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008018 endclass
8019 def Bar()
8020 var a = A.new()
8021 a.Fn = "abc"
8022 a.Fn = Foo
8023 enddef
8024 test_garbagecollect_now()
8025 Bar()
8026 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008027 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 +02008028
8029 " object variable with 'any" type. Can be assigned different types.
8030 let lines =<< trim END
8031 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008032 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008033 return {}
8034 enddef
8035 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008036 public var Fn: any = Foo
8037 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008038 endclass
8039
8040 var a = A.new()
8041 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008042 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008043 a.Fn = "abc"
8044 test_garbagecollect_now()
8045 assert_equal('string', typename(a.Fn))
8046 a.Fn2 = Foo
8047 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008048 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008049 a.Fn2 = "xyz"
8050 test_garbagecollect_now()
8051 assert_equal('string', typename(a.Fn2))
8052 END
8053 call v9.CheckSourceSuccess(lines)
8054
8055 " object variable with 'any" type. Can be assigned different types.
8056 let lines =<< trim END
8057 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008058 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008059 return {}
8060 enddef
8061 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008062 public var Fn: any = Foo
8063 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008064
8065 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008066 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008067 this.Fn = "abc"
8068 assert_equal('string', typename(this.Fn))
8069 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008070 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008071 this.Fn2 = "xyz"
8072 assert_equal('string', typename(this.Fn2))
8073 enddef
8074 endclass
8075
8076 var a = A.new()
8077 test_garbagecollect_now()
8078 a.Bar()
8079 test_garbagecollect_now()
8080 a.Fn = Foo
8081 a.Bar()
8082 END
8083 call v9.CheckSourceSuccess(lines)
8084
8085 " object variable with 'any" type. Can be assigned different types.
8086 let lines =<< trim END
8087 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008088 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008089 return {}
8090 enddef
8091 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008092 public var Fn: any = Foo
8093 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008094 endclass
8095
8096 def Bar()
8097 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008098 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008099 a.Fn = "abc"
8100 assert_equal('string', typename(a.Fn))
8101 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008102 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008103 a.Fn2 = "xyz"
8104 assert_equal('string', typename(a.Fn2))
8105 enddef
8106 test_garbagecollect_now()
8107 Bar()
8108 test_garbagecollect_now()
8109 Bar()
8110 END
8111 call v9.CheckSourceSuccess(lines)
8112endfunc
8113
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008114" Test for recursively calling an object method. This used to cause an
8115" use-after-free error.
8116def Test_recursive_object_method_call()
8117 var lines =<< trim END
8118 vim9script
8119 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008120 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008121 def Foo(): number
8122 if this.val >= 90
8123 return this.val
8124 endif
8125 this.val += 1
8126 return this.Foo()
8127 enddef
8128 endclass
8129 var a = A.new()
8130 assert_equal(90, a.Foo())
8131 END
8132 v9.CheckSourceSuccess(lines)
8133enddef
8134
8135" Test for recursively calling a class method.
8136def Test_recursive_class_method_call()
8137 var lines =<< trim END
8138 vim9script
8139 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008140 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008141 static def Foo(): number
8142 if val >= 90
8143 return val
8144 endif
8145 val += 1
8146 return Foo()
8147 enddef
8148 endclass
8149 assert_equal(90, A.Foo())
8150 END
8151 v9.CheckSourceSuccess(lines)
8152enddef
8153
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02008154" Test for checking the argument types and the return type when assigning a
8155" funcref to make sure the invariant class type is used.
8156def Test_funcref_argtype_returntype_check()
8157 var lines =<< trim END
8158 vim9script
8159 class A
8160 endclass
8161 class B extends A
8162 endclass
8163
8164 def Foo(p: B): B
8165 return B.new()
8166 enddef
8167
8168 var Bar: func(A): A = Foo
8169 END
8170 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
8171
8172 lines =<< trim END
8173 vim9script
8174 class A
8175 endclass
8176 class B extends A
8177 endclass
8178
8179 def Foo(p: B): B
8180 return B.new()
8181 enddef
8182
8183 def Baz()
8184 var Bar: func(A): A = Foo
8185 enddef
8186 Baz()
8187 END
8188 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
8189enddef
8190
Ernie Rael96952b22023-10-17 18:15:01 +02008191def Test_funcref_argtype_invariance_check()
8192 var lines =<< trim END
8193 vim9script
8194
8195 class A
8196 endclass
8197 class B extends A
8198 endclass
8199 class C extends B
8200 endclass
8201
8202 var Func: func(B): number
8203 Func = (o: B): number => 3
8204 assert_equal(3, Func(B.new()))
8205 END
8206 v9.CheckSourceSuccess(lines)
8207
8208 lines =<< trim END
8209 vim9script
8210
8211 class A
8212 endclass
8213 class B extends A
8214 endclass
8215 class C extends B
8216 endclass
8217
8218 var Func: func(B): number
8219 Func = (o: A): number => 3
8220 END
8221 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
8222
8223 lines =<< trim END
8224 vim9script
8225
8226 class A
8227 endclass
8228 class B extends A
8229 endclass
8230 class C extends B
8231 endclass
8232
8233 var Func: func(B): number
8234 Func = (o: C): number => 3
8235 END
8236 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
8237enddef
8238
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008239" Test for using an operator (e.g. +) with an assignment
8240def Test_op_and_assignment()
8241 # Using += with a class variable
8242 var lines =<< trim END
8243 vim9script
8244 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008245 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008246 static def Foo(): list<number>
8247 val += [1]
8248 return val
8249 enddef
8250 endclass
8251 def Bar(): list<number>
8252 A.val += [2]
8253 return A.val
8254 enddef
8255 assert_equal([1], A.Foo())
8256 assert_equal([1, 2], Bar())
8257 A.val += [3]
8258 assert_equal([1, 2, 3], A.val)
8259 END
8260 v9.CheckSourceSuccess(lines)
8261
8262 # Using += with an object variable
8263 lines =<< trim END
8264 vim9script
8265 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008266 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008267 def Foo(): list<number>
8268 this.val += [1]
8269 return this.val
8270 enddef
8271 endclass
8272 def Bar(bar_a: A): list<number>
8273 bar_a.val += [2]
8274 return bar_a.val
8275 enddef
8276 var a = A.new()
8277 assert_equal([1], a.Foo())
8278 assert_equal([1, 2], Bar(a))
8279 a.val += [3]
8280 assert_equal([1, 2, 3], a.val)
8281 END
8282 v9.CheckSourceSuccess(lines)
8283enddef
8284
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008285" Test for using an object method as a funcref
8286def Test_object_funcref()
8287 # Using object method funcref from a def function
8288 var lines =<< trim END
8289 vim9script
8290 class A
8291 def Foo(): list<number>
8292 return [3, 2, 1]
8293 enddef
8294 endclass
8295 def Bar()
8296 var a = A.new()
8297 var Fn = a.Foo
8298 assert_equal([3, 2, 1], Fn())
8299 enddef
8300 Bar()
8301 END
8302 v9.CheckSourceSuccess(lines)
8303
8304 # Using object method funcref at the script level
8305 lines =<< trim END
8306 vim9script
8307 class A
8308 def Foo(): dict<number>
8309 return {a: 1, b: 2}
8310 enddef
8311 endclass
8312 var a = A.new()
8313 var Fn = a.Foo
8314 assert_equal({a: 1, b: 2}, Fn())
8315 END
8316 v9.CheckSourceSuccess(lines)
8317
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008318 # Using object method funcref at the script level
8319 lines =<< trim END
8320 vim9script
8321 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008322 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008323 def Foo(): number
8324 return this.val
8325 enddef
8326 endclass
8327 var a = A.new(345)
8328 var Fn = a.Foo
8329 assert_equal(345, Fn())
8330 END
8331 v9.CheckSourceSuccess(lines)
8332
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008333 # Using object method funcref from another object method
8334 lines =<< trim END
8335 vim9script
8336 class A
8337 def Foo(): list<number>
8338 return [3, 2, 1]
8339 enddef
8340 def Bar()
8341 var Fn = this.Foo
8342 assert_equal([3, 2, 1], Fn())
8343 enddef
8344 endclass
8345 var a = A.new()
8346 a.Bar()
8347 END
8348 v9.CheckSourceSuccess(lines)
8349
8350 # Using function() to get a object method funcref
8351 lines =<< trim END
8352 vim9script
8353 class A
8354 def Foo(l: list<any>): list<any>
8355 return l
8356 enddef
8357 endclass
8358 var a = A.new()
8359 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8360 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8361 END
8362 v9.CheckSourceSuccess(lines)
8363
8364 # Use an object method with a function returning a funcref and then call the
8365 # funcref.
8366 lines =<< trim END
8367 vim9script
8368
8369 def Map(F: func(number): number): func(number): number
8370 return (n: number) => F(n)
8371 enddef
8372
8373 class Math
8374 def Double(n: number): number
8375 return 2 * n
8376 enddef
8377 endclass
8378
8379 const math = Math.new()
8380 assert_equal(48, Map(math.Double)(24))
8381 END
8382 v9.CheckSourceSuccess(lines)
8383
Ernie Rael03042a22023-11-11 08:53:32 +01008384 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008385 lines =<< trim END
8386 vim9script
8387 class A
8388 def _Foo()
8389 enddef
8390 endclass
8391 def Bar()
8392 var a = A.new()
8393 var Fn = a._Foo
8394 enddef
8395 Bar()
8396 END
Ernie Rael03042a22023-11-11 08:53:32 +01008397 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008398
Ernie Rael03042a22023-11-11 08:53:32 +01008399 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008400 lines =<< trim END
8401 vim9script
8402 class A
8403 def _Foo()
8404 enddef
8405 endclass
8406 var a = A.new()
8407 var Fn = a._Foo
8408 END
Ernie Rael03042a22023-11-11 08:53:32 +01008409 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008410
Ernie Rael03042a22023-11-11 08:53:32 +01008411 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008412 lines =<< trim END
8413 vim9script
8414 class A
8415 def _Foo(): list<number>
8416 return [3, 2, 1]
8417 enddef
8418 def Bar()
8419 var Fn = this._Foo
8420 assert_equal([3, 2, 1], Fn())
8421 enddef
8422 endclass
8423 var a = A.new()
8424 a.Bar()
8425 END
8426 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008427
8428 # Using object method funcref using call()
8429 lines =<< trim END
8430 vim9script
8431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008432 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008433 def Foo(): number
8434 return this.val
8435 enddef
8436 endclass
8437
8438 def Bar(obj: A)
8439 assert_equal(123, call(obj.Foo, []))
8440 enddef
8441
8442 var a = A.new(123)
8443 Bar(a)
8444 assert_equal(123, call(a.Foo, []))
8445 END
8446 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008447enddef
8448
8449" Test for using a class method as a funcref
8450def Test_class_funcref()
8451 # Using class method funcref in a def function
8452 var lines =<< trim END
8453 vim9script
8454 class A
8455 static def Foo(): list<number>
8456 return [3, 2, 1]
8457 enddef
8458 endclass
8459 def Bar()
8460 var Fn = A.Foo
8461 assert_equal([3, 2, 1], Fn())
8462 enddef
8463 Bar()
8464 END
8465 v9.CheckSourceSuccess(lines)
8466
8467 # Using class method funcref at script level
8468 lines =<< trim END
8469 vim9script
8470 class A
8471 static def Foo(): dict<number>
8472 return {a: 1, b: 2}
8473 enddef
8474 endclass
8475 var Fn = A.Foo
8476 assert_equal({a: 1, b: 2}, Fn())
8477 END
8478 v9.CheckSourceSuccess(lines)
8479
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008480 # Using class method funcref at the script level
8481 lines =<< trim END
8482 vim9script
8483 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008484 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008485 static def Foo(): number
8486 return val
8487 enddef
8488 endclass
8489 A.val = 567
8490 var Fn = A.Foo
8491 assert_equal(567, Fn())
8492 END
8493 v9.CheckSourceSuccess(lines)
8494
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008495 # Using function() to get a class method funcref
8496 lines =<< trim END
8497 vim9script
8498 class A
8499 static def Foo(l: list<any>): list<any>
8500 return l
8501 enddef
8502 endclass
8503 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8504 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8505 END
8506 v9.CheckSourceSuccess(lines)
8507
8508 # Using a class method funcref from another class method
8509 lines =<< trim END
8510 vim9script
8511 class A
8512 static def Foo(): list<number>
8513 return [3, 2, 1]
8514 enddef
8515 static def Bar()
8516 var Fn = Foo
8517 assert_equal([3, 2, 1], Fn())
8518 enddef
8519 endclass
8520 A.Bar()
8521 END
8522 v9.CheckSourceSuccess(lines)
8523
8524 # Use a class method with a function returning a funcref and then call the
8525 # funcref.
8526 lines =<< trim END
8527 vim9script
8528
8529 def Map(F: func(number): number): func(number): number
8530 return (n: number) => F(n)
8531 enddef
8532
8533 class Math
8534 static def StaticDouble(n: number): number
8535 return 2 * n
8536 enddef
8537 endclass
8538
8539 assert_equal(48, Map(Math.StaticDouble)(24))
8540 END
8541 v9.CheckSourceSuccess(lines)
8542
Ernie Rael03042a22023-11-11 08:53:32 +01008543 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008544 lines =<< trim END
8545 vim9script
8546 class A
8547 static def _Foo()
8548 enddef
8549 endclass
8550 def Bar()
8551 var Fn = A._Foo
8552 enddef
8553 Bar()
8554 END
Ernie Rael03042a22023-11-11 08:53:32 +01008555 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008556
Ernie Rael03042a22023-11-11 08:53:32 +01008557 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008558 lines =<< trim END
8559 vim9script
8560 class A
8561 static def _Foo()
8562 enddef
8563 endclass
8564 var Fn = A._Foo
8565 END
Ernie Rael03042a22023-11-11 08:53:32 +01008566 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008567
Ernie Rael03042a22023-11-11 08:53:32 +01008568 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008569 lines =<< trim END
8570 vim9script
8571 class A
8572 static def _Foo(): list<number>
8573 return [3, 2, 1]
8574 enddef
8575 static def Bar()
8576 var Fn = _Foo
8577 assert_equal([3, 2, 1], Fn())
8578 enddef
8579 endclass
8580 A.Bar()
8581 END
8582 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008583
8584 # Using class method funcref using call()
8585 lines =<< trim END
8586 vim9script
8587 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008588 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008589 static def Foo(): number
8590 return val
8591 enddef
8592 endclass
8593
8594 def Bar()
8595 A.val = 468
8596 assert_equal(468, call(A.Foo, []))
8597 enddef
8598 Bar()
8599 assert_equal(468, call(A.Foo, []))
8600 END
8601 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008602enddef
8603
8604" Test for using an object member as a funcref
8605def Test_object_member_funcref()
8606 # Using a funcref object variable in an object method
8607 var lines =<< trim END
8608 vim9script
8609 def Foo(n: number): number
8610 return n * 10
8611 enddef
8612
8613 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008614 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008615 def Bar()
8616 assert_equal(200, this.Cb(20))
8617 enddef
8618 endclass
8619
8620 var a = A.new()
8621 a.Bar()
8622 END
8623 v9.CheckSourceSuccess(lines)
8624
8625 # Using a funcref object variable in a def method
8626 lines =<< trim END
8627 vim9script
8628 def Foo(n: number): number
8629 return n * 10
8630 enddef
8631
8632 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008633 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008634 endclass
8635
8636 def Bar()
8637 var a = A.new()
8638 assert_equal(200, a.Cb(20))
8639 enddef
8640 Bar()
8641 END
8642 v9.CheckSourceSuccess(lines)
8643
8644 # Using a funcref object variable at script level
8645 lines =<< trim END
8646 vim9script
8647 def Foo(n: number): number
8648 return n * 10
8649 enddef
8650
8651 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008652 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008653 endclass
8654
8655 var a = A.new()
8656 assert_equal(200, a.Cb(20))
8657 END
8658 v9.CheckSourceSuccess(lines)
8659
8660 # Using a funcref object variable pointing to an object method in an object
8661 # method.
8662 lines =<< trim END
8663 vim9script
8664 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008665 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008666 def Foo(n: number): number
8667 return n * 10
8668 enddef
8669 def Bar()
8670 assert_equal(200, this.Cb(20))
8671 enddef
8672 endclass
8673
8674 var a = A.new()
8675 a.Bar()
8676 END
8677 v9.CheckSourceSuccess(lines)
8678
8679 # Using a funcref object variable pointing to an object method in a def
8680 # method.
8681 lines =<< trim END
8682 vim9script
8683 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008684 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008685 def Foo(n: number): number
8686 return n * 10
8687 enddef
8688 endclass
8689
8690 def Bar()
8691 var a = A.new()
8692 assert_equal(200, a.Cb(20))
8693 enddef
8694 Bar()
8695 END
8696 v9.CheckSourceSuccess(lines)
8697
8698 # Using a funcref object variable pointing to an object method at script
8699 # level.
8700 lines =<< trim END
8701 vim9script
8702 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008703 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008704 def Foo(n: number): number
8705 return n * 10
8706 enddef
8707 endclass
8708
8709 var a = A.new()
8710 assert_equal(200, a.Cb(20))
8711 END
8712 v9.CheckSourceSuccess(lines)
8713enddef
8714
8715" Test for using a class member as a funcref
8716def Test_class_member_funcref()
8717 # Using a funcref class variable in a class method
8718 var lines =<< trim END
8719 vim9script
8720 def Foo(n: number): number
8721 return n * 10
8722 enddef
8723
8724 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008725 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008726 static def Bar()
8727 assert_equal(200, Cb(20))
8728 enddef
8729 endclass
8730
8731 A.Bar()
8732 END
8733 v9.CheckSourceSuccess(lines)
8734
8735 # Using a funcref class variable in a def method
8736 lines =<< trim END
8737 vim9script
8738 def Foo(n: number): number
8739 return n * 10
8740 enddef
8741
8742 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008743 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008744 endclass
8745
8746 def Bar()
8747 assert_equal(200, A.Cb(20))
8748 enddef
8749 Bar()
8750 END
8751 v9.CheckSourceSuccess(lines)
8752
8753 # Using a funcref class variable at script level
8754 lines =<< trim END
8755 vim9script
8756 def Foo(n: number): number
8757 return n * 10
8758 enddef
8759
8760 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008761 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008762 endclass
8763
8764 assert_equal(200, A.Cb(20))
8765 END
8766 v9.CheckSourceSuccess(lines)
8767
8768 # Using a funcref class variable pointing to a class method in a class
8769 # method.
8770 lines =<< trim END
8771 vim9script
8772 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008773 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008774 static def Foo(n: number): number
8775 return n * 10
8776 enddef
8777 static def Init()
8778 Cb = Foo
8779 enddef
8780 static def Bar()
8781 assert_equal(200, Cb(20))
8782 enddef
8783 endclass
8784
8785 A.Init()
8786 A.Bar()
8787 END
8788 v9.CheckSourceSuccess(lines)
8789
8790 # Using a funcref class variable pointing to a class method in a def method.
8791 lines =<< trim END
8792 vim9script
8793 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008794 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008795 static def Foo(n: number): number
8796 return n * 10
8797 enddef
8798 static def Init()
8799 Cb = Foo
8800 enddef
8801 endclass
8802
8803 def Bar()
8804 A.Init()
8805 assert_equal(200, A.Cb(20))
8806 enddef
8807 Bar()
8808 END
8809 v9.CheckSourceSuccess(lines)
8810
8811 # Using a funcref class variable pointing to a class method at script level.
8812 lines =<< trim END
8813 vim9script
8814 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008815 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008816 static def Foo(n: number): number
8817 return n * 10
8818 enddef
8819 static def Init()
8820 Cb = Foo
8821 enddef
8822 endclass
8823
8824 A.Init()
8825 assert_equal(200, A.Cb(20))
8826 END
8827 v9.CheckSourceSuccess(lines)
8828enddef
8829
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008830" Test for using object methods as popup callback functions
8831def Test_objmethod_popup_callback()
8832 # Use the popup from the script level
8833 var lines =<< trim END
8834 vim9script
8835
8836 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008837 var selection: number = -1
8838 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008839
8840 def PopupFilter(id: number, key: string): bool
8841 add(this.filterkeys, key)
8842 return popup_filter_yesno(id, key)
8843 enddef
8844
8845 def PopupCb(id: number, result: number)
8846 this.selection = result ? 100 : 200
8847 enddef
8848 endclass
8849
8850 var a = A.new()
8851 feedkeys('', 'xt')
8852 var winid = popup_create('Y/N?',
8853 {filter: a.PopupFilter, callback: a.PopupCb})
8854 feedkeys('y', 'xt')
8855 popup_close(winid)
8856 assert_equal(100, a.selection)
8857 assert_equal(['y'], a.filterkeys)
8858 feedkeys('', 'xt')
8859 winid = popup_create('Y/N?',
8860 {filter: a.PopupFilter, callback: a.PopupCb})
8861 feedkeys('n', 'xt')
8862 popup_close(winid)
8863 assert_equal(200, a.selection)
8864 assert_equal(['y', 'n'], a.filterkeys)
8865 END
8866 v9.CheckSourceSuccess(lines)
8867
8868 # Use the popup from a def function
8869 lines =<< trim END
8870 vim9script
8871
8872 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008873 var selection: number = -1
8874 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008875
8876 def PopupFilter(id: number, key: string): bool
8877 add(this.filterkeys, key)
8878 return popup_filter_yesno(id, key)
8879 enddef
8880
8881 def PopupCb(id: number, result: number)
8882 this.selection = result ? 100 : 200
8883 enddef
8884 endclass
8885
8886 def Foo()
8887 var a = A.new()
8888 feedkeys('', 'xt')
8889 var winid = popup_create('Y/N?',
8890 {filter: a.PopupFilter, callback: a.PopupCb})
8891 feedkeys('y', 'xt')
8892 popup_close(winid)
8893 assert_equal(100, a.selection)
8894 assert_equal(['y'], a.filterkeys)
8895 feedkeys('', 'xt')
8896 winid = popup_create('Y/N?',
8897 {filter: a.PopupFilter, callback: a.PopupCb})
8898 feedkeys('n', 'xt')
8899 popup_close(winid)
8900 assert_equal(200, a.selection)
8901 assert_equal(['y', 'n'], a.filterkeys)
8902 enddef
8903 Foo()
8904 END
8905 v9.CheckSourceSuccess(lines)
8906enddef
8907
8908" Test for using class methods as popup callback functions
8909def Test_classmethod_popup_callback()
8910 # Use the popup from the script level
8911 var lines =<< trim END
8912 vim9script
8913
8914 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008915 static var selection: number = -1
8916 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008917
8918 static def PopupFilter(id: number, key: string): bool
8919 add(filterkeys, key)
8920 return popup_filter_yesno(id, key)
8921 enddef
8922
8923 static def PopupCb(id: number, result: number)
8924 selection = result ? 100 : 200
8925 enddef
8926 endclass
8927
8928 feedkeys('', 'xt')
8929 var winid = popup_create('Y/N?',
8930 {filter: A.PopupFilter, callback: A.PopupCb})
8931 feedkeys('y', 'xt')
8932 popup_close(winid)
8933 assert_equal(100, A.selection)
8934 assert_equal(['y'], A.filterkeys)
8935 feedkeys('', 'xt')
8936 winid = popup_create('Y/N?',
8937 {filter: A.PopupFilter, callback: A.PopupCb})
8938 feedkeys('n', 'xt')
8939 popup_close(winid)
8940 assert_equal(200, A.selection)
8941 assert_equal(['y', 'n'], A.filterkeys)
8942 END
8943 v9.CheckSourceSuccess(lines)
8944
8945 # Use the popup from a def function
8946 lines =<< trim END
8947 vim9script
8948
8949 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008950 static var selection: number = -1
8951 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008952
8953 static def PopupFilter(id: number, key: string): bool
8954 add(filterkeys, key)
8955 return popup_filter_yesno(id, key)
8956 enddef
8957
8958 static def PopupCb(id: number, result: number)
8959 selection = result ? 100 : 200
8960 enddef
8961 endclass
8962
8963 def Foo()
8964 feedkeys('', 'xt')
8965 var winid = popup_create('Y/N?',
8966 {filter: A.PopupFilter, callback: A.PopupCb})
8967 feedkeys('y', 'xt')
8968 popup_close(winid)
8969 assert_equal(100, A.selection)
8970 assert_equal(['y'], A.filterkeys)
8971 feedkeys('', 'xt')
8972 winid = popup_create('Y/N?',
8973 {filter: A.PopupFilter, callback: A.PopupCb})
8974 feedkeys('n', 'xt')
8975 popup_close(winid)
8976 assert_equal(200, A.selection)
8977 assert_equal(['y', 'n'], A.filterkeys)
8978 enddef
8979 Foo()
8980 END
8981 v9.CheckSourceSuccess(lines)
8982enddef
8983
8984" Test for using an object method as a timer callback function
8985def Test_objmethod_timer_callback()
8986 # Use the timer callback from script level
8987 var lines =<< trim END
8988 vim9script
8989
8990 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008991 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008992 def TimerCb(timerID: number)
8993 this.timerTick = 6
8994 enddef
8995 endclass
8996
8997 var a = A.new()
8998 timer_start(0, a.TimerCb)
8999 var maxWait = 5
9000 while maxWait > 0 && a.timerTick == -1
9001 :sleep 10m
9002 maxWait -= 1
9003 endwhile
9004 assert_equal(6, a.timerTick)
9005 END
9006 v9.CheckSourceSuccess(lines)
9007
9008 # Use the timer callback from a def function
9009 lines =<< trim END
9010 vim9script
9011
9012 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009013 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009014 def TimerCb(timerID: number)
9015 this.timerTick = 6
9016 enddef
9017 endclass
9018
9019 def Foo()
9020 var a = A.new()
9021 timer_start(0, a.TimerCb)
9022 var maxWait = 5
9023 while maxWait > 0 && a.timerTick == -1
9024 :sleep 10m
9025 maxWait -= 1
9026 endwhile
9027 assert_equal(6, a.timerTick)
9028 enddef
9029 Foo()
9030 END
9031 v9.CheckSourceSuccess(lines)
9032enddef
9033
9034" Test for using a class method as a timer callback function
9035def Test_classmethod_timer_callback()
9036 # Use the timer callback from script level
9037 var lines =<< trim END
9038 vim9script
9039
9040 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009041 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009042 static def TimerCb(timerID: number)
9043 timerTick = 6
9044 enddef
9045 endclass
9046
9047 timer_start(0, A.TimerCb)
9048 var maxWait = 5
9049 while maxWait > 0 && A.timerTick == -1
9050 :sleep 10m
9051 maxWait -= 1
9052 endwhile
9053 assert_equal(6, A.timerTick)
9054 END
9055 v9.CheckSourceSuccess(lines)
9056
9057 # Use the timer callback from a def function
9058 lines =<< trim END
9059 vim9script
9060
9061 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009062 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009063 static def TimerCb(timerID: number)
9064 timerTick = 6
9065 enddef
9066 endclass
9067
9068 def Foo()
9069 timer_start(0, A.TimerCb)
9070 var maxWait = 5
9071 while maxWait > 0 && A.timerTick == -1
9072 :sleep 10m
9073 maxWait -= 1
9074 endwhile
9075 assert_equal(6, A.timerTick)
9076 enddef
9077 Foo()
9078 END
9079 v9.CheckSourceSuccess(lines)
9080enddef
9081
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009082" Test for using a class variable as the first and/or second operand of a binary
9083" operator.
9084def Test_class_variable_as_operands()
9085 var lines =<< trim END
9086 vim9script
9087 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01009088 static var truthy: bool = true
9089 public static var TruthyFn: func
9090 static var list: list<any> = []
9091 static var four: number = 4
9092 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009093
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009094 static def Str(): string
9095 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009096 enddef
9097
9098 static def Four(): number
9099 return four
9100 enddef
9101
9102 static def List(): list<any>
9103 return list
9104 enddef
9105
9106 static def Truthy(): bool
9107 return truthy
9108 enddef
9109
9110 def TestOps()
9111 assert_true(Tests.truthy == truthy)
9112 assert_true(truthy == Tests.truthy)
9113 assert_true(Tests.list isnot [])
9114 assert_true([] isnot Tests.list)
9115 assert_equal(2, Tests.four >> 1)
9116 assert_equal(16, 1 << Tests.four)
9117 assert_equal(8, Tests.four + four)
9118 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009119 assert_equal('hellohello', Tests.str .. str)
9120 assert_equal('hellohello', str .. Tests.str)
9121
9122 # Using class variable for list indexing
9123 var l = range(10)
9124 assert_equal(4, l[Tests.four])
9125 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9126
9127 # Using class variable for Dict key
9128 var d = {hello: 'abc'}
9129 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009130 enddef
9131 endclass
9132
9133 def TestOps2()
9134 assert_true(Tests.truthy == Tests.Truthy())
9135 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009136 assert_true(Tests.truthy == Tests.TruthyFn())
9137 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009138 assert_true(Tests.list is Tests.List())
9139 assert_true(Tests.List() is Tests.list)
9140 assert_equal(2, Tests.four >> 1)
9141 assert_equal(16, 1 << Tests.four)
9142 assert_equal(8, Tests.four + Tests.Four())
9143 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009144 assert_equal('hellohello', Tests.str .. Tests.Str())
9145 assert_equal('hellohello', Tests.Str() .. Tests.str)
9146
9147 # Using class variable for list indexing
9148 var l = range(10)
9149 assert_equal(4, l[Tests.four])
9150 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9151
9152 # Using class variable for Dict key
9153 var d = {hello: 'abc'}
9154 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009155 enddef
9156
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009157 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009158 var t = Tests.new()
9159 t.TestOps()
9160 TestOps2()
9161
9162 assert_true(Tests.truthy == Tests.Truthy())
9163 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009164 assert_true(Tests.truthy == Tests.TruthyFn())
9165 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009166 assert_true(Tests.list is Tests.List())
9167 assert_true(Tests.List() is Tests.list)
9168 assert_equal(2, Tests.four >> 1)
9169 assert_equal(16, 1 << Tests.four)
9170 assert_equal(8, Tests.four + Tests.Four())
9171 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009172 assert_equal('hellohello', Tests.str .. Tests.Str())
9173 assert_equal('hellohello', Tests.Str() .. Tests.str)
9174
9175 # Using class variable for list indexing
9176 var l = range(10)
9177 assert_equal(4, l[Tests.four])
9178 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9179
9180 # Using class variable for Dict key
9181 var d = {hello: 'abc'}
9182 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009183 END
9184 v9.CheckSourceSuccess(lines)
9185enddef
9186
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009187" Test for checking the type of the key used to access an object dict member.
9188def Test_dict_member_key_type_check()
9189 var lines =<< trim END
9190 vim9script
9191
9192 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01009193 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009194 endclass
9195
9196 class Test extends State
9197 def ObjMethodTests()
9198 var cursor: number = 0
9199 var z: number = 0
9200 [this.numbers[cursor]] = ['zero.1']
9201 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9202 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9203 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9204 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9205 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9206 [this.numbers[cursor], z] = ['zero.4', 1]
9207 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9208 [z, this.numbers[cursor]] = [1, 'zero.5']
9209 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9210 enddef
9211
9212 static def ClassMethodTests(that: State)
9213 var cursor: number = 0
9214 var z: number = 0
9215 [that.numbers[cursor]] = ['zero.1']
9216 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9217 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9218 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9219 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9220 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9221 [that.numbers[cursor], z] = ['zero.4', 1]
9222 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9223 [z, that.numbers[cursor]] = [1, 'zero.5']
9224 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9225 enddef
9226
9227 def new()
9228 enddef
9229
9230 def newMethodTests()
9231 var cursor: number = 0
9232 var z: number
9233 [this.numbers[cursor]] = ['zero.1']
9234 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9235 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9236 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9237 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9238 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9239 [this.numbers[cursor], z] = ['zero.4', 1]
9240 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9241 [z, this.numbers[cursor]] = [1, 'zero.5']
9242 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9243 enddef
9244 endclass
9245
9246 def DefFuncTests(that: Test)
9247 var cursor: number = 0
9248 var z: number
9249 [that.numbers[cursor]] = ['zero.1']
9250 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9251 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9252 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9253 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9254 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9255 [that.numbers[cursor], z] = ['zero.4', 1]
9256 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9257 [z, that.numbers[cursor]] = [1, 'zero.5']
9258 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9259 enddef
9260
9261 Test.newMethodTests()
9262 Test.new().ObjMethodTests()
9263 Test.ClassMethodTests(Test.new())
9264 DefFuncTests(Test.new())
9265
9266 const test: Test = Test.new()
9267 var cursor: number = 0
9268 [test.numbers[cursor], cursor] = ['zero', 1]
9269 [cursor, test.numbers[cursor]] = [1, 'one']
9270 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
9271 END
9272 v9.CheckSourceSuccess(lines)
9273
9274 lines =<< trim END
9275 vim9script
9276
9277 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009278 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009279
9280 def new()
9281 enddef
9282
9283 def Foo()
9284 var z: number
9285 [this.numbers.a, z] = [{}, 10]
9286 enddef
9287 endclass
9288
9289 var a = A.new()
9290 a.Foo()
9291 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009292 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009293
9294 lines =<< trim END
9295 vim9script
9296
9297 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009298 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009299
9300 def new()
9301 enddef
9302
9303 def Foo()
9304 var x: string = 'a'
9305 var y: number
9306 [this.numbers[x], y] = [{}, 10]
9307 enddef
9308 endclass
9309
9310 var a = A.new()
9311 a.Foo()
9312 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009313 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009314enddef
9315
mityua5550692023-11-25 15:41:20 +01009316def Test_compile_many_def_functions_in_funcref_instr()
9317 # This used to crash Vim. This is reproducible only when run on new instance
9318 # of Vim.
9319 var lines =<< trim END
9320 vim9script
9321
9322 class A
9323 def new()
9324 this.TakeFunc(this.F00)
9325 enddef
9326
9327 def TakeFunc(F: func)
9328 enddef
9329
9330 def F00()
9331 this.F01()
9332 this.F02()
9333 this.F03()
9334 this.F04()
9335 this.F05()
9336 this.F06()
9337 this.F07()
9338 this.F08()
9339 this.F09()
9340 this.F10()
9341 this.F11()
9342 this.F12()
9343 this.F13()
9344 this.F14()
9345 this.F15()
9346 this.F16()
9347 this.F17()
9348 this.F18()
9349 this.F19()
9350 this.F20()
9351 this.F21()
9352 this.F22()
9353 this.F23()
9354 this.F24()
9355 this.F25()
9356 this.F26()
9357 this.F27()
9358 this.F28()
9359 this.F29()
9360 this.F30()
9361 this.F31()
9362 this.F32()
9363 this.F33()
9364 this.F34()
9365 this.F35()
9366 this.F36()
9367 this.F37()
9368 this.F38()
9369 this.F39()
9370 this.F40()
9371 this.F41()
9372 this.F42()
9373 this.F43()
9374 this.F44()
9375 this.F45()
9376 this.F46()
9377 this.F47()
9378 enddef
9379
9380 def F01()
9381 enddef
9382 def F02()
9383 enddef
9384 def F03()
9385 enddef
9386 def F04()
9387 enddef
9388 def F05()
9389 enddef
9390 def F06()
9391 enddef
9392 def F07()
9393 enddef
9394 def F08()
9395 enddef
9396 def F09()
9397 enddef
9398 def F10()
9399 enddef
9400 def F11()
9401 enddef
9402 def F12()
9403 enddef
9404 def F13()
9405 enddef
9406 def F14()
9407 enddef
9408 def F15()
9409 enddef
9410 def F16()
9411 enddef
9412 def F17()
9413 enddef
9414 def F18()
9415 enddef
9416 def F19()
9417 enddef
9418 def F20()
9419 enddef
9420 def F21()
9421 enddef
9422 def F22()
9423 enddef
9424 def F23()
9425 enddef
9426 def F24()
9427 enddef
9428 def F25()
9429 enddef
9430 def F26()
9431 enddef
9432 def F27()
9433 enddef
9434 def F28()
9435 enddef
9436 def F29()
9437 enddef
9438 def F30()
9439 enddef
9440 def F31()
9441 enddef
9442 def F32()
9443 enddef
9444 def F33()
9445 enddef
9446 def F34()
9447 enddef
9448 def F35()
9449 enddef
9450 def F36()
9451 enddef
9452 def F37()
9453 enddef
9454 def F38()
9455 enddef
9456 def F39()
9457 enddef
9458 def F40()
9459 enddef
9460 def F41()
9461 enddef
9462 def F42()
9463 enddef
9464 def F43()
9465 enddef
9466 def F44()
9467 enddef
9468 def F45()
9469 enddef
9470 def F46()
9471 enddef
9472 def F47()
9473 enddef
9474 endclass
9475
9476 A.new()
9477 END
9478 writefile(lines, 'Xscript', 'D')
9479 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9480 assert_equal(0, v:shell_error)
9481enddef
9482
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009483" Test for 'final' class and object variables
9484def Test_final_class_object_variable()
9485 # Test for changing a final object variable from an object function
9486 var lines =<< trim END
9487 vim9script
9488 class A
9489 final foo: string = "abc"
9490 def Foo()
9491 this.foo = "def"
9492 enddef
9493 endclass
9494 defcompile A.Foo
9495 END
9496 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9497
9498 # Test for changing a final object variable from the 'new' function
9499 lines =<< trim END
9500 vim9script
9501 class A
9502 final s1: string
9503 final s2: string
9504 def new(this.s1)
9505 this.s2 = 'def'
9506 enddef
9507 endclass
9508 var a = A.new('abc')
9509 assert_equal('abc', a.s1)
9510 assert_equal('def', a.s2)
9511 END
9512 v9.CheckSourceSuccess(lines)
9513
9514 # Test for a final class variable
9515 lines =<< trim END
9516 vim9script
9517 class A
9518 static final s1: string = "abc"
9519 endclass
9520 assert_equal('abc', A.s1)
9521 END
9522 v9.CheckSourceSuccess(lines)
9523
9524 # Test for changing a final class variable from a class function
9525 lines =<< trim END
9526 vim9script
9527 class A
9528 static final s1: string = "abc"
9529 static def Foo()
9530 s1 = "def"
9531 enddef
9532 endclass
9533 A.Foo()
9534 END
9535 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9536
9537 # Test for changing a public final class variable at script level
9538 lines =<< trim END
9539 vim9script
9540 class A
9541 public static final s1: string = "abc"
9542 endclass
9543 assert_equal('abc', A.s1)
9544 A.s1 = 'def'
9545 END
9546 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9547
9548 # Test for changing a public final class variable from a class function
9549 lines =<< trim END
9550 vim9script
9551 class A
9552 public static final s1: string = "abc"
9553 static def Foo()
9554 s1 = "def"
9555 enddef
9556 endclass
9557 A.Foo()
9558 END
9559 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9560
9561 # Test for changing a public final class variable from a function
9562 lines =<< trim END
9563 vim9script
9564 class A
9565 public static final s1: string = "abc"
9566 endclass
9567 def Foo()
9568 A.s1 = 'def'
9569 enddef
9570 defcompile
9571 END
9572 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9573
9574 # Test for using a final variable of composite type
9575 lines =<< trim END
9576 vim9script
9577 class A
9578 public final l: list<number>
9579 def new()
9580 this.l = [1, 2]
9581 enddef
9582 def Foo()
9583 this.l[0] = 3
9584 this.l->add(4)
9585 enddef
9586 endclass
9587 var a = A.new()
9588 assert_equal([1, 2], a.l)
9589 a.Foo()
9590 assert_equal([3, 2, 4], a.l)
9591 END
9592 v9.CheckSourceSuccess(lines)
9593
9594 # Test for changing a final variable of composite type from another object
9595 # function
9596 lines =<< trim END
9597 vim9script
9598 class A
9599 public final l: list<number> = [1, 2]
9600 def Foo()
9601 this.l = [3, 4]
9602 enddef
9603 endclass
9604 var a = A.new()
9605 a.Foo()
9606 END
9607 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9608
9609 # Test for modifying a final variable of composite type at script level
9610 lines =<< trim END
9611 vim9script
9612 class A
9613 public final l: list<number> = [1, 2]
9614 endclass
9615 var a = A.new()
9616 a.l[0] = 3
9617 a.l->add(4)
9618 assert_equal([3, 2, 4], a.l)
9619 END
9620 v9.CheckSourceSuccess(lines)
9621
9622 # Test for modifying a final variable of composite type from a function
9623 lines =<< trim END
9624 vim9script
9625 class A
9626 public final l: list<number> = [1, 2]
9627 endclass
9628 def Foo()
9629 var a = A.new()
9630 a.l[0] = 3
9631 a.l->add(4)
9632 assert_equal([3, 2, 4], a.l)
9633 enddef
9634 Foo()
9635 END
9636 v9.CheckSourceSuccess(lines)
9637
9638 # Test for modifying a final variable of composite type from another object
9639 # function
9640 lines =<< trim END
9641 vim9script
9642 class A
9643 public final l: list<number> = [1, 2]
9644 def Foo()
9645 this.l[0] = 3
9646 this.l->add(4)
9647 enddef
9648 endclass
9649 var a = A.new()
9650 a.Foo()
9651 assert_equal([3, 2, 4], a.l)
9652 END
9653 v9.CheckSourceSuccess(lines)
9654
9655 # Test for assigning a new value to a final variable of composite type at
9656 # script level
9657 lines =<< trim END
9658 vim9script
9659 class A
9660 public final l: list<number> = [1, 2]
9661 endclass
9662 var a = A.new()
9663 a.l = [3, 4]
9664 END
9665 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9666
9667 # Test for assigning a new value to a final variable of composite type from
9668 # another object function
9669 lines =<< trim END
9670 vim9script
9671 class A
9672 public final l: list<number> = [1, 2]
9673 def Foo()
9674 this.l = [3, 4]
9675 enddef
9676 endclass
9677 var a = A.new()
9678 a.Foo()
9679 END
9680 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9681
9682 # Test for assigning a new value to a final variable of composite type from
9683 # another function
9684 lines =<< trim END
9685 vim9script
9686 class A
9687 public final l: list<number> = [1, 2]
9688 endclass
9689 def Foo()
9690 var a = A.new()
9691 a.l = [3, 4]
9692 enddef
9693 Foo()
9694 END
9695 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9696
9697 # Error case: Use 'final' with just a variable name
9698 lines =<< trim END
9699 vim9script
9700 class A
9701 final foo
9702 endclass
9703 var a = A.new()
9704 END
9705 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9706
9707 # Error case: Use 'final' followed by 'public'
9708 lines =<< trim END
9709 vim9script
9710 class A
9711 final public foo: number
9712 endclass
9713 var a = A.new()
9714 END
9715 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9716
9717 # Error case: Use 'final' followed by 'static'
9718 lines =<< trim END
9719 vim9script
9720 class A
9721 final static foo: number
9722 endclass
9723 var a = A.new()
9724 END
9725 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9726
9727 # Error case: 'final' cannot be used in an interface
9728 lines =<< trim END
9729 vim9script
9730 interface A
9731 final foo: number = 10
9732 endinterface
9733 END
9734 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9735
9736 # Error case: 'final' not supported for an object method
9737 lines =<< trim END
9738 vim9script
9739 class A
9740 final def Foo()
9741 enddef
9742 endclass
9743 END
9744 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9745
9746 # Error case: 'final' not supported for a class method
9747 lines =<< trim END
9748 vim9script
9749 class A
9750 static final def Foo()
9751 enddef
9752 endclass
9753 END
9754 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9755enddef
9756
9757" Test for 'const' class and object variables
9758def Test_const_class_object_variable()
9759 # Test for changing a const object variable from an object function
9760 var lines =<< trim END
9761 vim9script
9762 class A
9763 const foo: string = "abc"
9764 def Foo()
9765 this.foo = "def"
9766 enddef
9767 endclass
9768 defcompile A.Foo
9769 END
9770 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9771
9772 # Test for changing a const object variable from the 'new' function
9773 lines =<< trim END
9774 vim9script
9775 class A
9776 const s1: string
9777 const s2: string
9778 def new(this.s1)
9779 this.s2 = 'def'
9780 enddef
9781 endclass
9782 var a = A.new('abc')
9783 assert_equal('abc', a.s1)
9784 assert_equal('def', a.s2)
9785 END
9786 v9.CheckSourceSuccess(lines)
9787
9788 # Test for changing a const object variable from an object method called from
9789 # the 'new' function
9790 lines =<< trim END
9791 vim9script
9792 class A
9793 const s1: string = 'abc'
9794 def new()
9795 this.ChangeStr()
9796 enddef
9797 def ChangeStr()
9798 this.s1 = 'def'
9799 enddef
9800 endclass
9801 var a = A.new()
9802 END
9803 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9804
9805 # Test for a const class variable
9806 lines =<< trim END
9807 vim9script
9808 class A
9809 static const s1: string = "abc"
9810 endclass
9811 assert_equal('abc', A.s1)
9812 END
9813 v9.CheckSourceSuccess(lines)
9814
9815 # Test for changing a const class variable from a class function
9816 lines =<< trim END
9817 vim9script
9818 class A
9819 static const s1: string = "abc"
9820 static def Foo()
9821 s1 = "def"
9822 enddef
9823 endclass
9824 A.Foo()
9825 END
9826 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9827
9828 # Test for changing a public const class variable at script level
9829 lines =<< trim END
9830 vim9script
9831 class A
9832 public static const s1: string = "abc"
9833 endclass
9834 assert_equal('abc', A.s1)
9835 A.s1 = 'def'
9836 END
9837 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9838
9839 # Test for changing a public const class variable from a class function
9840 lines =<< trim END
9841 vim9script
9842 class A
9843 public static const s1: string = "abc"
9844 static def Foo()
9845 s1 = "def"
9846 enddef
9847 endclass
9848 A.Foo()
9849 END
9850 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9851
9852 # Test for changing a public const class variable from a function
9853 lines =<< trim END
9854 vim9script
9855 class A
9856 public static const s1: string = "abc"
9857 endclass
9858 def Foo()
9859 A.s1 = 'def'
9860 enddef
9861 defcompile
9862 END
9863 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9864
9865 # Test for changing a const List item from an object function
9866 lines =<< trim END
9867 vim9script
9868 class A
9869 public const l: list<number>
9870 def new()
9871 this.l = [1, 2]
9872 enddef
9873 def Foo()
9874 this.l[0] = 3
9875 enddef
9876 endclass
9877 var a = A.new()
9878 assert_equal([1, 2], a.l)
9879 a.Foo()
9880 END
9881 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9882
9883 # Test for adding a value to a const List from an object function
9884 lines =<< trim END
9885 vim9script
9886 class A
9887 public const l: list<number>
9888 def new()
9889 this.l = [1, 2]
9890 enddef
9891 def Foo()
9892 this.l->add(3)
9893 enddef
9894 endclass
9895 var a = A.new()
9896 a.Foo()
9897 END
9898 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9899
9900 # Test for reassigning a const List from an object function
9901 lines =<< trim END
9902 vim9script
9903 class A
9904 public const l: list<number> = [1, 2]
9905 def Foo()
9906 this.l = [3, 4]
9907 enddef
9908 endclass
9909 var a = A.new()
9910 a.Foo()
9911 END
9912 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9913
9914 # Test for changing a const List item at script level
9915 lines =<< trim END
9916 vim9script
9917 class A
9918 public const l: list<number> = [1, 2]
9919 endclass
9920 var a = A.new()
9921 a.l[0] = 3
9922 END
9923 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9924
9925 # Test for adding a value to a const List item at script level
9926 lines =<< trim END
9927 vim9script
9928 class A
9929 public const l: list<number> = [1, 2]
9930 endclass
9931 var a = A.new()
9932 a.l->add(4)
9933 END
9934 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9935
9936 # Test for changing a const List item from a function
9937 lines =<< trim END
9938 vim9script
9939 class A
9940 public const l: list<number> = [1, 2]
9941 endclass
9942 def Foo()
9943 var a = A.new()
9944 a.l[0] = 3
9945 enddef
9946 Foo()
9947 END
9948 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9949
9950 # Test for adding a value to a const List item from a function
9951 lines =<< trim END
9952 vim9script
9953 class A
9954 public const l: list<number> = [1, 2]
9955 endclass
9956 def Foo()
9957 var a = A.new()
9958 a.l->add(4)
9959 enddef
9960 Foo()
9961 END
9962 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9963
9964 # Test for changing a const List item from an object method
9965 lines =<< trim END
9966 vim9script
9967 class A
9968 public const l: list<number> = [1, 2]
9969 def Foo()
9970 this.l[0] = 3
9971 enddef
9972 endclass
9973 var a = A.new()
9974 a.Foo()
9975 END
9976 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9977
9978 # Test for adding a value to a const List item from an object method
9979 lines =<< trim END
9980 vim9script
9981 class A
9982 public const l: list<number> = [1, 2]
9983 def Foo()
9984 this.l->add(4)
9985 enddef
9986 endclass
9987 var a = A.new()
9988 a.Foo()
9989 END
9990 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9991
9992 # Test for reassigning a const List object variable at script level
9993 lines =<< trim END
9994 vim9script
9995 class A
9996 public const l: list<number> = [1, 2]
9997 endclass
9998 var a = A.new()
9999 a.l = [3, 4]
10000 END
10001 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
10002
10003 # Test for reassigning a const List object variable from an object method
10004 lines =<< trim END
10005 vim9script
10006 class A
10007 public const l: list<number> = [1, 2]
10008 def Foo()
10009 this.l = [3, 4]
10010 enddef
10011 endclass
10012 var a = A.new()
10013 a.Foo()
10014 END
10015 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
10016
10017 # Test for reassigning a const List object variable from another function
10018 lines =<< trim END
10019 vim9script
10020 class A
10021 public const l: list<number> = [1, 2]
10022 endclass
10023 def Foo()
10024 var a = A.new()
10025 a.l = [3, 4]
10026 enddef
10027 Foo()
10028 END
10029 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
10030
10031 # Error case: Use 'const' with just a variable name
10032 lines =<< trim END
10033 vim9script
10034 class A
10035 const foo
10036 endclass
10037 var a = A.new()
10038 END
10039 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10040
10041 # Error case: Use 'const' followed by 'public'
10042 lines =<< trim END
10043 vim9script
10044 class A
10045 const public foo: number
10046 endclass
10047 var a = A.new()
10048 END
10049 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10050
10051 # Error case: Use 'const' followed by 'static'
10052 lines =<< trim END
10053 vim9script
10054 class A
10055 const static foo: number
10056 endclass
10057 var a = A.new()
10058 END
10059 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10060
10061 # Error case: 'const' cannot be used in an interface
10062 lines =<< trim END
10063 vim9script
10064 interface A
10065 const foo: number = 10
10066 endinterface
10067 END
10068 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
10069
10070 # Error case: 'const' not supported for an object method
10071 lines =<< trim END
10072 vim9script
10073 class A
10074 const def Foo()
10075 enddef
10076 endclass
10077 END
10078 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10079
10080 # Error case: 'const' not supported for a class method
10081 lines =<< trim END
10082 vim9script
10083 class A
10084 static const def Foo()
10085 enddef
10086 endclass
10087 END
10088 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10089enddef
10090
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +010010091" Test for compiling class/object methods using :defcompile
10092def Test_defcompile_class()
10093 # defcompile all the classes in the current script
10094 var lines =<< trim END
10095 vim9script
10096 class A
10097 def Foo()
10098 var i = 10
10099 enddef
10100 endclass
10101 class B
10102 def Bar()
10103 var i = 20
10104 xxx
10105 enddef
10106 endclass
10107 defcompile
10108 END
10109 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
10110
10111 # defcompile a specific class
10112 lines =<< trim END
10113 vim9script
10114 class A
10115 def Foo()
10116 xxx
10117 enddef
10118 endclass
10119 class B
10120 def Bar()
10121 yyy
10122 enddef
10123 endclass
10124 defcompile B
10125 END
10126 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
10127
10128 # defcompile a non-class
10129 lines =<< trim END
10130 vim9script
10131 class A
10132 def Foo()
10133 enddef
10134 endclass
10135 var X: list<number> = []
10136 defcompile X
10137 END
10138 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
10139
10140 # defcompile a class twice
10141 lines =<< trim END
10142 vim9script
10143 class A
10144 def new()
10145 enddef
10146 endclass
10147 defcompile A
10148 defcompile A
10149 assert_equal('Function A.new does not need compiling', v:statusmsg)
10150 END
10151 v9.CheckSourceSuccess(lines)
10152
10153 # defcompile should not compile an imported class
10154 lines =<< trim END
10155 vim9script
10156 export class A
10157 def Foo()
10158 xxx
10159 enddef
10160 endclass
10161 END
10162 writefile(lines, 'Xdefcompileimport.vim', 'D')
10163 lines =<< trim END
10164 vim9script
10165
10166 import './Xdefcompileimport.vim'
10167 class B
10168 endclass
10169 defcompile
10170 END
10171 v9.CheckScriptSuccess(lines)
10172enddef
10173
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +010010174" Test for cases common to all the object builtin methods
10175def Test_object_builtin_method()
10176 var lines =<< trim END
10177 vim9script
10178 class A
10179 def abc()
10180 enddef
10181 endclass
10182 END
10183 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
10184
10185 for funcname in ["len", "string", "empty"]
10186 lines =<< trim eval END
10187 vim9script
10188 class A
10189 static def {funcname}(): number
10190 enddef
10191 endclass
10192 END
10193 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
10194 endfor
10195enddef
10196
10197" Test for using the empty() builtin method with an object
10198" This is a legacy function to use the test_garbagecollect_now() function.
10199func Test_object_empty()
10200 let lines =<< trim END
10201 vim9script
10202 class A
10203 def empty(): bool
10204 return true
10205 enddef
10206 endclass
10207
10208 def Foo()
10209 var afoo = A.new()
10210 assert_equal(true, empty(afoo))
10211 assert_equal(true, afoo->empty())
10212 enddef
10213
10214 var a = A.new()
10215 assert_equal(1, empty(a))
10216 assert_equal(1, a->empty())
10217 test_garbagecollect_now()
10218 assert_equal(1, empty(a))
10219 Foo()
10220 test_garbagecollect_now()
10221 Foo()
10222 END
10223 call v9.CheckSourceSuccess(lines)
10224
10225 " empty() should return 1 without a builtin method
10226 let lines =<< trim END
10227 vim9script
10228 class A
10229 endclass
10230
10231 def Foo()
10232 var afoo = A.new()
10233 assert_equal(1, empty(afoo))
10234 enddef
10235
10236 var a = A.new()
10237 assert_equal(1, empty(a))
10238 Foo()
10239 END
10240 call v9.CheckSourceSuccess(lines)
10241
10242 " Unsupported signature for the empty() method
10243 let lines =<< trim END
10244 vim9script
10245 class A
10246 def empty()
10247 enddef
10248 endclass
10249 END
10250 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
10251
10252 " Error when calling the empty() method
10253 let lines =<< trim END
10254 vim9script
10255 class A
10256 def empty(): bool
10257 throw "Failed to check emptiness"
10258 enddef
10259 endclass
10260
10261 def Foo()
10262 var afoo = A.new()
10263 var i = empty(afoo)
10264 enddef
10265
10266 var a = A.new()
10267 assert_fails('empty(a)', 'Failed to check emptiness')
10268 assert_fails('Foo()', 'Failed to check emptiness')
10269 END
10270 call v9.CheckSourceSuccess(lines)
10271
10272 " call empty() using an object from a script
10273 let lines =<< trim END
10274 vim9script
10275 class A
10276 def empty(): bool
10277 return true
10278 enddef
10279 endclass
10280 var afoo = A.new()
10281 assert_equal(true, afoo.empty())
10282 END
10283 call v9.CheckSourceSuccess(lines)
10284
10285 " call empty() using an object from a method
10286 let lines =<< trim END
10287 vim9script
10288 class A
10289 def empty(): bool
10290 return true
10291 enddef
10292 endclass
10293 def Foo()
10294 var afoo = A.new()
10295 assert_equal(true, afoo.empty())
10296 enddef
10297 Foo()
10298 END
10299 call v9.CheckSourceSuccess(lines)
10300
10301 " call empty() using "this" from an object method
10302 let lines =<< trim END
10303 vim9script
10304 class A
10305 def empty(): bool
10306 return true
10307 enddef
10308 def Foo(): bool
10309 return this.empty()
10310 enddef
10311 endclass
10312 def Bar()
10313 var abar = A.new()
10314 assert_equal(true, abar.Foo())
10315 enddef
10316 Bar()
10317 END
10318 call v9.CheckSourceSuccess(lines)
10319
10320 " Call empty() from a derived object
10321 let lines =<< trim END
10322 vim9script
10323 class A
10324 def empty(): bool
10325 return false
10326 enddef
10327 endclass
10328 class B extends A
10329 def empty(): bool
10330 return true
10331 enddef
10332 endclass
10333 def Foo(afoo: A)
10334 assert_equal(true, empty(afoo))
10335 var bfoo = B.new()
10336 assert_equal(true, empty(bfoo))
10337 enddef
10338 var b = B.new()
10339 assert_equal(1, empty(b))
10340 Foo(b)
10341 END
10342 call v9.CheckSourceSuccess(lines)
10343
10344 " Invoking empty method using an interface
10345 let lines =<< trim END
10346 vim9script
10347 interface A
10348 def empty(): bool
10349 endinterface
10350 class B implements A
10351 def empty(): bool
10352 return false
10353 enddef
10354 endclass
10355 def Foo(a: A)
10356 assert_equal(false, empty(a))
10357 enddef
10358 var b = B.new()
10359 Foo(b)
10360 END
10361 call v9.CheckSourceSuccess(lines)
10362endfunc
10363
10364" Test for using the len() builtin method with an object
10365" This is a legacy function to use the test_garbagecollect_now() function.
10366func Test_object_length()
10367 let lines =<< trim END
10368 vim9script
10369 class A
10370 var mylen: number = 0
10371 def new(n: number)
10372 this.mylen = n
10373 enddef
10374 def len(): number
10375 return this.mylen
10376 enddef
10377 endclass
10378
10379 def Foo()
10380 var afoo = A.new(12)
10381 assert_equal(12, len(afoo))
10382 assert_equal(12, afoo->len())
10383 enddef
10384
10385 var a = A.new(22)
10386 assert_equal(22, len(a))
10387 assert_equal(22, a->len())
10388 test_garbagecollect_now()
10389 assert_equal(22, len(a))
10390 Foo()
10391 test_garbagecollect_now()
10392 Foo()
10393 END
10394 call v9.CheckSourceSuccess(lines)
10395
10396 " len() should return 0 without a builtin method
10397 let lines =<< trim END
10398 vim9script
10399 class A
10400 endclass
10401
10402 def Foo()
10403 var afoo = A.new()
10404 assert_equal(0, len(afoo))
10405 enddef
10406
10407 var a = A.new()
10408 assert_equal(0, len(a))
10409 Foo()
10410 END
10411 call v9.CheckSourceSuccess(lines)
10412
10413 " Unsupported signature for the len() method
10414 let lines =<< trim END
10415 vim9script
10416 class A
10417 def len()
10418 enddef
10419 endclass
10420 END
10421 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10422
10423 " Error when calling the len() method
10424 let lines =<< trim END
10425 vim9script
10426 class A
10427 def len(): number
10428 throw "Failed to compute length"
10429 enddef
10430 endclass
10431
10432 def Foo()
10433 var afoo = A.new()
10434 var i = len(afoo)
10435 enddef
10436
10437 var a = A.new()
10438 assert_fails('len(a)', 'Failed to compute length')
10439 assert_fails('Foo()', 'Failed to compute length')
10440 END
10441 call v9.CheckSourceSuccess(lines)
10442
10443 " call len() using an object from a script
10444 let lines =<< trim END
10445 vim9script
10446 class A
10447 def len(): number
10448 return 5
10449 enddef
10450 endclass
10451 var afoo = A.new()
10452 assert_equal(5, afoo.len())
10453 END
10454 call v9.CheckSourceSuccess(lines)
10455
10456 " call len() using an object from a method
10457 let lines =<< trim END
10458 vim9script
10459 class A
10460 def len(): number
10461 return 5
10462 enddef
10463 endclass
10464 def Foo()
10465 var afoo = A.new()
10466 assert_equal(5, afoo.len())
10467 enddef
10468 Foo()
10469 END
10470 call v9.CheckSourceSuccess(lines)
10471
10472 " call len() using "this" from an object method
10473 let lines =<< trim END
10474 vim9script
10475 class A
10476 def len(): number
10477 return 8
10478 enddef
10479 def Foo(): number
10480 return this.len()
10481 enddef
10482 endclass
10483 def Bar()
10484 var abar = A.new()
10485 assert_equal(8, abar.Foo())
10486 enddef
10487 Bar()
10488 END
10489 call v9.CheckSourceSuccess(lines)
10490
10491 " Call len() from a derived object
10492 let lines =<< trim END
10493 vim9script
10494 class A
10495 def len(): number
10496 return 10
10497 enddef
10498 endclass
10499 class B extends A
10500 def len(): number
10501 return 20
10502 enddef
10503 endclass
10504 def Foo(afoo: A)
10505 assert_equal(20, len(afoo))
10506 var bfoo = B.new()
10507 assert_equal(20, len(bfoo))
10508 enddef
10509 var b = B.new()
10510 assert_equal(20, len(b))
10511 Foo(b)
10512 END
10513 call v9.CheckSourceSuccess(lines)
10514
10515 " Invoking len method using an interface
10516 let lines =<< trim END
10517 vim9script
10518 interface A
10519 def len(): number
10520 endinterface
10521 class B implements A
10522 def len(): number
10523 return 123
10524 enddef
10525 endclass
10526 def Foo(a: A)
10527 assert_equal(123, len(a))
10528 enddef
10529 var b = B.new()
10530 Foo(b)
10531 END
10532 call v9.CheckSourceSuccess(lines)
10533endfunc
10534
10535" Test for using the string() builtin method with an object
10536" This is a legacy function to use the test_garbagecollect_now() function.
10537func Test_object_string()
10538 let lines =<< trim END
10539 vim9script
10540 class A
10541 var name: string
10542 def string(): string
10543 return this.name
10544 enddef
10545 endclass
10546
10547 def Foo()
10548 var afoo = A.new("foo-A")
10549 assert_equal('foo-A', string(afoo))
10550 assert_equal('foo-A', afoo->string())
10551 enddef
10552
10553 var a = A.new("script-A")
10554 assert_equal('script-A', string(a))
10555 assert_equal('script-A', a->string())
10556 assert_equal(['script-A'], execute('echo a')->split("\n"))
10557 test_garbagecollect_now()
10558 assert_equal('script-A', string(a))
10559 Foo()
10560 test_garbagecollect_now()
10561 Foo()
10562 END
10563 call v9.CheckSourceSuccess(lines)
10564
10565 " string() should return "object of A {}" without a builtin method
10566 let lines =<< trim END
10567 vim9script
10568 class A
10569 endclass
10570
10571 def Foo()
10572 var afoo = A.new()
10573 assert_equal('object of A {}', string(afoo))
10574 enddef
10575
10576 var a = A.new()
10577 assert_equal('object of A {}', string(a))
10578 Foo()
10579 END
10580 call v9.CheckSourceSuccess(lines)
10581
10582 " Unsupported signature for the string() method
10583 let lines =<< trim END
10584 vim9script
10585 class A
10586 def string()
10587 enddef
10588 endclass
10589 END
10590 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10591
10592 " Error when calling the string() method
10593 let lines =<< trim END
10594 vim9script
10595 class A
10596 def string(): string
10597 throw "Failed to get text"
10598 enddef
10599 endclass
10600
10601 def Foo()
10602 var afoo = A.new()
10603 var i = string(afoo)
10604 enddef
10605
10606 var a = A.new()
10607 assert_fails('string(a)', 'Failed to get text')
10608 assert_fails('Foo()', 'Failed to get text')
10609 END
10610 call v9.CheckSourceSuccess(lines)
10611
10612 " call string() using an object from a script
10613 let lines =<< trim END
10614 vim9script
10615 class A
10616 def string(): string
10617 return 'A'
10618 enddef
10619 endclass
10620 var afoo = A.new()
10621 assert_equal('A', afoo.string())
10622 END
10623 call v9.CheckSourceSuccess(lines)
10624
10625 " call string() using an object from a method
10626 let lines =<< trim END
10627 vim9script
10628 class A
10629 def string(): string
10630 return 'A'
10631 enddef
10632 endclass
10633 def Foo()
10634 var afoo = A.new()
10635 assert_equal('A', afoo.string())
10636 enddef
10637 Foo()
10638 END
10639 call v9.CheckSourceSuccess(lines)
10640
10641 " call string() using "this" from an object method
10642 let lines =<< trim END
10643 vim9script
10644 class A
10645 def string(): string
10646 return 'A'
10647 enddef
10648 def Foo(): string
10649 return this.string()
10650 enddef
10651 endclass
10652 def Bar()
10653 var abar = A.new()
10654 assert_equal('A', abar.string())
10655 enddef
10656 Bar()
10657 END
10658 call v9.CheckSourceSuccess(lines)
10659
10660 " Call string() from a derived object
10661 let lines =<< trim END
10662 vim9script
10663 class A
10664 def string(): string
10665 return 'A'
10666 enddef
10667 endclass
10668 class B extends A
10669 def string(): string
10670 return 'B'
10671 enddef
10672 endclass
10673 def Foo(afoo: A)
10674 assert_equal('B', string(afoo))
10675 var bfoo = B.new()
10676 assert_equal('B', string(bfoo))
10677 enddef
10678 var b = B.new()
10679 assert_equal('B', string(b))
10680 Foo(b)
10681 END
10682 call v9.CheckSourceSuccess(lines)
10683
10684 " Invoking string method using an interface
10685 let lines =<< trim END
10686 vim9script
10687 interface A
10688 def string(): string
10689 endinterface
10690 class B implements A
10691 def string(): string
10692 return 'B'
10693 enddef
10694 endclass
10695 def Foo(a: A)
10696 assert_equal('B', string(a))
10697 enddef
10698 var b = B.new()
10699 Foo(b)
10700 END
10701 call v9.CheckSourceSuccess(lines)
10702endfunc
10703
Ernie Rael9d779c52024-07-07 20:41:44 +020010704" Test for using the string() builtin method with an object's method
10705def Test_method_string()
10706 var lines =<< trim END
10707 vim9script
10708 class A
10709 def F()
10710 enddef
10711 endclass
10712 assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F))
10713 END
10714 v9.CheckScriptSuccess(lines)
10715enddef
10716
10717
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010718" Test for using a class in the class definition
10719def Test_Ref_Class_Within_Same_Class()
10720 var lines =<< trim END
10721 vim9script
10722 class A
10723 var n: number = 0
10724 def Equals(other: A): bool
10725 return this.n == other.n
10726 enddef
10727 endclass
10728
10729 var a1 = A.new(10)
10730 var a2 = A.new(10)
10731 var a3 = A.new(20)
10732 assert_equal(true, a1.Equals(a2))
10733 assert_equal(false, a2.Equals(a3))
10734 END
10735 v9.CheckScriptSuccess(lines)
10736
10737 lines =<< trim END
10738 vim9script
10739
10740 class Foo
10741 var num: number
10742 def Clone(): Foo
10743 return Foo.new(this.num)
10744 enddef
10745 endclass
10746
10747 var f1 = Foo.new(1)
10748
10749 def F()
10750 var f2: Foo = f1.Clone()
10751 assert_equal(false, f2 is f1)
10752 assert_equal(true, f2.num == f1.num)
10753 enddef
10754 F()
10755
10756 var f3: Foo = f1.Clone()
10757 assert_equal(false, f3 is f1)
10758 assert_equal(true, f3.num == f1.num)
10759 END
10760 v9.CheckScriptSuccess(lines)
10761
10762 # Test for trying to use a class to extend when defining the same class
10763 lines =<< trim END
10764 vim9script
10765 class A extends A
10766 endclass
10767 END
10768 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10769
10770 # Test for trying to use a class to implement when defining the same class
10771 lines =<< trim END
10772 vim9script
10773 class A implements A
10774 endclass
10775 END
10776 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10777enddef
10778
Ernie Raelf0e69142024-06-22 11:12:00 +020010779" Test for comparing a class referencing itself
10780def Test_Object_Compare_With_Recursive_Class_Ref()
10781 var lines =<< trim END
10782 vim9script
10783
10784 class C
10785 public var nest: C
10786 endclass
10787
10788 var o1 = C.new()
10789 o1.nest = o1
10790
10791 var result = o1 == o1
10792 assert_equal(true, result)
10793 END
10794 v9.CheckScriptSuccess(lines)
Ernie Rael86257142024-06-23 09:54:45 +020010795
10796 lines =<< trim END
10797 vim9script
10798
10799 class C
10800 public var nest: C
10801 endclass
10802 var o1 = C.new()
10803 var o2 = C.new(C.new())
10804
10805 var result = o1 == o2
10806 assert_equal(false, result)
10807 END
10808 v9.CheckScriptSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +020010809
10810 lines =<< trim END
10811 vim9script
10812 class C
10813 var nest1: C
10814 var nest2: C
10815 def Init(n1: C, n2: C)
10816 this.nest1 = n1
10817 this.nest2 = n2
10818 enddef
10819 endclass
10820
10821 var o1 = C.new()
10822 var o2 = C.new()
10823 o1.Init(o1, o2)
10824 o2.Init(o2, o1)
10825
10826 var result = o1 == o2
10827 assert_equal(true, result)
10828 END
10829 v9.CheckScriptSuccess(lines)
Ernie Raelf0e69142024-06-22 11:12:00 +020010830enddef
10831
Ernie Raelf3975492024-07-06 11:44:37 +020010832" Test for comparing a class with nesting objects
10833def Test_Object_Compare_With_Nesting_Objects()
10834 # On a compare, after vim equal recurses 1000 times, not finding an unequal,
10835 # return the compare is equal.
10836 # Test that limit
10837
10838 var lines =<< trim END
10839 vim9script
10840 class C
10841 public var n: number
10842 public var nest: C
10843
10844 # Create a "C" that chains/nests to indicated depth.
10845 # return {head: firstC, tail: lastC}
10846 static def CreateNested(depth: number): dict<C>
10847 var first = C.new(1, null_object)
10848 var last = first
10849 for i in range(2, depth)
10850 last.nest = C.new(i, null_object)
10851 last = last.nest
10852 endfor
10853 return {head: first, tail: last}
10854 enddef
10855
10856 # Return pointer to nth item in chain.
10857 def GetLink(depth: number): C
10858 var count = 1
10859 var p: C = this
10860 while count < depth
10861 p = p.nest
10862 if p == null
10863 throw "too deep"
10864 endif
10865 count += 1
10866 endwhile
10867 return p
10868 enddef
10869
10870 # Return the length of the chain
10871 def len(): number
10872 var count = 1
10873 var p: C = this
10874 while p.nest != null
10875 p = p.nest
10876 count += 1
10877 endwhile
10878 return count
10879 enddef
10880 endclass
10881
10882 var chain = C.CreateNested(3)
10883 var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}"
10884 assert_equal(s, string(chain.head))
10885 assert_equal(3, chain.head->len())
10886
10887 var chain1 = C.CreateNested(100)
10888 var chain2 = C.CreateNested(100)
10889 assert_true(chain1.head == chain2.head)
10890
10891 # modify the tail of chain2, compare not equal
10892 chain2.tail.n = 123456
10893 assert_true(chain1.head != chain2.head)
10894
10895 # a tail of a different length compares not equal
10896 chain2 = C.CreateNested(101)
10897 assert_true(chain1.head != chain2.head)
10898
10899 chain1 = C.CreateNested(1000)
10900 chain2 = C.CreateNested(1000)
10901 assert_true(chain1.head == chain2.head)
10902
10903 # modify the tail of chain2, compare not equal
10904 chain2.tail.n = 123456
10905 assert_true(chain1.head != chain2.head)
10906
10907 # try a chain longer that the limit
10908 chain1 = C.CreateNested(1001)
10909 chain2 = C.CreateNested(1001)
10910 assert_true(chain1.head == chain2.head)
10911
10912 # modify the tail, but still equal
10913 chain2.tail.n = 123456
10914 assert_true(chain1.head == chain2.head)
10915
10916 # remove 2 items from front, shorten the chain by two.
10917 chain1.head = chain1.head.GetLink(3)
10918 chain2.head = chain2.head.GetLink(3)
10919 assert_equal(3, chain1.head.n)
10920 assert_equal(3, chain2.head.n)
10921 assert_equal(999, chain1.head->len())
10922 assert_equal(999, chain2.head->len())
10923 # Now less than the limit, compare not equal
10924 assert_true(chain1.head != chain2.head)
10925 END
10926 v9.CheckScriptSuccess(lines)
10927enddef
10928
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010929" Test for using a compound operator from a lambda function in an object method
10930def Test_compound_op_in_objmethod_lambda()
10931 # Test using the "+=" operator
10932 var lines =<< trim END
10933 vim9script
10934 class A
10935 var n: number = 10
10936 def Foo()
10937 var Fn = () => {
10938 this.n += 1
10939 }
10940 Fn()
10941 enddef
10942 endclass
10943
10944 var a = A.new()
10945 a.Foo()
10946 assert_equal(11, a.n)
10947 END
10948 v9.CheckScriptSuccess(lines)
10949
10950 # Test using the "..=" operator
10951 lines =<< trim END
10952 vim9script
10953 class A
10954 var s: string = "a"
10955 def Foo()
10956 var Fn = () => {
10957 this.s ..= "a"
10958 }
10959 Fn()
10960 enddef
10961 endclass
10962
10963 var a = A.new()
10964 a.Foo()
10965 a.Foo()
10966 assert_equal("aaa", a.s)
10967 END
10968 v9.CheckScriptSuccess(lines)
10969enddef
10970
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010971" Test for using test_refcount() with a class and an object
10972def Test_class_object_refcount()
10973 var lines =<< trim END
10974 vim9script
10975 class A
10976 endclass
10977 var a: A = A.new()
10978 assert_equal(2, test_refcount(A))
10979 assert_equal(1, test_refcount(a))
10980 var b = a
10981 assert_equal(2, test_refcount(A))
10982 assert_equal(2, test_refcount(a))
10983 assert_equal(2, test_refcount(b))
10984 END
10985 v9.CheckScriptSuccess(lines)
10986enddef
10987
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010988" call a lambda function in one object from another object
10989def Test_lambda_invocation_across_classes()
10990 var lines =<< trim END
10991 vim9script
10992 class A
10993 var s: string = "foo"
10994 def GetFn(): func
10995 var Fn = (): string => {
10996 return this.s
10997 }
10998 return Fn
10999 enddef
11000 endclass
11001
11002 class B
11003 var s: string = "bar"
11004 def GetFn(): func
11005 var a = A.new()
11006 return a.GetFn()
11007 enddef
11008 endclass
11009
11010 var b = B.new()
11011 var Fn = b.GetFn()
11012 assert_equal("foo", Fn())
11013 END
11014 v9.CheckScriptSuccess(lines)
11015enddef
11016
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010011017" Test for using a class member which is an object of the current class
11018def Test_current_class_object_class_member()
11019 var lines =<< trim END
11020 vim9script
11021 class A
11022 public static var obj1: A = A.new(10)
11023 var n: number
11024 endclass
11025 defcompile
11026 assert_equal(10, A.obj1.n)
11027 END
11028 v9.CheckScriptSuccess(lines)
11029enddef
11030
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020011031" Test for updating a base class variable from a base class method without the
11032" class name. This used to crash Vim (Github issue #14352).
11033def Test_use_base_class_variable_from_base_class_method()
11034 var lines =<< trim END
11035 vim9script
11036
11037 class DictKeyClass
11038 static var _obj_id_count = 1
11039 def _GenerateKey()
11040 _obj_id_count += 1
11041 enddef
11042 static def GetIdCount(): number
11043 return _obj_id_count
11044 enddef
11045 endclass
11046
11047 class C extends DictKeyClass
11048 def F()
11049 this._GenerateKey()
11050 enddef
11051 endclass
11052
11053 C.new().F()
11054 assert_equal(2, DictKeyClass.GetIdCount())
11055 END
11056 v9.CheckScriptSuccess(lines)
11057enddef
11058
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020011059" Test for accessing protected funcref object and class variables
11060def Test_protected_funcref()
11061 # protected funcref object variable
11062 var lines =<< trim END
11063 vim9script
11064 class Test1
11065 const _Id: func(any): any = (v) => v
11066 endclass
11067 var n = Test1.new()._Id(1)
11068 END
11069 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
11070
11071 # protected funcref class variable
11072 lines =<< trim END
11073 vim9script
11074 class Test2
11075 static const _Id: func(any): any = (v) => v
11076 endclass
11077 var n = Test2._Id(2)
11078 END
11079 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
11080enddef
11081
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020011082" Test for using lambda block in classes
11083def Test_lambda_block_in_class()
11084 # This used to crash Vim
11085 var lines =<< trim END
11086 vim9script
11087 class IdClass1
11088 const Id: func(number): number = (num: number): number => {
11089 # Return a ID
11090 return num * 10
11091 }
11092 endclass
11093 var id = IdClass1.new()
11094 assert_equal(20, id.Id(2))
11095 END
11096 v9.CheckScriptSuccess(lines)
11097
11098 # This used to crash Vim
11099 lines =<< trim END
11100 vim9script
11101 class IdClass2
11102 static const Id: func(number): number = (num: number): number => {
11103 # Return a ID
11104 return num * 2
11105 }
11106 endclass
11107 assert_equal(16, IdClass2.Id(8))
11108 END
11109 v9.CheckScriptSuccess(lines)
11110enddef
11111
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020011112" Test for defcompiling an abstract method
11113def Test_abstract_method_defcompile()
11114 # Compile an abstract class with abstract object methods
11115 var lines =<< trim END
11116 vim9script
11117 abstract class A
11118 abstract def Foo(): string
11119 abstract def Bar(): list<string>
11120 endclass
11121 defcompile
11122 END
11123 v9.CheckScriptSuccess(lines)
11124
11125 # Compile a concrete object method in an abstract class
11126 lines =<< trim END
11127 vim9script
11128 abstract class A
11129 abstract def Foo(): string
11130 abstract def Bar(): list<string>
11131 def Baz(): string
11132 pass
11133 enddef
11134 endclass
11135 defcompile
11136 END
11137 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
11138
11139 # Compile a concrete class method in an abstract class
11140 lines =<< trim END
11141 vim9script
11142 abstract class A
11143 abstract def Foo(): string
11144 abstract def Bar(): list<string>
11145 static def Baz(): string
11146 pass
11147 enddef
11148 endclass
11149 defcompile
11150 END
11151 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
11152enddef
11153
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020011154" Test for defining a class in a function
11155def Test_class_definition_in_a_function()
11156 var lines =<< trim END
11157 vim9script
11158 def Foo()
11159 class A
11160 endclass
11161 enddef
11162 defcompile
11163 END
11164 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
11165enddef
11166
Yegappan Lakshmanandbac0da2024-05-25 20:23:54 +020011167" Test for using [] with a class and an object
11168def Test_class_object_index()
11169 var lines =<< trim END
11170 vim9script
11171 class A
11172 endclass
11173 A[10] = 1
11174 END
11175 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a class: A[10] = 1', 4)
11176
11177 lines =<< trim END
11178 vim9script
11179 class A
11180 endclass
11181 var a = A.new()
11182 a[10] = 1
11183 END
11184 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5)
11185enddef
11186
LemonBoyf4af3312024-07-04 13:43:12 +020011187def Test_class_member_init_typecheck()
11188 # Ensure the class member is assigned its declared type.
11189 var lines =<< trim END
11190 vim9script
11191 class S
11192 static var l: list<string> = []
11193 endclass
11194 S.l->add(123)
11195 END
11196 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5)
11197
11198 # Ensure the initializer value and the declared type match.
11199 lines =<< trim END
11200 vim9script
11201 class S
11202 var l: list<string> = [1, 2, 3]
11203 endclass
11204 var o = S.new()
11205 END
11206 v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>')
11207
11208 # Ensure the class member is assigned its declared type.
11209 lines =<< trim END
11210 vim9script
11211 class S
11212 var l: list<string> = []
11213 endclass
11214 var o = S.new()
11215 o.l->add(123)
11216 END
11217 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6)
11218enddef
11219
LemonBoy50d48542024-07-04 17:03:17 +020011220def Test_class_cast()
11221 var lines =<< trim END
11222 vim9script
11223 class A
11224 endclass
11225 class B extends A
11226 var mylen: number
11227 endclass
11228 def F(o: A): number
11229 return (<B>o).mylen
11230 enddef
11231
11232 defcompile F
11233 END
11234 v9.CheckScriptSuccess(lines)
11235enddef
11236
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011237" Test for using a variable of type "any" with an object
11238def Test_any_obj_var_type()
11239 var lines =<< trim END
11240 vim9script
11241 class A
11242 var name: string = "foobar"
11243 def Foo(): string
11244 return "func foo"
11245 enddef
11246 endclass
11247
11248 def CheckVals(x: any)
11249 assert_equal("foobar", x.name)
11250 assert_equal("func foo", x.Foo())
11251 enddef
11252
11253 var a = A.new()
11254 CheckVals(a)
11255 END
11256 v9.CheckScriptSuccess(lines)
11257
11258 # Try to set a non-existing variable
11259 lines =<< trim END
11260 vim9script
11261 class A
11262 var name: string = "foobar"
11263 endclass
11264
11265 def SetNonExistingVar(x: any)
11266 x.bar = [1, 2, 3]
11267 enddef
11268
11269 var a = A.new()
11270 SetNonExistingVar(a)
11271 END
11272 v9.CheckScriptFailure(lines, 'E1326: Variable "bar" not found in object "A"', 1)
11273
11274 # Try to read a non-existing variable
11275 lines =<< trim END
11276 vim9script
11277 class A
11278 var name: string = "foobar"
11279 endclass
11280
11281 def GetNonExistingVar(x: any)
11282 var i: dict<any> = x.bar
11283 enddef
11284
11285 var a = A.new()
11286 GetNonExistingVar(a)
11287 END
11288 v9.CheckScriptFailure(lines, 'E1326: Variable "bar" not found in object "A"', 1)
11289
11290 # Try to invoke a non-existing method
11291 lines =<< trim END
11292 vim9script
11293 class A
11294 def Foo(): number
11295 return 10
11296 enddef
11297 endclass
11298
11299 def CallNonExistingMethod(x: any)
11300 var i: number = x.Bar()
11301 enddef
11302
11303 var a = A.new()
11304 CallNonExistingMethod(a)
11305 END
11306 v9.CheckScriptFailure(lines, 'E1326: Variable "Bar" not found in object "A"', 1)
11307
11308 # Use an object which is a Dict value
11309 lines =<< trim END
11310 vim9script
11311 class Foo
11312 def Bar(): number
11313 return 369
11314 enddef
11315 endclass
11316
11317 def GetValue(FooDict: dict<any>): number
11318 var n: number = 0
11319 for foo in values(FooDict)
11320 n += foo.Bar()
11321 endfor
11322 return n
11323 enddef
11324
11325 var d = {'x': Foo.new()}
11326 assert_equal(369, GetValue(d))
11327 END
11328 v9.CheckScriptSuccess(lines)
11329
zeertzjqd32bf0a2024-12-17 20:55:13 +010011330 # Nested data. Object containing a Dict containing another Object.
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011331 lines =<< trim END
11332 vim9script
11333 class Context
11334 public var state: dict<any> = {}
11335 endclass
11336
11337 class Metadata
11338 public var value = 0
11339 endclass
11340
11341 var ctx = Context.new()
11342 ctx.state["meta"] = Metadata.new(2468)
11343
11344 const foo = ctx.state.meta.value
11345
11346 def F(): number
11347 const bar = ctx.state.meta.value
11348 return bar
11349 enddef
11350
11351 assert_equal(2468, F())
11352 END
11353 v9.CheckScriptSuccess(lines)
11354
11355 # Accessing an object from a method inside the class using any type
11356 lines =<< trim END
11357 vim9script
11358 class C
11359 def _G(): string
11360 return '_G'
11361 enddef
11362 static def S(o_any: any): string
11363 return o_any._G()
11364 enddef
11365 endclass
11366
11367 var o1 = C.new()
11368 assert_equal('_G', C.S(o1))
11369 END
11370 v9.CheckScriptSuccess(lines)
11371
11372 # Modifying an object private variable from a method in another class using
11373 # any type
11374 lines =<< trim END
11375 vim9script
11376
11377 class A
11378 var num = 10
11379 endclass
11380
11381 class B
11382 def SetVal(x: any)
11383 x.num = 20
11384 enddef
11385 endclass
11386
11387 var a = A.new()
11388 var b = B.new()
11389 b.SetVal(a)
11390 END
11391 v9.CheckScriptFailure(lines, 'E1335: Variable "num" in class "A" is not writable', 1)
11392
11393 # Accessing a object protected variable from a method in another class using
11394 # any type
11395 lines =<< trim END
11396 vim9script
11397
11398 class A
11399 var _num = 10
11400 endclass
11401
11402 class B
11403 def GetVal(x: any): number
11404 return x._num
11405 enddef
11406 endclass
11407
11408 var a = A.new()
11409 var b = B.new()
11410 var i = b.GetVal(a)
11411 END
11412 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_num" in class "A"', 1)
11413
11414 # Accessing an object returned from an imported function and class
11415 lines =<< trim END
11416 vim9script
11417 export class Foo
11418 public var name: string
11419 endclass
11420
11421 export def ReturnFooObject(): Foo
11422 var r = Foo.new('star')
11423 return r
11424 enddef
11425 END
11426 writefile(lines, 'Xanyvar1.vim', 'D')
11427
11428 lines =<< trim END
11429 vim9script
11430
11431 import './Xanyvar1.vim'
11432
11433 def GetName(): string
11434 var whatever = Xanyvar1.ReturnFooObject()
11435 return whatever.name
11436 enddef
11437
11438 assert_equal('star', GetName())
11439 END
11440 v9.CheckScriptSuccess(lines)
11441
11442 # Try to modify a private object variable using a variable of type "any"
11443 lines =<< trim END
11444 vim9script
11445
11446 class Foo
11447 var n: number = 10
11448 endclass
11449 def Fn(x: any)
11450 x.n = 20
11451 enddef
11452 var a = Foo.new()
11453 Fn(a)
11454 END
11455 v9.CheckScriptFailure(lines, 'E1335: Variable "n" in class "Foo" is not writable', 1)
11456
11457 # Try to read a protected object variable using a variable of type "any"
11458 lines =<< trim END
11459 vim9script
11460
11461 class Foo
11462 var _n: number = 10
11463 endclass
11464 def Fn(x: any): number
11465 return x._n
11466 enddef
11467
11468 var a = Foo.new()
11469 Fn(a)
11470 END
11471 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_n" in class "Foo"', 1)
11472
11473 # Read a protected object variable using a variable of type "any" in an object
11474 # method
11475 lines =<< trim END
11476 vim9script
11477
11478 class Foo
11479 var _n: number = 10
11480 def Fn(x: any): number
11481 return x._n
11482 enddef
11483 endclass
11484
11485 var a = Foo.new()
11486 assert_equal(10, a.Fn(a))
11487 END
11488 v9.CheckScriptSuccess(lines)
11489
11490 # Try to call a protected object method using a "any" type variable
11491 lines =<< trim END
11492 vim9script
11493
11494 class Foo
11495 def _GetVal(): number
11496 return 234
11497 enddef
11498 endclass
11499 def Fn(x: any): number
11500 return x._GetVal()
11501 enddef
11502
11503 var a = Foo.new()
11504 Fn(a)
11505 END
11506 v9.CheckScriptFailure(lines, 'E1366: Cannot access protected method: _GetVal', 1)
11507
11508 # Call a protected object method using a "any" type variable from another
11509 # object method
11510 lines =<< trim END
11511 vim9script
11512
11513 class Foo
11514 def _GetVal(): number
11515 return 234
11516 enddef
11517 def FooVal(x: any): number
11518 return x._GetVal()
11519 enddef
11520 endclass
11521
11522 var a = Foo.new()
11523 assert_equal(234, a.FooVal(a))
11524 END
11525 v9.CheckScriptSuccess(lines)
11526
11527 # Method chaining
11528 lines =<< trim END
11529 vim9script
11530
11531 export class T
11532 var id: number = 268
11533 def F(): any
11534 return this
11535 enddef
11536 endclass
11537
11538 def H()
11539 var a = T.new().F().F()
11540 assert_equal(268, a.id)
11541 enddef
11542 H()
11543
11544 var b: T = T.new().F().F()
11545 assert_equal(268, b.id)
11546 END
11547 v9.CheckScriptSuccess(lines)
11548
11549 # Using a null object to access a member variable
11550 lines =<< trim END
11551 vim9script
11552 def Fn(x: any): number
11553 return x.num
11554 enddef
11555
11556 Fn(null_object)
11557 END
11558 v9.CheckScriptFailure(lines, 'E1360: Using a null object', 1)
11559
11560 # Using a null object to invoke a method
11561 lines =<< trim END
11562 vim9script
11563 def Fn(x: any)
11564 x.Foo()
11565 enddef
11566
11567 Fn(null_object)
11568 END
11569 v9.CheckScriptFailure(lines, 'E1360: Using a null object', 1)
Yegappan Lakshmanane7984462024-11-12 21:03:00 +010011570
11571 # Try to change a const object variable using a "any" variable
11572 lines =<< trim END
11573 vim9script
11574 class A
11575 public const v1: number = 123
11576 endclass
11577
11578 def Fn(o: any)
11579 o.v1 = 321
11580 enddef
11581
11582 var a = A.new()
11583 Fn(a)
11584 END
11585 v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
11586
11587 # Try to change a final object variable using a "any" variable
11588 lines =<< trim END
11589 vim9script
11590 class A
11591 public final v1: number = 123
11592 endclass
11593
11594 def Fn(o: any)
11595 o.v1 = 321
11596 enddef
11597
11598 var a = A.new()
11599 Fn(a)
11600 END
11601 v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
11602
11603 # Assign a different type of value to an "any" type object variable
11604 lines =<< trim END
11605 vim9script
11606 class A
11607 public var v1: list<any> = [1, 2]
11608 endclass
11609
11610 def Fn(o: A)
11611 o.v1 = 'abc'
11612 enddef
11613
11614 var a = A.new()
11615 Fn(a)
11616 END
11617 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected list<any> but got string', 1)
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011618enddef
11619
Yegappan Lakshmanan481992c2024-12-06 18:35:12 +010011620" Test for using an object method with mapnew()
11621def Test_mapnew_with_instance_method()
11622 var lines =<< trim END
11623 vim9script
11624
11625 class Foo
11626 var str: string
11627 var nums: list<number> = [1, 2, 3]
11628
11629 def InstanceMethod(n: number): string
11630 return this.str .. n
11631 enddef
11632
11633 def MapperMethod(idx: number, elem: number): string
11634 return elem->this.InstanceMethod()
11635 enddef
11636
11637 def MapTest()
11638 this.str = "foo"
11639 var l = ['foo1', 'foo2', 'foo3']
11640 assert_equal(l, this.nums->mapnew(this.MapperMethod))
11641 enddef
11642 endclass
11643
11644 Foo.new().MapTest()
11645 END
11646 v9.CheckSourceSuccess(lines)
11647
11648 # Error in the mapnew() function
11649 lines =<< trim END
11650 vim9script
11651
11652 class Foo
11653 var str: string
11654 var nums: list<number> = [1, 2, 3]
11655
11656 def InstanceMethod(n: number): string
11657 throw "InstanceMethod failed"
11658 enddef
11659
11660 def MapperMethod(idx: number, elem: number): string
11661 return elem->this.InstanceMethod()
11662 enddef
11663
11664 def MapTest()
11665 this.str = "foo"
11666 var caught_exception: bool = false
11667 try
11668 this.nums->mapnew(this.MapperMethod)
11669 catch /InstanceMethod failed/
11670 caught_exception = true
11671 endtry
11672 assert_true(caught_exception)
11673 enddef
11674 endclass
11675
11676 Foo.new().MapTest()
11677 END
11678 v9.CheckSourceSuccess(lines)
11679enddef
11680
Yegappan Lakshmananb0206e92024-12-30 09:52:16 +010011681" Test for using an object method in a method call.
11682def Test_use_object_method_in_a_method_call()
11683 var lines =<< trim END
11684 vim9script
11685
11686 class Foo
11687 def Cost(nums: list<number>): number
11688 return nums[0] * nums[1]
11689 enddef
11690
11691 def ShowCost(): string
11692 var g = [4, 5]
11693 return $"Cost is: {g->this.Cost()}"
11694 enddef
11695 endclass
11696
11697 var d = Foo.new()
11698 assert_equal('Cost is: 20', d.ShowCost())
11699 END
11700 v9.CheckSourceSuccess(lines)
11701
11702 # Test for using a non-existing object method in string interpolation
11703 lines =<< trim END
11704 vim9script
11705
11706 class Foo
11707 def Cost(nums: list<number>): number
11708 return nums[0] * nums[1]
11709 enddef
11710
11711 def ShowCost(): string
11712 var g = [4, 5]
11713 echo $"Cost is: {g->this.NewCost()}"
11714 enddef
11715 endclass
11716
11717 var d = Foo.new()
11718 d.ShowCost()
11719 END
11720 v9.CheckSourceFailure(lines, 'E1326: Variable "NewCost" not found in object "Foo"')
11721enddef
11722
Yegappan Lakshmananb04af4c2025-01-03 10:50:08 +010011723" Test for referencing an object variable which is not yet initialized
11724def Test_uninitialized_object_var()
11725 var lines =<< trim END
11726 vim9script
11727 class Foo
11728 const two: number = Foo.Two(this)
11729 const one: number = 1
11730
11731 static def Two(that: Foo): number
11732 return that.one + 2
11733 enddef
11734 endclass
11735
11736 echo Foo.Two(Foo.new())
11737 END
11738 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'one' referenced")
11739
11740 lines =<< trim END
11741 vim9script
11742 class Foo
11743 const one: number = Foo.One(this)
11744
11745 static def One(that: Foo): number
11746 return 1
11747 enddef
11748 endclass
11749
11750 assert_equal(1, Foo.One(Foo.new()))
11751 END
11752 v9.CheckSourceSuccess(lines)
11753
11754 lines =<< trim END
11755 vim9script
11756 class Foo
11757 const one: number = 1
11758 const two: number = Foo.Two(this)
11759
11760 static def Two(that: Foo): number
11761 return that.one + 1
11762 enddef
11763 endclass
11764
11765 assert_equal(2, Foo.Two(Foo.new()))
11766 END
11767 v9.CheckSourceSuccess(lines)
11768
11769 lines =<< trim END
11770 vim9script
11771 class Foo
11772 const Id: func(any): any = ((_) => (v) => v)(this)
11773
11774 static def Id(that: Foo): func(any): any
11775 return that.Id
11776 enddef
11777 endclass
11778
11779 assert_equal(5, Foo.Id(Foo.new())(5))
11780 assert_equal(7, Foo.new().Id(7))
11781 END
11782 v9.CheckSourceSuccess(lines)
11783
11784 lines =<< trim END
11785 vim9script
11786 class Foo
11787 const Id: func(any): any = ((that) => (_) => that)(this)
11788
11789 static def Id(that: Foo): func(any): any
11790 return that.Id
11791 enddef
11792 endclass
11793
11794 const Id0: func(any): any = Foo.Id(Foo.new())
11795 const Id1: func(any): any = Foo.new().Id
11796 END
11797 v9.CheckSourceSuccess(lines)
11798
11799 lines =<< trim END
11800 vim9script
11801 class Foo
11802 const Id: any = Foo.Id(this)
11803
11804 static def Id(that: Foo): any
11805 return that.Id
11806 enddef
11807 endclass
11808
11809 const Id2: any = Foo.Id(Foo.new())
11810 const Id3: any = Foo.new().Id
11811 END
11812 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'Id' referenced")
11813
11814 lines =<< trim END
11815 vim9script
11816
11817 class Foo
11818 var x: string = ''
11819 var Y: func(): string = () => this.x
11820 endclass
11821
11822 var foo = Foo.new('ok')
11823 assert_equal('ok', foo.Y())
11824 END
11825 v9.CheckSourceSuccess(lines)
11826
11827 lines =<< trim END
11828 vim9script
11829
11830 class Foo
11831 var x: string = this.x
11832 endclass
11833
11834 var foo = Foo.new('ok')
11835 END
11836 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'x' referenced")
11837enddef
11838
Yegappan Lakshmanan2050dcc2025-01-06 18:34:49 +010011839" Test for initializing member variables of compound type in the constructor
11840def Test_constructor_init_compound_member_var()
11841 var lines =<< trim END
11842 vim9script
11843
11844 class Foo
11845 var v1: string = "aaa"
11846 var v2: list<number> = [1, 2]
11847 var v3: dict<string> = {a: 'a', b: 'b'}
11848 endclass
11849
11850 class Bar
11851 var v4: string = "bbb"
11852 var v5: Foo = Foo.new()
11853 var v6: list<number> = [1, 2]
11854 endclass
11855
11856 var b: Bar = Bar.new()
11857 assert_equal("aaa", b.v5.v1)
11858 assert_equal([1, 2], b.v5.v2)
11859 assert_equal({a: 'a', b: 'b'}, b.v5.v3)
11860 assert_equal("bbb", b.v4)
11861 assert_equal([1, 2], b.v6)
11862 END
11863 v9.CheckSourceSuccess(lines)
11864enddef
11865
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011866" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker