blob: 0c11c078e721ec25fa86f8860134b34ef62cf0d3 [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
4348 # TODO: the following tests use type "any" for argument. Need a run time
4349 # check for access. Probably OK as is for now.
4350
4351 # read-only lockvar from object method arg
4352 lines =<< trim END
4353 vim9script
4354
4355 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004356 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004357 def Lock(o_any: any)
4358 lockvar o_any.val5
4359 enddef
4360 endclass
4361 var o = C.new(3)
4362 o.Lock(C.new(5))
4363 END
Ernie Rael64885642023-10-04 20:16:22 +02004364 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004365
4366 # read-only lockvar from class method arg
4367 lines =<< trim END
4368 vim9script
4369
4370 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004371 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004372 static def Lock(o_any: any)
4373 lockvar o_any.val6
4374 enddef
4375 endclass
4376 var o = C.new(3)
4377 C.Lock(o)
4378 END
Ernie Rael64885642023-10-04 20:16:22 +02004379 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004380
4381 #
4382 # lockvar of public object variable
4383 #
4384
4385 # lockvar from object method
4386 lines =<< trim END
4387 vim9script
4388
4389 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004390 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004391 def Lock()
4392 lockvar this.val1
4393 enddef
4394 endclass
4395 var o = C.new(3)
4396 o.Lock()
4397 END
4398 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4399
4400 # lockvar from scriptlevel
4401 lines =<< trim END
4402 vim9script
4403
4404 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004405 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004406 endclass
4407 var o = C.new(3)
4408 lockvar o.val2
4409 END
4410 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4411
4412 # lockvar of scriptlevel variable from def
4413 lines =<< trim END
4414 vim9script
4415
4416 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004417 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004418 endclass
4419 var o = C.new(3)
4420 def Lock()
4421 lockvar o.val3
4422 enddef
4423 Lock()
4424 END
4425 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4426
4427 # lockvar of def argument variable
4428 lines =<< trim END
4429 vim9script
4430
4431 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004432 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004433 endclass
4434 def Lock(o: C)
4435 lockvar o.val4
4436 enddef
4437 Lock(C.new(3))
4438 END
4439 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4440
4441 # lockvar from object method arg
4442 lines =<< trim END
4443 vim9script
4444
4445 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004446 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004447 def Lock(o_any: any)
4448 lockvar o_any.val5
4449 enddef
4450 endclass
4451 var o = C.new(3)
4452 o.Lock(C.new(5))
4453 END
4454 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4455
4456 # lockvar from class method arg
4457 lines =<< trim END
4458 vim9script
4459
4460 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004461 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004462 static def Lock(o_any: any)
4463 lockvar o_any.val6
4464 enddef
4465 endclass
4466 var o = C.new(3)
4467 C.Lock(o)
4468 END
4469 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4470enddef
4471
4472" Test trying to lock a class variable from various places
4473def Test_lockvar_class_variable()
4474
4475 # lockvar bare static from object method
4476 var lines =<< trim END
4477 vim9script
4478
4479 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004480 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004481 def Lock()
4482 lockvar sval1
4483 enddef
4484 endclass
4485 var o = C.new()
4486 o.Lock()
4487 END
4488 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4489
4490 # lockvar C.static from object method
4491 lines =<< trim END
4492 vim9script
4493
4494 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004495 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004496 def Lock()
4497 lockvar C.sval2
4498 enddef
4499 endclass
4500 var o = C.new()
4501 o.Lock()
4502 END
4503 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4504
4505 # lockvar bare static from class method
4506 lines =<< trim END
4507 vim9script
4508
4509 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004510 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004511 static def Lock()
4512 lockvar sval3
4513 enddef
4514 endclass
4515 C.Lock()
4516 END
4517 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4518
4519 # lockvar C.static from class method
4520 lines =<< trim END
4521 vim9script
4522
4523 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004524 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004525 static def Lock()
4526 lockvar C.sval4
4527 enddef
4528 endclass
4529 C.Lock()
4530 END
4531 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4532
4533 # lockvar C.static from script level
4534 lines =<< trim END
4535 vim9script
4536
4537 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004538 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004539 endclass
4540 lockvar C.sval5
4541 END
4542 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4543
4544 # lockvar o.static from script level
4545 lines =<< trim END
4546 vim9script
4547
4548 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004549 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004550 endclass
4551 var o = C.new()
4552 lockvar o.sval6
4553 END
4554 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4555enddef
4556
4557" Test locking an argument to :def
4558def Test_lockvar_argument()
4559 # Lockvar a function arg
4560 var lines =<< trim END
4561 vim9script
4562
4563 def Lock(val: any)
4564 lockvar val
4565 enddef
4566
4567 var d = {a: 1, b: 2}
4568 Lock(d)
4569
4570 d->extend({c: 3})
4571 END
4572 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4573
4574 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4575 # class member in "C". This tests lval_root_is_arg.
4576 lines =<< trim END
4577 vim9script
4578
4579 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004580 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004581 endclass
4582
4583 def Lock2(sval: any)
4584 lockvar sval
4585 enddef
4586
4587 var o = C.new()
4588 Lock2(o)
4589 END
4590 v9.CheckSourceSuccess(lines)
4591
4592 # Lock a class.
4593 lines =<< trim END
4594 vim9script
4595
4596 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004597 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004598 endclass
4599
4600 def Lock2(sval: any)
4601 lockvar sval
4602 enddef
4603
4604 Lock2(C)
4605 END
Ernie Raelb077b582023-12-14 20:11:44 +01004606 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004607
4608 # Lock an object.
4609 lines =<< trim END
4610 vim9script
4611
4612 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004613 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004614 endclass
4615
4616 def Lock2(sval: any)
4617 lockvar sval
4618 enddef
4619
4620 Lock2(C.new())
4621 END
4622 v9.CheckSourceSuccess(lines)
4623
4624 # In this case (unlike previous) "lockvar sval" is a class member.
4625 lines =<< trim END
4626 vim9script
4627
4628 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004629 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004630 def Lock2()
4631 lockvar sval
4632 enddef
4633 endclass
4634
4635
4636 var o = C.new()
4637 o.Lock2()
4638 END
4639 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4640enddef
4641
4642" Test that this can be locked without error
4643def Test_lockvar_this()
4644 # lockvar this
4645 var lines =<< trim END
4646 vim9script
4647 class C
4648 def TLock()
4649 lockvar this
4650 enddef
4651 endclass
4652 var o = C.new()
4653 o.TLock()
4654 END
4655 v9.CheckSourceSuccess(lines)
4656
4657 # lockvar four (four letter word, but not this)
4658 lines =<< trim END
4659 vim9script
4660 class C
4661 def TLock4()
4662 var four: number
4663 lockvar four
4664 enddef
4665 endclass
4666 var o = C.new()
4667 o.TLock4()
4668 END
4669 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4670
4671 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4672 lines =<< trim END
4673 vim9script
4674 class C
4675 def TLock5()
4676 var this5: number
4677 lockvar this5
4678 enddef
4679 endclass
4680 var o = C.new()
4681 o.TLock5()
4682 END
4683 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4684enddef
4685
4686" Test some general lockvar cases
4687def Test_lockvar_general()
4688 # lockvar an object and a class. It does nothing
4689 var lines =<< trim END
4690 vim9script
4691 class C
4692 endclass
4693 var o = C.new()
4694 lockvar o
4695 lockvar C
4696 END
4697 v9.CheckSourceSuccess(lines)
4698
4699 # Lock a list element that's nested in an object variable from a :def
4700 lines =<< trim END
4701 vim9script
4702
4703 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004704 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004705 endclass
4706 def Lock2(obj: any)
4707 lockvar obj.val[1]
4708 enddef
4709
4710 var o = C.new()
4711 Lock2(o)
4712 o.val[0] = [9]
4713 assert_equal([ [9], [2], [3] ], o.val)
4714 try
4715 o.val[1] = [999]
4716 call assert_false(true, 'assign should have failed')
4717 catch
4718 assert_exception('E741:')
4719 endtry
4720 o.val[2] = [8]
4721 assert_equal([ [9], [2], [8] ], o.val)
4722 END
4723 v9.CheckSourceSuccess(lines)
4724
4725 # Lock a list element that's nested in an object variable from scriptlevel
4726 lines =<< trim END
4727 vim9script
4728
4729 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004730 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004731 endclass
4732
4733 var o = C.new()
4734 lockvar o.val[1]
4735 o.val[0] = [9]
4736 assert_equal([ [9], [2], [3] ], o.val)
4737 try
4738 o.val[1] = [999]
4739 call assert_false(true, 'assign should have failed')
4740 catch
4741 assert_exception('E741:')
4742 endtry
4743 o.val[2] = [8]
4744 assert_equal([ [9], [2], [8] ], o.val)
4745 END
4746 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004747
4748 # lock a script level variable from an object method
4749 lines =<< trim END
4750 vim9script
4751
4752 class C
4753 def Lock()
4754 lockvar l
4755 enddef
4756 endclass
4757
4758 var l = [1]
4759 C.new().Lock()
4760 l[0] = 11
4761 END
4762 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4763
Ernie Rael03042a22023-11-11 08:53:32 +01004764 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004765 # in an object fetched via a script level list
4766 lines =<< trim END
4767 vim9script
4768
4769 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004770 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004771 def Lock()
4772 lockvar lc[0]._v1[1]
4773 enddef
4774 endclass
4775
4776 var l = [[1], [2], [3]]
4777 var o = C.new(l)
4778 var lc: list<C> = [ o ]
4779
4780 o.Lock()
4781 l[0] = [22]
4782 l[1] = [33]
4783 END
4784 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4785
4786 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004787 # in a class that does not own the protected variable.
4788 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004789 # the same name.
4790 lines =<< trim END
4791 vim9script
4792
4793 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004794 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004795 def Lock(obj: any)
4796 lockvar lc[0]._v1[1]
4797 enddef
4798 endclass
4799
4800 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004801 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004802 endclass
4803
4804 var l = [[1], [2], [3]]
4805 var o = C.new(l)
4806 var lc: list<C> = [ o ]
4807
4808 var o2 = C2.new()
4809 o2.Lock(o)
4810 END
Ernie Rael03042a22023-11-11 08:53:32 +01004811 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004812enddef
4813
Ernie Rael9771b2a2023-10-07 22:05:40 +02004814" Test builtin islocked()
4815def Test_lockvar_islocked()
4816 # Can't lock class/object variable
4817 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004818 # Lock item of variable's value (a list item)
4819 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004820 var lines =<< trim END
4821 vim9script
4822
4823 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004824 var o0: list<list<number>> = [ [0], [1], [2]]
4825 var o1: list<list<number>> = [[10], [11], [12]]
4826 static var c0: list<list<number>> = [[20], [21], [22]]
4827 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004828 endclass
4829
4830 def LockIt(arg: any)
4831 lockvar arg
4832 enddef
4833
4834 def UnlockIt(arg: any)
4835 unlockvar arg
4836 enddef
4837
4838 var obj = C.new()
4839 #lockvar obj.o1 # can't lock something you can't write to
4840
4841 try
4842 lockvar obj.o1 # can't lock something you can't write to
4843 call assert_false(1, '"lockvar obj.o1" should have failed')
4844 catch
4845 call assert_exception('E1335:')
4846 endtry
4847
4848 LockIt(obj.o1) # but can lock it's value
4849 assert_equal(1, islocked("obj.o1"))
4850 assert_equal(1, islocked("obj.o1[0]"))
4851 assert_equal(1, islocked("obj.o1[1]"))
4852 UnlockIt(obj.o1)
4853 assert_equal(0, islocked("obj.o1"))
4854 assert_equal(0, islocked("obj.o1[0]"))
4855
4856 lockvar obj.o1[0]
4857 assert_equal(0, islocked("obj.o1"))
4858 assert_equal(1, islocked("obj.o1[0]"))
4859 assert_equal(0, islocked("obj.o1[1]"))
4860 unlockvar obj.o1[0]
4861 assert_equal(0, islocked("obj.o1"))
4862 assert_equal(0, islocked("obj.o1[0]"))
4863
4864 # Same thing, but with a static
4865
4866 try
4867 lockvar C.c1 # can't lock something you can't write to
4868 call assert_false(1, '"lockvar C.c1" should have failed')
4869 catch
4870 call assert_exception('E1335:')
4871 endtry
4872
4873 LockIt(C.c1) # but can lock it's value
4874 assert_equal(1, islocked("C.c1"))
4875 assert_equal(1, islocked("C.c1[0]"))
4876 assert_equal(1, islocked("C.c1[1]"))
4877 UnlockIt(C.c1)
4878 assert_equal(0, islocked("C.c1"))
4879 assert_equal(0, islocked("C.c1[0]"))
4880
4881 lockvar C.c1[0]
4882 assert_equal(0, islocked("C.c1"))
4883 assert_equal(1, islocked("C.c1[0]"))
4884 assert_equal(0, islocked("C.c1[1]"))
4885 unlockvar C.c1[0]
4886 assert_equal(0, islocked("C.c1"))
4887 assert_equal(0, islocked("C.c1[0]"))
4888 END
4889 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004890
4891 # Do islocked() from an object method
4892 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004893 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004894 vim9script
4895
4896 var l0o0 = [ [0], [1], [2]]
4897 var l0o1 = [ [10], [11], [12]]
4898 var l0c0 = [[120], [121], [122]]
4899 var l0c1 = [[130], [131], [132]]
4900
4901 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004902 var o0: list<list<number>> = l0o0
4903 var o1: list<list<number>> = l0o1
4904 static var c0: list<list<number>> = l0c0
4905 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004906 def Islocked(arg: string): number
4907 return islocked(arg)
4908 enddef
4909 static def SIslocked(arg: string): number
4910 return islocked(arg)
4911 enddef
4912 endclass
4913
4914 var l2o0 = [[20000], [20001], [20002]]
4915 var l2o1 = [[20010], [20011], [20012]]
4916 var l2c0 = [[20120], [20121], [20122]]
4917 var l2c1 = [[20130], [20131], [20132]]
4918
4919 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004920 var o0: list<list<number>> = l2o0
4921 var o1: list<list<number>> = l2o1
4922 static var c0: list<list<number>> = l2c0
4923 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004924 def Islocked(arg: string): number
4925 return islocked(arg)
4926 enddef
4927 static def SIslocked(arg: string): number
4928 return islocked(arg)
4929 enddef
4930 endclass
4931
4932 var obj0 = C0.new()
4933 var obj2 = C2.new()
4934
4935 var l = [ obj0, null_object, obj2 ]
4936
4937 # lock list, object func access through script var expr
4938 assert_equal(0, obj0.Islocked("l[0].o0"))
4939 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4940 lockvar l0o0
4941 assert_equal(1, obj0.Islocked("l[0].o0"))
4942 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4943
4944 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4945
4946 # lock list element, object func access through script var expr
4947 lockvar l0o1[1]
4948 assert_equal(0, obj0.Islocked("this.o1[0]"))
4949 assert_equal(1, obj0.Islocked("this.o1[1]"))
4950
4951 assert_equal(0, obj0.Islocked("this.o1"))
4952 lockvar l0o1
4953 assert_equal(1, obj0.Islocked("this.o1"))
4954 unlockvar l0o1
4955
4956 lockvar l0c1[1]
4957
4958 # static by class name member expr from same class
4959 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4960 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4961 # static by bare name member expr from same class
4962 assert_equal(0, obj0.Islocked("c1[0]"))
4963 assert_equal(1, obj0.Islocked("c1[1]"))
4964
4965 # static by class name member expr from other class
4966 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4967 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4968 # static by bare name member expr from other class
4969 assert_equal(0, obj2.Islocked("c1[0]"))
4970 assert_equal(0, obj2.Islocked("c1[1]"))
4971
4972
4973 # static by bare name in same class
4974 assert_equal(0, obj0.Islocked("c0"))
4975 lockvar l0c0
4976 assert_equal(1, obj0.Islocked("c0"))
4977
4978 #
4979 # similar stuff, but use static method
4980 #
4981
4982 unlockvar l0o0
4983
4984 # lock list, object func access through script var expr
4985 assert_equal(0, C0.SIslocked("l[0].o0"))
4986 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4987 lockvar l0o0
4988 assert_equal(1, C0.SIslocked("l[0].o0"))
4989 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4990
4991 unlockvar l0o1
4992
4993 # can't access "this" from class method
4994 try
4995 C0.SIslocked("this.o1[0]")
4996 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4997 catch
4998 call assert_exception('E121: Undefined variable: this')
4999 endtry
5000
5001 lockvar l0c1[1]
5002
5003 # static by class name member expr from same class
5004 assert_equal(0, C0.SIslocked("C0.c1[0]"))
5005 assert_equal(1, C0.SIslocked("C0.c1[1]"))
5006 # static by bare name member expr from same class
5007 assert_equal(0, C0.SIslocked("c1[0]"))
5008 assert_equal(1, C0.SIslocked("c1[1]"))
5009
5010 # static by class name member expr from other class
5011 assert_equal(0, C2.SIslocked("C0.c1[0]"))
5012 assert_equal(1, C2.SIslocked("C0.c1[1]"))
5013 # static by bare name member expr from other class
5014 assert_equal(0, C2.SIslocked("c1[0]"))
5015 assert_equal(0, C2.SIslocked("c1[1]"))
5016
5017
5018 # static by bare name in same class
5019 unlockvar l0c0
5020 assert_equal(0, C0.SIslocked("c0"))
5021 lockvar l0c0
5022 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02005023 END
Ernie Rael4c8da022023-10-11 21:35:11 +02005024 v9.CheckSourceSuccess(lines)
5025
5026 # Check islocked class/object from various places.
5027 lines =<< trim END
5028 vim9script
5029
5030 class C
5031 def Islocked(arg: string): number
5032 return islocked(arg)
5033 enddef
5034 static def SIslocked(arg: string): number
5035 return islocked(arg)
5036 enddef
5037 endclass
5038 var obj = C.new()
5039
5040 # object method
5041 assert_equal(0, obj.Islocked("this"))
5042 assert_equal(0, obj.Islocked("C"))
5043
5044 # class method
5045 ### assert_equal(0, C.SIslocked("this"))
5046 assert_equal(0, C.SIslocked("C"))
5047
5048 #script level
5049 var v: number
5050 v = islocked("C")
5051 assert_equal(0, v)
5052 v = islocked("obj")
5053 assert_equal(0, v)
5054 END
5055 v9.CheckSourceSuccess(lines)
5056enddef
5057
5058def Test_lockvar_islocked_notfound()
5059 # Try non-existent things
5060 var lines =<< trim END
5061 vim9script
5062
5063 class C
5064 def Islocked(arg: string): number
5065 return islocked(arg)
5066 enddef
5067 static def SIslocked(arg: string): number
5068 return islocked(arg)
5069 enddef
5070 endclass
5071 var obj = C.new()
5072 assert_equal(-1, obj.Islocked("anywhere"))
5073 assert_equal(-1, C.SIslocked("notanywhere"))
5074 END
5075 v9.CheckSourceSuccess(lines)
5076
5077 # Something not found of the form "name1.name2" is an error
5078 lines =<< trim END
5079 vim9script
5080
5081 islocked("one.two")
5082 END
5083 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
5084
5085 lines =<< trim END
5086 vim9script
5087
5088 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005089 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02005090 def Islocked(arg: string): number
5091 return islocked(arg)
5092 enddef
5093 endclass
5094 var obj = C.new()
5095 obj.Islocked("this.val.not_there"))
5096 END
5097 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
5098
5099 lines =<< trim END
5100 vim9script
5101
5102 class C
5103 def Islocked(arg: string): number
5104 return islocked(arg)
5105 enddef
5106 endclass
5107 var obj = C.new()
5108 obj.Islocked("this.notobjmember")
5109 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005110 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02005111
5112 # access a script variable through methods
5113 lines =<< trim END
5114 vim9script
5115
5116 var l = [1]
5117 class C
5118 def Islocked(arg: string): number
5119 return islocked(arg)
5120 enddef
5121 static def SIslocked(arg: string): number
5122 return islocked(arg)
5123 enddef
5124 endclass
5125 var obj = C.new()
5126 assert_equal(0, obj.Islocked("l"))
5127 assert_equal(0, C.SIslocked("l"))
5128 lockvar l
5129 assert_equal(1, obj.Islocked("l"))
5130 assert_equal(1, C.SIslocked("l"))
5131 END
5132 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02005133enddef
5134
Ernie Rael03042a22023-11-11 08:53:32 +01005135" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005136def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005137 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005138 var lines =<< trim END
5139 vim9script
5140
5141 class A
5142 def _Foo(): number
5143 return 1234
5144 enddef
5145 endclass
5146 var a = A.new()
5147 a._Foo()
5148 END
Ernie Rael03042a22023-11-11 08:53:32 +01005149 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005150
Ernie Rael03042a22023-11-11 08:53:32 +01005151 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005152 lines =<< trim END
5153 vim9script
5154
5155 class A
5156 def _Foo(): number
5157 return 1234
5158 enddef
5159 endclass
5160 def T()
5161 var a = A.new()
5162 a._Foo()
5163 enddef
5164 T()
5165 END
Ernie Rael03042a22023-11-11 08:53:32 +01005166 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005167
Ernie Rael03042a22023-11-11 08:53:32 +01005168 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005169 lines =<< trim END
5170 vim9script
5171
5172 class A
5173 def _Foo(): number
5174 return 1234
5175 enddef
5176 def Bar(): number
5177 return this._Foo()
5178 enddef
5179 endclass
5180 var a = A.new()
5181 assert_equal(1234, a.Bar())
5182 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005183 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005184
Ernie Rael03042a22023-11-11 08:53:32 +01005185 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005186 lines =<< trim END
5187 vim9script
5188
5189 class A
5190 def _Foo(): number
5191 return 1234
5192 enddef
5193 def Bar(): number
5194 return this._Foo()
5195 enddef
5196 endclass
5197 def T()
5198 var a = A.new()
5199 assert_equal(1234, a.Bar())
5200 enddef
5201 T()
5202 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005203 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005204
Ernie Rael03042a22023-11-11 08:53:32 +01005205 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005206 lines =<< trim END
5207 vim9script
5208
5209 class A
5210 def _Foo(): number
5211 return 1234
5212 enddef
5213 def Bar(): number
5214 return _Foo()
5215 enddef
5216 endclass
5217 var a = A.new()
5218 a.Bar()
5219 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005220 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005221
Ernie Rael03042a22023-11-11 08:53:32 +01005222 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005223 lines =<< trim END
5224 vim9script
5225
5226 class A
5227 def _Foo(): number
5228 return 1234
5229 enddef
5230 endclass
5231 A._Foo()
5232 END
Ernie Rael03042a22023-11-11 08:53:32 +01005233 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005234
Ernie Rael03042a22023-11-11 08:53:32 +01005235 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005236 lines =<< trim END
5237 vim9script
5238
5239 class A
5240 def _Foo()
5241 enddef
5242 def _Foo()
5243 enddef
5244 endclass
5245 var a = A.new()
5246 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005247 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005248
Ernie Rael03042a22023-11-11 08:53:32 +01005249 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005250 lines =<< trim END
5251 vim9script
5252
5253 class A
5254 def _Foo()
5255 enddef
5256 def Foo()
5257 enddef
5258 endclass
5259 var a = A.new()
5260 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005261 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005262
Ernie Rael03042a22023-11-11 08:53:32 +01005263 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005264 lines =<< trim END
5265 vim9script
5266
5267 class A
5268 def Foo()
5269 enddef
5270 def _Foo()
5271 enddef
5272 endclass
5273 var a = A.new()
5274 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005275 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005276
Ernie Rael03042a22023-11-11 08:53:32 +01005277 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005278 lines =<< trim END
5279 vim9script
5280
5281 class A
5282 def Foo(): number
5283 return 100
5284 enddef
5285 def _Bar(): number
5286 return 200
5287 enddef
5288 def _Baz()
5289 assert_equal(100, this.Foo())
5290 assert_equal(200, this._Bar())
5291 enddef
5292 def T()
5293 this._Baz()
5294 enddef
5295 endclass
5296 var a = A.new()
5297 a.T()
5298 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005299 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005300
Ernie Rael03042a22023-11-11 08:53:32 +01005301 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005302 lines =<< trim END
5303 vim9script
5304
5305 class A
5306 def _Foo(): number
5307 return 100
5308 enddef
5309 endclass
5310 class B
5311 def Foo(): number
5312 var a = A.new()
5313 a._Foo()
5314 enddef
5315 endclass
5316 var b = B.new()
5317 b.Foo()
5318 END
Ernie Rael03042a22023-11-11 08:53:32 +01005319 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005320
Ernie Rael03042a22023-11-11 08:53:32 +01005321 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005322 lines =<< trim END
5323 vim9script
5324 class A
5325 def _Foo(): number
5326 return 1234
5327 enddef
5328 endclass
5329 class B extends A
5330 def Bar()
5331 enddef
5332 endclass
5333 class C extends B
5334 def Baz(): number
5335 return this._Foo()
5336 enddef
5337 endclass
5338 var c = C.new()
5339 assert_equal(1234, c.Baz())
5340 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005341 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005342
Ernie Rael03042a22023-11-11 08:53:32 +01005343 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005344 lines =<< trim END
5345 vim9script
5346 class A
5347 def _Foo(): number
5348 return 1234
5349 enddef
5350 endclass
5351 class B extends A
5352 def Bar()
5353 enddef
5354 endclass
5355 class C extends B
5356 def Baz(): number
5357 enddef
5358 endclass
5359 var c = C.new()
5360 assert_equal(1234, c._Foo())
5361 END
Ernie Rael03042a22023-11-11 08:53:32 +01005362 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005363
5364 # Using "_" prefix in a method name should fail outside of a class
5365 lines =<< trim END
5366 vim9script
5367 def _Foo(): number
5368 return 1234
5369 enddef
5370 var a = _Foo()
5371 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005372 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005373enddef
5374
Ernie Rael03042a22023-11-11 08:53:32 +01005375" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005376def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005377 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005378 var lines =<< trim END
5379 vim9script
5380
5381 class A
5382 static def _Foo(): number
5383 return 1234
5384 enddef
5385 endclass
5386 A._Foo()
5387 END
Ernie Rael03042a22023-11-11 08:53:32 +01005388 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005389
Ernie Rael03042a22023-11-11 08:53:32 +01005390 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005391 lines =<< trim END
5392 vim9script
5393
5394 class A
5395 static def _Foo(): number
5396 return 1234
5397 enddef
5398 endclass
5399 def T()
5400 A._Foo()
5401 enddef
5402 T()
5403 END
Ernie Rael03042a22023-11-11 08:53:32 +01005404 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005405
Ernie Rael03042a22023-11-11 08:53:32 +01005406 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005407 lines =<< trim END
5408 vim9script
5409
5410 class A
5411 static def _Foo(): number
5412 return 1234
5413 enddef
5414 endclass
5415 var a = A.new()
5416 a._Foo()
5417 END
Ernie Rael03042a22023-11-11 08:53:32 +01005418 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005419
Ernie Rael03042a22023-11-11 08:53:32 +01005420 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005421 lines =<< trim END
5422 vim9script
5423
5424 class A
5425 static def _Foo(): number
5426 return 1234
5427 enddef
5428 endclass
5429 def T()
5430 var a = A.new()
5431 a._Foo()
5432 enddef
5433 T()
5434 END
Ernie Rael03042a22023-11-11 08:53:32 +01005435 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005436
Ernie Rael03042a22023-11-11 08:53:32 +01005437 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005438 lines =<< trim END
5439 vim9script
5440
5441 class A
5442 static def _Foo(): number
5443 return 1234
5444 enddef
5445 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005446 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005447 enddef
5448 endclass
5449 var a = A.new()
5450 a.Bar()
5451 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005452 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005453
Ernie Rael03042a22023-11-11 08:53:32 +01005454 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005455 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005456 lines =<< trim END
5457 vim9script
5458
5459 class A
5460 static def _Foo1(): number
5461 return 1234
5462 enddef
5463 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005464 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005465 enddef
5466 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005467 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005468 enddef
5469 endclass
5470 var a = A.new()
5471 a.Bar()
5472 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005473 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005474
Ernie Rael03042a22023-11-11 08:53:32 +01005475 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005476 lines =<< trim END
5477 vim9script
5478
5479 class A
5480 static def _Foo()
5481 enddef
5482 static def Foo()
5483 enddef
5484 endclass
5485 var a = A.new()
5486 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005487 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005488
Ernie Rael03042a22023-11-11 08:53:32 +01005489 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005490 lines =<< trim END
5491 vim9script
5492
5493 class A
5494 static def _Foo(): number
5495 return 1234
5496 enddef
5497 endclass
5498 class B
5499 def Foo(): number
5500 return A._Foo()
5501 enddef
5502 endclass
5503 var b = B.new()
5504 assert_equal(1234, b.Foo())
5505 END
Ernie Rael03042a22023-11-11 08:53:32 +01005506 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005507
Ernie Rael03042a22023-11-11 08:53:32 +01005508 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005509 lines =<< trim END
5510 vim9script
5511 class A
5512 static def _Foo(): number
5513 return 1234
5514 enddef
5515 endclass
5516 class B extends A
5517 def Bar()
5518 enddef
5519 endclass
5520 class C extends B
5521 def Baz(): number
5522 return A._Foo()
5523 enddef
5524 endclass
5525 var c = C.new()
5526 assert_equal(1234, c.Baz())
5527 END
Ernie Rael03042a22023-11-11 08:53:32 +01005528 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005529
Ernie Rael03042a22023-11-11 08:53:32 +01005530 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005531 lines =<< trim END
5532 vim9script
5533 class A
5534 static def _Foo(): number
5535 return 1234
5536 enddef
5537 endclass
5538 class B extends A
5539 def Bar()
5540 enddef
5541 endclass
5542 class C extends B
5543 static def Baz(): number
5544 return A._Foo()
5545 enddef
5546 endclass
5547 assert_equal(1234, C.Baz())
5548 END
Ernie Rael03042a22023-11-11 08:53:32 +01005549 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005550
Ernie Rael03042a22023-11-11 08:53:32 +01005551 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005552 lines =<< trim END
5553 vim9script
5554 class A
5555 static def _Foo(): number
5556 return 1234
5557 enddef
5558 endclass
5559 class B extends A
5560 def Bar()
5561 enddef
5562 endclass
5563 class C extends B
5564 def Baz(): number
5565 enddef
5566 endclass
5567 var c = C.new()
5568 assert_equal(1234, C._Foo())
5569 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005570 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005571enddef
5572
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005573" Test for using the return value of a class/object method as a function
5574" argument.
5575def Test_objmethod_funcarg()
5576 var lines =<< trim END
5577 vim9script
5578
5579 class C
5580 def Foo(): string
5581 return 'foo'
5582 enddef
5583 endclass
5584
5585 def Bar(a: number, s: string): string
5586 return s
5587 enddef
5588
5589 def Baz(c: C)
5590 assert_equal('foo', Bar(10, c.Foo()))
5591 enddef
5592
5593 var t = C.new()
5594 Baz(t)
5595 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005596 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005597
5598 lines =<< trim END
5599 vim9script
5600
5601 class C
5602 static def Foo(): string
5603 return 'foo'
5604 enddef
5605 endclass
5606
5607 def Bar(a: number, s: string): string
5608 return s
5609 enddef
5610
5611 def Baz()
5612 assert_equal('foo', Bar(10, C.Foo()))
5613 enddef
5614
5615 Baz()
5616 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005617 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005618enddef
5619
Ernie Raelcf138d42023-09-06 20:45:03 +02005620def Test_static_inheritence()
5621 # subclasses get their own static copy
5622 var lines =<< trim END
5623 vim9script
5624
5625 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005626 static var _svar: number
5627 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005628 def new()
5629 _svar = 1
5630 this._mvar = 101
5631 enddef
5632 def AccessObject(): number
5633 return this._mvar
5634 enddef
5635 def AccessStaticThroughObject(): number
5636 return _svar
5637 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005638 endclass
5639
5640 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005641 def new()
5642 this._mvar = 102
5643 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005644 endclass
5645
5646 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005647 def new()
5648 this._mvar = 103
5649 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005650
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005651 def AccessPrivateStaticThroughClassName(): number
5652 assert_equal(1, A._svar)
5653 return 444
5654 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005655 endclass
5656
5657 var oa = A.new()
5658 var ob = B.new()
5659 var oc = C.new()
5660 assert_equal(101, oa.AccessObject())
5661 assert_equal(102, ob.AccessObject())
5662 assert_equal(103, oc.AccessObject())
5663
Ernie Rael03042a22023-11-11 08:53:32 +01005664 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005665
5666 # verify object properly resolves to correct static
5667 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005668 assert_equal(1, ob.AccessStaticThroughObject())
5669 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005670 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005671 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005672enddef
5673
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005674" Test for declaring duplicate object and class members
5675def Test_dup_member_variable()
5676 # Duplicate member variable
5677 var lines =<< trim END
5678 vim9script
5679 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005680 var val = 10
5681 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005682 endclass
5683 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005684 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005685
Ernie Rael03042a22023-11-11 08:53:32 +01005686 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005687 lines =<< trim END
5688 vim9script
5689 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005690 var _val = 10
5691 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005692 endclass
5693 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005694 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005695
5696 # Duplicate public member variable
5697 lines =<< trim END
5698 vim9script
5699 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005700 public var val = 10
5701 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005702 endclass
5703 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005704 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005705
Ernie Rael03042a22023-11-11 08:53:32 +01005706 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005707 lines =<< trim END
5708 vim9script
5709 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005710 var val = 10
5711 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005712 endclass
5713 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005714 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005715
Ernie Rael03042a22023-11-11 08:53:32 +01005716 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005717 lines =<< trim END
5718 vim9script
5719 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005720 var _val = 20
5721 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005722 endclass
5723 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005724 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005725
5726 # Duplicate class member variable
5727 lines =<< trim END
5728 vim9script
5729 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005730 static var s: string = "abc"
5731 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005732 endclass
5733 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005734 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005735
Ernie Rael03042a22023-11-11 08:53:32 +01005736 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005737 lines =<< trim END
5738 vim9script
5739 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005740 public static var s: string = "abc"
5741 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005742 endclass
5743 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005744 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005745
5746 # Duplicate class and object member variable
5747 lines =<< trim END
5748 vim9script
5749 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005750 static var val = 10
5751 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005752 def new()
5753 enddef
5754 endclass
5755 var c = C.new()
5756 assert_equal(10, C.val)
5757 assert_equal(20, c.val)
5758 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005759 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005760
5761 # Duplicate object member variable in a derived class
5762 lines =<< trim END
5763 vim9script
5764 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005765 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005766 endclass
5767 class B extends A
5768 endclass
5769 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005770 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005771 endclass
5772 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005773 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005774
Ernie Rael03042a22023-11-11 08:53:32 +01005775 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005776 lines =<< trim END
5777 vim9script
5778 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005779 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005780 endclass
5781 class B extends A
5782 endclass
5783 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005784 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005785 endclass
5786 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005787 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005788
Ernie Rael03042a22023-11-11 08:53:32 +01005789 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005790 lines =<< trim END
5791 vim9script
5792 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005793 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005794 endclass
5795 class B extends A
5796 endclass
5797 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005798 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005799 endclass
5800 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005801 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005802
5803 # Duplicate object member variable in a derived class
5804 lines =<< trim END
5805 vim9script
5806 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005807 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005808 endclass
5809 class B extends A
5810 endclass
5811 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005812 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005813 endclass
5814 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005815 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005816
5817 # Two member variables with a common prefix
5818 lines =<< trim END
5819 vim9script
5820 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005821 public static var svar2: number
5822 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005823 endclass
5824 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005825 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005826enddef
5827
Ernie Rael03042a22023-11-11 08:53:32 +01005828" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005829def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005830 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005831 var lines =<< trim END
5832 vim9script
5833 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005834 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005835 def GetVal(): number
5836 return this._val
5837 enddef
5838 endclass
5839 def T()
5840 var a = A.new()
5841 a._val = 20
5842 enddef
5843 T()
5844 END
Ernie Rael03042a22023-11-11 08:53:32 +01005845 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005846
Ernie Rael03042a22023-11-11 08:53:32 +01005847 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005848 lines =<< trim END
5849 vim9script
5850 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005851 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005852 endclass
5853 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005854 var a = A.new()
5855 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005856 enddef
5857 T()
5858 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005859 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005860
Ernie Rael03042a22023-11-11 08:53:32 +01005861 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005862 lines =<< trim END
5863 vim9script
5864 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005865 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005866 endclass
5867 def T()
5868 var a = A.new()
5869 var x = a._val
5870 enddef
5871 T()
5872 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005873 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005874
Ernie Rael03042a22023-11-11 08:53:32 +01005875 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005876 lines =<< trim END
5877 vim9script
5878 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005879 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005880 endclass
5881 def T()
5882 var a = A.new()
5883 a._val = 3
5884 enddef
5885 T()
5886 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005887 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005888
Ernie Rael03042a22023-11-11 08:53:32 +01005889 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005890 lines =<< trim END
5891 vim9script
5892 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005893 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005894 endclass
5895 def T()
5896 var x = A._val
5897 enddef
5898 T()
5899 END
Ernie Rael03042a22023-11-11 08:53:32 +01005900 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005901
Ernie Rael03042a22023-11-11 08:53:32 +01005902 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005903 lines =<< trim END
5904 vim9script
5905 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005906 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005907 endclass
5908 def T()
5909 A._val = 3
5910 enddef
5911 T()
5912 END
Ernie Rael03042a22023-11-11 08:53:32 +01005913 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005914enddef
5915
5916" Test for changing the member access of an interface in a implementation class
5917def Test_change_interface_member_access()
5918 var lines =<< trim END
5919 vim9script
5920 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005921 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005922 endinterface
5923 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005924 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005925 endclass
5926 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005927 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005928
5929 lines =<< trim END
5930 vim9script
5931 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005932 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005933 endinterface
5934 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005935 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005936 endclass
5937 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005938 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005939enddef
5940
5941" Test for trying to change a readonly member from a def function
5942def Test_readonly_member_change_in_def_func()
5943 var lines =<< trim END
5944 vim9script
5945 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005946 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005947 endclass
5948 def T()
5949 var a = A.new()
5950 a.val = 20
5951 enddef
5952 T()
5953 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005954 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005955enddef
5956
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005957" Test for reading and writing a class member from a def function
5958def Test_modify_class_member_from_def_function()
5959 var lines =<< trim END
5960 vim9script
5961 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005962 var var1: number = 10
5963 public static var var2: list<number> = [1, 2]
5964 public static var var3: dict<number> = {a: 1, b: 2}
5965 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005966 endclass
5967 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005968 assert_equal([1, 2], A.var2)
5969 assert_equal({a: 1, b: 2}, A.var3)
5970 A.var2 = [3, 4]
5971 A.var3 = {c: 3, d: 4}
5972 assert_equal([3, 4], A.var2)
5973 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005974 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005975 enddef
5976 T()
5977 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005978 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005979enddef
5980
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005981" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005982def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005983 var lines =<< trim END
5984 vim9script
5985 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005986 public static var svar1: list<number> = [1]
5987 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005988 endclass
5989
5990 A.svar1->add(3)
5991 A.svar2->add(4)
5992 assert_equal([1, 3], A.svar1)
5993 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005994
5995 def Foo()
5996 A.svar1->add(7)
5997 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005998 assert_equal([1, 3, 7], A.svar1)
5999 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006000 enddef
6001 Foo()
6002 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006003 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006004
6005 # Cannot read from a class variable using an object in script context
6006 lines =<< trim END
6007 vim9script
6008 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006009 public var var1: number
6010 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006011 endclass
6012
6013 var a = A.new()
6014 echo a.svar2
6015 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006016 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006017
6018 # Cannot write to a class variable using an object in script context
6019 lines =<< trim END
6020 vim9script
6021 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006022 public var var1: number
6023 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006024 endclass
6025
6026 var a = A.new()
6027 a.svar2 = [2]
6028 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006029 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006030
6031 # Cannot read from a class variable using an object in def method context
6032 lines =<< trim END
6033 vim9script
6034 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006035 public var var1: number
6036 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006037 endclass
6038
6039 def T()
6040 var a = A.new()
6041 echo a.svar2
6042 enddef
6043 T()
6044 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006045 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006046
6047 # Cannot write to a class variable using an object in def method context
6048 lines =<< trim END
6049 vim9script
6050 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006051 public var var1: number
6052 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006053 endclass
6054
6055 def T()
6056 var a = A.new()
6057 a.svar2 = [2]
6058 enddef
6059 T()
6060 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006061 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006062enddef
6063
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006064" Test for using a interface method using a child object
6065def Test_interface_method_from_child()
6066 var lines =<< trim END
6067 vim9script
6068
6069 interface A
6070 def Foo(): string
6071 endinterface
6072
6073 class B implements A
6074 def Foo(): string
6075 return 'foo'
6076 enddef
6077 endclass
6078
6079 class C extends B
6080 def Bar(): string
6081 return 'bar'
6082 enddef
6083 endclass
6084
6085 def T1(a: A)
6086 assert_equal('foo', a.Foo())
6087 enddef
6088
6089 def T2(b: B)
6090 assert_equal('foo', b.Foo())
6091 enddef
6092
6093 var c = C.new()
6094 T1(c)
6095 T2(c)
6096 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006097 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006098enddef
6099
6100" Test for using an interface method using a child object when it is overridden
6101" by the child class.
6102" FIXME: This test fails.
6103" def Test_interface_overridden_method_from_child()
6104" var lines =<< trim END
6105" vim9script
6106"
6107" interface A
6108" def Foo(): string
6109" endinterface
6110"
6111" class B implements A
6112" def Foo(): string
6113" return 'b-foo'
6114" enddef
6115" endclass
6116"
6117" class C extends B
6118" def Bar(): string
6119" return 'bar'
6120" enddef
6121" def Foo(): string
6122" return 'c-foo'
6123" enddef
6124" endclass
6125"
6126" def T1(a: A)
6127" assert_equal('c-foo', a.Foo())
6128" enddef
6129"
6130" def T2(b: B)
6131" assert_equal('c-foo', b.Foo())
6132" enddef
6133"
6134" var c = C.new()
6135" T1(c)
6136" T2(c)
6137" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006138" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006139" enddef
6140
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006141" Test for abstract methods
6142def Test_abstract_method()
6143 # Use two abstract methods
6144 var lines =<< trim END
6145 vim9script
6146 abstract class A
6147 def M1(): number
6148 return 10
6149 enddef
6150 abstract def M2(): number
6151 abstract def M3(): number
6152 endclass
6153 class B extends A
6154 def M2(): number
6155 return 20
6156 enddef
6157 def M3(): number
6158 return 30
6159 enddef
6160 endclass
6161 var b = B.new()
6162 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
6163 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006164 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006165
6166 # Don't define an abstract method
6167 lines =<< trim END
6168 vim9script
6169 abstract class A
6170 abstract def Foo()
6171 endclass
6172 class B extends A
6173 endclass
6174 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006175 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006176
6177 # Use abstract method in a concrete class
6178 lines =<< trim END
6179 vim9script
6180 class A
6181 abstract def Foo()
6182 endclass
6183 class B extends A
6184 endclass
6185 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006186 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006187
6188 # Use abstract method in an interface
6189 lines =<< trim END
6190 vim9script
6191 interface A
6192 abstract def Foo()
6193 endinterface
6194 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006195 def Foo()
6196 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006197 endclass
6198 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01006199 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6200
6201 # Use abstract static method in an interface
6202 lines =<< trim END
6203 vim9script
6204 interface A
6205 abstract static def Foo()
6206 enddef
6207 endinterface
6208 END
6209 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6210
6211 # Use abstract static variable in an interface
6212 lines =<< trim END
6213 vim9script
6214 interface A
6215 abstract static foo: number = 10
6216 endinterface
6217 END
6218 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006219
6220 # Abbreviate the "abstract" keyword
6221 lines =<< trim END
6222 vim9script
6223 class A
6224 abs def Foo()
6225 endclass
6226 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006227 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006228
6229 # Use "abstract" with a member variable
6230 lines =<< trim END
6231 vim9script
6232 abstract class A
6233 abstract this.val = 10
6234 endclass
6235 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006236 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006237
6238 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01006239 lines =<< trim END
6240 vim9script
6241 abstract class A
6242 abstract static def Foo(): number
6243 endclass
6244 END
6245 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006246
6247 # Type mismatch between abstract method and concrete method
6248 lines =<< trim END
6249 vim9script
6250 abstract class A
6251 abstract def Foo(a: string, b: number): list<number>
6252 endclass
6253 class B extends A
6254 def Foo(a: number, b: string): list<string>
6255 return []
6256 enddef
6257 endclass
6258 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006259 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 +02006260
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006261 # Invoke an abstract method from a def function
6262 lines =<< trim END
6263 vim9script
6264 abstract class A
6265 abstract def Foo(): list<number>
6266 endclass
6267 class B extends A
6268 def Foo(): list<number>
6269 return [3, 5]
6270 enddef
6271 endclass
6272 def Bar(c: B)
6273 assert_equal([3, 5], c.Foo())
6274 enddef
6275 var b = B.new()
6276 Bar(b)
6277 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006278 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006279
6280 # Use a static method in an abstract class
6281 lines =<< trim END
6282 vim9script
6283 abstract class A
6284 static def Foo(): string
6285 return 'foo'
6286 enddef
6287 endclass
6288 assert_equal('foo', A.Foo())
6289 END
6290 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006291enddef
6292
6293" Test for calling a class method from a subclass
6294def Test_class_method_call_from_subclass()
6295 # class method call from a subclass
6296 var lines =<< trim END
6297 vim9script
6298
6299 class A
6300 static def Foo()
6301 echo "foo"
6302 enddef
6303 endclass
6304
6305 class B extends A
6306 def Bar()
6307 Foo()
6308 enddef
6309 endclass
6310
6311 var b = B.new()
6312 b.Bar()
6313 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006314 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006315enddef
6316
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006317" Test for calling a class method using an object in a def function context and
6318" script context.
6319def Test_class_method_call_using_object()
6320 # script context
6321 var lines =<< trim END
6322 vim9script
6323 class A
6324 static def Foo(): list<string>
6325 return ['a', 'b']
6326 enddef
6327 def Bar()
6328 assert_equal(['a', 'b'], A.Foo())
6329 assert_equal(['a', 'b'], Foo())
6330 enddef
6331 endclass
6332
6333 def T()
6334 assert_equal(['a', 'b'], A.Foo())
6335 var t_a = A.new()
6336 t_a.Bar()
6337 enddef
6338
6339 assert_equal(['a', 'b'], A.Foo())
6340 var a = A.new()
6341 a.Bar()
6342 T()
6343 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006344 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006345
6346 # script context
6347 lines =<< trim END
6348 vim9script
6349 class A
6350 static def Foo(): string
6351 return 'foo'
6352 enddef
6353 endclass
6354
6355 var a = A.new()
6356 assert_equal('foo', a.Foo())
6357 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006358 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006359
6360 # def function context
6361 lines =<< trim END
6362 vim9script
6363 class A
6364 static def Foo(): string
6365 return 'foo'
6366 enddef
6367 endclass
6368
6369 def T()
6370 var a = A.new()
6371 assert_equal('foo', a.Foo())
6372 enddef
6373 T()
6374 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006375 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006376enddef
6377
6378def Test_class_variable()
6379 var lines =<< trim END
6380 vim9script
6381
6382 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006383 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006384 static def ClassFunc()
6385 assert_equal(10, val)
6386 enddef
6387 def ObjFunc()
6388 assert_equal(10, val)
6389 enddef
6390 endclass
6391
6392 class B extends A
6393 endclass
6394
6395 assert_equal(10, A.val)
6396 A.ClassFunc()
6397 var a = A.new()
6398 a.ObjFunc()
6399 var b = B.new()
6400 b.ObjFunc()
6401
6402 def T1(a1: A)
6403 a1.ObjFunc()
6404 A.ClassFunc()
6405 enddef
6406 T1(b)
6407
6408 A.val = 20
6409 assert_equal(20, A.val)
6410 END
6411 v9.CheckSourceSuccess(lines)
6412
6413 # Modifying a parent class variable from a child class method
6414 lines =<< trim END
6415 vim9script
6416
6417 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006418 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006419 endclass
6420
6421 class B extends A
6422 static def ClassFunc()
6423 val = 20
6424 enddef
6425 endclass
6426 B.ClassFunc()
6427 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006428 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006429
6430 # Reading a parent class variable from a child class method
6431 lines =<< trim END
6432 vim9script
6433
6434 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006435 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006436 endclass
6437
6438 class B extends A
6439 static def ClassFunc()
6440 var i = val
6441 enddef
6442 endclass
6443 B.ClassFunc()
6444 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006445 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006446
6447 # Modifying a parent class variable from a child object method
6448 lines =<< trim END
6449 vim9script
6450
6451 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006452 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006453 endclass
6454
6455 class B extends A
6456 def ObjFunc()
6457 val = 20
6458 enddef
6459 endclass
6460 var b = B.new()
6461 b.ObjFunc()
6462 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006463 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006464
6465 # Reading a parent class variable from a child object method
6466 lines =<< trim END
6467 vim9script
6468
6469 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006470 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006471 endclass
6472
6473 class B extends A
6474 def ObjFunc()
6475 var i = val
6476 enddef
6477 endclass
6478 var b = B.new()
6479 b.ObjFunc()
6480 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006481 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006482
6483 # Modifying a class variable using an object at script level
6484 lines =<< trim END
6485 vim9script
6486
6487 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006488 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006489 endclass
6490 var a = A.new()
6491 a.val = 20
6492 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006493 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006494
6495 # Reading a class variable using an object at script level
6496 lines =<< trim END
6497 vim9script
6498
6499 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006500 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006501 endclass
6502 var a = A.new()
6503 var i = a.val
6504 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006505 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006506
6507 # Modifying a class variable using an object at function level
6508 lines =<< trim END
6509 vim9script
6510
6511 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006512 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006513 endclass
6514
6515 def T()
6516 var a = A.new()
6517 a.val = 20
6518 enddef
6519 T()
6520 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006521 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006522
6523 # Reading a class variable using an object at function level
6524 lines =<< trim END
6525 vim9script
6526
6527 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006528 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006529 endclass
6530 def T()
6531 var a = A.new()
6532 var i = a.val
6533 enddef
6534 T()
6535 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006536 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006537
6538 # Use old implicit var declaration syntax (without initialization)
6539 lines =<< trim END
6540 vim9script
6541
6542 class A
6543 static val: number
6544 endclass
6545 END
6546 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6547
6548 # Use old implicit var declaration syntax (with initialization)
6549 lines =<< trim END
6550 vim9script
6551
6552 class A
6553 static val: number = 10
6554 endclass
6555 END
6556 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6557
6558 # Use old implicit var declaration syntax (type inferred)
6559 lines =<< trim END
6560 vim9script
6561
6562 class A
6563 static val = 10
6564 endclass
6565 END
6566 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6567
6568 # Missing ":var" in "var" class variable declaration (without initialization)
6569 lines =<< trim END
6570 vim9script
6571
6572 class A
6573 static var: number
6574 endclass
6575 END
6576 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6577
6578 # Missing ":var" in "var" class variable declaration (with initialization)
6579 lines =<< trim END
6580 vim9script
6581
6582 class A
6583 static var: number = 10
6584 endclass
6585 END
6586 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6587
6588 # Missing ":var" in "var" class variable declaration (type inferred)
6589 lines =<< trim END
6590 vim9script
6591
6592 class A
6593 static var = 10
6594 endclass
6595 END
6596 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6597
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006598enddef
6599
6600" Test for using a duplicate class method and class variable in a child class
6601def Test_dup_class_member()
6602 # duplicate class variable, class method and overridden object method
6603 var lines =<< trim END
6604 vim9script
6605 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006606 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006607 static def Check()
6608 assert_equal(100, sval)
6609 enddef
6610 def GetVal(): number
6611 return sval
6612 enddef
6613 endclass
6614
6615 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006616 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006617 static def Check()
6618 assert_equal(200, sval)
6619 enddef
6620 def GetVal(): number
6621 return sval
6622 enddef
6623 endclass
6624
6625 def T1(aa: A): number
6626 return aa.GetVal()
6627 enddef
6628
6629 def T2(bb: B): number
6630 return bb.GetVal()
6631 enddef
6632
6633 assert_equal(100, A.sval)
6634 assert_equal(200, B.sval)
6635 var a = A.new()
6636 assert_equal(100, a.GetVal())
6637 var b = B.new()
6638 assert_equal(200, b.GetVal())
6639 assert_equal(200, T1(b))
6640 assert_equal(200, T2(b))
6641 END
6642 v9.CheckSourceSuccess(lines)
6643
6644 # duplicate class variable and class method
6645 lines =<< trim END
6646 vim9script
6647 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006648 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006649 static def Check()
6650 assert_equal(100, sval)
6651 enddef
6652 def GetVal(): number
6653 return sval
6654 enddef
6655 endclass
6656
6657 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006658 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006659 static def Check()
6660 assert_equal(200, sval)
6661 enddef
6662 endclass
6663
6664 def T1(aa: A): number
6665 return aa.GetVal()
6666 enddef
6667
6668 def T2(bb: B): number
6669 return bb.GetVal()
6670 enddef
6671
6672 assert_equal(100, A.sval)
6673 assert_equal(200, B.sval)
6674 var a = A.new()
6675 assert_equal(100, a.GetVal())
6676 var b = B.new()
6677 assert_equal(100, b.GetVal())
6678 assert_equal(100, T1(b))
6679 assert_equal(100, T2(b))
6680 END
6681 v9.CheckSourceSuccess(lines)
6682enddef
6683
6684" Test for calling an instance method using the class
6685def Test_instance_method_call_using_class()
6686 # Invoke an object method using a class in script context
6687 var lines =<< trim END
6688 vim9script
6689 class A
6690 def Foo()
6691 echo "foo"
6692 enddef
6693 endclass
6694 A.Foo()
6695 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006696 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006697
6698 # Invoke an object method using a class in def function context
6699 lines =<< trim END
6700 vim9script
6701 class A
6702 def Foo()
6703 echo "foo"
6704 enddef
6705 endclass
6706 def T()
6707 A.Foo()
6708 enddef
6709 T()
6710 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006711 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006712enddef
6713
6714" Test for duplicate class method and instance method
6715def Test_dup_classmethod_objmethod()
6716 # Duplicate instance method
6717 var lines =<< trim END
6718 vim9script
6719 class A
6720 static def Foo()
6721 enddef
6722 def Foo()
6723 enddef
6724 endclass
6725 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006726 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006727
Ernie Rael03042a22023-11-11 08:53:32 +01006728 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006729 lines =<< trim END
6730 vim9script
6731 class A
6732 static def Foo()
6733 enddef
6734 def _Foo()
6735 enddef
6736 endclass
6737 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006738 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006739
6740 # Duplicate class method
6741 lines =<< trim END
6742 vim9script
6743 class A
6744 def Foo()
6745 enddef
6746 static def Foo()
6747 enddef
6748 endclass
6749 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006750 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006751
Ernie Rael03042a22023-11-11 08:53:32 +01006752 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006753 lines =<< trim END
6754 vim9script
6755 class A
6756 def Foo()
6757 enddef
6758 static def _Foo()
6759 enddef
6760 endclass
6761 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006762 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006763
Ernie Rael03042a22023-11-11 08:53:32 +01006764 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006765 lines =<< trim END
6766 vim9script
6767 class A
6768 def _Foo()
6769 enddef
6770 static def _Foo()
6771 enddef
6772 endclass
6773 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006774 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006775enddef
6776
6777" Test for an instance method access level comparison with parent instance
6778" methods.
6779def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006780 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006781 var lines =<< trim END
6782 vim9script
6783 class A
6784 def Foo()
6785 enddef
6786 endclass
6787 class B extends A
6788 endclass
6789 class C extends B
6790 def _Foo()
6791 enddef
6792 endclass
6793 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006794 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006795
6796 # Public method in subclass
6797 lines =<< trim END
6798 vim9script
6799 class A
6800 def _Foo()
6801 enddef
6802 endclass
6803 class B extends A
6804 endclass
6805 class C extends B
6806 def Foo()
6807 enddef
6808 endclass
6809 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006810 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006811enddef
6812
6813def Test_extend_empty_class()
6814 var lines =<< trim END
6815 vim9script
6816 class A
6817 endclass
6818 class B extends A
6819 endclass
6820 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006821 public static var rw_class_var = 1
6822 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006823 static def ClassMethod(): number
6824 return 3
6825 enddef
6826 def ObjMethod(): number
6827 return 4
6828 enddef
6829 endclass
6830 assert_equal(1, C.rw_class_var)
6831 assert_equal(3, C.ClassMethod())
6832 var c = C.new()
6833 assert_equal(2, c.rw_obj_var)
6834 assert_equal(4, c.ObjMethod())
6835 END
6836 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006837enddef
6838
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006839" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006840" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006841def Test_interface_with_unsupported_members()
6842 var lines =<< trim END
6843 vim9script
6844 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006845 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006846 endinterface
6847 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006848 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006849
6850 lines =<< trim END
6851 vim9script
6852 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006853 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006854 endinterface
6855 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006856 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006857
6858 lines =<< trim END
6859 vim9script
6860 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006861 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006862 endinterface
6863 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006864 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006865
6866 lines =<< trim END
6867 vim9script
6868 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006869 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006870 endinterface
6871 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006872 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006873
6874 lines =<< trim END
6875 vim9script
6876 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006877 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006878 endinterface
6879 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006880 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006881
6882 lines =<< trim END
6883 vim9script
6884 interface A
6885 static def Foo(d: dict<any>): list<string>
6886 endinterface
6887 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006888 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006889
6890 lines =<< trim END
6891 vim9script
6892 interface A
6893 static def _Foo(d: dict<any>): list<string>
6894 endinterface
6895 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006896 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006897
6898 lines =<< trim END
6899 vim9script
6900 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006901 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006902 endinterface
6903 END
Ernie Rael03042a22023-11-11 08:53:32 +01006904 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006905
6906 lines =<< trim END
6907 vim9script
6908 interface A
6909 def _Foo(d: dict<any>): list<string>
6910 endinterface
6911 END
Ernie Rael03042a22023-11-11 08:53:32 +01006912 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006913enddef
6914
6915" Test for extending an interface
6916def Test_extend_interface()
6917 var lines =<< trim END
6918 vim9script
6919 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006920 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006921 def Foo()
6922 endinterface
6923 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006924 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006925 def Bar()
6926 endinterface
6927 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006928 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006929 def Foo()
6930 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006931 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006932 def Bar()
6933 enddef
6934 endclass
6935 END
6936 v9.CheckSourceSuccess(lines)
6937
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006938 # extending empty interface
6939 lines =<< trim END
6940 vim9script
6941 interface A
6942 endinterface
6943 interface B extends A
6944 endinterface
6945 class C implements B
6946 endclass
6947 END
6948 v9.CheckSourceSuccess(lines)
6949
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006950 lines =<< trim END
6951 vim9script
6952 interface A
6953 def Foo()
6954 endinterface
6955 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006956 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006957 endinterface
6958 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006959 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006960 endclass
6961 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006962 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006963
6964 lines =<< trim END
6965 vim9script
6966 interface A
6967 def Foo()
6968 endinterface
6969 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006970 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006971 endinterface
6972 class C implements A, B
6973 def Foo()
6974 enddef
6975 endclass
6976 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006977 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006978
6979 # interface cannot extend a class
6980 lines =<< trim END
6981 vim9script
6982 class A
6983 endclass
6984 interface B extends A
6985 endinterface
6986 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006987 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006988
6989 # class cannot extend an interface
6990 lines =<< trim END
6991 vim9script
6992 interface A
6993 endinterface
6994 class B extends A
6995 endclass
6996 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006997 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006998
6999 # interface cannot implement another interface
7000 lines =<< trim END
7001 vim9script
7002 interface A
7003 endinterface
7004 interface B implements A
7005 endinterface
7006 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007007 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007008
7009 # interface cannot extend multiple interfaces
7010 lines =<< trim END
7011 vim9script
7012 interface A
7013 endinterface
7014 interface B
7015 endinterface
7016 interface C extends A, B
7017 endinterface
7018 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007019 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007020
7021 # Variable type in an extended interface is of different type
7022 lines =<< trim END
7023 vim9script
7024 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007025 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007026 endinterface
7027 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007028 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007029 endinterface
7030 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007031 var val1: string
7032 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007033 endinterface
7034 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007035 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007036enddef
7037
7038" Test for a child class implementing an interface when some of the methods are
7039" defined in the parent class.
7040def Test_child_class_implements_interface()
7041 var lines =<< trim END
7042 vim9script
7043
7044 interface Intf
7045 def F1(): list<list<number>>
7046 def F2(): list<list<number>>
7047 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01007048 var var1: list<dict<number>>
7049 var var2: list<dict<number>>
7050 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007051 endinterface
7052
7053 class A
7054 def A1()
7055 enddef
7056 def F3(): list<list<number>>
7057 return [[3]]
7058 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007059 var v1: list<list<number>> = [[0]]
7060 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007061 endclass
7062
7063 class B extends A
7064 def B1()
7065 enddef
7066 def F2(): list<list<number>>
7067 return [[2]]
7068 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007069 var v2: list<list<number>> = [[0]]
7070 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007071 endclass
7072
7073 class C extends B implements Intf
7074 def C1()
7075 enddef
7076 def F1(): list<list<number>>
7077 return [[1]]
7078 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007079 var v3: list<list<number>> = [[0]]
7080 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007081 endclass
7082
7083 def T(if: Intf)
7084 assert_equal([[1]], if.F1())
7085 assert_equal([[2]], if.F2())
7086 assert_equal([[3]], if.F3())
7087 assert_equal([{a: 10}], if.var1)
7088 assert_equal([{b: 20}], if.var2)
7089 assert_equal([{c: 30}], if.var3)
7090 enddef
7091
7092 var c = C.new()
7093 T(c)
7094 assert_equal([[1]], c.F1())
7095 assert_equal([[2]], c.F2())
7096 assert_equal([[3]], c.F3())
7097 assert_equal([{a: 10}], c.var1)
7098 assert_equal([{b: 20}], c.var2)
7099 assert_equal([{c: 30}], c.var3)
7100 END
7101 v9.CheckSourceSuccess(lines)
7102
7103 # One of the interface methods is not found
7104 lines =<< trim END
7105 vim9script
7106
7107 interface Intf
7108 def F1()
7109 def F2()
7110 def F3()
7111 endinterface
7112
7113 class A
7114 def A1()
7115 enddef
7116 endclass
7117
7118 class B extends A
7119 def B1()
7120 enddef
7121 def F2()
7122 enddef
7123 endclass
7124
7125 class C extends B implements Intf
7126 def C1()
7127 enddef
7128 def F1()
7129 enddef
7130 endclass
7131 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007132 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007133
7134 # One of the interface methods is of different type
7135 lines =<< trim END
7136 vim9script
7137
7138 interface Intf
7139 def F1()
7140 def F2()
7141 def F3()
7142 endinterface
7143
7144 class A
7145 def F3(): number
7146 return 0
7147 enddef
7148 def A1()
7149 enddef
7150 endclass
7151
7152 class B extends A
7153 def B1()
7154 enddef
7155 def F2()
7156 enddef
7157 endclass
7158
7159 class C extends B implements Intf
7160 def C1()
7161 enddef
7162 def F1()
7163 enddef
7164 endclass
7165 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007166 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007167
7168 # One of the interface variables is not present
7169 lines =<< trim END
7170 vim9script
7171
7172 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007173 var var1: list<dict<number>>
7174 var var2: list<dict<number>>
7175 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007176 endinterface
7177
7178 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007179 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007180 endclass
7181
7182 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007183 var v2: list<list<number>> = [[0]]
7184 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007185 endclass
7186
7187 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007188 var v3: list<list<number>> = [[0]]
7189 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007190 endclass
7191 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007192 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007193
7194 # One of the interface variables is of different type
7195 lines =<< trim END
7196 vim9script
7197
7198 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007199 var var1: list<dict<number>>
7200 var var2: list<dict<number>>
7201 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007202 endinterface
7203
7204 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007205 var v1: list<list<number>> = [[0]]
7206 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007207 endclass
7208
7209 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007210 var v2: list<list<number>> = [[0]]
7211 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007212 endclass
7213
7214 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007215 var v3: list<list<number>> = [[0]]
7216 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007217 endclass
7218 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007219 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 +02007220enddef
7221
7222" Test for extending an interface with duplicate variables and methods
7223def Test_interface_extends_with_dup_members()
7224 var lines =<< trim END
7225 vim9script
7226 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007227 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007228 def Foo1(): number
7229 endinterface
7230 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007231 var n2: number
7232 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007233 def Foo2(): number
7234 def Foo1(): number
7235 endinterface
7236 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007237 var n1 = 10
7238 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007239 def Foo1(): number
7240 return 30
7241 enddef
7242 def Foo2(): number
7243 return 40
7244 enddef
7245 endclass
7246 def T1(a: A)
7247 assert_equal(10, a.n1)
7248 assert_equal(30, a.Foo1())
7249 enddef
7250 def T2(b: B)
7251 assert_equal(10, b.n1)
7252 assert_equal(20, b.n2)
7253 assert_equal(30, b.Foo1())
7254 assert_equal(40, b.Foo2())
7255 enddef
7256 var c = C.new()
7257 T1(c)
7258 T2(c)
7259 END
7260 v9.CheckSourceSuccess(lines)
7261enddef
7262
7263" Test for using "any" type for a variable in a sub-class while it has a
7264" concrete type in the interface
7265def Test_implements_using_var_type_any()
7266 var lines =<< trim END
7267 vim9script
7268 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007269 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007270 endinterface
7271 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007272 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007273 endclass
7274 var b = B.new()
7275 assert_equal([{a: '1'}, {b: '2'}], b.val)
7276 END
7277 v9.CheckSourceSuccess(lines)
7278
7279 # initialize instance variable using a different type
7280 lines =<< trim END
7281 vim9script
7282 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007283 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007284 endinterface
7285 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007286 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007287 endclass
7288 var b = B.new()
7289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007290 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007291enddef
7292
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007293" Test for assigning to a member variable in a nested class
7294def Test_nested_object_assignment()
7295 var lines =<< trim END
7296 vim9script
7297
7298 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007299 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007300 endclass
7301
7302 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007303 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007304 endclass
7305
7306 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007307 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007308 endclass
7309
7310 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007311 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007312 endclass
7313
7314 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007315 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007316 enddef
7317
7318 var d = D.new()
7319 T(d)
7320 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007321 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007322enddef
7323
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007324" Test for calling methods using a null object
7325def Test_null_object_method_call()
7326 # Calling a object method using a null object in script context
7327 var lines =<< trim END
7328 vim9script
7329
7330 class C
7331 def Foo()
7332 assert_report('This method should not be executed')
7333 enddef
7334 endclass
7335
7336 var o: C
7337 o.Foo()
7338 END
7339 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7340
7341 # Calling a object method using a null object in def function context
7342 lines =<< trim END
7343 vim9script
7344
7345 class C
7346 def Foo()
7347 assert_report('This method should not be executed')
7348 enddef
7349 endclass
7350
7351 def T()
7352 var o: C
7353 o.Foo()
7354 enddef
7355 T()
7356 END
7357 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7358
7359 # Calling a object method through another class method using a null object in
7360 # script context
7361 lines =<< trim END
7362 vim9script
7363
7364 class C
7365 def Foo()
7366 assert_report('This method should not be executed')
7367 enddef
7368
7369 static def Bar(o_any: any)
7370 var o_typed: C = o_any
7371 o_typed.Foo()
7372 enddef
7373 endclass
7374
7375 var o: C
7376 C.Bar(o)
7377 END
7378 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7379
7380 # Calling a object method through another class method using a null object in
7381 # def function context
7382 lines =<< trim END
7383 vim9script
7384
7385 class C
7386 def Foo()
7387 assert_report('This method should not be executed')
7388 enddef
7389
7390 static def Bar(o_any: any)
7391 var o_typed: C = o_any
7392 o_typed.Foo()
7393 enddef
7394 endclass
7395
7396 def T()
7397 var o: C
7398 C.Bar(o)
7399 enddef
7400 T()
7401 END
7402 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Ernie Raelbe828252024-07-26 18:37:02 +02007403
7404 # Calling an object method defined in a class that is extended. This differs
7405 # from the previous by invoking ISN_METHODCALL instead of ISN_DCALL.
7406 lines =<< trim END
7407 vim9script
7408
7409 class C0
7410 def F()
7411 enddef
7412 endclass
7413
7414 class C extends C0
7415 endclass
7416
7417 def X()
7418 var o: C0 = null_object
7419 o.F()
7420 enddef
7421 X()
7422 END
7423 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7424
7425 # Getting a function ref an object method.
7426 lines =<< trim END
7427 vim9script
7428
7429 class C0
7430 def F()
7431 enddef
7432 endclass
7433
7434 class C extends C0
7435 endclass
7436
7437 def X()
7438 var o: C0 = null_object
7439 var XXX = o.F
7440 enddef
7441 X()
7442 END
7443 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007444enddef
7445
7446" Test for using a dict as an object member
7447def Test_dict_object_member()
7448 var lines =<< trim END
7449 vim9script
7450
7451 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007452 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007453 def GetState(): dict<number>
7454 return this.state
7455 enddef
7456 endclass
7457
7458 var ctx = Context.new()
7459 ctx.state->extend({a: 1})
7460 ctx.state['b'] = 2
7461 assert_equal({a: 1, b: 2}, ctx.GetState())
7462
7463 def F()
7464 ctx.state['c'] = 3
7465 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7466 enddef
7467 F()
7468 assert_equal(3, ctx.state.c)
7469 ctx.state.c = 4
7470 assert_equal(4, ctx.state.c)
7471 END
7472 v9.CheckSourceSuccess(lines)
7473enddef
7474
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007475" The following test was failing after 9.0.1914. This was caused by using a
7476" freed object from a previous method call.
7477def Test_freed_object_from_previous_method_call()
7478 var lines =<< trim END
7479 vim9script
7480
7481 class Context
7482 endclass
7483
7484 class Result
7485 endclass
7486
7487 def Failure(): Result
7488 return Result.new()
7489 enddef
7490
7491 def GetResult(ctx: Context): Result
7492 return Failure()
7493 enddef
7494
7495 def Test_GetResult()
7496 var ctx = Context.new()
7497 var result = GetResult(ctx)
7498 enddef
7499
7500 Test_GetResult()
7501 END
7502 v9.CheckSourceSuccess(lines)
7503enddef
7504
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007505" Test for duplicate object and class variable
7506def Test_duplicate_variable()
7507 # Object variable name is same as the class variable name
7508 var lines =<< trim END
7509 vim9script
7510 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007511 public static var sval: number
7512 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007513 endclass
7514 var a = A.new()
7515 END
7516 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7517
7518 # Duplicate variable name and calling a class method
7519 lines =<< trim END
7520 vim9script
7521 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007522 public static var sval: number
7523 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007524 def F1()
7525 echo this.sval
7526 enddef
7527 static def F2()
7528 echo sval
7529 enddef
7530 endclass
7531 A.F2()
7532 END
7533 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7534
7535 # Duplicate variable with an empty constructor
7536 lines =<< trim END
7537 vim9script
7538 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007539 public static var sval: number
7540 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007541 def new()
7542 enddef
7543 endclass
7544 var a = A.new()
7545 END
7546 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7547enddef
7548
7549" Test for using a reserved keyword as a variable name
7550def Test_reserved_varname()
7551 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7552 'null_function', 'null_list', 'null_partial', 'null_string',
7553 'null_channel', 'null_job', 'super', 'this']
7554
7555 var lines =<< trim eval END
7556 vim9script
7557 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007558 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007559 endclass
7560 var o = C.new()
7561 END
7562 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7563
7564 lines =<< trim eval END
7565 vim9script
7566 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007567 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007568 def new()
7569 enddef
7570 endclass
7571 var o = C.new()
7572 END
7573 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7574
7575 lines =<< trim eval END
7576 vim9script
7577 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007578 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007579 def new()
7580 enddef
7581 def F()
7582 echo this.{kword}
7583 enddef
7584 endclass
7585 var o = C.new()
7586 o.F()
7587 END
7588 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007589
7590 # class variable name
7591 if kword != 'this'
7592 lines =<< trim eval END
7593 vim9script
7594 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007595 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007596 endclass
7597 END
7598 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7599 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007600 endfor
7601enddef
7602
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007603" Test for checking the type of the arguments and the return value of a object
7604" method in an extended class.
7605def Test_extended_obj_method_type_check()
7606 var lines =<< trim END
7607 vim9script
7608
7609 class A
7610 endclass
7611 class B extends A
7612 endclass
7613 class C extends B
7614 endclass
7615
7616 class Foo
7617 def Doit(p: B): B
7618 return B.new()
7619 enddef
7620 endclass
7621
7622 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007623 def Doit(p: C): B
7624 return B.new()
7625 enddef
7626 endclass
7627 END
7628 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7629
7630 lines =<< trim END
7631 vim9script
7632
7633 class A
7634 endclass
7635 class B extends A
7636 endclass
7637 class C extends B
7638 endclass
7639
7640 class Foo
7641 def Doit(p: B): B
7642 return B.new()
7643 enddef
7644 endclass
7645
7646 class Bar extends Foo
7647 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007648 return C.new()
7649 enddef
7650 endclass
7651 END
7652 v9.CheckSourceSuccess(lines)
7653
7654 lines =<< trim END
7655 vim9script
7656
7657 class A
7658 endclass
7659 class B extends A
7660 endclass
7661 class C extends B
7662 endclass
7663
7664 class Foo
7665 def Doit(p: B): B
7666 return B.new()
7667 enddef
7668 endclass
7669
7670 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007671 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007672 return B.new()
7673 enddef
7674 endclass
7675 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007676 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 +02007677
7678 lines =<< trim END
7679 vim9script
7680
7681 class A
7682 endclass
7683 class B extends A
7684 endclass
7685 class C extends B
7686 endclass
7687
7688 class Foo
7689 def Doit(p: B): B
7690 return B.new()
7691 enddef
7692 endclass
7693
7694 class Bar extends Foo
7695 def Doit(p: B): A
7696 return A.new()
7697 enddef
7698 endclass
7699 END
7700 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 +02007701
7702 # check varargs type mismatch
7703 lines =<< trim END
7704 vim9script
7705
7706 class B
7707 def F(...xxx: list<any>)
7708 enddef
7709 endclass
7710 class C extends B
7711 def F(xxx: list<any>)
7712 enddef
7713 endclass
7714 END
7715 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 +02007716enddef
7717
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007718" Test type checking for class variable in assignments
7719func Test_class_variable_complex_type_check()
7720 " class variable with a specific type. Try assigning a different type at
7721 " script level.
7722 let lines =<< trim END
7723 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007724 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007725 return {}
7726 enddef
7727 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007728 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007729 endclass
7730 test_garbagecollect_now()
7731 A.Fn = "abc"
7732 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007733 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 +02007734
7735 " class variable with a specific type. Try assigning a different type at
7736 " class def method level.
7737 let lines =<< trim END
7738 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007739 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007740 return {}
7741 enddef
7742 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007743 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007744 def Bar()
7745 Fn = "abc"
7746 enddef
7747 endclass
7748 var a = A.new()
7749 test_garbagecollect_now()
7750 a.Bar()
7751 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007752 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 +02007753
7754 " class variable with a specific type. Try assigning a different type at
7755 " script def method level.
7756 let lines =<< trim END
7757 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007758 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007759 return {}
7760 enddef
7761 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007762 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007763 endclass
7764 def Bar()
7765 A.Fn = "abc"
7766 enddef
7767 test_garbagecollect_now()
7768 Bar()
7769 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007770 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 +02007771
7772 " class variable without any type. Should be set to the initialization
7773 " expression type. Try assigning a different type from script level.
7774 let lines =<< trim END
7775 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007776 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007777 return {}
7778 enddef
7779 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007780 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007781 endclass
7782 test_garbagecollect_now()
7783 A.Fn = "abc"
7784 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007785 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 +02007786
7787 " class variable without any type. Should be set to the initialization
7788 " expression type. Try assigning a different type at class def level.
7789 let lines =<< trim END
7790 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007791 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007792 return {}
7793 enddef
7794 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007795 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007796 def Bar()
7797 Fn = "abc"
7798 enddef
7799 endclass
7800 var a = A.new()
7801 test_garbagecollect_now()
7802 a.Bar()
7803 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007804 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 +02007805
7806 " class variable without any type. Should be set to the initialization
7807 " expression type. Try assigning a different type at script def level.
7808 let lines =<< trim END
7809 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007810 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007811 return {}
7812 enddef
7813 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007814 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007815 endclass
7816 def Bar()
7817 A.Fn = "abc"
7818 enddef
7819 test_garbagecollect_now()
7820 Bar()
7821 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007822 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 +02007823
7824 " class variable with 'any" type. Can be assigned different types.
7825 let lines =<< trim END
7826 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007827 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007828 return {}
7829 enddef
7830 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007831 public static var Fn: any = Foo
7832 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007833 endclass
7834 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007835 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007836 A.Fn = "abc"
7837 test_garbagecollect_now()
7838 assert_equal('string', typename(A.Fn))
7839 A.Fn2 = Foo
7840 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007841 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007842 A.Fn2 = "xyz"
7843 test_garbagecollect_now()
7844 assert_equal('string', typename(A.Fn2))
7845 END
7846 call v9.CheckSourceSuccess(lines)
7847
7848 " class variable with 'any" type. Can be assigned different types.
7849 let lines =<< trim END
7850 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007851 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007852 return {}
7853 enddef
7854 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007855 public static var Fn: any = Foo
7856 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007857
7858 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007859 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007860 Fn = "abc"
7861 assert_equal('string', typename(Fn))
7862 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007863 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007864 Fn2 = "xyz"
7865 assert_equal('string', typename(Fn2))
7866 enddef
7867 endclass
7868 var a = A.new()
7869 test_garbagecollect_now()
7870 a.Bar()
7871 test_garbagecollect_now()
7872 A.Fn = Foo
7873 a.Bar()
7874 END
7875 call v9.CheckSourceSuccess(lines)
7876
7877 " class variable with 'any" type. Can be assigned different types.
7878 let lines =<< trim END
7879 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007880 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007881 return {}
7882 enddef
7883 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007884 public static var Fn: any = Foo
7885 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007886 endclass
7887
7888 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007889 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007890 A.Fn = "abc"
7891 assert_equal('string', typename(A.Fn))
7892 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007893 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007894 A.Fn2 = "xyz"
7895 assert_equal('string', typename(A.Fn2))
7896 enddef
7897 Bar()
7898 test_garbagecollect_now()
7899 A.Fn = Foo
7900 Bar()
7901 END
7902 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007903
7904 let lines =<< trim END
7905 vim9script
7906 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007907 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007908 endclass
7909 assert_equal([0z10, 0z20], A.foo)
7910 A.foo = [0z30]
7911 assert_equal([0z30], A.foo)
7912 var a = A.foo
7913 assert_equal([0z30], a)
7914 END
7915 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007916endfunc
7917
7918" Test type checking for object variable in assignments
7919func Test_object_variable_complex_type_check()
7920 " object variable with a specific type. Try assigning a different type at
7921 " script level.
7922 let lines =<< trim END
7923 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007924 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007925 return {}
7926 enddef
7927 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007928 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007929 endclass
7930 var a = A.new()
7931 test_garbagecollect_now()
7932 a.Fn = "abc"
7933 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007934 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 +02007935
7936 " object variable with a specific type. Try assigning a different type at
7937 " object def method level.
7938 let lines =<< trim END
7939 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007940 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007941 return {}
7942 enddef
7943 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007944 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007945 def Bar()
7946 this.Fn = "abc"
7947 this.Fn = Foo
7948 enddef
7949 endclass
7950 var a = A.new()
7951 test_garbagecollect_now()
7952 a.Bar()
7953 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007954 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 +02007955
7956 " object variable with a specific type. Try assigning a different type at
7957 " script def method level.
7958 let lines =<< trim END
7959 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007960 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007961 return {}
7962 enddef
7963 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007964 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007965 endclass
7966 def Bar()
7967 var a = A.new()
7968 a.Fn = "abc"
7969 a.Fn = Foo
7970 enddef
7971 test_garbagecollect_now()
7972 Bar()
7973 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007974 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 +02007975
7976 " object variable without any type. Should be set to the initialization
7977 " expression type. Try assigning a different type from script level.
7978 let lines =<< trim END
7979 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007980 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007981 return {}
7982 enddef
7983 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007984 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007985 endclass
7986 var a = A.new()
7987 test_garbagecollect_now()
7988 a.Fn = "abc"
7989 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007990 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 +02007991
7992 " object variable without any type. Should be set to the initialization
7993 " expression type. Try assigning a different type at object def level.
7994 let lines =<< trim END
7995 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007996 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007997 return {}
7998 enddef
7999 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008000 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008001 def Bar()
8002 this.Fn = "abc"
8003 this.Fn = Foo
8004 enddef
8005 endclass
8006 var a = A.new()
8007 test_garbagecollect_now()
8008 a.Bar()
8009 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008010 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 +02008011
8012 " object variable without any type. Should be set to the initialization
8013 " expression type. Try assigning a different type at script def level.
8014 let lines =<< trim END
8015 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008016 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008017 return {}
8018 enddef
8019 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008020 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008021 endclass
8022 def Bar()
8023 var a = A.new()
8024 a.Fn = "abc"
8025 a.Fn = Foo
8026 enddef
8027 test_garbagecollect_now()
8028 Bar()
8029 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008030 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 +02008031
8032 " object variable with 'any" type. Can be assigned different types.
8033 let lines =<< trim END
8034 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008035 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008036 return {}
8037 enddef
8038 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008039 public var Fn: any = Foo
8040 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008041 endclass
8042
8043 var a = A.new()
8044 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008045 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008046 a.Fn = "abc"
8047 test_garbagecollect_now()
8048 assert_equal('string', typename(a.Fn))
8049 a.Fn2 = Foo
8050 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008051 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008052 a.Fn2 = "xyz"
8053 test_garbagecollect_now()
8054 assert_equal('string', typename(a.Fn2))
8055 END
8056 call v9.CheckSourceSuccess(lines)
8057
8058 " object variable with 'any" type. Can be assigned different types.
8059 let lines =<< trim END
8060 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008061 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008062 return {}
8063 enddef
8064 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008065 public var Fn: any = Foo
8066 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008067
8068 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008069 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008070 this.Fn = "abc"
8071 assert_equal('string', typename(this.Fn))
8072 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008073 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008074 this.Fn2 = "xyz"
8075 assert_equal('string', typename(this.Fn2))
8076 enddef
8077 endclass
8078
8079 var a = A.new()
8080 test_garbagecollect_now()
8081 a.Bar()
8082 test_garbagecollect_now()
8083 a.Fn = Foo
8084 a.Bar()
8085 END
8086 call v9.CheckSourceSuccess(lines)
8087
8088 " object variable with 'any" type. Can be assigned different types.
8089 let lines =<< trim END
8090 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008091 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008092 return {}
8093 enddef
8094 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008095 public var Fn: any = Foo
8096 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008097 endclass
8098
8099 def Bar()
8100 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008101 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008102 a.Fn = "abc"
8103 assert_equal('string', typename(a.Fn))
8104 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008105 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008106 a.Fn2 = "xyz"
8107 assert_equal('string', typename(a.Fn2))
8108 enddef
8109 test_garbagecollect_now()
8110 Bar()
8111 test_garbagecollect_now()
8112 Bar()
8113 END
8114 call v9.CheckSourceSuccess(lines)
8115endfunc
8116
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008117" Test for recursively calling an object method. This used to cause an
8118" use-after-free error.
8119def Test_recursive_object_method_call()
8120 var lines =<< trim END
8121 vim9script
8122 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008123 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008124 def Foo(): number
8125 if this.val >= 90
8126 return this.val
8127 endif
8128 this.val += 1
8129 return this.Foo()
8130 enddef
8131 endclass
8132 var a = A.new()
8133 assert_equal(90, a.Foo())
8134 END
8135 v9.CheckSourceSuccess(lines)
8136enddef
8137
8138" Test for recursively calling a class method.
8139def Test_recursive_class_method_call()
8140 var lines =<< trim END
8141 vim9script
8142 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008143 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008144 static def Foo(): number
8145 if val >= 90
8146 return val
8147 endif
8148 val += 1
8149 return Foo()
8150 enddef
8151 endclass
8152 assert_equal(90, A.Foo())
8153 END
8154 v9.CheckSourceSuccess(lines)
8155enddef
8156
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02008157" Test for checking the argument types and the return type when assigning a
8158" funcref to make sure the invariant class type is used.
8159def Test_funcref_argtype_returntype_check()
8160 var lines =<< trim END
8161 vim9script
8162 class A
8163 endclass
8164 class B extends A
8165 endclass
8166
8167 def Foo(p: B): B
8168 return B.new()
8169 enddef
8170
8171 var Bar: func(A): A = Foo
8172 END
8173 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
8174
8175 lines =<< trim END
8176 vim9script
8177 class A
8178 endclass
8179 class B extends A
8180 endclass
8181
8182 def Foo(p: B): B
8183 return B.new()
8184 enddef
8185
8186 def Baz()
8187 var Bar: func(A): A = Foo
8188 enddef
8189 Baz()
8190 END
8191 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
8192enddef
8193
Ernie Rael96952b22023-10-17 18:15:01 +02008194def Test_funcref_argtype_invariance_check()
8195 var lines =<< trim END
8196 vim9script
8197
8198 class A
8199 endclass
8200 class B extends A
8201 endclass
8202 class C extends B
8203 endclass
8204
8205 var Func: func(B): number
8206 Func = (o: B): number => 3
8207 assert_equal(3, Func(B.new()))
8208 END
8209 v9.CheckSourceSuccess(lines)
8210
8211 lines =<< trim END
8212 vim9script
8213
8214 class A
8215 endclass
8216 class B extends A
8217 endclass
8218 class C extends B
8219 endclass
8220
8221 var Func: func(B): number
8222 Func = (o: A): number => 3
8223 END
8224 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
8225
8226 lines =<< trim END
8227 vim9script
8228
8229 class A
8230 endclass
8231 class B extends A
8232 endclass
8233 class C extends B
8234 endclass
8235
8236 var Func: func(B): number
8237 Func = (o: C): number => 3
8238 END
8239 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
8240enddef
8241
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008242" Test for using an operator (e.g. +) with an assignment
8243def Test_op_and_assignment()
8244 # Using += with a class variable
8245 var lines =<< trim END
8246 vim9script
8247 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008248 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008249 static def Foo(): list<number>
8250 val += [1]
8251 return val
8252 enddef
8253 endclass
8254 def Bar(): list<number>
8255 A.val += [2]
8256 return A.val
8257 enddef
8258 assert_equal([1], A.Foo())
8259 assert_equal([1, 2], Bar())
8260 A.val += [3]
8261 assert_equal([1, 2, 3], A.val)
8262 END
8263 v9.CheckSourceSuccess(lines)
8264
8265 # Using += with an object variable
8266 lines =<< trim END
8267 vim9script
8268 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008269 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008270 def Foo(): list<number>
8271 this.val += [1]
8272 return this.val
8273 enddef
8274 endclass
8275 def Bar(bar_a: A): list<number>
8276 bar_a.val += [2]
8277 return bar_a.val
8278 enddef
8279 var a = A.new()
8280 assert_equal([1], a.Foo())
8281 assert_equal([1, 2], Bar(a))
8282 a.val += [3]
8283 assert_equal([1, 2, 3], a.val)
8284 END
8285 v9.CheckSourceSuccess(lines)
8286enddef
8287
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008288" Test for using an object method as a funcref
8289def Test_object_funcref()
8290 # Using object method funcref from a def function
8291 var lines =<< trim END
8292 vim9script
8293 class A
8294 def Foo(): list<number>
8295 return [3, 2, 1]
8296 enddef
8297 endclass
8298 def Bar()
8299 var a = A.new()
8300 var Fn = a.Foo
8301 assert_equal([3, 2, 1], Fn())
8302 enddef
8303 Bar()
8304 END
8305 v9.CheckSourceSuccess(lines)
8306
8307 # Using object method funcref at the script level
8308 lines =<< trim END
8309 vim9script
8310 class A
8311 def Foo(): dict<number>
8312 return {a: 1, b: 2}
8313 enddef
8314 endclass
8315 var a = A.new()
8316 var Fn = a.Foo
8317 assert_equal({a: 1, b: 2}, Fn())
8318 END
8319 v9.CheckSourceSuccess(lines)
8320
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008321 # Using object method funcref at the script level
8322 lines =<< trim END
8323 vim9script
8324 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008325 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008326 def Foo(): number
8327 return this.val
8328 enddef
8329 endclass
8330 var a = A.new(345)
8331 var Fn = a.Foo
8332 assert_equal(345, Fn())
8333 END
8334 v9.CheckSourceSuccess(lines)
8335
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008336 # Using object method funcref from another object method
8337 lines =<< trim END
8338 vim9script
8339 class A
8340 def Foo(): list<number>
8341 return [3, 2, 1]
8342 enddef
8343 def Bar()
8344 var Fn = this.Foo
8345 assert_equal([3, 2, 1], Fn())
8346 enddef
8347 endclass
8348 var a = A.new()
8349 a.Bar()
8350 END
8351 v9.CheckSourceSuccess(lines)
8352
8353 # Using function() to get a object method funcref
8354 lines =<< trim END
8355 vim9script
8356 class A
8357 def Foo(l: list<any>): list<any>
8358 return l
8359 enddef
8360 endclass
8361 var a = A.new()
8362 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8363 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8364 END
8365 v9.CheckSourceSuccess(lines)
8366
8367 # Use an object method with a function returning a funcref and then call the
8368 # funcref.
8369 lines =<< trim END
8370 vim9script
8371
8372 def Map(F: func(number): number): func(number): number
8373 return (n: number) => F(n)
8374 enddef
8375
8376 class Math
8377 def Double(n: number): number
8378 return 2 * n
8379 enddef
8380 endclass
8381
8382 const math = Math.new()
8383 assert_equal(48, Map(math.Double)(24))
8384 END
8385 v9.CheckSourceSuccess(lines)
8386
Ernie Rael03042a22023-11-11 08:53:32 +01008387 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008388 lines =<< trim END
8389 vim9script
8390 class A
8391 def _Foo()
8392 enddef
8393 endclass
8394 def Bar()
8395 var a = A.new()
8396 var Fn = a._Foo
8397 enddef
8398 Bar()
8399 END
Ernie Rael03042a22023-11-11 08:53:32 +01008400 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008401
Ernie Rael03042a22023-11-11 08:53:32 +01008402 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008403 lines =<< trim END
8404 vim9script
8405 class A
8406 def _Foo()
8407 enddef
8408 endclass
8409 var a = A.new()
8410 var Fn = a._Foo
8411 END
Ernie Rael03042a22023-11-11 08:53:32 +01008412 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008413
Ernie Rael03042a22023-11-11 08:53:32 +01008414 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008415 lines =<< trim END
8416 vim9script
8417 class A
8418 def _Foo(): list<number>
8419 return [3, 2, 1]
8420 enddef
8421 def Bar()
8422 var Fn = this._Foo
8423 assert_equal([3, 2, 1], Fn())
8424 enddef
8425 endclass
8426 var a = A.new()
8427 a.Bar()
8428 END
8429 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008430
8431 # Using object method funcref using call()
8432 lines =<< trim END
8433 vim9script
8434 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008435 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008436 def Foo(): number
8437 return this.val
8438 enddef
8439 endclass
8440
8441 def Bar(obj: A)
8442 assert_equal(123, call(obj.Foo, []))
8443 enddef
8444
8445 var a = A.new(123)
8446 Bar(a)
8447 assert_equal(123, call(a.Foo, []))
8448 END
8449 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008450enddef
8451
8452" Test for using a class method as a funcref
8453def Test_class_funcref()
8454 # Using class method funcref in a def function
8455 var lines =<< trim END
8456 vim9script
8457 class A
8458 static def Foo(): list<number>
8459 return [3, 2, 1]
8460 enddef
8461 endclass
8462 def Bar()
8463 var Fn = A.Foo
8464 assert_equal([3, 2, 1], Fn())
8465 enddef
8466 Bar()
8467 END
8468 v9.CheckSourceSuccess(lines)
8469
8470 # Using class method funcref at script level
8471 lines =<< trim END
8472 vim9script
8473 class A
8474 static def Foo(): dict<number>
8475 return {a: 1, b: 2}
8476 enddef
8477 endclass
8478 var Fn = A.Foo
8479 assert_equal({a: 1, b: 2}, Fn())
8480 END
8481 v9.CheckSourceSuccess(lines)
8482
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008483 # Using class method funcref at the script level
8484 lines =<< trim END
8485 vim9script
8486 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008487 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008488 static def Foo(): number
8489 return val
8490 enddef
8491 endclass
8492 A.val = 567
8493 var Fn = A.Foo
8494 assert_equal(567, Fn())
8495 END
8496 v9.CheckSourceSuccess(lines)
8497
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008498 # Using function() to get a class method funcref
8499 lines =<< trim END
8500 vim9script
8501 class A
8502 static def Foo(l: list<any>): list<any>
8503 return l
8504 enddef
8505 endclass
8506 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8507 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8508 END
8509 v9.CheckSourceSuccess(lines)
8510
8511 # Using a class method funcref from another class method
8512 lines =<< trim END
8513 vim9script
8514 class A
8515 static def Foo(): list<number>
8516 return [3, 2, 1]
8517 enddef
8518 static def Bar()
8519 var Fn = Foo
8520 assert_equal([3, 2, 1], Fn())
8521 enddef
8522 endclass
8523 A.Bar()
8524 END
8525 v9.CheckSourceSuccess(lines)
8526
8527 # Use a class method with a function returning a funcref and then call the
8528 # funcref.
8529 lines =<< trim END
8530 vim9script
8531
8532 def Map(F: func(number): number): func(number): number
8533 return (n: number) => F(n)
8534 enddef
8535
8536 class Math
8537 static def StaticDouble(n: number): number
8538 return 2 * n
8539 enddef
8540 endclass
8541
8542 assert_equal(48, Map(Math.StaticDouble)(24))
8543 END
8544 v9.CheckSourceSuccess(lines)
8545
Ernie Rael03042a22023-11-11 08:53:32 +01008546 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008547 lines =<< trim END
8548 vim9script
8549 class A
8550 static def _Foo()
8551 enddef
8552 endclass
8553 def Bar()
8554 var Fn = A._Foo
8555 enddef
8556 Bar()
8557 END
Ernie Rael03042a22023-11-11 08:53:32 +01008558 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008559
Ernie Rael03042a22023-11-11 08:53:32 +01008560 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008561 lines =<< trim END
8562 vim9script
8563 class A
8564 static def _Foo()
8565 enddef
8566 endclass
8567 var Fn = A._Foo
8568 END
Ernie Rael03042a22023-11-11 08:53:32 +01008569 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008570
Ernie Rael03042a22023-11-11 08:53:32 +01008571 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008572 lines =<< trim END
8573 vim9script
8574 class A
8575 static def _Foo(): list<number>
8576 return [3, 2, 1]
8577 enddef
8578 static def Bar()
8579 var Fn = _Foo
8580 assert_equal([3, 2, 1], Fn())
8581 enddef
8582 endclass
8583 A.Bar()
8584 END
8585 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008586
8587 # Using class method funcref using call()
8588 lines =<< trim END
8589 vim9script
8590 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008591 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008592 static def Foo(): number
8593 return val
8594 enddef
8595 endclass
8596
8597 def Bar()
8598 A.val = 468
8599 assert_equal(468, call(A.Foo, []))
8600 enddef
8601 Bar()
8602 assert_equal(468, call(A.Foo, []))
8603 END
8604 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008605enddef
8606
8607" Test for using an object member as a funcref
8608def Test_object_member_funcref()
8609 # Using a funcref object variable in an object method
8610 var lines =<< trim END
8611 vim9script
8612 def Foo(n: number): number
8613 return n * 10
8614 enddef
8615
8616 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008617 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008618 def Bar()
8619 assert_equal(200, this.Cb(20))
8620 enddef
8621 endclass
8622
8623 var a = A.new()
8624 a.Bar()
8625 END
8626 v9.CheckSourceSuccess(lines)
8627
8628 # Using a funcref object variable in a def method
8629 lines =<< trim END
8630 vim9script
8631 def Foo(n: number): number
8632 return n * 10
8633 enddef
8634
8635 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008636 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008637 endclass
8638
8639 def Bar()
8640 var a = A.new()
8641 assert_equal(200, a.Cb(20))
8642 enddef
8643 Bar()
8644 END
8645 v9.CheckSourceSuccess(lines)
8646
8647 # Using a funcref object variable at script level
8648 lines =<< trim END
8649 vim9script
8650 def Foo(n: number): number
8651 return n * 10
8652 enddef
8653
8654 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008655 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008656 endclass
8657
8658 var a = A.new()
8659 assert_equal(200, a.Cb(20))
8660 END
8661 v9.CheckSourceSuccess(lines)
8662
8663 # Using a funcref object variable pointing to an object method in an object
8664 # method.
8665 lines =<< trim END
8666 vim9script
8667 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008668 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008669 def Foo(n: number): number
8670 return n * 10
8671 enddef
8672 def Bar()
8673 assert_equal(200, this.Cb(20))
8674 enddef
8675 endclass
8676
8677 var a = A.new()
8678 a.Bar()
8679 END
8680 v9.CheckSourceSuccess(lines)
8681
8682 # Using a funcref object variable pointing to an object method in a def
8683 # method.
8684 lines =<< trim END
8685 vim9script
8686 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008687 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008688 def Foo(n: number): number
8689 return n * 10
8690 enddef
8691 endclass
8692
8693 def Bar()
8694 var a = A.new()
8695 assert_equal(200, a.Cb(20))
8696 enddef
8697 Bar()
8698 END
8699 v9.CheckSourceSuccess(lines)
8700
8701 # Using a funcref object variable pointing to an object method at script
8702 # level.
8703 lines =<< trim END
8704 vim9script
8705 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008706 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008707 def Foo(n: number): number
8708 return n * 10
8709 enddef
8710 endclass
8711
8712 var a = A.new()
8713 assert_equal(200, a.Cb(20))
8714 END
8715 v9.CheckSourceSuccess(lines)
8716enddef
8717
8718" Test for using a class member as a funcref
8719def Test_class_member_funcref()
8720 # Using a funcref class variable in a class method
8721 var lines =<< trim END
8722 vim9script
8723 def Foo(n: number): number
8724 return n * 10
8725 enddef
8726
8727 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008728 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008729 static def Bar()
8730 assert_equal(200, Cb(20))
8731 enddef
8732 endclass
8733
8734 A.Bar()
8735 END
8736 v9.CheckSourceSuccess(lines)
8737
8738 # Using a funcref class variable in a def method
8739 lines =<< trim END
8740 vim9script
8741 def Foo(n: number): number
8742 return n * 10
8743 enddef
8744
8745 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008746 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008747 endclass
8748
8749 def Bar()
8750 assert_equal(200, A.Cb(20))
8751 enddef
8752 Bar()
8753 END
8754 v9.CheckSourceSuccess(lines)
8755
8756 # Using a funcref class variable at script level
8757 lines =<< trim END
8758 vim9script
8759 def Foo(n: number): number
8760 return n * 10
8761 enddef
8762
8763 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008764 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008765 endclass
8766
8767 assert_equal(200, A.Cb(20))
8768 END
8769 v9.CheckSourceSuccess(lines)
8770
8771 # Using a funcref class variable pointing to a class method in a class
8772 # method.
8773 lines =<< trim END
8774 vim9script
8775 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008776 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008777 static def Foo(n: number): number
8778 return n * 10
8779 enddef
8780 static def Init()
8781 Cb = Foo
8782 enddef
8783 static def Bar()
8784 assert_equal(200, Cb(20))
8785 enddef
8786 endclass
8787
8788 A.Init()
8789 A.Bar()
8790 END
8791 v9.CheckSourceSuccess(lines)
8792
8793 # Using a funcref class variable pointing to a class method in a def method.
8794 lines =<< trim END
8795 vim9script
8796 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008797 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008798 static def Foo(n: number): number
8799 return n * 10
8800 enddef
8801 static def Init()
8802 Cb = Foo
8803 enddef
8804 endclass
8805
8806 def Bar()
8807 A.Init()
8808 assert_equal(200, A.Cb(20))
8809 enddef
8810 Bar()
8811 END
8812 v9.CheckSourceSuccess(lines)
8813
8814 # Using a funcref class variable pointing to a class method at script level.
8815 lines =<< trim END
8816 vim9script
8817 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008818 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008819 static def Foo(n: number): number
8820 return n * 10
8821 enddef
8822 static def Init()
8823 Cb = Foo
8824 enddef
8825 endclass
8826
8827 A.Init()
8828 assert_equal(200, A.Cb(20))
8829 END
8830 v9.CheckSourceSuccess(lines)
8831enddef
8832
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008833" Test for using object methods as popup callback functions
8834def Test_objmethod_popup_callback()
8835 # Use the popup from the script level
8836 var lines =<< trim END
8837 vim9script
8838
8839 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008840 var selection: number = -1
8841 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008842
8843 def PopupFilter(id: number, key: string): bool
8844 add(this.filterkeys, key)
8845 return popup_filter_yesno(id, key)
8846 enddef
8847
8848 def PopupCb(id: number, result: number)
8849 this.selection = result ? 100 : 200
8850 enddef
8851 endclass
8852
8853 var a = A.new()
8854 feedkeys('', 'xt')
8855 var winid = popup_create('Y/N?',
8856 {filter: a.PopupFilter, callback: a.PopupCb})
8857 feedkeys('y', 'xt')
8858 popup_close(winid)
8859 assert_equal(100, a.selection)
8860 assert_equal(['y'], a.filterkeys)
8861 feedkeys('', 'xt')
8862 winid = popup_create('Y/N?',
8863 {filter: a.PopupFilter, callback: a.PopupCb})
8864 feedkeys('n', 'xt')
8865 popup_close(winid)
8866 assert_equal(200, a.selection)
8867 assert_equal(['y', 'n'], a.filterkeys)
8868 END
8869 v9.CheckSourceSuccess(lines)
8870
8871 # Use the popup from a def function
8872 lines =<< trim END
8873 vim9script
8874
8875 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008876 var selection: number = -1
8877 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008878
8879 def PopupFilter(id: number, key: string): bool
8880 add(this.filterkeys, key)
8881 return popup_filter_yesno(id, key)
8882 enddef
8883
8884 def PopupCb(id: number, result: number)
8885 this.selection = result ? 100 : 200
8886 enddef
8887 endclass
8888
8889 def Foo()
8890 var a = A.new()
8891 feedkeys('', 'xt')
8892 var winid = popup_create('Y/N?',
8893 {filter: a.PopupFilter, callback: a.PopupCb})
8894 feedkeys('y', 'xt')
8895 popup_close(winid)
8896 assert_equal(100, a.selection)
8897 assert_equal(['y'], a.filterkeys)
8898 feedkeys('', 'xt')
8899 winid = popup_create('Y/N?',
8900 {filter: a.PopupFilter, callback: a.PopupCb})
8901 feedkeys('n', 'xt')
8902 popup_close(winid)
8903 assert_equal(200, a.selection)
8904 assert_equal(['y', 'n'], a.filterkeys)
8905 enddef
8906 Foo()
8907 END
8908 v9.CheckSourceSuccess(lines)
8909enddef
8910
8911" Test for using class methods as popup callback functions
8912def Test_classmethod_popup_callback()
8913 # Use the popup from the script level
8914 var lines =<< trim END
8915 vim9script
8916
8917 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008918 static var selection: number = -1
8919 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008920
8921 static def PopupFilter(id: number, key: string): bool
8922 add(filterkeys, key)
8923 return popup_filter_yesno(id, key)
8924 enddef
8925
8926 static def PopupCb(id: number, result: number)
8927 selection = result ? 100 : 200
8928 enddef
8929 endclass
8930
8931 feedkeys('', 'xt')
8932 var winid = popup_create('Y/N?',
8933 {filter: A.PopupFilter, callback: A.PopupCb})
8934 feedkeys('y', 'xt')
8935 popup_close(winid)
8936 assert_equal(100, A.selection)
8937 assert_equal(['y'], A.filterkeys)
8938 feedkeys('', 'xt')
8939 winid = popup_create('Y/N?',
8940 {filter: A.PopupFilter, callback: A.PopupCb})
8941 feedkeys('n', 'xt')
8942 popup_close(winid)
8943 assert_equal(200, A.selection)
8944 assert_equal(['y', 'n'], A.filterkeys)
8945 END
8946 v9.CheckSourceSuccess(lines)
8947
8948 # Use the popup from a def function
8949 lines =<< trim END
8950 vim9script
8951
8952 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008953 static var selection: number = -1
8954 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008955
8956 static def PopupFilter(id: number, key: string): bool
8957 add(filterkeys, key)
8958 return popup_filter_yesno(id, key)
8959 enddef
8960
8961 static def PopupCb(id: number, result: number)
8962 selection = result ? 100 : 200
8963 enddef
8964 endclass
8965
8966 def Foo()
8967 feedkeys('', 'xt')
8968 var winid = popup_create('Y/N?',
8969 {filter: A.PopupFilter, callback: A.PopupCb})
8970 feedkeys('y', 'xt')
8971 popup_close(winid)
8972 assert_equal(100, A.selection)
8973 assert_equal(['y'], A.filterkeys)
8974 feedkeys('', 'xt')
8975 winid = popup_create('Y/N?',
8976 {filter: A.PopupFilter, callback: A.PopupCb})
8977 feedkeys('n', 'xt')
8978 popup_close(winid)
8979 assert_equal(200, A.selection)
8980 assert_equal(['y', 'n'], A.filterkeys)
8981 enddef
8982 Foo()
8983 END
8984 v9.CheckSourceSuccess(lines)
8985enddef
8986
8987" Test for using an object method as a timer callback function
8988def Test_objmethod_timer_callback()
8989 # Use the timer callback from script level
8990 var lines =<< trim END
8991 vim9script
8992
8993 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008994 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008995 def TimerCb(timerID: number)
8996 this.timerTick = 6
8997 enddef
8998 endclass
8999
9000 var a = A.new()
9001 timer_start(0, a.TimerCb)
9002 var maxWait = 5
9003 while maxWait > 0 && a.timerTick == -1
9004 :sleep 10m
9005 maxWait -= 1
9006 endwhile
9007 assert_equal(6, a.timerTick)
9008 END
9009 v9.CheckSourceSuccess(lines)
9010
9011 # Use the timer callback from a def function
9012 lines =<< trim END
9013 vim9script
9014
9015 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009016 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009017 def TimerCb(timerID: number)
9018 this.timerTick = 6
9019 enddef
9020 endclass
9021
9022 def Foo()
9023 var a = A.new()
9024 timer_start(0, a.TimerCb)
9025 var maxWait = 5
9026 while maxWait > 0 && a.timerTick == -1
9027 :sleep 10m
9028 maxWait -= 1
9029 endwhile
9030 assert_equal(6, a.timerTick)
9031 enddef
9032 Foo()
9033 END
9034 v9.CheckSourceSuccess(lines)
9035enddef
9036
9037" Test for using a class method as a timer callback function
9038def Test_classmethod_timer_callback()
9039 # Use the timer callback from script level
9040 var lines =<< trim END
9041 vim9script
9042
9043 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009044 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009045 static def TimerCb(timerID: number)
9046 timerTick = 6
9047 enddef
9048 endclass
9049
9050 timer_start(0, A.TimerCb)
9051 var maxWait = 5
9052 while maxWait > 0 && A.timerTick == -1
9053 :sleep 10m
9054 maxWait -= 1
9055 endwhile
9056 assert_equal(6, A.timerTick)
9057 END
9058 v9.CheckSourceSuccess(lines)
9059
9060 # Use the timer callback from a def function
9061 lines =<< trim END
9062 vim9script
9063
9064 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009065 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009066 static def TimerCb(timerID: number)
9067 timerTick = 6
9068 enddef
9069 endclass
9070
9071 def Foo()
9072 timer_start(0, A.TimerCb)
9073 var maxWait = 5
9074 while maxWait > 0 && A.timerTick == -1
9075 :sleep 10m
9076 maxWait -= 1
9077 endwhile
9078 assert_equal(6, A.timerTick)
9079 enddef
9080 Foo()
9081 END
9082 v9.CheckSourceSuccess(lines)
9083enddef
9084
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009085" Test for using a class variable as the first and/or second operand of a binary
9086" operator.
9087def Test_class_variable_as_operands()
9088 var lines =<< trim END
9089 vim9script
9090 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01009091 static var truthy: bool = true
9092 public static var TruthyFn: func
9093 static var list: list<any> = []
9094 static var four: number = 4
9095 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009096
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009097 static def Str(): string
9098 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009099 enddef
9100
9101 static def Four(): number
9102 return four
9103 enddef
9104
9105 static def List(): list<any>
9106 return list
9107 enddef
9108
9109 static def Truthy(): bool
9110 return truthy
9111 enddef
9112
9113 def TestOps()
9114 assert_true(Tests.truthy == truthy)
9115 assert_true(truthy == Tests.truthy)
9116 assert_true(Tests.list isnot [])
9117 assert_true([] isnot Tests.list)
9118 assert_equal(2, Tests.four >> 1)
9119 assert_equal(16, 1 << Tests.four)
9120 assert_equal(8, Tests.four + four)
9121 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009122 assert_equal('hellohello', Tests.str .. str)
9123 assert_equal('hellohello', str .. Tests.str)
9124
9125 # Using class variable for list indexing
9126 var l = range(10)
9127 assert_equal(4, l[Tests.four])
9128 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9129
9130 # Using class variable for Dict key
9131 var d = {hello: 'abc'}
9132 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009133 enddef
9134 endclass
9135
9136 def TestOps2()
9137 assert_true(Tests.truthy == Tests.Truthy())
9138 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009139 assert_true(Tests.truthy == Tests.TruthyFn())
9140 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009141 assert_true(Tests.list is Tests.List())
9142 assert_true(Tests.List() is Tests.list)
9143 assert_equal(2, Tests.four >> 1)
9144 assert_equal(16, 1 << Tests.four)
9145 assert_equal(8, Tests.four + Tests.Four())
9146 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009147 assert_equal('hellohello', Tests.str .. Tests.Str())
9148 assert_equal('hellohello', Tests.Str() .. Tests.str)
9149
9150 # Using class variable for list indexing
9151 var l = range(10)
9152 assert_equal(4, l[Tests.four])
9153 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9154
9155 # Using class variable for Dict key
9156 var d = {hello: 'abc'}
9157 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009158 enddef
9159
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009160 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009161 var t = Tests.new()
9162 t.TestOps()
9163 TestOps2()
9164
9165 assert_true(Tests.truthy == Tests.Truthy())
9166 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009167 assert_true(Tests.truthy == Tests.TruthyFn())
9168 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009169 assert_true(Tests.list is Tests.List())
9170 assert_true(Tests.List() is Tests.list)
9171 assert_equal(2, Tests.four >> 1)
9172 assert_equal(16, 1 << Tests.four)
9173 assert_equal(8, Tests.four + Tests.Four())
9174 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009175 assert_equal('hellohello', Tests.str .. Tests.Str())
9176 assert_equal('hellohello', Tests.Str() .. Tests.str)
9177
9178 # Using class variable for list indexing
9179 var l = range(10)
9180 assert_equal(4, l[Tests.four])
9181 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9182
9183 # Using class variable for Dict key
9184 var d = {hello: 'abc'}
9185 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009186 END
9187 v9.CheckSourceSuccess(lines)
9188enddef
9189
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009190" Test for checking the type of the key used to access an object dict member.
9191def Test_dict_member_key_type_check()
9192 var lines =<< trim END
9193 vim9script
9194
9195 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01009196 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009197 endclass
9198
9199 class Test extends State
9200 def ObjMethodTests()
9201 var cursor: number = 0
9202 var z: number = 0
9203 [this.numbers[cursor]] = ['zero.1']
9204 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9205 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9206 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9207 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9208 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9209 [this.numbers[cursor], z] = ['zero.4', 1]
9210 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9211 [z, this.numbers[cursor]] = [1, 'zero.5']
9212 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9213 enddef
9214
9215 static def ClassMethodTests(that: State)
9216 var cursor: number = 0
9217 var z: number = 0
9218 [that.numbers[cursor]] = ['zero.1']
9219 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9220 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9221 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9222 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9223 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9224 [that.numbers[cursor], z] = ['zero.4', 1]
9225 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9226 [z, that.numbers[cursor]] = [1, 'zero.5']
9227 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9228 enddef
9229
9230 def new()
9231 enddef
9232
9233 def newMethodTests()
9234 var cursor: number = 0
9235 var z: number
9236 [this.numbers[cursor]] = ['zero.1']
9237 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9238 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9239 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9240 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9241 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9242 [this.numbers[cursor], z] = ['zero.4', 1]
9243 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9244 [z, this.numbers[cursor]] = [1, 'zero.5']
9245 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9246 enddef
9247 endclass
9248
9249 def DefFuncTests(that: Test)
9250 var cursor: number = 0
9251 var z: number
9252 [that.numbers[cursor]] = ['zero.1']
9253 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9254 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9255 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9256 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9257 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9258 [that.numbers[cursor], z] = ['zero.4', 1]
9259 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9260 [z, that.numbers[cursor]] = [1, 'zero.5']
9261 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9262 enddef
9263
9264 Test.newMethodTests()
9265 Test.new().ObjMethodTests()
9266 Test.ClassMethodTests(Test.new())
9267 DefFuncTests(Test.new())
9268
9269 const test: Test = Test.new()
9270 var cursor: number = 0
9271 [test.numbers[cursor], cursor] = ['zero', 1]
9272 [cursor, test.numbers[cursor]] = [1, 'one']
9273 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
9274 END
9275 v9.CheckSourceSuccess(lines)
9276
9277 lines =<< trim END
9278 vim9script
9279
9280 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009281 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009282
9283 def new()
9284 enddef
9285
9286 def Foo()
9287 var z: number
9288 [this.numbers.a, z] = [{}, 10]
9289 enddef
9290 endclass
9291
9292 var a = A.new()
9293 a.Foo()
9294 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009295 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009296
9297 lines =<< trim END
9298 vim9script
9299
9300 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009301 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009302
9303 def new()
9304 enddef
9305
9306 def Foo()
9307 var x: string = 'a'
9308 var y: number
9309 [this.numbers[x], y] = [{}, 10]
9310 enddef
9311 endclass
9312
9313 var a = A.new()
9314 a.Foo()
9315 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009316 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009317enddef
9318
mityua5550692023-11-25 15:41:20 +01009319def Test_compile_many_def_functions_in_funcref_instr()
9320 # This used to crash Vim. This is reproducible only when run on new instance
9321 # of Vim.
9322 var lines =<< trim END
9323 vim9script
9324
9325 class A
9326 def new()
9327 this.TakeFunc(this.F00)
9328 enddef
9329
9330 def TakeFunc(F: func)
9331 enddef
9332
9333 def F00()
9334 this.F01()
9335 this.F02()
9336 this.F03()
9337 this.F04()
9338 this.F05()
9339 this.F06()
9340 this.F07()
9341 this.F08()
9342 this.F09()
9343 this.F10()
9344 this.F11()
9345 this.F12()
9346 this.F13()
9347 this.F14()
9348 this.F15()
9349 this.F16()
9350 this.F17()
9351 this.F18()
9352 this.F19()
9353 this.F20()
9354 this.F21()
9355 this.F22()
9356 this.F23()
9357 this.F24()
9358 this.F25()
9359 this.F26()
9360 this.F27()
9361 this.F28()
9362 this.F29()
9363 this.F30()
9364 this.F31()
9365 this.F32()
9366 this.F33()
9367 this.F34()
9368 this.F35()
9369 this.F36()
9370 this.F37()
9371 this.F38()
9372 this.F39()
9373 this.F40()
9374 this.F41()
9375 this.F42()
9376 this.F43()
9377 this.F44()
9378 this.F45()
9379 this.F46()
9380 this.F47()
9381 enddef
9382
9383 def F01()
9384 enddef
9385 def F02()
9386 enddef
9387 def F03()
9388 enddef
9389 def F04()
9390 enddef
9391 def F05()
9392 enddef
9393 def F06()
9394 enddef
9395 def F07()
9396 enddef
9397 def F08()
9398 enddef
9399 def F09()
9400 enddef
9401 def F10()
9402 enddef
9403 def F11()
9404 enddef
9405 def F12()
9406 enddef
9407 def F13()
9408 enddef
9409 def F14()
9410 enddef
9411 def F15()
9412 enddef
9413 def F16()
9414 enddef
9415 def F17()
9416 enddef
9417 def F18()
9418 enddef
9419 def F19()
9420 enddef
9421 def F20()
9422 enddef
9423 def F21()
9424 enddef
9425 def F22()
9426 enddef
9427 def F23()
9428 enddef
9429 def F24()
9430 enddef
9431 def F25()
9432 enddef
9433 def F26()
9434 enddef
9435 def F27()
9436 enddef
9437 def F28()
9438 enddef
9439 def F29()
9440 enddef
9441 def F30()
9442 enddef
9443 def F31()
9444 enddef
9445 def F32()
9446 enddef
9447 def F33()
9448 enddef
9449 def F34()
9450 enddef
9451 def F35()
9452 enddef
9453 def F36()
9454 enddef
9455 def F37()
9456 enddef
9457 def F38()
9458 enddef
9459 def F39()
9460 enddef
9461 def F40()
9462 enddef
9463 def F41()
9464 enddef
9465 def F42()
9466 enddef
9467 def F43()
9468 enddef
9469 def F44()
9470 enddef
9471 def F45()
9472 enddef
9473 def F46()
9474 enddef
9475 def F47()
9476 enddef
9477 endclass
9478
9479 A.new()
9480 END
9481 writefile(lines, 'Xscript', 'D')
9482 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9483 assert_equal(0, v:shell_error)
9484enddef
9485
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009486" Test for 'final' class and object variables
9487def Test_final_class_object_variable()
9488 # Test for changing a final object variable from an object function
9489 var lines =<< trim END
9490 vim9script
9491 class A
9492 final foo: string = "abc"
9493 def Foo()
9494 this.foo = "def"
9495 enddef
9496 endclass
9497 defcompile A.Foo
9498 END
9499 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9500
9501 # Test for changing a final object variable from the 'new' function
9502 lines =<< trim END
9503 vim9script
9504 class A
9505 final s1: string
9506 final s2: string
9507 def new(this.s1)
9508 this.s2 = 'def'
9509 enddef
9510 endclass
9511 var a = A.new('abc')
9512 assert_equal('abc', a.s1)
9513 assert_equal('def', a.s2)
9514 END
9515 v9.CheckSourceSuccess(lines)
9516
9517 # Test for a final class variable
9518 lines =<< trim END
9519 vim9script
9520 class A
9521 static final s1: string = "abc"
9522 endclass
9523 assert_equal('abc', A.s1)
9524 END
9525 v9.CheckSourceSuccess(lines)
9526
9527 # Test for changing a final class variable from a class function
9528 lines =<< trim END
9529 vim9script
9530 class A
9531 static final s1: string = "abc"
9532 static def Foo()
9533 s1 = "def"
9534 enddef
9535 endclass
9536 A.Foo()
9537 END
9538 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9539
9540 # Test for changing a public final class variable at script level
9541 lines =<< trim END
9542 vim9script
9543 class A
9544 public static final s1: string = "abc"
9545 endclass
9546 assert_equal('abc', A.s1)
9547 A.s1 = 'def'
9548 END
9549 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9550
9551 # Test for changing a public final class variable from a class function
9552 lines =<< trim END
9553 vim9script
9554 class A
9555 public static final s1: string = "abc"
9556 static def Foo()
9557 s1 = "def"
9558 enddef
9559 endclass
9560 A.Foo()
9561 END
9562 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9563
9564 # Test for changing a public final class variable from a function
9565 lines =<< trim END
9566 vim9script
9567 class A
9568 public static final s1: string = "abc"
9569 endclass
9570 def Foo()
9571 A.s1 = 'def'
9572 enddef
9573 defcompile
9574 END
9575 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9576
9577 # Test for using a final variable of composite type
9578 lines =<< trim END
9579 vim9script
9580 class A
9581 public final l: list<number>
9582 def new()
9583 this.l = [1, 2]
9584 enddef
9585 def Foo()
9586 this.l[0] = 3
9587 this.l->add(4)
9588 enddef
9589 endclass
9590 var a = A.new()
9591 assert_equal([1, 2], a.l)
9592 a.Foo()
9593 assert_equal([3, 2, 4], a.l)
9594 END
9595 v9.CheckSourceSuccess(lines)
9596
9597 # Test for changing a final variable of composite type from another object
9598 # function
9599 lines =<< trim END
9600 vim9script
9601 class A
9602 public final l: list<number> = [1, 2]
9603 def Foo()
9604 this.l = [3, 4]
9605 enddef
9606 endclass
9607 var a = A.new()
9608 a.Foo()
9609 END
9610 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9611
9612 # Test for modifying a final variable of composite type at script level
9613 lines =<< trim END
9614 vim9script
9615 class A
9616 public final l: list<number> = [1, 2]
9617 endclass
9618 var a = A.new()
9619 a.l[0] = 3
9620 a.l->add(4)
9621 assert_equal([3, 2, 4], a.l)
9622 END
9623 v9.CheckSourceSuccess(lines)
9624
9625 # Test for modifying a final variable of composite type from a function
9626 lines =<< trim END
9627 vim9script
9628 class A
9629 public final l: list<number> = [1, 2]
9630 endclass
9631 def Foo()
9632 var a = A.new()
9633 a.l[0] = 3
9634 a.l->add(4)
9635 assert_equal([3, 2, 4], a.l)
9636 enddef
9637 Foo()
9638 END
9639 v9.CheckSourceSuccess(lines)
9640
9641 # Test for modifying a final variable of composite type from another object
9642 # function
9643 lines =<< trim END
9644 vim9script
9645 class A
9646 public final l: list<number> = [1, 2]
9647 def Foo()
9648 this.l[0] = 3
9649 this.l->add(4)
9650 enddef
9651 endclass
9652 var a = A.new()
9653 a.Foo()
9654 assert_equal([3, 2, 4], a.l)
9655 END
9656 v9.CheckSourceSuccess(lines)
9657
9658 # Test for assigning a new value to a final variable of composite type at
9659 # script level
9660 lines =<< trim END
9661 vim9script
9662 class A
9663 public final l: list<number> = [1, 2]
9664 endclass
9665 var a = A.new()
9666 a.l = [3, 4]
9667 END
9668 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9669
9670 # Test for assigning a new value to a final variable of composite type from
9671 # another object function
9672 lines =<< trim END
9673 vim9script
9674 class A
9675 public final l: list<number> = [1, 2]
9676 def Foo()
9677 this.l = [3, 4]
9678 enddef
9679 endclass
9680 var a = A.new()
9681 a.Foo()
9682 END
9683 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9684
9685 # Test for assigning a new value to a final variable of composite type from
9686 # another function
9687 lines =<< trim END
9688 vim9script
9689 class A
9690 public final l: list<number> = [1, 2]
9691 endclass
9692 def Foo()
9693 var a = A.new()
9694 a.l = [3, 4]
9695 enddef
9696 Foo()
9697 END
9698 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9699
9700 # Error case: Use 'final' with just a variable name
9701 lines =<< trim END
9702 vim9script
9703 class A
9704 final foo
9705 endclass
9706 var a = A.new()
9707 END
9708 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9709
9710 # Error case: Use 'final' followed by 'public'
9711 lines =<< trim END
9712 vim9script
9713 class A
9714 final public foo: number
9715 endclass
9716 var a = A.new()
9717 END
9718 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9719
9720 # Error case: Use 'final' followed by 'static'
9721 lines =<< trim END
9722 vim9script
9723 class A
9724 final static foo: number
9725 endclass
9726 var a = A.new()
9727 END
9728 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9729
9730 # Error case: 'final' cannot be used in an interface
9731 lines =<< trim END
9732 vim9script
9733 interface A
9734 final foo: number = 10
9735 endinterface
9736 END
9737 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9738
9739 # Error case: 'final' not supported for an object method
9740 lines =<< trim END
9741 vim9script
9742 class A
9743 final def Foo()
9744 enddef
9745 endclass
9746 END
9747 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9748
9749 # Error case: 'final' not supported for a class method
9750 lines =<< trim END
9751 vim9script
9752 class A
9753 static final def Foo()
9754 enddef
9755 endclass
9756 END
9757 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9758enddef
9759
9760" Test for 'const' class and object variables
9761def Test_const_class_object_variable()
9762 # Test for changing a const object variable from an object function
9763 var lines =<< trim END
9764 vim9script
9765 class A
9766 const foo: string = "abc"
9767 def Foo()
9768 this.foo = "def"
9769 enddef
9770 endclass
9771 defcompile A.Foo
9772 END
9773 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9774
9775 # Test for changing a const object variable from the 'new' function
9776 lines =<< trim END
9777 vim9script
9778 class A
9779 const s1: string
9780 const s2: string
9781 def new(this.s1)
9782 this.s2 = 'def'
9783 enddef
9784 endclass
9785 var a = A.new('abc')
9786 assert_equal('abc', a.s1)
9787 assert_equal('def', a.s2)
9788 END
9789 v9.CheckSourceSuccess(lines)
9790
9791 # Test for changing a const object variable from an object method called from
9792 # the 'new' function
9793 lines =<< trim END
9794 vim9script
9795 class A
9796 const s1: string = 'abc'
9797 def new()
9798 this.ChangeStr()
9799 enddef
9800 def ChangeStr()
9801 this.s1 = 'def'
9802 enddef
9803 endclass
9804 var a = A.new()
9805 END
9806 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9807
9808 # Test for a const class variable
9809 lines =<< trim END
9810 vim9script
9811 class A
9812 static const s1: string = "abc"
9813 endclass
9814 assert_equal('abc', A.s1)
9815 END
9816 v9.CheckSourceSuccess(lines)
9817
9818 # Test for changing a const class variable from a class function
9819 lines =<< trim END
9820 vim9script
9821 class A
9822 static const s1: string = "abc"
9823 static def Foo()
9824 s1 = "def"
9825 enddef
9826 endclass
9827 A.Foo()
9828 END
9829 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9830
9831 # Test for changing a public const class variable at script level
9832 lines =<< trim END
9833 vim9script
9834 class A
9835 public static const s1: string = "abc"
9836 endclass
9837 assert_equal('abc', A.s1)
9838 A.s1 = 'def'
9839 END
9840 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9841
9842 # Test for changing a public const class variable from a class function
9843 lines =<< trim END
9844 vim9script
9845 class A
9846 public static const s1: string = "abc"
9847 static def Foo()
9848 s1 = "def"
9849 enddef
9850 endclass
9851 A.Foo()
9852 END
9853 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9854
9855 # Test for changing a public const class variable from a function
9856 lines =<< trim END
9857 vim9script
9858 class A
9859 public static const s1: string = "abc"
9860 endclass
9861 def Foo()
9862 A.s1 = 'def'
9863 enddef
9864 defcompile
9865 END
9866 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9867
9868 # Test for changing a const List item from an object function
9869 lines =<< trim END
9870 vim9script
9871 class A
9872 public const l: list<number>
9873 def new()
9874 this.l = [1, 2]
9875 enddef
9876 def Foo()
9877 this.l[0] = 3
9878 enddef
9879 endclass
9880 var a = A.new()
9881 assert_equal([1, 2], a.l)
9882 a.Foo()
9883 END
9884 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9885
9886 # Test for adding a value to a const List from an object function
9887 lines =<< trim END
9888 vim9script
9889 class A
9890 public const l: list<number>
9891 def new()
9892 this.l = [1, 2]
9893 enddef
9894 def Foo()
9895 this.l->add(3)
9896 enddef
9897 endclass
9898 var a = A.new()
9899 a.Foo()
9900 END
9901 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9902
9903 # Test for reassigning a const List from an object function
9904 lines =<< trim END
9905 vim9script
9906 class A
9907 public const l: list<number> = [1, 2]
9908 def Foo()
9909 this.l = [3, 4]
9910 enddef
9911 endclass
9912 var a = A.new()
9913 a.Foo()
9914 END
9915 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9916
9917 # Test for changing a const List item at script level
9918 lines =<< trim END
9919 vim9script
9920 class A
9921 public const l: list<number> = [1, 2]
9922 endclass
9923 var a = A.new()
9924 a.l[0] = 3
9925 END
9926 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9927
9928 # Test for adding a value to a const List item at script level
9929 lines =<< trim END
9930 vim9script
9931 class A
9932 public const l: list<number> = [1, 2]
9933 endclass
9934 var a = A.new()
9935 a.l->add(4)
9936 END
9937 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9938
9939 # Test for changing a const List item from a function
9940 lines =<< trim END
9941 vim9script
9942 class A
9943 public const l: list<number> = [1, 2]
9944 endclass
9945 def Foo()
9946 var a = A.new()
9947 a.l[0] = 3
9948 enddef
9949 Foo()
9950 END
9951 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9952
9953 # Test for adding a value to a const List item from a function
9954 lines =<< trim END
9955 vim9script
9956 class A
9957 public const l: list<number> = [1, 2]
9958 endclass
9959 def Foo()
9960 var a = A.new()
9961 a.l->add(4)
9962 enddef
9963 Foo()
9964 END
9965 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9966
9967 # Test for changing a const List item from an object method
9968 lines =<< trim END
9969 vim9script
9970 class A
9971 public const l: list<number> = [1, 2]
9972 def Foo()
9973 this.l[0] = 3
9974 enddef
9975 endclass
9976 var a = A.new()
9977 a.Foo()
9978 END
9979 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9980
9981 # Test for adding a value to a const List item from an object method
9982 lines =<< trim END
9983 vim9script
9984 class A
9985 public const l: list<number> = [1, 2]
9986 def Foo()
9987 this.l->add(4)
9988 enddef
9989 endclass
9990 var a = A.new()
9991 a.Foo()
9992 END
9993 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9994
9995 # Test for reassigning a const List object variable at script level
9996 lines =<< trim END
9997 vim9script
9998 class A
9999 public const l: list<number> = [1, 2]
10000 endclass
10001 var a = A.new()
10002 a.l = [3, 4]
10003 END
10004 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
10005
10006 # Test for reassigning a const List object variable from an object method
10007 lines =<< trim END
10008 vim9script
10009 class A
10010 public const l: list<number> = [1, 2]
10011 def Foo()
10012 this.l = [3, 4]
10013 enddef
10014 endclass
10015 var a = A.new()
10016 a.Foo()
10017 END
10018 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
10019
10020 # Test for reassigning a const List object variable from another function
10021 lines =<< trim END
10022 vim9script
10023 class A
10024 public const l: list<number> = [1, 2]
10025 endclass
10026 def Foo()
10027 var a = A.new()
10028 a.l = [3, 4]
10029 enddef
10030 Foo()
10031 END
10032 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
10033
10034 # Error case: Use 'const' with just a variable name
10035 lines =<< trim END
10036 vim9script
10037 class A
10038 const foo
10039 endclass
10040 var a = A.new()
10041 END
10042 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10043
10044 # Error case: Use 'const' followed by 'public'
10045 lines =<< trim END
10046 vim9script
10047 class A
10048 const public foo: number
10049 endclass
10050 var a = A.new()
10051 END
10052 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10053
10054 # Error case: Use 'const' followed by 'static'
10055 lines =<< trim END
10056 vim9script
10057 class A
10058 const static foo: number
10059 endclass
10060 var a = A.new()
10061 END
10062 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10063
10064 # Error case: 'const' cannot be used in an interface
10065 lines =<< trim END
10066 vim9script
10067 interface A
10068 const foo: number = 10
10069 endinterface
10070 END
10071 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
10072
10073 # Error case: 'const' not supported for an object method
10074 lines =<< trim END
10075 vim9script
10076 class A
10077 const def Foo()
10078 enddef
10079 endclass
10080 END
10081 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10082
10083 # Error case: 'const' not supported for a class method
10084 lines =<< trim END
10085 vim9script
10086 class A
10087 static const def Foo()
10088 enddef
10089 endclass
10090 END
10091 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10092enddef
10093
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +010010094" Test for compiling class/object methods using :defcompile
10095def Test_defcompile_class()
10096 # defcompile all the classes in the current script
10097 var lines =<< trim END
10098 vim9script
10099 class A
10100 def Foo()
10101 var i = 10
10102 enddef
10103 endclass
10104 class B
10105 def Bar()
10106 var i = 20
10107 xxx
10108 enddef
10109 endclass
10110 defcompile
10111 END
10112 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
10113
10114 # defcompile a specific class
10115 lines =<< trim END
10116 vim9script
10117 class A
10118 def Foo()
10119 xxx
10120 enddef
10121 endclass
10122 class B
10123 def Bar()
10124 yyy
10125 enddef
10126 endclass
10127 defcompile B
10128 END
10129 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
10130
10131 # defcompile a non-class
10132 lines =<< trim END
10133 vim9script
10134 class A
10135 def Foo()
10136 enddef
10137 endclass
10138 var X: list<number> = []
10139 defcompile X
10140 END
10141 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
10142
10143 # defcompile a class twice
10144 lines =<< trim END
10145 vim9script
10146 class A
10147 def new()
10148 enddef
10149 endclass
10150 defcompile A
10151 defcompile A
10152 assert_equal('Function A.new does not need compiling', v:statusmsg)
10153 END
10154 v9.CheckSourceSuccess(lines)
10155
10156 # defcompile should not compile an imported class
10157 lines =<< trim END
10158 vim9script
10159 export class A
10160 def Foo()
10161 xxx
10162 enddef
10163 endclass
10164 END
10165 writefile(lines, 'Xdefcompileimport.vim', 'D')
10166 lines =<< trim END
10167 vim9script
10168
10169 import './Xdefcompileimport.vim'
10170 class B
10171 endclass
10172 defcompile
10173 END
10174 v9.CheckScriptSuccess(lines)
10175enddef
10176
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +010010177" Test for cases common to all the object builtin methods
10178def Test_object_builtin_method()
10179 var lines =<< trim END
10180 vim9script
10181 class A
10182 def abc()
10183 enddef
10184 endclass
10185 END
10186 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
10187
10188 for funcname in ["len", "string", "empty"]
10189 lines =<< trim eval END
10190 vim9script
10191 class A
10192 static def {funcname}(): number
10193 enddef
10194 endclass
10195 END
10196 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
10197 endfor
10198enddef
10199
10200" Test for using the empty() builtin method with an object
10201" This is a legacy function to use the test_garbagecollect_now() function.
10202func Test_object_empty()
10203 let lines =<< trim END
10204 vim9script
10205 class A
10206 def empty(): bool
10207 return true
10208 enddef
10209 endclass
10210
10211 def Foo()
10212 var afoo = A.new()
10213 assert_equal(true, empty(afoo))
10214 assert_equal(true, afoo->empty())
10215 enddef
10216
10217 var a = A.new()
10218 assert_equal(1, empty(a))
10219 assert_equal(1, a->empty())
10220 test_garbagecollect_now()
10221 assert_equal(1, empty(a))
10222 Foo()
10223 test_garbagecollect_now()
10224 Foo()
10225 END
10226 call v9.CheckSourceSuccess(lines)
10227
10228 " empty() should return 1 without a builtin method
10229 let lines =<< trim END
10230 vim9script
10231 class A
10232 endclass
10233
10234 def Foo()
10235 var afoo = A.new()
10236 assert_equal(1, empty(afoo))
10237 enddef
10238
10239 var a = A.new()
10240 assert_equal(1, empty(a))
10241 Foo()
10242 END
10243 call v9.CheckSourceSuccess(lines)
10244
10245 " Unsupported signature for the empty() method
10246 let lines =<< trim END
10247 vim9script
10248 class A
10249 def empty()
10250 enddef
10251 endclass
10252 END
10253 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
10254
10255 " Error when calling the empty() method
10256 let lines =<< trim END
10257 vim9script
10258 class A
10259 def empty(): bool
10260 throw "Failed to check emptiness"
10261 enddef
10262 endclass
10263
10264 def Foo()
10265 var afoo = A.new()
10266 var i = empty(afoo)
10267 enddef
10268
10269 var a = A.new()
10270 assert_fails('empty(a)', 'Failed to check emptiness')
10271 assert_fails('Foo()', 'Failed to check emptiness')
10272 END
10273 call v9.CheckSourceSuccess(lines)
10274
10275 " call empty() using an object from a script
10276 let lines =<< trim END
10277 vim9script
10278 class A
10279 def empty(): bool
10280 return true
10281 enddef
10282 endclass
10283 var afoo = A.new()
10284 assert_equal(true, afoo.empty())
10285 END
10286 call v9.CheckSourceSuccess(lines)
10287
10288 " call empty() using an object from a method
10289 let lines =<< trim END
10290 vim9script
10291 class A
10292 def empty(): bool
10293 return true
10294 enddef
10295 endclass
10296 def Foo()
10297 var afoo = A.new()
10298 assert_equal(true, afoo.empty())
10299 enddef
10300 Foo()
10301 END
10302 call v9.CheckSourceSuccess(lines)
10303
10304 " call empty() using "this" from an object method
10305 let lines =<< trim END
10306 vim9script
10307 class A
10308 def empty(): bool
10309 return true
10310 enddef
10311 def Foo(): bool
10312 return this.empty()
10313 enddef
10314 endclass
10315 def Bar()
10316 var abar = A.new()
10317 assert_equal(true, abar.Foo())
10318 enddef
10319 Bar()
10320 END
10321 call v9.CheckSourceSuccess(lines)
10322
10323 " Call empty() from a derived object
10324 let lines =<< trim END
10325 vim9script
10326 class A
10327 def empty(): bool
10328 return false
10329 enddef
10330 endclass
10331 class B extends A
10332 def empty(): bool
10333 return true
10334 enddef
10335 endclass
10336 def Foo(afoo: A)
10337 assert_equal(true, empty(afoo))
10338 var bfoo = B.new()
10339 assert_equal(true, empty(bfoo))
10340 enddef
10341 var b = B.new()
10342 assert_equal(1, empty(b))
10343 Foo(b)
10344 END
10345 call v9.CheckSourceSuccess(lines)
10346
10347 " Invoking empty method using an interface
10348 let lines =<< trim END
10349 vim9script
10350 interface A
10351 def empty(): bool
10352 endinterface
10353 class B implements A
10354 def empty(): bool
10355 return false
10356 enddef
10357 endclass
10358 def Foo(a: A)
10359 assert_equal(false, empty(a))
10360 enddef
10361 var b = B.new()
10362 Foo(b)
10363 END
10364 call v9.CheckSourceSuccess(lines)
10365endfunc
10366
10367" Test for using the len() builtin method with an object
10368" This is a legacy function to use the test_garbagecollect_now() function.
10369func Test_object_length()
10370 let lines =<< trim END
10371 vim9script
10372 class A
10373 var mylen: number = 0
10374 def new(n: number)
10375 this.mylen = n
10376 enddef
10377 def len(): number
10378 return this.mylen
10379 enddef
10380 endclass
10381
10382 def Foo()
10383 var afoo = A.new(12)
10384 assert_equal(12, len(afoo))
10385 assert_equal(12, afoo->len())
10386 enddef
10387
10388 var a = A.new(22)
10389 assert_equal(22, len(a))
10390 assert_equal(22, a->len())
10391 test_garbagecollect_now()
10392 assert_equal(22, len(a))
10393 Foo()
10394 test_garbagecollect_now()
10395 Foo()
10396 END
10397 call v9.CheckSourceSuccess(lines)
10398
10399 " len() should return 0 without a builtin method
10400 let lines =<< trim END
10401 vim9script
10402 class A
10403 endclass
10404
10405 def Foo()
10406 var afoo = A.new()
10407 assert_equal(0, len(afoo))
10408 enddef
10409
10410 var a = A.new()
10411 assert_equal(0, len(a))
10412 Foo()
10413 END
10414 call v9.CheckSourceSuccess(lines)
10415
10416 " Unsupported signature for the len() method
10417 let lines =<< trim END
10418 vim9script
10419 class A
10420 def len()
10421 enddef
10422 endclass
10423 END
10424 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10425
10426 " Error when calling the len() method
10427 let lines =<< trim END
10428 vim9script
10429 class A
10430 def len(): number
10431 throw "Failed to compute length"
10432 enddef
10433 endclass
10434
10435 def Foo()
10436 var afoo = A.new()
10437 var i = len(afoo)
10438 enddef
10439
10440 var a = A.new()
10441 assert_fails('len(a)', 'Failed to compute length')
10442 assert_fails('Foo()', 'Failed to compute length')
10443 END
10444 call v9.CheckSourceSuccess(lines)
10445
10446 " call len() using an object from a script
10447 let lines =<< trim END
10448 vim9script
10449 class A
10450 def len(): number
10451 return 5
10452 enddef
10453 endclass
10454 var afoo = A.new()
10455 assert_equal(5, afoo.len())
10456 END
10457 call v9.CheckSourceSuccess(lines)
10458
10459 " call len() using an object from a method
10460 let lines =<< trim END
10461 vim9script
10462 class A
10463 def len(): number
10464 return 5
10465 enddef
10466 endclass
10467 def Foo()
10468 var afoo = A.new()
10469 assert_equal(5, afoo.len())
10470 enddef
10471 Foo()
10472 END
10473 call v9.CheckSourceSuccess(lines)
10474
10475 " call len() using "this" from an object method
10476 let lines =<< trim END
10477 vim9script
10478 class A
10479 def len(): number
10480 return 8
10481 enddef
10482 def Foo(): number
10483 return this.len()
10484 enddef
10485 endclass
10486 def Bar()
10487 var abar = A.new()
10488 assert_equal(8, abar.Foo())
10489 enddef
10490 Bar()
10491 END
10492 call v9.CheckSourceSuccess(lines)
10493
10494 " Call len() from a derived object
10495 let lines =<< trim END
10496 vim9script
10497 class A
10498 def len(): number
10499 return 10
10500 enddef
10501 endclass
10502 class B extends A
10503 def len(): number
10504 return 20
10505 enddef
10506 endclass
10507 def Foo(afoo: A)
10508 assert_equal(20, len(afoo))
10509 var bfoo = B.new()
10510 assert_equal(20, len(bfoo))
10511 enddef
10512 var b = B.new()
10513 assert_equal(20, len(b))
10514 Foo(b)
10515 END
10516 call v9.CheckSourceSuccess(lines)
10517
10518 " Invoking len method using an interface
10519 let lines =<< trim END
10520 vim9script
10521 interface A
10522 def len(): number
10523 endinterface
10524 class B implements A
10525 def len(): number
10526 return 123
10527 enddef
10528 endclass
10529 def Foo(a: A)
10530 assert_equal(123, len(a))
10531 enddef
10532 var b = B.new()
10533 Foo(b)
10534 END
10535 call v9.CheckSourceSuccess(lines)
10536endfunc
10537
10538" Test for using the string() builtin method with an object
10539" This is a legacy function to use the test_garbagecollect_now() function.
10540func Test_object_string()
10541 let lines =<< trim END
10542 vim9script
10543 class A
10544 var name: string
10545 def string(): string
10546 return this.name
10547 enddef
10548 endclass
10549
10550 def Foo()
10551 var afoo = A.new("foo-A")
10552 assert_equal('foo-A', string(afoo))
10553 assert_equal('foo-A', afoo->string())
10554 enddef
10555
10556 var a = A.new("script-A")
10557 assert_equal('script-A', string(a))
10558 assert_equal('script-A', a->string())
10559 assert_equal(['script-A'], execute('echo a')->split("\n"))
10560 test_garbagecollect_now()
10561 assert_equal('script-A', string(a))
10562 Foo()
10563 test_garbagecollect_now()
10564 Foo()
10565 END
10566 call v9.CheckSourceSuccess(lines)
10567
10568 " string() should return "object of A {}" without a builtin method
10569 let lines =<< trim END
10570 vim9script
10571 class A
10572 endclass
10573
10574 def Foo()
10575 var afoo = A.new()
10576 assert_equal('object of A {}', string(afoo))
10577 enddef
10578
10579 var a = A.new()
10580 assert_equal('object of A {}', string(a))
10581 Foo()
10582 END
10583 call v9.CheckSourceSuccess(lines)
10584
10585 " Unsupported signature for the string() method
10586 let lines =<< trim END
10587 vim9script
10588 class A
10589 def string()
10590 enddef
10591 endclass
10592 END
10593 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10594
10595 " Error when calling the string() method
10596 let lines =<< trim END
10597 vim9script
10598 class A
10599 def string(): string
10600 throw "Failed to get text"
10601 enddef
10602 endclass
10603
10604 def Foo()
10605 var afoo = A.new()
10606 var i = string(afoo)
10607 enddef
10608
10609 var a = A.new()
10610 assert_fails('string(a)', 'Failed to get text')
10611 assert_fails('Foo()', 'Failed to get text')
10612 END
10613 call v9.CheckSourceSuccess(lines)
10614
10615 " call string() using an object from a script
10616 let lines =<< trim END
10617 vim9script
10618 class A
10619 def string(): string
10620 return 'A'
10621 enddef
10622 endclass
10623 var afoo = A.new()
10624 assert_equal('A', afoo.string())
10625 END
10626 call v9.CheckSourceSuccess(lines)
10627
10628 " call string() using an object from a method
10629 let lines =<< trim END
10630 vim9script
10631 class A
10632 def string(): string
10633 return 'A'
10634 enddef
10635 endclass
10636 def Foo()
10637 var afoo = A.new()
10638 assert_equal('A', afoo.string())
10639 enddef
10640 Foo()
10641 END
10642 call v9.CheckSourceSuccess(lines)
10643
10644 " call string() using "this" from an object method
10645 let lines =<< trim END
10646 vim9script
10647 class A
10648 def string(): string
10649 return 'A'
10650 enddef
10651 def Foo(): string
10652 return this.string()
10653 enddef
10654 endclass
10655 def Bar()
10656 var abar = A.new()
10657 assert_equal('A', abar.string())
10658 enddef
10659 Bar()
10660 END
10661 call v9.CheckSourceSuccess(lines)
10662
10663 " Call string() from a derived object
10664 let lines =<< trim END
10665 vim9script
10666 class A
10667 def string(): string
10668 return 'A'
10669 enddef
10670 endclass
10671 class B extends A
10672 def string(): string
10673 return 'B'
10674 enddef
10675 endclass
10676 def Foo(afoo: A)
10677 assert_equal('B', string(afoo))
10678 var bfoo = B.new()
10679 assert_equal('B', string(bfoo))
10680 enddef
10681 var b = B.new()
10682 assert_equal('B', string(b))
10683 Foo(b)
10684 END
10685 call v9.CheckSourceSuccess(lines)
10686
10687 " Invoking string method using an interface
10688 let lines =<< trim END
10689 vim9script
10690 interface A
10691 def string(): string
10692 endinterface
10693 class B implements A
10694 def string(): string
10695 return 'B'
10696 enddef
10697 endclass
10698 def Foo(a: A)
10699 assert_equal('B', string(a))
10700 enddef
10701 var b = B.new()
10702 Foo(b)
10703 END
10704 call v9.CheckSourceSuccess(lines)
10705endfunc
10706
Ernie Rael9d779c52024-07-07 20:41:44 +020010707" Test for using the string() builtin method with an object's method
10708def Test_method_string()
10709 var lines =<< trim END
10710 vim9script
10711 class A
10712 def F()
10713 enddef
10714 endclass
10715 assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F))
10716 END
10717 v9.CheckScriptSuccess(lines)
10718enddef
10719
10720
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010721" Test for using a class in the class definition
10722def Test_Ref_Class_Within_Same_Class()
10723 var lines =<< trim END
10724 vim9script
10725 class A
10726 var n: number = 0
10727 def Equals(other: A): bool
10728 return this.n == other.n
10729 enddef
10730 endclass
10731
10732 var a1 = A.new(10)
10733 var a2 = A.new(10)
10734 var a3 = A.new(20)
10735 assert_equal(true, a1.Equals(a2))
10736 assert_equal(false, a2.Equals(a3))
10737 END
10738 v9.CheckScriptSuccess(lines)
10739
10740 lines =<< trim END
10741 vim9script
10742
10743 class Foo
10744 var num: number
10745 def Clone(): Foo
10746 return Foo.new(this.num)
10747 enddef
10748 endclass
10749
10750 var f1 = Foo.new(1)
10751
10752 def F()
10753 var f2: Foo = f1.Clone()
10754 assert_equal(false, f2 is f1)
10755 assert_equal(true, f2.num == f1.num)
10756 enddef
10757 F()
10758
10759 var f3: Foo = f1.Clone()
10760 assert_equal(false, f3 is f1)
10761 assert_equal(true, f3.num == f1.num)
10762 END
10763 v9.CheckScriptSuccess(lines)
10764
10765 # Test for trying to use a class to extend when defining the same class
10766 lines =<< trim END
10767 vim9script
10768 class A extends A
10769 endclass
10770 END
10771 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10772
10773 # Test for trying to use a class to implement when defining the same class
10774 lines =<< trim END
10775 vim9script
10776 class A implements A
10777 endclass
10778 END
10779 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10780enddef
10781
Ernie Raelf0e69142024-06-22 11:12:00 +020010782" Test for comparing a class referencing itself
10783def Test_Object_Compare_With_Recursive_Class_Ref()
10784 var lines =<< trim END
10785 vim9script
10786
10787 class C
10788 public var nest: C
10789 endclass
10790
10791 var o1 = C.new()
10792 o1.nest = o1
10793
10794 var result = o1 == o1
10795 assert_equal(true, result)
10796 END
10797 v9.CheckScriptSuccess(lines)
Ernie Rael86257142024-06-23 09:54:45 +020010798
10799 lines =<< trim END
10800 vim9script
10801
10802 class C
10803 public var nest: C
10804 endclass
10805 var o1 = C.new()
10806 var o2 = C.new(C.new())
10807
10808 var result = o1 == o2
10809 assert_equal(false, result)
10810 END
10811 v9.CheckScriptSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +020010812
10813 lines =<< trim END
10814 vim9script
10815 class C
10816 var nest1: C
10817 var nest2: C
10818 def Init(n1: C, n2: C)
10819 this.nest1 = n1
10820 this.nest2 = n2
10821 enddef
10822 endclass
10823
10824 var o1 = C.new()
10825 var o2 = C.new()
10826 o1.Init(o1, o2)
10827 o2.Init(o2, o1)
10828
10829 var result = o1 == o2
10830 assert_equal(true, result)
10831 END
10832 v9.CheckScriptSuccess(lines)
Ernie Raelf0e69142024-06-22 11:12:00 +020010833enddef
10834
Ernie Raelf3975492024-07-06 11:44:37 +020010835" Test for comparing a class with nesting objects
10836def Test_Object_Compare_With_Nesting_Objects()
10837 # On a compare, after vim equal recurses 1000 times, not finding an unequal,
10838 # return the compare is equal.
10839 # Test that limit
10840
10841 var lines =<< trim END
10842 vim9script
10843 class C
10844 public var n: number
10845 public var nest: C
10846
10847 # Create a "C" that chains/nests to indicated depth.
10848 # return {head: firstC, tail: lastC}
10849 static def CreateNested(depth: number): dict<C>
10850 var first = C.new(1, null_object)
10851 var last = first
10852 for i in range(2, depth)
10853 last.nest = C.new(i, null_object)
10854 last = last.nest
10855 endfor
10856 return {head: first, tail: last}
10857 enddef
10858
10859 # Return pointer to nth item in chain.
10860 def GetLink(depth: number): C
10861 var count = 1
10862 var p: C = this
10863 while count < depth
10864 p = p.nest
10865 if p == null
10866 throw "too deep"
10867 endif
10868 count += 1
10869 endwhile
10870 return p
10871 enddef
10872
10873 # Return the length of the chain
10874 def len(): number
10875 var count = 1
10876 var p: C = this
10877 while p.nest != null
10878 p = p.nest
10879 count += 1
10880 endwhile
10881 return count
10882 enddef
10883 endclass
10884
10885 var chain = C.CreateNested(3)
10886 var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}"
10887 assert_equal(s, string(chain.head))
10888 assert_equal(3, chain.head->len())
10889
10890 var chain1 = C.CreateNested(100)
10891 var chain2 = C.CreateNested(100)
10892 assert_true(chain1.head == chain2.head)
10893
10894 # modify the tail of chain2, compare not equal
10895 chain2.tail.n = 123456
10896 assert_true(chain1.head != chain2.head)
10897
10898 # a tail of a different length compares not equal
10899 chain2 = C.CreateNested(101)
10900 assert_true(chain1.head != chain2.head)
10901
10902 chain1 = C.CreateNested(1000)
10903 chain2 = C.CreateNested(1000)
10904 assert_true(chain1.head == chain2.head)
10905
10906 # modify the tail of chain2, compare not equal
10907 chain2.tail.n = 123456
10908 assert_true(chain1.head != chain2.head)
10909
10910 # try a chain longer that the limit
10911 chain1 = C.CreateNested(1001)
10912 chain2 = C.CreateNested(1001)
10913 assert_true(chain1.head == chain2.head)
10914
10915 # modify the tail, but still equal
10916 chain2.tail.n = 123456
10917 assert_true(chain1.head == chain2.head)
10918
10919 # remove 2 items from front, shorten the chain by two.
10920 chain1.head = chain1.head.GetLink(3)
10921 chain2.head = chain2.head.GetLink(3)
10922 assert_equal(3, chain1.head.n)
10923 assert_equal(3, chain2.head.n)
10924 assert_equal(999, chain1.head->len())
10925 assert_equal(999, chain2.head->len())
10926 # Now less than the limit, compare not equal
10927 assert_true(chain1.head != chain2.head)
10928 END
10929 v9.CheckScriptSuccess(lines)
10930enddef
10931
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010932" Test for using a compound operator from a lambda function in an object method
10933def Test_compound_op_in_objmethod_lambda()
10934 # Test using the "+=" operator
10935 var lines =<< trim END
10936 vim9script
10937 class A
10938 var n: number = 10
10939 def Foo()
10940 var Fn = () => {
10941 this.n += 1
10942 }
10943 Fn()
10944 enddef
10945 endclass
10946
10947 var a = A.new()
10948 a.Foo()
10949 assert_equal(11, a.n)
10950 END
10951 v9.CheckScriptSuccess(lines)
10952
10953 # Test using the "..=" operator
10954 lines =<< trim END
10955 vim9script
10956 class A
10957 var s: string = "a"
10958 def Foo()
10959 var Fn = () => {
10960 this.s ..= "a"
10961 }
10962 Fn()
10963 enddef
10964 endclass
10965
10966 var a = A.new()
10967 a.Foo()
10968 a.Foo()
10969 assert_equal("aaa", a.s)
10970 END
10971 v9.CheckScriptSuccess(lines)
10972enddef
10973
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010974" Test for using test_refcount() with a class and an object
10975def Test_class_object_refcount()
10976 var lines =<< trim END
10977 vim9script
10978 class A
10979 endclass
10980 var a: A = A.new()
10981 assert_equal(2, test_refcount(A))
10982 assert_equal(1, test_refcount(a))
10983 var b = a
10984 assert_equal(2, test_refcount(A))
10985 assert_equal(2, test_refcount(a))
10986 assert_equal(2, test_refcount(b))
10987 END
10988 v9.CheckScriptSuccess(lines)
10989enddef
10990
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010991" call a lambda function in one object from another object
10992def Test_lambda_invocation_across_classes()
10993 var lines =<< trim END
10994 vim9script
10995 class A
10996 var s: string = "foo"
10997 def GetFn(): func
10998 var Fn = (): string => {
10999 return this.s
11000 }
11001 return Fn
11002 enddef
11003 endclass
11004
11005 class B
11006 var s: string = "bar"
11007 def GetFn(): func
11008 var a = A.new()
11009 return a.GetFn()
11010 enddef
11011 endclass
11012
11013 var b = B.new()
11014 var Fn = b.GetFn()
11015 assert_equal("foo", Fn())
11016 END
11017 v9.CheckScriptSuccess(lines)
11018enddef
11019
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010011020" Test for using a class member which is an object of the current class
11021def Test_current_class_object_class_member()
11022 var lines =<< trim END
11023 vim9script
11024 class A
11025 public static var obj1: A = A.new(10)
11026 var n: number
11027 endclass
11028 defcompile
11029 assert_equal(10, A.obj1.n)
11030 END
11031 v9.CheckScriptSuccess(lines)
11032enddef
11033
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020011034" Test for updating a base class variable from a base class method without the
11035" class name. This used to crash Vim (Github issue #14352).
11036def Test_use_base_class_variable_from_base_class_method()
11037 var lines =<< trim END
11038 vim9script
11039
11040 class DictKeyClass
11041 static var _obj_id_count = 1
11042 def _GenerateKey()
11043 _obj_id_count += 1
11044 enddef
11045 static def GetIdCount(): number
11046 return _obj_id_count
11047 enddef
11048 endclass
11049
11050 class C extends DictKeyClass
11051 def F()
11052 this._GenerateKey()
11053 enddef
11054 endclass
11055
11056 C.new().F()
11057 assert_equal(2, DictKeyClass.GetIdCount())
11058 END
11059 v9.CheckScriptSuccess(lines)
11060enddef
11061
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020011062" Test for accessing protected funcref object and class variables
11063def Test_protected_funcref()
11064 # protected funcref object variable
11065 var lines =<< trim END
11066 vim9script
11067 class Test1
11068 const _Id: func(any): any = (v) => v
11069 endclass
11070 var n = Test1.new()._Id(1)
11071 END
11072 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
11073
11074 # protected funcref class variable
11075 lines =<< trim END
11076 vim9script
11077 class Test2
11078 static const _Id: func(any): any = (v) => v
11079 endclass
11080 var n = Test2._Id(2)
11081 END
11082 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
11083enddef
11084
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020011085" Test for using lambda block in classes
11086def Test_lambda_block_in_class()
11087 # This used to crash Vim
11088 var lines =<< trim END
11089 vim9script
11090 class IdClass1
11091 const Id: func(number): number = (num: number): number => {
11092 # Return a ID
11093 return num * 10
11094 }
11095 endclass
11096 var id = IdClass1.new()
11097 assert_equal(20, id.Id(2))
11098 END
11099 v9.CheckScriptSuccess(lines)
11100
11101 # This used to crash Vim
11102 lines =<< trim END
11103 vim9script
11104 class IdClass2
11105 static const Id: func(number): number = (num: number): number => {
11106 # Return a ID
11107 return num * 2
11108 }
11109 endclass
11110 assert_equal(16, IdClass2.Id(8))
11111 END
11112 v9.CheckScriptSuccess(lines)
11113enddef
11114
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020011115" Test for defcompiling an abstract method
11116def Test_abstract_method_defcompile()
11117 # Compile an abstract class with abstract object methods
11118 var lines =<< trim END
11119 vim9script
11120 abstract class A
11121 abstract def Foo(): string
11122 abstract def Bar(): list<string>
11123 endclass
11124 defcompile
11125 END
11126 v9.CheckScriptSuccess(lines)
11127
11128 # Compile a concrete object method in an abstract class
11129 lines =<< trim END
11130 vim9script
11131 abstract class A
11132 abstract def Foo(): string
11133 abstract def Bar(): list<string>
11134 def Baz(): string
11135 pass
11136 enddef
11137 endclass
11138 defcompile
11139 END
11140 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
11141
11142 # Compile a concrete class method in an abstract class
11143 lines =<< trim END
11144 vim9script
11145 abstract class A
11146 abstract def Foo(): string
11147 abstract def Bar(): list<string>
11148 static def Baz(): string
11149 pass
11150 enddef
11151 endclass
11152 defcompile
11153 END
11154 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
11155enddef
11156
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020011157" Test for defining a class in a function
11158def Test_class_definition_in_a_function()
11159 var lines =<< trim END
11160 vim9script
11161 def Foo()
11162 class A
11163 endclass
11164 enddef
11165 defcompile
11166 END
11167 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
11168enddef
11169
Yegappan Lakshmanandbac0da2024-05-25 20:23:54 +020011170" Test for using [] with a class and an object
11171def Test_class_object_index()
11172 var lines =<< trim END
11173 vim9script
11174 class A
11175 endclass
11176 A[10] = 1
11177 END
11178 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a class: A[10] = 1', 4)
11179
11180 lines =<< trim END
11181 vim9script
11182 class A
11183 endclass
11184 var a = A.new()
11185 a[10] = 1
11186 END
11187 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5)
11188enddef
11189
LemonBoyf4af3312024-07-04 13:43:12 +020011190def Test_class_member_init_typecheck()
11191 # Ensure the class member is assigned its declared type.
11192 var lines =<< trim END
11193 vim9script
11194 class S
11195 static var l: list<string> = []
11196 endclass
11197 S.l->add(123)
11198 END
11199 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5)
11200
11201 # Ensure the initializer value and the declared type match.
11202 lines =<< trim END
11203 vim9script
11204 class S
11205 var l: list<string> = [1, 2, 3]
11206 endclass
11207 var o = S.new()
11208 END
11209 v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>')
11210
11211 # Ensure the class member is assigned its declared type.
11212 lines =<< trim END
11213 vim9script
11214 class S
11215 var l: list<string> = []
11216 endclass
11217 var o = S.new()
11218 o.l->add(123)
11219 END
11220 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6)
11221enddef
11222
LemonBoy50d48542024-07-04 17:03:17 +020011223def Test_class_cast()
11224 var lines =<< trim END
11225 vim9script
11226 class A
11227 endclass
11228 class B extends A
11229 var mylen: number
11230 endclass
11231 def F(o: A): number
11232 return (<B>o).mylen
11233 enddef
11234
11235 defcompile F
11236 END
11237 v9.CheckScriptSuccess(lines)
11238enddef
11239
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011240" Test for using a variable of type "any" with an object
11241def Test_any_obj_var_type()
11242 var lines =<< trim END
11243 vim9script
11244 class A
11245 var name: string = "foobar"
11246 def Foo(): string
11247 return "func foo"
11248 enddef
11249 endclass
11250
11251 def CheckVals(x: any)
11252 assert_equal("foobar", x.name)
11253 assert_equal("func foo", x.Foo())
11254 enddef
11255
11256 var a = A.new()
11257 CheckVals(a)
11258 END
11259 v9.CheckScriptSuccess(lines)
11260
11261 # Try to set a non-existing variable
11262 lines =<< trim END
11263 vim9script
11264 class A
11265 var name: string = "foobar"
11266 endclass
11267
11268 def SetNonExistingVar(x: any)
11269 x.bar = [1, 2, 3]
11270 enddef
11271
11272 var a = A.new()
11273 SetNonExistingVar(a)
11274 END
11275 v9.CheckScriptFailure(lines, 'E1326: Variable "bar" not found in object "A"', 1)
11276
11277 # Try to read a non-existing variable
11278 lines =<< trim END
11279 vim9script
11280 class A
11281 var name: string = "foobar"
11282 endclass
11283
11284 def GetNonExistingVar(x: any)
11285 var i: dict<any> = x.bar
11286 enddef
11287
11288 var a = A.new()
11289 GetNonExistingVar(a)
11290 END
11291 v9.CheckScriptFailure(lines, 'E1326: Variable "bar" not found in object "A"', 1)
11292
11293 # Try to invoke a non-existing method
11294 lines =<< trim END
11295 vim9script
11296 class A
11297 def Foo(): number
11298 return 10
11299 enddef
11300 endclass
11301
11302 def CallNonExistingMethod(x: any)
11303 var i: number = x.Bar()
11304 enddef
11305
11306 var a = A.new()
11307 CallNonExistingMethod(a)
11308 END
11309 v9.CheckScriptFailure(lines, 'E1326: Variable "Bar" not found in object "A"', 1)
11310
11311 # Use an object which is a Dict value
11312 lines =<< trim END
11313 vim9script
11314 class Foo
11315 def Bar(): number
11316 return 369
11317 enddef
11318 endclass
11319
11320 def GetValue(FooDict: dict<any>): number
11321 var n: number = 0
11322 for foo in values(FooDict)
11323 n += foo.Bar()
11324 endfor
11325 return n
11326 enddef
11327
11328 var d = {'x': Foo.new()}
11329 assert_equal(369, GetValue(d))
11330 END
11331 v9.CheckScriptSuccess(lines)
11332
zeertzjqd32bf0a2024-12-17 20:55:13 +010011333 # Nested data. Object containing a Dict containing another Object.
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011334 lines =<< trim END
11335 vim9script
11336 class Context
11337 public var state: dict<any> = {}
11338 endclass
11339
11340 class Metadata
11341 public var value = 0
11342 endclass
11343
11344 var ctx = Context.new()
11345 ctx.state["meta"] = Metadata.new(2468)
11346
11347 const foo = ctx.state.meta.value
11348
11349 def F(): number
11350 const bar = ctx.state.meta.value
11351 return bar
11352 enddef
11353
11354 assert_equal(2468, F())
11355 END
11356 v9.CheckScriptSuccess(lines)
11357
11358 # Accessing an object from a method inside the class using any type
11359 lines =<< trim END
11360 vim9script
11361 class C
11362 def _G(): string
11363 return '_G'
11364 enddef
11365 static def S(o_any: any): string
11366 return o_any._G()
11367 enddef
11368 endclass
11369
11370 var o1 = C.new()
11371 assert_equal('_G', C.S(o1))
11372 END
11373 v9.CheckScriptSuccess(lines)
11374
11375 # Modifying an object private variable from a method in another class using
11376 # any type
11377 lines =<< trim END
11378 vim9script
11379
11380 class A
11381 var num = 10
11382 endclass
11383
11384 class B
11385 def SetVal(x: any)
11386 x.num = 20
11387 enddef
11388 endclass
11389
11390 var a = A.new()
11391 var b = B.new()
11392 b.SetVal(a)
11393 END
11394 v9.CheckScriptFailure(lines, 'E1335: Variable "num" in class "A" is not writable', 1)
11395
11396 # Accessing a object protected variable from a method in another class using
11397 # any type
11398 lines =<< trim END
11399 vim9script
11400
11401 class A
11402 var _num = 10
11403 endclass
11404
11405 class B
11406 def GetVal(x: any): number
11407 return x._num
11408 enddef
11409 endclass
11410
11411 var a = A.new()
11412 var b = B.new()
11413 var i = b.GetVal(a)
11414 END
11415 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_num" in class "A"', 1)
11416
11417 # Accessing an object returned from an imported function and class
11418 lines =<< trim END
11419 vim9script
11420 export class Foo
11421 public var name: string
11422 endclass
11423
11424 export def ReturnFooObject(): Foo
11425 var r = Foo.new('star')
11426 return r
11427 enddef
11428 END
11429 writefile(lines, 'Xanyvar1.vim', 'D')
11430
11431 lines =<< trim END
11432 vim9script
11433
11434 import './Xanyvar1.vim'
11435
11436 def GetName(): string
11437 var whatever = Xanyvar1.ReturnFooObject()
11438 return whatever.name
11439 enddef
11440
11441 assert_equal('star', GetName())
11442 END
11443 v9.CheckScriptSuccess(lines)
11444
11445 # Try to modify a private object variable using a variable of type "any"
11446 lines =<< trim END
11447 vim9script
11448
11449 class Foo
11450 var n: number = 10
11451 endclass
11452 def Fn(x: any)
11453 x.n = 20
11454 enddef
11455 var a = Foo.new()
11456 Fn(a)
11457 END
11458 v9.CheckScriptFailure(lines, 'E1335: Variable "n" in class "Foo" is not writable', 1)
11459
11460 # Try to read a protected object variable using a variable of type "any"
11461 lines =<< trim END
11462 vim9script
11463
11464 class Foo
11465 var _n: number = 10
11466 endclass
11467 def Fn(x: any): number
11468 return x._n
11469 enddef
11470
11471 var a = Foo.new()
11472 Fn(a)
11473 END
11474 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_n" in class "Foo"', 1)
11475
11476 # Read a protected object variable using a variable of type "any" in an object
11477 # method
11478 lines =<< trim END
11479 vim9script
11480
11481 class Foo
11482 var _n: number = 10
11483 def Fn(x: any): number
11484 return x._n
11485 enddef
11486 endclass
11487
11488 var a = Foo.new()
11489 assert_equal(10, a.Fn(a))
11490 END
11491 v9.CheckScriptSuccess(lines)
11492
11493 # Try to call a protected object method using a "any" type variable
11494 lines =<< trim END
11495 vim9script
11496
11497 class Foo
11498 def _GetVal(): number
11499 return 234
11500 enddef
11501 endclass
11502 def Fn(x: any): number
11503 return x._GetVal()
11504 enddef
11505
11506 var a = Foo.new()
11507 Fn(a)
11508 END
11509 v9.CheckScriptFailure(lines, 'E1366: Cannot access protected method: _GetVal', 1)
11510
11511 # Call a protected object method using a "any" type variable from another
11512 # object method
11513 lines =<< trim END
11514 vim9script
11515
11516 class Foo
11517 def _GetVal(): number
11518 return 234
11519 enddef
11520 def FooVal(x: any): number
11521 return x._GetVal()
11522 enddef
11523 endclass
11524
11525 var a = Foo.new()
11526 assert_equal(234, a.FooVal(a))
11527 END
11528 v9.CheckScriptSuccess(lines)
11529
11530 # Method chaining
11531 lines =<< trim END
11532 vim9script
11533
11534 export class T
11535 var id: number = 268
11536 def F(): any
11537 return this
11538 enddef
11539 endclass
11540
11541 def H()
11542 var a = T.new().F().F()
11543 assert_equal(268, a.id)
11544 enddef
11545 H()
11546
11547 var b: T = T.new().F().F()
11548 assert_equal(268, b.id)
11549 END
11550 v9.CheckScriptSuccess(lines)
11551
11552 # Using a null object to access a member variable
11553 lines =<< trim END
11554 vim9script
11555 def Fn(x: any): number
11556 return x.num
11557 enddef
11558
11559 Fn(null_object)
11560 END
11561 v9.CheckScriptFailure(lines, 'E1360: Using a null object', 1)
11562
11563 # Using a null object to invoke a method
11564 lines =<< trim END
11565 vim9script
11566 def Fn(x: any)
11567 x.Foo()
11568 enddef
11569
11570 Fn(null_object)
11571 END
11572 v9.CheckScriptFailure(lines, 'E1360: Using a null object', 1)
Yegappan Lakshmanane7984462024-11-12 21:03:00 +010011573
11574 # Try to change a const object variable using a "any" variable
11575 lines =<< trim END
11576 vim9script
11577 class A
11578 public const v1: number = 123
11579 endclass
11580
11581 def Fn(o: any)
11582 o.v1 = 321
11583 enddef
11584
11585 var a = A.new()
11586 Fn(a)
11587 END
11588 v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
11589
11590 # Try to change a final object variable using a "any" variable
11591 lines =<< trim END
11592 vim9script
11593 class A
11594 public final v1: number = 123
11595 endclass
11596
11597 def Fn(o: any)
11598 o.v1 = 321
11599 enddef
11600
11601 var a = A.new()
11602 Fn(a)
11603 END
11604 v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
11605
11606 # Assign a different type of value to an "any" type object variable
11607 lines =<< trim END
11608 vim9script
11609 class A
11610 public var v1: list<any> = [1, 2]
11611 endclass
11612
11613 def Fn(o: A)
11614 o.v1 = 'abc'
11615 enddef
11616
11617 var a = A.new()
11618 Fn(a)
11619 END
11620 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected list<any> but got string', 1)
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011621enddef
11622
Yegappan Lakshmanan481992c2024-12-06 18:35:12 +010011623" Test for using an object method with mapnew()
11624def Test_mapnew_with_instance_method()
11625 var lines =<< trim END
11626 vim9script
11627
11628 class Foo
11629 var str: string
11630 var nums: list<number> = [1, 2, 3]
11631
11632 def InstanceMethod(n: number): string
11633 return this.str .. n
11634 enddef
11635
11636 def MapperMethod(idx: number, elem: number): string
11637 return elem->this.InstanceMethod()
11638 enddef
11639
11640 def MapTest()
11641 this.str = "foo"
11642 var l = ['foo1', 'foo2', 'foo3']
11643 assert_equal(l, this.nums->mapnew(this.MapperMethod))
11644 enddef
11645 endclass
11646
11647 Foo.new().MapTest()
11648 END
11649 v9.CheckSourceSuccess(lines)
11650
11651 # Error in the mapnew() function
11652 lines =<< trim END
11653 vim9script
11654
11655 class Foo
11656 var str: string
11657 var nums: list<number> = [1, 2, 3]
11658
11659 def InstanceMethod(n: number): string
11660 throw "InstanceMethod failed"
11661 enddef
11662
11663 def MapperMethod(idx: number, elem: number): string
11664 return elem->this.InstanceMethod()
11665 enddef
11666
11667 def MapTest()
11668 this.str = "foo"
11669 var caught_exception: bool = false
11670 try
11671 this.nums->mapnew(this.MapperMethod)
11672 catch /InstanceMethod failed/
11673 caught_exception = true
11674 endtry
11675 assert_true(caught_exception)
11676 enddef
11677 endclass
11678
11679 Foo.new().MapTest()
11680 END
11681 v9.CheckSourceSuccess(lines)
11682enddef
11683
Yegappan Lakshmananb0206e92024-12-30 09:52:16 +010011684" Test for using an object method in a method call.
11685def Test_use_object_method_in_a_method_call()
11686 var lines =<< trim END
11687 vim9script
11688
11689 class Foo
11690 def Cost(nums: list<number>): number
11691 return nums[0] * nums[1]
11692 enddef
11693
11694 def ShowCost(): string
11695 var g = [4, 5]
11696 return $"Cost is: {g->this.Cost()}"
11697 enddef
11698 endclass
11699
11700 var d = Foo.new()
11701 assert_equal('Cost is: 20', d.ShowCost())
11702 END
11703 v9.CheckSourceSuccess(lines)
11704
11705 # Test for using a non-existing object method in string interpolation
11706 lines =<< trim END
11707 vim9script
11708
11709 class Foo
11710 def Cost(nums: list<number>): number
11711 return nums[0] * nums[1]
11712 enddef
11713
11714 def ShowCost(): string
11715 var g = [4, 5]
11716 echo $"Cost is: {g->this.NewCost()}"
11717 enddef
11718 endclass
11719
11720 var d = Foo.new()
11721 d.ShowCost()
11722 END
11723 v9.CheckSourceFailure(lines, 'E1326: Variable "NewCost" not found in object "Foo"')
11724enddef
11725
Yegappan Lakshmananb04af4c2025-01-03 10:50:08 +010011726" Test for referencing an object variable which is not yet initialized
11727def Test_uninitialized_object_var()
11728 var lines =<< trim END
11729 vim9script
11730 class Foo
11731 const two: number = Foo.Two(this)
11732 const one: number = 1
11733
11734 static def Two(that: Foo): number
11735 return that.one + 2
11736 enddef
11737 endclass
11738
11739 echo Foo.Two(Foo.new())
11740 END
11741 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'one' referenced")
11742
11743 lines =<< trim END
11744 vim9script
11745 class Foo
11746 const one: number = Foo.One(this)
11747
11748 static def One(that: Foo): number
11749 return 1
11750 enddef
11751 endclass
11752
11753 assert_equal(1, Foo.One(Foo.new()))
11754 END
11755 v9.CheckSourceSuccess(lines)
11756
11757 lines =<< trim END
11758 vim9script
11759 class Foo
11760 const one: number = 1
11761 const two: number = Foo.Two(this)
11762
11763 static def Two(that: Foo): number
11764 return that.one + 1
11765 enddef
11766 endclass
11767
11768 assert_equal(2, Foo.Two(Foo.new()))
11769 END
11770 v9.CheckSourceSuccess(lines)
11771
11772 lines =<< trim END
11773 vim9script
11774 class Foo
11775 const Id: func(any): any = ((_) => (v) => v)(this)
11776
11777 static def Id(that: Foo): func(any): any
11778 return that.Id
11779 enddef
11780 endclass
11781
11782 assert_equal(5, Foo.Id(Foo.new())(5))
11783 assert_equal(7, Foo.new().Id(7))
11784 END
11785 v9.CheckSourceSuccess(lines)
11786
11787 lines =<< trim END
11788 vim9script
11789 class Foo
11790 const Id: func(any): any = ((that) => (_) => that)(this)
11791
11792 static def Id(that: Foo): func(any): any
11793 return that.Id
11794 enddef
11795 endclass
11796
11797 const Id0: func(any): any = Foo.Id(Foo.new())
11798 const Id1: func(any): any = Foo.new().Id
11799 END
11800 v9.CheckSourceSuccess(lines)
11801
11802 lines =<< trim END
11803 vim9script
11804 class Foo
11805 const Id: any = Foo.Id(this)
11806
11807 static def Id(that: Foo): any
11808 return that.Id
11809 enddef
11810 endclass
11811
11812 const Id2: any = Foo.Id(Foo.new())
11813 const Id3: any = Foo.new().Id
11814 END
11815 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'Id' referenced")
11816
11817 lines =<< trim END
11818 vim9script
11819
11820 class Foo
11821 var x: string = ''
11822 var Y: func(): string = () => this.x
11823 endclass
11824
11825 var foo = Foo.new('ok')
11826 assert_equal('ok', foo.Y())
11827 END
11828 v9.CheckSourceSuccess(lines)
11829
11830 lines =<< trim END
11831 vim9script
11832
11833 class Foo
11834 var x: string = this.x
11835 endclass
11836
11837 var foo = Foo.new('ok')
11838 END
11839 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'x' referenced")
11840enddef
11841
Yegappan Lakshmanan2050dcc2025-01-06 18:34:49 +010011842" Test for initializing member variables of compound type in the constructor
11843def Test_constructor_init_compound_member_var()
11844 var lines =<< trim END
11845 vim9script
11846
11847 class Foo
11848 var v1: string = "aaa"
11849 var v2: list<number> = [1, 2]
11850 var v3: dict<string> = {a: 'a', b: 'b'}
11851 endclass
11852
11853 class Bar
11854 var v4: string = "bbb"
11855 var v5: Foo = Foo.new()
11856 var v6: list<number> = [1, 2]
11857 endclass
11858
11859 var b: Bar = Bar.new()
11860 assert_equal("aaa", b.v5.v1)
11861 assert_equal([1, 2], b.v5.v2)
11862 assert_equal({a: 'a', b: 'b'}, b.v5.v3)
11863 assert_equal("bbb", b.v4)
11864 assert_equal([1, 2], b.v6)
11865 END
11866 v9.CheckSourceSuccess(lines)
11867enddef
11868
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011869" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker