blob: ed3aac0be2978a1b70b92d1cc039321e40a107ed [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'])
Bram Moolenaard13dd302023-03-11 20:56:35 +0000548enddef
549
Bram Moolenaar657aea72023-01-27 13:16:19 +0000550def Test_class_interface_wrong_end()
551 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200552 vim9script
553 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100554 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200555 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000556 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200557 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000558
559 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200560 vim9script
561 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100562 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200563 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000564 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200565 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000566enddef
567
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000568def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200569 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000570 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200571 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000572
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200573 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100574 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200575 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000576
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200577 var state: State
578 var db = {'xyz': 789}
579 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000580 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200581 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000582
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200583 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000584 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200585 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000586
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200587 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100588 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200589 def Method1()
590 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000591 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200592 endclass
593
594 var obj: Class
595 def Func()
596 obj.Method1()
597 enddef
598 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000599 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200600 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000601
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200602 # Pass an uninitialized object variable to a "new" function and try to call an
603 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000604 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200605 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000606
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200607 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100608 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200609 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000610
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200611 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100612 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000613
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200614 def GetBackground(): string
615 return this._bg.background
616 enddef
617 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000618
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200619 var bg: Background # UNINITIALIZED
620 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000621 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200622 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000623
624 # TODO: this should not give an error but be handled at runtime
625 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200626 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000627
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200628 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100629 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200630 def Method1()
631 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000632 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200633 endclass
634
635 var obj = null_object
636 def Func()
637 obj.Method1()
638 enddef
639 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000640 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200641 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000642enddef
643
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200644" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200645def Test_null_object_assign_compare()
646 var lines =<< trim END
647 vim9script
648
649 var nullo = null_object
650 def F(): any
651 return nullo
652 enddef
653 assert_equal('object<Unknown>', typename(F()))
654
655 var o0 = F()
656 assert_true(o0 == null_object)
657 assert_true(o0 == null)
658
659 var o1: any = nullo
660 assert_true(o1 == null_object)
661 assert_true(o1 == null)
662
663 def G()
664 var x = null_object
665 enddef
666
667 class C
668 endclass
669 var o2: C
670 assert_true(o2 == null_object)
671 assert_true(o2 == null)
672
673 o2 = null_object
674 assert_true(o2 == null)
675
676 o2 = C.new()
677 assert_true(o2 != null)
678
679 o2 = null_object
680 assert_true(o2 == null)
681 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200682 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200683enddef
684
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200685" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000686def Test_class_member_initializer()
687 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200688 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000689
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200690 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100691 var lnum: number = 1
692 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000693
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200694 # constructor with only the line number
695 def new(lnum: number)
696 this.lnum = lnum
697 enddef
698 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000699
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200700 var pos = TextPosition.new(3)
701 assert_equal(3, pos.lnum)
702 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000703
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200704 var instr = execute('disassemble TextPosition.new')
705 assert_match('new\_s*' ..
706 '0 NEW TextPosition size \d\+\_s*' ..
707 '\d PUSHNR 1\_s*' ..
708 '\d STORE_THIS 0\_s*' ..
709 '\d PUSHNR 1\_s*' ..
710 '\d STORE_THIS 1\_s*' ..
711 'this.lnum = lnum\_s*' ..
712 '\d LOAD arg\[-1]\_s*' ..
713 '\d PUSHNR 0\_s*' ..
714 '\d LOAD $0\_s*' ..
715 '\d\+ STOREINDEX object\_s*' ..
716 '\d\+ RETURN object.*',
717 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000718 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200719 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000720enddef
721
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000722def Test_member_any_used_as_object()
723 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200724 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000725
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200726 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100727 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200728 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000729
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200730 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100731 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200732 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000733
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200734 def F(outer: Outer)
735 outer.inner.value = 1
736 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000737
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200738 var inner_obj = Inner.new(0)
739 var outer_obj = Outer.new(inner_obj)
740 F(outer_obj)
741 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000742 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200743 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000744
Ernie Rael03042a22023-11-11 08:53:32 +0100745 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200746 lines =<< trim END
747 vim9script
748
749 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100750 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200751 endclass
752
753 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100754 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200755 endclass
756
757 def F(outer: Outer)
758 outer.inner._value = 'b'
759 enddef
760
761 var inner_obj = Inner.new('a')
762 var outer_obj = Outer.new(inner_obj)
763 F(outer_obj)
764 END
Ernie Rael03042a22023-11-11 08:53:32 +0100765 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200766
767 # Try modifying a non-existing variable using an "any" object
768 lines =<< trim END
769 vim9script
770
771 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100772 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200773 endclass
774
775 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100776 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200777 endclass
778
779 def F(outer: Outer)
780 outer.inner.someval = 'b'
781 enddef
782
783 var inner_obj = Inner.new('a')
784 var outer_obj = Outer.new(inner_obj)
785 F(outer_obj)
786 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200787 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000788enddef
789
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200790" Nested assignment to a object variable which is of another class type
791def Test_assignment_nested_type()
792 var lines =<< trim END
793 vim9script
794
795 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100796 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200797 endclass
798
799 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100800 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200801 endclass
802
803 def F(outer: Outer)
804 outer.inner.value = 1
805 enddef
806
807 def Test_assign_to_nested_typed_member()
808 var inner = Inner.new(0)
809 var outer = Outer.new(inner)
810 F(outer)
811 assert_equal(1, inner.value)
812 enddef
813
814 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200815
816 var script_inner = Inner.new(0)
817 var script_outer = Outer.new(script_inner)
818 script_outer.inner.value = 1
819 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200820 END
821 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200822
823 # Assignment where target item is read only in :def
824 lines =<< trim END
825 vim9script
826
827 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100828 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200829 endclass
830
831 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100832 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200833 endclass
834
835 def F(outer: Outer)
836 outer.inner.value = 1
837 enddef
838
839 def Test_assign_to_nested_typed_member()
840 var inner = Inner.new(0)
841 var outer = Outer.new(inner)
842 F(outer)
843 assert_equal(1, inner.value)
844 enddef
845
846 Test_assign_to_nested_typed_member()
847 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200848 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200849
850 # Assignment where target item is read only script level
851 lines =<< trim END
852 vim9script
853
854 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100855 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200856 endclass
857
858 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100859 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200860 endclass
861
862 def F(outer: Outer)
863 outer.inner.value = 1
864 enddef
865
866 var script_inner = Inner.new(0)
867 var script_outer = Outer.new(script_inner)
868 script_outer.inner.value = 1
869 assert_equal(1, script_inner.value)
870 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200871 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200872enddef
873
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000874def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200875 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000876 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200877 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000878
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200879 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100880 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000881
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200882 def Add(n: number)
883 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100884 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200885 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100886
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200887 var f = Foo.new(3)
888 f.Add(17)
889 assert_equal(20, f.x)
890
891 def AddToFoo(obj: Foo)
892 obj.x += 3
893 enddef
894
895 AddToFoo(f)
896 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000897 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200898 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000899enddef
900
Bram Moolenaarf4508042023-01-15 16:54:57 +0000901def Test_list_of_objects()
902 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200903 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000904
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200905 class Foo
906 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000907 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200908 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000909
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200910 def ProcessList(fooList: list<Foo>)
911 for foo in fooList
912 foo.Add()
913 endfor
914 enddef
915
916 var l: list<Foo> = [Foo.new()]
917 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000918 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200919 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000920enddef
921
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000922def Test_expr_after_using_object()
923 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200924 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000925
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200926 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100927 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200928 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000929
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200930 def Foo(): Something
931 var v = Something.new()
932 echo 'in Foo(): ' .. typename(v)
933 return v
934 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000935
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200936 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000937 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200938 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000939enddef
940
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000941def Test_class_default_new()
942 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200943 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000944
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200945 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100946 var lnum: number = 1
947 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200948 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000949
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200950 var pos = TextPosition.new()
951 assert_equal(1, pos.lnum)
952 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000953
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200954 pos = TextPosition.new(v:none, v:none)
955 assert_equal(1, pos.lnum)
956 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000957
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200958 pos = TextPosition.new(3, 22)
959 assert_equal(3, pos.lnum)
960 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000961
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200962 pos = TextPosition.new(v:none, 33)
963 assert_equal(1, pos.lnum)
964 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000965 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200966 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000967
968 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200969 vim9script
970 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100971 var name: string
972 var age: number = 42
973 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000974
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200975 def new(this.name, this.age = v:none, this.education = v:none)
976 enddef
977 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000978
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200979 var piet = Person.new("Piet")
980 assert_equal("Piet", piet.name)
981 assert_equal(42, piet.age)
982 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000983
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200984 var chris = Person.new("Chris", 4, "none")
985 assert_equal("Chris", chris.name)
986 assert_equal(4, chris.age)
987 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000988 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200989 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000990
991 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200992 vim9script
993 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100994 var name: string
995 var age: number = 42
996 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +0000997
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200998 def new(this.name, this.age = v:none, this.education = v:none)
999 enddef
1000 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001001
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001002 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +00001003 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001004 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001005
1006 # Using a specific value to initialize an instance variable in the new()
1007 # method.
1008 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001009 vim9script
1010 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001011 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001012 def new(this.val = 'a')
1013 enddef
1014 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001015 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001016 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001017enddef
1018
h-east2261c892023-08-16 21:49:54 +09001019def Test_class_new_with_object_member()
1020 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001021 vim9script
h-east2261c892023-08-16 21:49:54 +09001022
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001023 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001024 var str: string
1025 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001026 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +09001027 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001028 def newVals(this.str, this.num)
1029 enddef
1030 endclass
h-east2261c892023-08-16 21:49:54 +09001031
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001032 def Check()
1033 try
1034 var c = C.new('cats', 2)
1035 assert_equal('cats', c.str)
1036 assert_equal(2, c.num)
1037
1038 c = C.newVals('dogs', 4)
1039 assert_equal('dogs', c.str)
1040 assert_equal(4, c.num)
1041 catch
1042 assert_report($'Unexpected exception was caught: {v:exception}')
1043 endtry
1044 enddef
1045
1046 Check()
h-east2261c892023-08-16 21:49:54 +09001047 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001048 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001049
1050 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001051 vim9script
1052
1053 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001054 var str: string
1055 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001056 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001057 enddef
1058 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001059
1060 def Check()
1061 try
1062 var c = C.new(1, 2)
1063 catch
1064 assert_report($'Unexpected exception was caught: {v:exception}')
1065 endtry
1066 enddef
1067
1068 Check()
h-eastdb385522023-09-28 22:18:19 +02001069 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001070 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001071
1072 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001073 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001074
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001075 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001076 var str: string
1077 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001078 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001079 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001080 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001081
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001082 def Check()
1083 try
1084 var c = C.newVals('dogs', 'apes')
1085 catch
1086 assert_report($'Unexpected exception was caught: {v:exception}')
1087 endtry
1088 enddef
1089
1090 Check()
1091 END
1092 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1093
1094 lines =<< trim END
1095 vim9script
1096
1097 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001098 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001099 def new(str: any)
1100 enddef
1101 endclass
1102
1103 def Check()
1104 try
1105 var c = C.new(1)
1106 catch
1107 assert_report($'Unexpected exception was caught: {v:exception}')
1108 endtry
1109 enddef
1110
1111 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001112 END
1113 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001114
1115 # Try using "this." argument in a class method
1116 lines =<< trim END
1117 vim9script
1118 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001119 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001120 static def Foo(this.val: number)
1121 enddef
1122 endclass
1123 END
1124 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1125
1126 # Try using "this." argument in an object method
1127 lines =<< trim END
1128 vim9script
1129 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001130 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001131 def Foo(this.val: number)
1132 enddef
1133 endclass
1134 END
1135 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001136enddef
1137
Bram Moolenaar74e12742022-12-13 21:14:28 +00001138def Test_class_object_member_inits()
1139 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001140 vim9script
1141 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001142 var lnum: number
1143 var col = 1
1144 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001145 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001146
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001147 var pos = TextPosition.new()
1148 assert_equal(0, pos.lnum)
1149 assert_equal(1, pos.col)
1150 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001151 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001152 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001153
1154 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001155 vim9script
1156 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001157 var lnum
1158 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001159 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001160 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001161 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001162
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001163 # If the type is not specified for a member, then it should be set during
1164 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001165 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001166 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001167
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001168 var init_count = 0
1169 def Init(): string
1170 init_count += 1
1171 return 'foo'
1172 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001173
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001174 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001175 var str1 = Init()
1176 var str2: string = Init()
1177 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001178 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001179
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001180 assert_equal(init_count, 0)
1181 var a = A.new()
1182 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001183 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001184 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001185
1186 # Test for initializing an object member with an unknown variable/type
1187 lines =<< trim END
1188 vim9script
1189 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001190 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001191 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001192 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001193 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001194 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001195
1196 # Test for initializing an object member with an special type
1197 lines =<< trim END
1198 vim9script
1199 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001200 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001201 endclass
1202 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001203 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001204enddef
1205
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001206" Test for instance variable access
1207def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001208 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001209 vim9script
1210 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001211 var _one = 1
1212 var two = 2
1213 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001214
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001215 def GetOne(): number
1216 return this._one
1217 enddef
1218 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001219
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001220 var trip = Triple.new()
1221 assert_equal(1, trip.GetOne())
1222 assert_equal(2, trip.two)
1223 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001224 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001225
Ernie Rael03042a22023-11-11 08:53:32 +01001226 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001227 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1228 trip.three = 33
1229 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001230
Ernie Raeld4802ec2023-10-20 11:59:00 +02001231 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001232 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001233 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001234
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001235 # Test for a public member variable name beginning with an underscore
1236 lines =<< trim END
1237 vim9script
1238 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001239 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001240 endclass
1241 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001242 v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001243
Bram Moolenaar590162c2022-12-24 21:24:06 +00001244 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001245 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001246
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001247 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001248 var make: string
1249 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001250
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001251 def new(make_arg: string)
1252 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001253 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001254
1255 def GetMake(): string
1256 return $"make = {this.make}"
1257 enddef
1258 def GetAge(): number
1259 return this.age
1260 enddef
1261 endclass
1262
1263 var c = MyCar.new("abc")
1264 assert_equal('make = abc', c.GetMake())
1265
1266 c = MyCar.new("def")
1267 assert_equal('make = def', c.GetMake())
1268
1269 var c2 = MyCar.new("123")
1270 assert_equal('make = 123', c2.GetMake())
1271
1272 def CheckCar()
1273 assert_equal("make = def", c.GetMake())
1274 assert_equal(5, c.GetAge())
1275 enddef
1276 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001277 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001278 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001279
1280 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001281 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001282
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001283 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001284 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001285
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001286 def new(make_arg: string)
1287 this.make = make_arg
1288 enddef
1289 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001290
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001291 var c = MyCar.new("abc")
1292 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001293 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001294 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001295
1296 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001297 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001298
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001299 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001300 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001301
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001302 def Add(n: number): any
1303 this.x->add(n)
1304 return this
1305 enddef
1306 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001307
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001308 echo Foo.new().Add(1).Add(2).x
1309 echo Foo.new().Add(1).Add(2)
1310 .x
1311 echo Foo.new().Add(1)
1312 .Add(2).x
1313 echo Foo.new()
1314 .Add(1).Add(2).x
1315 echo Foo.new()
1316 .Add(1)
1317 .Add(2)
1318 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001319 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001320 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001321
1322 # Test for "public" cannot be abbreviated
1323 lines =<< trim END
1324 vim9script
1325 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001326 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001327 endclass
1328 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001329 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001330
Doug Kearns74da0ee2023-12-14 20:26:26 +01001331 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001332 lines =<< trim END
1333 vim9script
1334 class Something
1335 public val = 1
1336 endclass
1337 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001338 v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001339
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001340 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001341 lines =<< trim END
1342 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001343 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001344 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001345 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001346 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001347 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001348 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001349
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001350 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001351 lines =<< trim END
1352 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001353 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001354 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001355 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001356 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001357 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001358 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001359
1360 # Modify a instance variable using the class name in a def function
1361 lines =<< trim END
1362 vim9script
1363 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001364 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001365 endclass
1366 def T()
1367 A.val = 1
1368 enddef
1369 T()
1370 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001371 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001372
1373 # Read a instance variable using the class name in a def function
1374 lines =<< trim END
1375 vim9script
1376 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001377 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001378 endclass
1379 def T()
1380 var i = A.val
1381 enddef
1382 T()
1383 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001384 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001385
1386 # Access from child class extending a class:
1387 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001388 vim9script
1389 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001390 var ro_obj_var = 10
1391 public var rw_obj_var = 20
1392 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001393 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001394
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001395 class B extends A
1396 def Foo()
1397 var x: number
1398 x = this.ro_obj_var
1399 this.ro_obj_var = 0
1400 x = this.rw_obj_var
1401 this.rw_obj_var = 0
1402 x = this._priv_obj_var
1403 this._priv_obj_var = 0
1404 enddef
1405 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001406
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001407 var b = B.new()
1408 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001409 END
1410 v9.CheckSourceSuccess(lines)
1411enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001412
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001413" Test for class variable access
1414def Test_class_variable_access()
1415 # Test for "static" cannot be abbreviated
1416 var lines =<< trim END
1417 vim9script
1418 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001419 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001420 endclass
1421 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001422 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001423
1424 # Test for "static" cannot be followed by "public".
1425 lines =<< trim END
1426 vim9script
1427 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001428 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001429 endclass
1430 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001431 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001432
1433 # A readonly class variable cannot be modified from a child class
1434 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001435 vim9script
1436 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001437 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001438 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001439
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001440 class B extends A
1441 def Foo()
1442 A.ro_class_var = 50
1443 enddef
1444 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001445
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001446 var b = B.new()
1447 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001448 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001449 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001450
Ernie Rael03042a22023-11-11 08:53:32 +01001451 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001452 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001453 vim9script
1454 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001455 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001456 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001457
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001458 class B extends A
1459 def Foo()
1460 var i = A._priv_class_var
1461 enddef
1462 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001463
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001464 var b = B.new()
1465 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001466 END
Ernie Rael03042a22023-11-11 08:53:32 +01001467 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001468
Ernie Rael03042a22023-11-11 08:53:32 +01001469 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001470 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001471 vim9script
1472 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001473 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001474 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001475
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001476 class B extends A
1477 def Foo()
1478 A._priv_class_var = 0
1479 enddef
1480 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001481
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001482 var b = B.new()
1483 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001484 END
Ernie Rael03042a22023-11-11 08:53:32 +01001485 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001486
1487 # Access from child class extending a class and from script context
1488 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001489 vim9script
1490 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001491 static var ro_class_var = 10
1492 public static var rw_class_var = 20
1493 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001494 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001495
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001496 class B extends A
1497 def Foo()
1498 var x: number
1499 x = A.ro_class_var
1500 assert_equal(10, x)
1501 x = A.rw_class_var
1502 assert_equal(25, x)
1503 A.rw_class_var = 20
1504 assert_equal(20, A.rw_class_var)
1505 enddef
1506 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001507
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001508 assert_equal(10, A.ro_class_var)
1509 assert_equal(20, A.rw_class_var)
1510 A.rw_class_var = 25
1511 assert_equal(25, A.rw_class_var)
1512 var b = B.new()
1513 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001514 END
1515 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001516enddef
1517
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001518def Test_class_object_compare()
1519 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001520 vim9script
1521 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001522 var nr = 0
1523 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001524 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001525 END
1526
1527 # used at the script level and in a compiled function
1528 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001529 var i1 = Item.new()
1530 assert_equal(i1, i1)
1531 assert_true(i1 is i1)
1532 var i2 = Item.new()
1533 assert_equal(i1, i2)
1534 assert_false(i1 is i2)
1535 var i3 = Item.new(0, 'xx')
1536 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001537
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001538 var io1 = Item.new(1, 'xx')
1539 assert_notequal(i1, io1)
1540 var io2 = Item.new(0, 'yy')
1541 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001542 END
1543
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001544 v9.CheckSourceSuccess(class_lines + test_lines)
1545 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001546 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001547
1548 for op in ['>', '>=', '<', '<=', '=~', '!~']
1549 var op_lines = [
1550 'var i1 = Item.new()',
1551 'var i2 = Item.new()',
1552 'echo i1 ' .. op .. ' i2',
1553 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001554 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001555 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001556 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001557 endfor
1558enddef
1559
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001560def Test_object_type()
1561 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001562 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001563
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001564 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001565 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001566 endclass
1567 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001568 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001569 endclass
1570 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001571 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001572 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001573
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001574 var o: One = One.new()
1575 var t: Two = Two.new()
1576 var m: TwoMore = TwoMore.new()
1577 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001578
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001579 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001580 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001581 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001582
1583 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001584 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001585
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001586 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001587 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001588 endclass
1589 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001590 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001591 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001592
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001593 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001594 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001595 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001596
1597 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001598 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001599
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001600 interface One
1601 def GetMember(): number
1602 endinterface
1603 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001604 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001605 def GetMember(): number
1606 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001607 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001608 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001609
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001610 var o: One = Two.new(5)
1611 assert_equal(5, o.GetMember())
1612 END
1613 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001614
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001615 lines =<< trim END
1616 vim9script
1617
1618 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001619 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001620 endclass
1621
1622 def Ref(name: string): func(Num): Num
1623 return (arg: Num): Num => {
1624 return eval(name)(arg)
1625 }
1626 enddef
1627
1628 const Fn = Ref('Double')
1629 var Double = (m: Num): Num => Num.new(m.n * 2)
1630
1631 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001632 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001633 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001634enddef
1635
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001636def Test_class_member()
1637 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001638 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001639 vim9script
1640 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001641 var lnum = 1
1642 var col = 1
1643 static var counter = 0
1644 static var _secret = 7
1645 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001646
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001647 static def AddToCounter(nr: number)
1648 counter += nr
1649 enddef
1650 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001651
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001652 assert_equal(0, TextPos.counter)
1653 TextPos.AddToCounter(3)
1654 assert_equal(3, TextPos.counter)
1655 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001656
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001657 def GetCounter(): number
1658 return TextPos.counter
1659 enddef
1660 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001661
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001662 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1663 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1664 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001665
Ernie Rael03042a22023-11-11 08:53:32 +01001666 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1667 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001668
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001669 assert_equal(42, TextPos.anybody)
1670 TextPos.anybody = 12
1671 assert_equal(12, TextPos.anybody)
1672 TextPos.anybody += 5
1673 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001674 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001675 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001676
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001677 # example in the help
1678 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001679 vim9script
1680 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001681 var size: number
1682 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001683
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001684 def new(this.size)
1685 totalSize += this.size
1686 enddef
1687 endclass
1688 assert_equal(0, OtherThing.totalSize)
1689 var to3 = OtherThing.new(3)
1690 assert_equal(3, OtherThing.totalSize)
1691 var to7 = OtherThing.new(7)
1692 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001693 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001694 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001695
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001696 # using static class member twice
1697 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001698 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001699
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001700 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001701 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001702
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001703 static def MacroSubstitute(s: string): string
1704 return substitute(s, '{{author}}', author, 'gi')
1705 enddef
1706 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001707
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001708 assert_equal('some text', HTML.MacroSubstitute('some text'))
1709 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001710 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001711 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001712
Ernie Rael03042a22023-11-11 08:53:32 +01001713 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001714 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001715 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001716
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001717 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001718 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001719
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001720 def Add(n: number): number
1721 const F = (): number => this._x + n
1722 return F()
1723 enddef
1724 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001725
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001726 var foo = Foo.new()
1727 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001728 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001729 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001730
Ernie Rael03042a22023-11-11 08:53:32 +01001731 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001732 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001733 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001734
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001735 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001736 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001737
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001738 def Add(n: number): number
1739 var Lam = () => {
1740 this._x = this._x + n
1741 }
1742 Lam()
1743 return this._x
1744 enddef
1745 endclass
h-east2bd6a092023-05-19 19:01:17 +01001746
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001747 var foo = Foo.new()
1748 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001749 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001750 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001751
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001752 # check shadowing
1753 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001754 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001755
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001756 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001757 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001758 def Method(count: number)
1759 echo count
1760 enddef
1761 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001762
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001763 var s = Some.new()
1764 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001765 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001766 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001767
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001768 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001769 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001770 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001771
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001772 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001773 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001774 def Method(arg: number)
1775 var count = 3
1776 echo arg count
1777 enddef
1778 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001779
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001780 var s = Some.new()
1781 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001782 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001783 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001784
1785 # Test for using an invalid type for a member variable
1786 lines =<< trim END
1787 vim9script
1788 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001789 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001790 endclass
1791 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001792 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001793
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001794 # Test for setting a member on a null object
1795 lines =<< trim END
1796 vim9script
1797 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001798 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001799 endclass
1800
1801 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001802 var obj: A
1803 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001804 enddef
1805 F()
1806 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001807 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001808
1809 # Test for accessing a member on a null object
1810 lines =<< trim END
1811 vim9script
1812 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001813 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001814 endclass
1815
1816 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001817 var obj: A
1818 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001819 enddef
1820 F()
1821 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001822 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001823
1824 # Test for setting a member on a null object, at script level
1825 lines =<< trim END
1826 vim9script
1827 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001828 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001829 endclass
1830
1831 var obj: A
1832 obj.val = ""
1833 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001834 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001835
1836 # Test for accessing a member on a null object, at script level
1837 lines =<< trim END
1838 vim9script
1839 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001840 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001841 endclass
1842
1843 var obj: A
1844 echo obj.val
1845 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001846 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001847
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001848 # Test for no space before or after the '=' when initializing a member
1849 # variable
1850 lines =<< trim END
1851 vim9script
1852 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001853 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001854 endclass
1855 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001856 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001857 lines =<< trim END
1858 vim9script
1859 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001860 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001861 endclass
1862 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001863 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001864
1865 # Access a non-existing member
1866 lines =<< trim END
1867 vim9script
1868 class A
1869 endclass
1870 var a = A.new()
1871 var v = a.bar
1872 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001873 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001874enddef
1875
Ernie Raele6c9aa52023-10-06 19:55:52 +02001876" These messages should show the defining class of the variable (base class),
1877" not the class that did the reference (super class)
1878def Test_defining_class_message()
1879 var lines =<< trim END
1880 vim9script
1881
1882 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001883 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001884 endclass
1885
1886 class Child extends Base
1887 endclass
1888
1889 var o = Child.new()
1890 var x = o._v1
1891 END
Ernie Rael03042a22023-11-11 08:53:32 +01001892 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001893 lines =<< trim END
1894 vim9script
1895
1896 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001897 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001898 endclass
1899
1900 class Child extends Base
1901 endclass
1902
1903 def F()
1904 var o = Child.new()
1905 var x = o._v1
1906 enddef
1907 F()
1908 END
Ernie Rael03042a22023-11-11 08:53:32 +01001909 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001910 lines =<< trim END
1911 vim9script
1912
1913 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001914 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001915 endclass
1916
1917 class Child extends Base
1918 endclass
1919
1920 var o = Child.new()
1921 o.v1 = []
1922 END
1923 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1924 lines =<< trim END
1925 vim9script
1926
1927 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001928 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001929 endclass
1930
1931 class Child extends Base
1932 endclass
1933
1934 def F()
1935 var o = Child.new()
1936 o.v1 = []
1937 enddef
1938 F()
1939 END
1940
Ernie Rael03042a22023-11-11 08:53:32 +01001941 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001942 # of the class hierarchy.
1943 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1944 lines =<< trim END
1945 vim9script
1946
1947 class Base0
1948 endclass
1949
1950 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01001951 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001952 endclass
1953
1954 class Child extends Base
1955 endclass
1956
1957 def F()
1958 var o = Child.new()
1959 var x = o._v1
1960 enddef
1961 F()
1962 END
Ernie Rael03042a22023-11-11 08:53:32 +01001963 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001964
Ernie Rael03042a22023-11-11 08:53:32 +01001965 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02001966 # of the class hierarchy.
1967 lines =<< trim END
1968 vim9script
1969
1970 class Base0
1971 endclass
1972
1973 class Base extends Base0
1974 endclass
1975
1976 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001977 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001978 endclass
1979
1980 def F()
1981 var o = Child.new()
1982 var x = o._v1
1983 enddef
1984 F()
1985 END
Ernie Rael03042a22023-11-11 08:53:32 +01001986 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001987enddef
1988
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001989func Test_class_garbagecollect()
1990 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001991 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001992
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001993 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01001994 var p = [2, 3]
1995 static var pl = ['a', 'b']
1996 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001997 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001998
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001999 echo Point.pl Point.pd
2000 call test_garbagecollect_now()
2001 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002002 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002003 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002004
2005 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002006 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002007
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002008 interface View
2009 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002010
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002011 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01002012 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002013 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002014
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002015 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01002016 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002017
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002018 def new()
2019 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01002020 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002021 enddef
2022 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002023
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002024 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002025
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002026 # overwrite "view", will be garbage-collected next
2027 view = MyView.new()
2028 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002029 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002030 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002031endfunc
2032
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002033" Test interface garbage collection
2034func Test_interface_garbagecollect()
2035 let lines =<< trim END
2036 vim9script
2037
2038 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002039 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002040
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002041 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002042 endinterface
2043
2044 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002045 static var ro_class_var: number = 10
2046 public static var rw_class_var: number = 20
2047 static var _priv_class_var: number = 30
2048 var ro_obj_var: number = 40
2049 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002050
2051 static def _ClassBar(): number
2052 return _priv_class_var
2053 enddef
2054
2055 static def ClassFoo(): number
2056 return ro_class_var + rw_class_var + A._ClassBar()
2057 enddef
2058
2059 def _ObjBar(): number
2060 return this._priv_obj_var
2061 enddef
2062
2063 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002064 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002065 enddef
2066 endclass
2067
2068 assert_equal(60, A.ClassFoo())
2069 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002070 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002071 test_garbagecollect_now()
2072 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002073 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002074 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002075 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002076endfunc
2077
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002078def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002079 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002080 vim9script
2081 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002082 var value = 0
2083 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002084
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002085 def new(v: number)
2086 this.value = v
2087 ++objects
2088 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002089
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002090 static def GetCount(): number
2091 return objects
2092 enddef
2093 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002094
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002095 assert_equal(0, Value.GetCount())
2096 var v1 = Value.new(2)
2097 assert_equal(1, Value.GetCount())
2098 var v2 = Value.new(7)
2099 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002100 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002101 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002102
2103 # Test for cleaning up after a class definition failure when using class
2104 # functions.
2105 lines =<< trim END
2106 vim9script
2107 class A
2108 static def Foo()
2109 enddef
2110 aaa
2111 endclass
2112 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002113 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002114
2115 # Test for calling a class method from another class method without the class
2116 # name prefix.
2117 lines =<< trim END
2118 vim9script
2119 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002120 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002121 static def Foo(n: number)
2122 myList->add(n)
2123 enddef
2124 static def Bar()
2125 Foo(2)
2126 enddef
2127 def Baz()
2128 Foo(3)
2129 enddef
2130 endclass
2131 A.Bar()
2132 var a = A.new()
2133 a.Baz()
2134 assert_equal([1, 2, 3], A.myList)
2135 END
2136 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002137enddef
2138
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002139def Test_class_defcompile()
2140 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002141 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002142
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002143 class C
2144 def Fo(i: number): string
2145 return i
2146 enddef
2147 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002148
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002149 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002150 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002151 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002152
2153 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002154 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002155
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002156 class C
2157 static def Fc(): number
2158 return 'x'
2159 enddef
2160 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002161
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002162 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002163 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002164 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002165
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002166 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002167 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002168
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002169 class C
2170 static def new()
2171 enddef
2172 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002173
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002174 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002175 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002176 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002177
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002178 # Trying to compile a function using a non-existing class variable
2179 lines =<< trim END
2180 vim9script
2181 defcompile x.Foo()
2182 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002183 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002184
2185 # Trying to compile a function using a variable which is not a class
2186 lines =<< trim END
2187 vim9script
2188 var x: number
2189 defcompile x.Foo()
2190 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002191 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002192
2193 # Trying to compile a function without specifying the name
2194 lines =<< trim END
2195 vim9script
2196 class A
2197 endclass
2198 defcompile A.
2199 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002200 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002201
2202 # Trying to compile a non-existing class object member function
2203 lines =<< trim END
2204 vim9script
2205 class A
2206 endclass
2207 var a = A.new()
2208 defcompile a.Foo()
2209 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002210 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002211enddef
2212
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002213def Test_class_object_to_string()
2214 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002215 vim9script
2216 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002217 var lnum = 1
2218 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002219 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002220
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002221 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002222
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002223 var pos = TextPosition.new()
2224 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002225 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002226 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002227enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002228
Bram Moolenaar554d0312023-01-05 19:59:18 +00002229def Test_interface_basics()
2230 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002231 vim9script
2232 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002233 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002234 def GetCount(): number
2235 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002236 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002237 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002238
2239 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002240 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002241 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002242 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002243 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002244 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002245
2246 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002247 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002248
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002249 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002250 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002251 def Method(value: number)
2252 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002253 END
h-east61378a12023-04-18 19:07:29 +01002254 # The argument name and the object member name are the same, but this is not a
2255 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002256 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002257
2258 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002259 vim9script
2260 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002261 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002262 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002263 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002264 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002265
2266 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002267 vim9script
2268 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002269 var value: string
2270 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002271 def GetCount(): number
2272 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002273 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002274 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002275
2276 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002277 vim9script
2278 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002279 var value: string
2280 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002281 def GetCount(): number
2282 return 5
2283 enddef
2284 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002285 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002286 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002287
Yegappan Lakshmananac773182024-04-27 11:36:12 +02002288 # Additional commands after "interface name"
2289 lines =<< trim END
2290 vim9script
2291 interface Something | var x = 10 | var y = 20
2292 endinterface
2293 END
2294 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
2295
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002296 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002297 vim9script
2298 export interface EnterExit
2299 def Enter(): void
2300 def Exit(): void
2301 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002302 END
2303 writefile(lines, 'XdefIntf.vim', 'D')
2304
2305 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002306 vim9script
2307 import './XdefIntf.vim' as defIntf
2308 export def With(ee: defIntf.EnterExit, F: func)
2309 ee.Enter()
2310 try
2311 F()
2312 finally
2313 ee.Exit()
2314 endtry
2315 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002316 END
2317 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002318
2319 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002320 vim9script
2321 export abstract class EnterExit
2322 def Enter(): void
2323 enddef
2324 def Exit(): void
2325 enddef
2326 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002327 END
2328 writefile(imported, 'XdefIntf2.vim', 'D')
2329
2330 lines[1] = " import './XdefIntf2.vim' as defIntf"
2331 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002332enddef
2333
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002334" Test for using string() with an interface
2335def Test_interface_to_string()
2336 var lines =<< trim END
2337 vim9script
2338 interface Intf
2339 def Method(nr: number)
2340 endinterface
2341 assert_equal("interface Intf", string(Intf))
2342 END
2343 v9.CheckSourceSuccess(lines)
2344enddef
2345
Bram Moolenaar94674f22023-01-06 18:42:20 +00002346def Test_class_implements_interface()
2347 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002348 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002349
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002350 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002351 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002352 def Method(nr: number)
2353 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002354
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002355 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002356 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002357 def Method(nr: number)
2358 echo nr
2359 enddef
2360 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002361
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002362 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002363 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002364 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002365
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002366 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002367 var member = 'abc'
2368 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002369 def Method(nr: number)
2370 echo nr
2371 enddef
2372 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002373 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002374 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002375
2376 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002377 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002378
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002379 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002380 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002381 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002382
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002383 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002384 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002385 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002386 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002387 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002388
2389 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002390 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002391
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002392 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002393 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002394 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002395
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002396 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002397 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002398 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002399 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002400 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002401
2402 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002403 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002404
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002405 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002406 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002407 def Method(nr: number)
2408 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002409
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002410 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002411 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002412 def Method(nr: number)
2413 echo nr
2414 enddef
2415 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002416 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002417 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002418
2419 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002420 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002421
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002422 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002423 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002424 def Methods(nr: number)
2425 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002426
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002427 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002428 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002429 def Method(nr: number)
2430 echo nr
2431 enddef
2432 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002433 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002434 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002435
2436 # Check different order of members in class and interface works.
2437 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002438 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002439
2440 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002441 var label: string
2442 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002443 endinterface
2444
2445 # order of members is opposite of interface
2446 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002447 public var lnum: number = 5
2448 var errpos: number = 42
2449 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002450 endclass
2451
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002452 def Test()
2453 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002454
2455 assert_equal('label', result.label)
2456 assert_equal(42, result.errpos)
2457 enddef
2458
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002459 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002460 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002461 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002462
2463 # Interface name after "extends" doesn't end in a space or NUL character
2464 lines =<< trim END
2465 vim9script
2466 interface A
2467 endinterface
2468 class B extends A"
2469 endclass
2470 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002471 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002472
2473 # Trailing characters after a class name
2474 lines =<< trim END
2475 vim9script
2476 class A bbb
2477 endclass
2478 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002479 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002480
2481 # using "implements" with a non-existing class
2482 lines =<< trim END
2483 vim9script
2484 class A implements B
2485 endclass
2486 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002487 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002488
2489 # using "implements" with a regular class
2490 lines =<< trim END
2491 vim9script
2492 class A
2493 endclass
2494 class B implements A
2495 endclass
2496 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002497 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002498
2499 # using "implements" with a variable
2500 lines =<< trim END
2501 vim9script
2502 var T: number = 10
2503 class A implements T
2504 endclass
2505 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002506 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002507
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002508 # implements should be followed by a white space
2509 lines =<< trim END
2510 vim9script
2511 interface A
2512 endinterface
2513 class B implements A;
2514 endclass
2515 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002516 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002517
LemonBoyc5d27442023-08-19 13:02:35 +02002518 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002519 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002520
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002521 interface One
2522 def IsEven(nr: number): bool
2523 endinterface
2524 class Two implements One
2525 def IsEven(nr: number): string
2526 enddef
2527 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002528 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002529 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002530
2531 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002532 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002533
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002534 interface One
2535 def IsEven(nr: number): bool
2536 endinterface
2537 class Two implements One
2538 def IsEven(nr: bool): bool
2539 enddef
2540 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002541 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002542 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002543
2544 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002545 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002546
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002547 interface One
2548 def IsEven(nr: number): bool
2549 endinterface
2550 class Two implements One
2551 def IsEven(nr: number, ...extra: list<number>): bool
2552 enddef
2553 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002554 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002555 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 +02002556
2557 # access superclass interface members from subclass, mix variable order
2558 lines =<< trim END
2559 vim9script
2560
2561 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002562 var mvar1: number
2563 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002564 endinterface
2565
2566 # NOTE: the order is swapped
2567 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002568 var mvar2: number
2569 var mvar1: number
2570 public static var svar2: number
2571 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002572 def new()
2573 svar1 = 11
2574 svar2 = 12
2575 this.mvar1 = 111
2576 this.mvar2 = 112
2577 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002578 endclass
2579
2580 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002581 def new()
2582 this.mvar1 = 121
2583 this.mvar2 = 122
2584 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002585 endclass
2586
2587 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002588 def new()
2589 this.mvar1 = 131
2590 this.mvar2 = 132
2591 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002592 endclass
2593
Ernie Raelcf138d42023-09-06 20:45:03 +02002594 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002595 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002596 enddef
2597
2598 var oa = A.new()
2599 var ob = B.new()
2600 var oc = C.new()
2601
Ernie Raelcf138d42023-09-06 20:45:03 +02002602 assert_equal([111, 112], F2(oa))
2603 assert_equal([121, 122], F2(ob))
2604 assert_equal([131, 132], F2(oc))
2605 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002606 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002607
2608 # Access superclass interface members from subclass, mix variable order.
2609 # Two interfaces, one on A, one on B; each has both kinds of variables
2610 lines =<< trim END
2611 vim9script
2612
2613 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002614 var mvar1: number
2615 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002616 endinterface
2617
2618 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002619 var mvar3: number
2620 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002621 endinterface
2622
2623 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002624 public static var svar1: number
2625 public static var svar2: number
2626 var mvar1: number
2627 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002628 def new()
2629 svar1 = 11
2630 svar2 = 12
2631 this.mvar1 = 111
2632 this.mvar2 = 112
2633 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002634 endclass
2635
2636 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002637 static var svar3: number
2638 static var svar4: number
2639 var mvar3: number
2640 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002641 def new()
2642 svar3 = 23
2643 svar4 = 24
2644 this.mvar1 = 121
2645 this.mvar2 = 122
2646 this.mvar3 = 123
2647 this.mvar4 = 124
2648 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002649 endclass
2650
2651 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002652 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002653 def new()
2654 svar5 = 1001
2655 this.mvar1 = 131
2656 this.mvar2 = 132
2657 this.mvar3 = 133
2658 this.mvar4 = 134
2659 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002660 endclass
2661
Ernie Raelcf138d42023-09-06 20:45:03 +02002662 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002663 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002664 enddef
2665
Ernie Raelcf138d42023-09-06 20:45:03 +02002666 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002667 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002668 enddef
2669
Ernie Raelcf138d42023-09-06 20:45:03 +02002670 var oa = A.new()
2671 var ob = B.new()
2672 var oc = C.new()
2673
Ernie Raelcf138d42023-09-06 20:45:03 +02002674 assert_equal([[111, 112]], [F2(oa)])
2675 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2676 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002677 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002678 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002679
2680 # Using two interface names without a space after the ","
2681 lines =<< trim END
2682 vim9script
2683 interface A
2684 endinterface
2685 interface B
2686 endinterface
2687 class C implements A,B
2688 endclass
2689 END
2690 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2691
2692 # No interface name after a comma
2693 lines =<< trim END
2694 vim9script
2695 interface A
2696 endinterface
2697 class B implements A,
2698 endclass
2699 END
2700 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2701
2702 # No interface name after implements
2703 lines =<< trim END
2704 vim9script
2705 class A implements
2706 endclass
2707 END
2708 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002709enddef
2710
Bram Moolenaard0200c82023-01-28 15:19:40 +00002711def Test_call_interface_method()
2712 var lines =<< trim END
2713 vim9script
2714 interface Base
2715 def Enter(): void
2716 endinterface
2717
2718 class Child implements Base
2719 def Enter(): void
2720 g:result ..= 'child'
2721 enddef
2722 endclass
2723
2724 def F(obj: Base)
2725 obj.Enter()
2726 enddef
2727
2728 g:result = ''
2729 F(Child.new())
2730 assert_equal('child', g:result)
2731 unlet g:result
2732 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002733 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002734
2735 lines =<< trim END
2736 vim9script
2737 class Base
2738 def Enter(): void
2739 g:result ..= 'base'
2740 enddef
2741 endclass
2742
2743 class Child extends Base
2744 def Enter(): void
2745 g:result ..= 'child'
2746 enddef
2747 endclass
2748
2749 def F(obj: Base)
2750 obj.Enter()
2751 enddef
2752
2753 g:result = ''
2754 F(Child.new())
2755 assert_equal('child', g:result)
2756 unlet g:result
2757 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002758 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002759
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002760 # method of interface returns a value
2761 lines =<< trim END
2762 vim9script
2763 interface Base
2764 def Enter(): string
2765 endinterface
2766
2767 class Child implements Base
2768 def Enter(): string
2769 g:result ..= 'child'
2770 return "/resource"
2771 enddef
2772 endclass
2773
2774 def F(obj: Base)
2775 var r = obj.Enter()
2776 g:result ..= r
2777 enddef
2778
2779 g:result = ''
2780 F(Child.new())
2781 assert_equal('child/resource', g:result)
2782 unlet g:result
2783 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002784 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002785
2786 lines =<< trim END
2787 vim9script
2788 class Base
2789 def Enter(): string
2790 return null_string
2791 enddef
2792 endclass
2793
2794 class Child extends Base
2795 def Enter(): string
2796 g:result ..= 'child'
2797 return "/resource"
2798 enddef
2799 endclass
2800
2801 def F(obj: Base)
2802 var r = obj.Enter()
2803 g:result ..= r
2804 enddef
2805
2806 g:result = ''
2807 F(Child.new())
2808 assert_equal('child/resource', g:result)
2809 unlet g:result
2810 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002811 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002812
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002813 # No class that implements the interface.
2814 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002815 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002816
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002817 interface IWithEE
2818 def Enter(): any
2819 def Exit(): void
2820 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002821
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002822 def With1(ee: IWithEE, F: func)
2823 var r = ee.Enter()
2824 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002825
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002826 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002827 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002828 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002829enddef
2830
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002831def Test_class_used_as_type()
2832 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002833 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002834
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002835 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002836 var x = 0
2837 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002838 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002839
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002840 var p: Point
2841 p = Point.new(2, 33)
2842 assert_equal(2, p.x)
2843 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002844 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002845 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002846
2847 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002848 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002849
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002850 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002851 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002852 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002853
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002854 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002855 var x = 0
2856 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002857 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002858
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002859 var p: Point
2860 p = Point.new(2, 33)
2861 var hx = p
2862 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002863 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002864 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002865
2866 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002867 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002868
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002869 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002870 var x = 0
2871 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002872 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002873
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002874 var p: Point
2875 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002876 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002877 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002878enddef
2879
Bram Moolenaar83677162023-01-08 19:54:10 +00002880def Test_class_extends()
2881 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002882 vim9script
2883 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002884 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002885 def GetOne(): number
2886 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002887 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002888 endclass
2889 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002890 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002891 def GetTotal(): number
2892 return this.one + this.two
2893 enddef
2894 endclass
2895 var o = Child.new()
2896 assert_equal(1, o.one)
2897 assert_equal(2, o.two)
2898 assert_equal(1, o.GetOne())
2899 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002900 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002901 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002902
2903 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002904 vim9script
2905 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002906 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002907 endclass
2908 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002909 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002910 endclass
2911 var o = Child.new(3, 44)
2912 assert_equal(3, o.one)
2913 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002914 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002915 v9.CheckSourceSuccess(lines)
2916
2917 lines =<< trim END
2918 vim9script
2919 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002920 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002921 endclass
2922 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002923 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002924 endclass
2925 END
2926 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2927
2928 lines =<< trim END
2929 vim9script
2930 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01002931 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002932 endclass
2933 END
2934 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2935
2936 lines =<< trim END
2937 vim9script
2938 var SomeVar = 99
2939 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01002940 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002941 endclass
2942 END
2943 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2944
2945 lines =<< trim END
2946 vim9script
2947 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002948 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002949 def ToString(): string
2950 return this.name
2951 enddef
2952 endclass
2953
2954 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002955 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002956 def ToString(): string
2957 return super.ToString() .. ': ' .. this.age
2958 enddef
2959 endclass
2960
2961 var o = Child.new('John', 42)
2962 assert_equal('John: 42', o.ToString())
2963 END
2964 v9.CheckSourceSuccess(lines)
2965
2966 lines =<< trim END
2967 vim9script
2968 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002969 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002970 def ToString(): number
2971 return this.age
2972 enddef
2973 def ToString(): string
2974 return this.age
2975 enddef
2976 endclass
2977 END
2978 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2979
2980 lines =<< trim END
2981 vim9script
2982 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002983 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002984 def ToString(): string
2985 return super .ToString() .. ': ' .. this.age
2986 enddef
2987 endclass
2988 var o = Child.new(42)
2989 echo o.ToString()
2990 END
2991 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2992
2993 lines =<< trim END
2994 vim9script
2995 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002996 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002997 def ToString(): string
2998 return this.name
2999 enddef
3000 endclass
3001
3002 var age = 42
3003 def ToString(): string
3004 return super.ToString() .. ': ' .. age
3005 enddef
3006 echo ToString()
3007 END
3008 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
3009
3010 lines =<< trim END
3011 vim9script
3012 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003013 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003014 def ToString(): string
3015 return super.ToString() .. ': ' .. this.age
3016 enddef
3017 endclass
3018 var o = Child.new(42)
3019 echo o.ToString()
3020 END
3021 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
3022
3023 lines =<< trim END
3024 vim9script
3025 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003026 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003027 static def ToString(): string
3028 return 'Base class'
3029 enddef
3030 endclass
3031
3032 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003033 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003034 def ToString(): string
3035 return Base.ToString() .. ': ' .. this.age
3036 enddef
3037 endclass
3038
3039 var o = Child.new('John', 42)
3040 assert_equal('Base class: 42', o.ToString())
3041 END
3042 v9.CheckSourceSuccess(lines)
3043
3044 lines =<< trim END
3045 vim9script
3046 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003047 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003048 def new(init: number)
3049 this.value = number + 1
3050 enddef
3051 endclass
3052 class Child extends Base
3053 def new()
3054 this.new(3)
3055 enddef
3056 endclass
3057 var c = Child.new()
3058 END
3059 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003060
3061 # base class with more than one object member
3062 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003063 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003064
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003065 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003066 var success: bool
3067 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003068 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003069
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003070 class Success extends Result
3071 def new(this.value = v:none)
3072 this.success = true
3073 enddef
3074 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003075
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003076 var v = Success.new('asdf')
3077 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003078 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003079 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003080
3081 # class name after "extends" doesn't end in a space or NUL character
3082 lines =<< trim END
3083 vim9script
3084 class A
3085 endclass
3086 class B extends A"
3087 endclass
3088 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003089 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003090enddef
3091
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003092def Test_using_base_class()
3093 var lines =<< trim END
3094 vim9script
3095
3096 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003097 def Enter(): any
3098 return null
3099 enddef
3100 def Exit(resource: any): void
3101 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003102 endclass
3103
3104 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003105 def Enter(): any
3106 return 42
3107 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003108
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003109 def Exit(resource: number): void
3110 g:result ..= '/exit'
3111 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003112 endclass
3113
3114 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003115 var r = ee.Enter()
3116 try
3117 g:result ..= r
3118 finally
3119 g:result ..= '/finally'
3120 ee.Exit(r)
3121 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003122 enddef
3123
3124 g:result = ''
3125 With(ChildEE.new())
3126 assert_equal('42/finally/exit', g:result)
3127 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003128 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003129 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003130
3131 # Using super, Child invokes Base method which has optional arg. #12471
3132 lines =<< trim END
3133 vim9script
3134
3135 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003136 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003137 def Method(arg = 0)
3138 this.success = true
3139 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003140 endclass
3141
3142 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003143 def new()
3144 super.Method()
3145 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003146 endclass
3147
3148 var obj = Child.new()
3149 assert_equal(true, obj.success)
3150 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003151 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003152enddef
3153
Bram Moolenaara86655a2023-01-12 17:06:27 +00003154def Test_class_import()
3155 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003156 vim9script
3157 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003158 var kind: string
3159 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003160 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003161 END
3162 writefile(lines, 'Xanimal.vim', 'D')
3163
3164 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003165 vim9script
3166 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003167
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003168 var a: animal.Animal
3169 a = animal.Animal.new('fish', 'Eric')
3170 assert_equal('fish', a.kind)
3171 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003172
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003173 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3174 assert_equal('cat', b.kind)
3175 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003176 END
3177 v9.CheckScriptSuccess(lines)
3178enddef
3179
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003180" Test for importing a class into a legacy script and calling the class method
3181def Test_class_method_from_legacy_script()
3182 var lines =<< trim END
3183 vim9script
3184 export class A
3185 static var name: string = 'a'
3186 static def SetName(n: string)
3187 name = n
3188 enddef
3189 endclass
3190 END
3191 writefile(lines, 'Xvim9export.vim', 'D')
3192
3193 lines =<< trim END
3194 import './Xvim9export.vim' as vim9
3195
3196 call s:vim9.A.SetName('b')
3197 call assert_equal('b', s:vim9.A.name)
3198 END
3199 v9.CheckScriptSuccess(lines)
3200enddef
3201
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003202" Test for implementing an imported interface
3203def Test_implement_imported_interface()
3204 var lines =<< trim END
3205 vim9script
3206 export interface Imp_Intf1
3207 def Fn1(): number
3208 endinterface
3209 export interface Imp_Intf2
3210 def Fn2(): number
3211 endinterface
3212 END
3213 writefile(lines, 'Ximportinterface.vim', 'D')
3214
3215 lines =<< trim END
3216 vim9script
3217 import './Ximportinterface.vim' as Xintf
3218
3219 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3220 def Fn1(): number
3221 return 10
3222 enddef
3223 def Fn2(): number
3224 return 20
3225 enddef
3226 endclass
3227 var a = A.new()
3228 assert_equal(10, a.Fn1())
3229 assert_equal(20, a.Fn2())
3230 END
3231 v9.CheckScriptSuccess(lines)
3232enddef
3233
3234" Test for extending an imported class
3235def Test_extend_imported_class()
3236 var lines =<< trim END
3237 vim9script
3238 export class Imp_C1
3239 def Fn1(): number
3240 return 5
3241 enddef
3242 endclass
3243 END
3244 writefile(lines, 'Xextendimportclass.vim', 'D')
3245
3246 lines =<< trim END
3247 vim9script
3248 import './Xextendimportclass.vim' as XClass
3249
3250 class A extends XClass.Imp_C1
3251 endclass
3252 var a = A.new()
3253 assert_equal(5, a.Fn1())
3254 END
3255 v9.CheckScriptSuccess(lines)
3256enddef
3257
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003258def Test_abstract_class()
3259 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003260 vim9script
3261 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003262 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003263 endclass
3264 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003265 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003266 endclass
3267 var p: Base = Person.new('Peter', 42)
3268 assert_equal('Peter', p.name)
3269 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003270 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003271 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003272
3273 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003274 vim9script
3275 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003276 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003277 endclass
3278 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003279 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003280 endclass
3281 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003282 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003283 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003284
3285 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003286 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003287 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003288 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003290 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003291
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003292 # Additional commands after "abstract class"
3293 lines =<< trim END
3294 vim9script
3295 abstract class Something | var x = []
3296 endclass
3297 END
3298 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3299
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003300 # Abstract class cannot have a "new" function
3301 lines =<< trim END
3302 vim9script
3303 abstract class Base
3304 def new()
3305 enddef
3306 endclass
3307 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003308 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003309
3310 # extending an abstract class with class methods and variables
3311 lines =<< trim END
3312 vim9script
3313 abstract class A
3314 static var s: string = 'vim'
3315 static def Fn(): list<number>
3316 return [10]
3317 enddef
3318 endclass
3319 class B extends A
3320 endclass
3321 var b = B.new()
3322 assert_equal('vim', A.s)
3323 assert_equal([10], A.Fn())
3324 END
3325 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003326enddef
3327
Bram Moolenaar486fc252023-01-18 14:51:07 +00003328def Test_closure_in_class()
3329 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003330 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003331
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003332 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003333 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003334
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003335 def new()
3336 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3337 enddef
3338 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003339
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003340 Foo.new()
3341 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003342 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003343 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003344enddef
3345
Ernie Rael9ed53752023-12-11 17:40:46 +01003346def Test_construct_object_from_legacy()
3347 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003348 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003349 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003350
Ernie Rael9ed53752023-12-11 17:40:46 +01003351 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003352
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003353 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003354 def new(arg: string)
3355 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003356 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003357 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003358
Ernie Rael9ed53752023-12-11 17:40:46 +01003359 export def CreateA(...args: list<any>): A
3360 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003361 enddef
3362
Ernie Rael9ed53752023-12-11 17:40:46 +01003363 g:P = CreateA
3364 legacy call g:P('some_arg')
3365 assert_equal(true, newCalled)
3366 unlet g:P
3367 END
3368 v9.CheckSourceSuccess(lines)
3369
3370 lines =<< trim END
3371 vim9script
3372
3373 var newCalled = false
3374
3375 class A
3376 static def CreateA(options = {}): any
3377 return A.new()
3378 enddef
3379 def new()
3380 newCalled = true
3381 enddef
3382 endclass
3383
3384 g:P = A.CreateA
3385 legacy call g:P()
3386 assert_equal(true, newCalled)
3387 unlet g:P
3388 END
3389 v9.CheckSourceSuccess(lines)
3390
3391 # This also tests invoking "new()" with "call"
3392 lines =<< trim END
3393 vim9script
3394
3395 var createdObject: any
3396
3397 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003398 var val1: number
3399 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003400 static def CreateA(...args: list<any>): any
3401 createdObject = call(A.new, args)
3402 return createdObject
3403 enddef
3404 endclass
3405
3406 g:P = A.CreateA
3407 legacy call g:P(3, 5)
3408 assert_equal(3, createdObject.val1)
3409 assert_equal(5, createdObject.val2)
3410 legacy call g:P()
3411 assert_equal(0, createdObject.val1)
3412 assert_equal(0, createdObject.val2)
3413 legacy call g:P(7)
3414 assert_equal(7, createdObject.val1)
3415 assert_equal(0, createdObject.val2)
3416 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003417 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003418 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003419enddef
3420
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003421def Test_defer_with_object()
3422 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003423 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003424
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003425 class CWithEE
3426 def Enter()
3427 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003428 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003429 def Exit()
3430 g:result ..= "exited"
3431 enddef
3432 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003433
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003434 def With(ee: CWithEE, F: func)
3435 ee.Enter()
3436 defer ee.Exit()
3437 F()
3438 enddef
3439
3440 g:result = ''
3441 var obj = CWithEE.new()
3442 obj->With(() => {
3443 g:result ..= "called/"
3444 })
3445 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003446 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003447 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003448 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003449
3450 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003451 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003452
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003453 class BaseWithEE
3454 def Enter()
3455 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003456 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003457 def Exit()
3458 g:result ..= "exited-base"
3459 enddef
3460 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003461
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003462 class CWithEE extends BaseWithEE
3463 def Enter()
3464 g:result ..= "entered-child/"
3465 enddef
3466 def Exit()
3467 g:result ..= "exited-child"
3468 enddef
3469 endclass
3470
3471 def With(ee: BaseWithEE, F: func)
3472 ee.Enter()
3473 defer ee.Exit()
3474 F()
3475 enddef
3476
3477 g:result = ''
3478 var obj = CWithEE.new()
3479 obj->With(() => {
3480 g:result ..= "called/"
3481 })
3482 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003483 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003484 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003485 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003486enddef
3487
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003488" The following test used to crash Vim (Github issue #12676)
3489def Test_extends_method_crashes_vim()
3490 var lines =<< trim END
3491 vim9script
3492
3493 class Observer
3494 endclass
3495
3496 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003497 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003498
3499 def Set(v: any)
3500 if v != this.value
3501 this.value = v
3502 endif
3503 enddef
3504
3505 def Register(observer: Observer)
3506 enddef
3507 endclass
3508
3509 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003510 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003511 endclass
3512
3513 def Observe(obj: Property, who: Observer)
3514 obj.Register(who)
3515 enddef
3516
3517 var p = Bool.new(false)
3518 var myObserver = Observer.new()
3519
3520 Observe(p, myObserver)
3521
3522 p.Set(true)
3523 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003524 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003525enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003526
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003527" Test for calling a method in a class that is extended
3528def Test_call_method_in_extended_class()
3529 var lines =<< trim END
3530 vim9script
3531
3532 var prop_init_called = false
3533 var prop_register_called = false
3534
3535 class Property
3536 def Init()
3537 prop_init_called = true
3538 enddef
3539
3540 def Register()
3541 prop_register_called = true
3542 enddef
3543 endclass
3544
3545 class Bool extends Property
3546 endclass
3547
3548 def Observe(obj: Property)
3549 obj.Register()
3550 enddef
3551
3552 var p = Property.new()
3553 Observe(p)
3554
3555 p.Init()
3556 assert_true(prop_init_called)
3557 assert_true(prop_register_called)
3558 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003559 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003560enddef
3561
LemonBoyafe04662023-08-23 21:08:11 +02003562def Test_instanceof()
3563 var lines =<< trim END
3564 vim9script
3565
3566 class Base1
3567 endclass
3568
3569 class Base2 extends Base1
3570 endclass
3571
3572 interface Intf1
3573 endinterface
3574
3575 class Mix1 implements Intf1
3576 endclass
3577
3578 class Base3 extends Mix1
3579 endclass
3580
Ernie Rael2025af12023-12-12 16:58:00 +01003581 type AliasBase1 = Base1
3582 type AliasBase2 = Base2
3583 type AliasIntf1 = Intf1
3584 type AliasMix1 = Mix1
3585
LemonBoyafe04662023-08-23 21:08:11 +02003586 var b1 = Base1.new()
3587 var b2 = Base2.new()
3588 var b3 = Base3.new()
3589
3590 assert_true(instanceof(b1, Base1))
3591 assert_true(instanceof(b2, Base1))
3592 assert_false(instanceof(b1, Base2))
3593 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003594 assert_true(instanceof(b3, Base1, Base2, Intf1))
3595
3596 assert_true(instanceof(b1, AliasBase1))
3597 assert_true(instanceof(b2, AliasBase1))
3598 assert_false(instanceof(b1, AliasBase2))
3599 assert_true(instanceof(b3, AliasMix1))
3600 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003601
3602 def Foo()
3603 var a1 = Base1.new()
3604 var a2 = Base2.new()
3605 var a3 = Base3.new()
3606
3607 assert_true(instanceof(a1, Base1))
3608 assert_true(instanceof(a2, Base1))
3609 assert_false(instanceof(a1, Base2))
3610 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003611 assert_true(instanceof(a3, Base1, Base2, Intf1))
3612
3613 assert_true(instanceof(a1, AliasBase1))
3614 assert_true(instanceof(a2, AliasBase1))
3615 assert_false(instanceof(a1, AliasBase2))
3616 assert_true(instanceof(a3, AliasMix1))
3617 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003618 enddef
3619 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003620
3621 var o_null: Base1
3622 assert_false(instanceof(o_null, Base1))
3623
LemonBoyafe04662023-08-23 21:08:11 +02003624 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003625 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003626
3627 lines =<< trim END
3628 vim9script
3629
3630 class Base1
3631 endclass
3632 instanceof(Base1.new())
3633 END
3634 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3635
3636 lines =<< trim END
3637 vim9script
3638
3639 class Base1
3640 endclass
3641 def F()
3642 instanceof(Base1.new())
3643 enddef
3644 F()
3645 END
3646 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3647
3648 lines =<< trim END
3649 vim9script
3650
3651 class Base1
3652 endclass
3653
3654 class Base2
3655 endclass
3656
3657 var o = Base2.new()
3658 instanceof(o, Base1, Base2, 3)
3659 END
3660 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3661
3662 lines =<< trim END
3663 vim9script
3664
3665 class Base1
3666 endclass
3667
3668 class Base2
3669 endclass
3670
3671 def F()
3672 var o = Base2.new()
3673 instanceof(o, Base1, Base2, 3)
3674 enddef
3675 F()
3676 END
3677 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003678enddef
3679
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003680" Test for calling a method in the parent class that is extended partially.
3681" This used to fail with the 'E118: Too many arguments for function: Text' error
3682" message (Github issue #12524).
3683def Test_call_method_in_parent_class()
3684 var lines =<< trim END
3685 vim9script
3686
3687 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003688 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003689
3690 def SetY(lnum: number)
3691 this._lnum = lnum
3692 enddef
3693
3694 def Text(): string
3695 return ''
3696 enddef
3697 endclass
3698
3699 class Foo extends Widget
3700 def Text(): string
3701 return '<Foo>'
3702 enddef
3703 endclass
3704
3705 def Stack(w1: Widget, w2: Widget): list<Widget>
3706 w1.SetY(1)
3707 w2.SetY(2)
3708 return [w1, w2]
3709 enddef
3710
3711 var foo1 = Foo.new()
3712 var foo2 = Foo.new()
3713 var l = Stack(foo1, foo2)
3714 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003715 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003716enddef
3717
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003718" Test for calling methods from three levels of classes
3719def Test_multi_level_method_call()
3720 var lines =<< trim END
3721 vim9script
3722
3723 var A_func1: number = 0
3724 var A_func2: number = 0
3725 var A_func3: number = 0
3726 var B_func2: number = 0
3727 var B_func3: number = 0
3728 var C_func3: number = 0
3729
3730 class A
3731 def Func1()
3732 A_func1 += 1
3733 enddef
3734
3735 def Func2()
3736 A_func2 += 1
3737 enddef
3738
3739 def Func3()
3740 A_func3 += 1
3741 enddef
3742 endclass
3743
3744 class B extends A
3745 def Func2()
3746 B_func2 += 1
3747 enddef
3748
3749 def Func3()
3750 B_func3 += 1
3751 enddef
3752 endclass
3753
3754 class C extends B
3755 def Func3()
3756 C_func3 += 1
3757 enddef
3758 endclass
3759
3760 def A_CallFuncs(a: A)
3761 a.Func1()
3762 a.Func2()
3763 a.Func3()
3764 enddef
3765
3766 def B_CallFuncs(b: B)
3767 b.Func1()
3768 b.Func2()
3769 b.Func3()
3770 enddef
3771
3772 def C_CallFuncs(c: C)
3773 c.Func1()
3774 c.Func2()
3775 c.Func3()
3776 enddef
3777
3778 var cobj = C.new()
3779 A_CallFuncs(cobj)
3780 B_CallFuncs(cobj)
3781 C_CallFuncs(cobj)
3782 assert_equal(3, A_func1)
3783 assert_equal(0, A_func2)
3784 assert_equal(0, A_func3)
3785 assert_equal(3, B_func2)
3786 assert_equal(0, B_func3)
3787 assert_equal(3, C_func3)
3788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003789 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003790enddef
3791
3792" Test for using members from three levels of classes
3793def Test_multi_level_member_access()
3794 var lines =<< trim END
3795 vim9script
3796
3797 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003798 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003799 endclass
3800
3801 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003802 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003803 endclass
3804
3805 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003806 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003807 endclass
3808
3809 def A_members(a: A)
3810 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003811 enddef
3812
3813 def B_members(b: B)
3814 b.val1 += 1
3815 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003816 enddef
3817
3818 def C_members(c: C)
3819 c.val1 += 1
3820 c.val2 += 1
3821 c.val3 += 1
3822 enddef
3823
3824 var cobj = C.new()
3825 A_members(cobj)
3826 B_members(cobj)
3827 C_members(cobj)
3828 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003829 assert_equal(2, cobj.val2)
3830 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003831 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003832 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003833enddef
3834
LemonBoy0ffc17a2023-08-20 18:09:11 +02003835" Test expansion of <stack> with class methods.
3836def Test_stack_expansion_with_methods()
3837 var lines =<< trim END
3838 vim9script
3839
3840 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003841 def M1()
3842 F0()
3843 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003844 endclass
3845
3846 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02003847 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02003848 enddef
3849
3850 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003851 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003852 enddef
3853
3854 F()
3855 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003856 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003857enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003858
3859" Test the return type of the new() constructor
3860def Test_new_return_type()
3861 # new() uses the default return type and there is no return statement
3862 var lines =<< trim END
3863 vim9script
3864
3865 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003866 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003867
3868 def new(this._bufnr)
3869 if !bufexists(this._bufnr)
3870 this._bufnr = -1
3871 endif
3872 enddef
3873 endclass
3874
3875 var c = C.new(12345)
3876 assert_equal('object<C>', typename(c))
3877
3878 var v1: C
3879 v1 = C.new(12345)
3880 assert_equal('object<C>', typename(v1))
3881
3882 def F()
3883 var v2: C
3884 v2 = C.new(12345)
3885 assert_equal('object<C>', typename(v2))
3886 enddef
3887 F()
3888 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003889 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003890
3891 # new() uses the default return type and an empty 'return' statement
3892 lines =<< trim END
3893 vim9script
3894
3895 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003896 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003897
3898 def new(this._bufnr)
3899 if !bufexists(this._bufnr)
3900 this._bufnr = -1
3901 return
3902 endif
3903 enddef
3904 endclass
3905
3906 var c = C.new(12345)
3907 assert_equal('object<C>', typename(c))
3908
3909 var v1: C
3910 v1 = C.new(12345)
3911 assert_equal('object<C>', typename(v1))
3912
3913 def F()
3914 var v2: C
3915 v2 = C.new(12345)
3916 assert_equal('object<C>', typename(v2))
3917 enddef
3918 F()
3919 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003920 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003921
3922 # new() uses "any" return type and returns "this"
3923 lines =<< trim END
3924 vim9script
3925
3926 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003927 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003928
3929 def new(this._bufnr): any
3930 if !bufexists(this._bufnr)
3931 this._bufnr = -1
3932 return this
3933 endif
3934 enddef
3935 endclass
3936 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003937 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003938
3939 # new() uses 'Dict' return type and returns a Dict
3940 lines =<< trim END
3941 vim9script
3942
3943 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003944 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003945
3946 def new(): dict<any>
3947 this._state = {}
3948 return this._state
3949 enddef
3950 endclass
3951
3952 var c = C.new()
3953 assert_equal('object<C>', typename(c))
3954 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003955 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003956enddef
3957
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003958" Test for checking a member initialization type at run time.
3959def Test_runtime_type_check_for_member_init()
3960 var lines =<< trim END
3961 vim9script
3962
3963 var retnum: bool = false
3964
3965 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003966 retnum = !retnum
3967 if retnum
3968 return 1
3969 else
3970 return "hello"
3971 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003972 enddef
3973
3974 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003975 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003976 endclass
3977
3978 var c1 = C.new()
3979 var c2 = C.new()
3980 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003981 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003982enddef
3983
3984" Test for locking a variable referring to an object and reassigning to another
3985" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003986def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003987 var lines =<< trim END
3988 vim9script
3989
3990 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003991 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003992 def new(this.val)
3993 enddef
3994 endclass
3995
3996 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3997 lockvar 2 some_dict
3998
3999 var current: C
4000 current = some_dict['c']
4001 assert_equal(3, current.val)
4002 current = some_dict['b']
4003 assert_equal(2, current.val)
4004
4005 def F()
4006 current = some_dict['c']
4007 enddef
4008
4009 def G()
4010 current = some_dict['b']
4011 enddef
4012
4013 F()
4014 assert_equal(3, current.val)
4015 G()
4016 assert_equal(2, current.val)
4017 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004018 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004019enddef
4020
Ernie Raelee865f32023-09-29 19:53:55 +02004021" Test trying to lock an object variable from various places
4022def Test_lockvar_object_variable()
4023 # An object variable lockvar has several cases:
4024 # object method, scriptlevel, scriplevel from :def, :def arg
4025 # method arg, static method arg.
4026 # Also different depths
4027
Ernie Raelee865f32023-09-29 19:53:55 +02004028 #
4029 # lockvar of read-only object variable
4030 #
4031
4032 # read-only lockvar from object method
4033 var lines =<< trim END
4034 vim9script
4035
4036 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004037 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004038 def Lock()
4039 lockvar this.val1
4040 enddef
4041 endclass
4042 var o = C.new(3)
4043 o.Lock()
4044 END
Ernie Rael64885642023-10-04 20:16:22 +02004045 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004046
4047 # read-only lockvar from scriptlevel
4048 lines =<< trim END
4049 vim9script
4050
4051 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004052 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004053 endclass
4054 var o = C.new(3)
4055 lockvar o.val2
4056 END
4057 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4058
4059 # read-only lockvar of scriptlevel variable from def
4060 lines =<< trim END
4061 vim9script
4062
4063 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004064 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004065 endclass
4066 var o = C.new(3)
4067 def Lock()
4068 lockvar o.val3
4069 enddef
4070 Lock()
4071 END
4072 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4073
4074 # read-only lockvar of def argument variable
4075 lines =<< trim END
4076 vim9script
4077
4078 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004079 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004080 endclass
4081 def Lock(o: C)
4082 lockvar o.val4
4083 enddef
4084 Lock(C.new(3))
4085 END
4086 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4087
4088 # TODO: the following tests use type "any" for argument. Need a run time
4089 # check for access. Probably OK as is for now.
4090
4091 # read-only lockvar from object method arg
4092 lines =<< trim END
4093 vim9script
4094
4095 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004096 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004097 def Lock(o_any: any)
4098 lockvar o_any.val5
4099 enddef
4100 endclass
4101 var o = C.new(3)
4102 o.Lock(C.new(5))
4103 END
Ernie Rael64885642023-10-04 20:16:22 +02004104 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004105
4106 # read-only lockvar from class method arg
4107 lines =<< trim END
4108 vim9script
4109
4110 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004111 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004112 static def Lock(o_any: any)
4113 lockvar o_any.val6
4114 enddef
4115 endclass
4116 var o = C.new(3)
4117 C.Lock(o)
4118 END
Ernie Rael64885642023-10-04 20:16:22 +02004119 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004120
4121 #
4122 # lockvar of public object variable
4123 #
4124
4125 # lockvar from object method
4126 lines =<< trim END
4127 vim9script
4128
4129 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004130 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004131 def Lock()
4132 lockvar this.val1
4133 enddef
4134 endclass
4135 var o = C.new(3)
4136 o.Lock()
4137 END
4138 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4139
4140 # lockvar from scriptlevel
4141 lines =<< trim END
4142 vim9script
4143
4144 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004145 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004146 endclass
4147 var o = C.new(3)
4148 lockvar o.val2
4149 END
4150 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4151
4152 # lockvar of scriptlevel variable from def
4153 lines =<< trim END
4154 vim9script
4155
4156 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004157 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004158 endclass
4159 var o = C.new(3)
4160 def Lock()
4161 lockvar o.val3
4162 enddef
4163 Lock()
4164 END
4165 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4166
4167 # lockvar of def argument variable
4168 lines =<< trim END
4169 vim9script
4170
4171 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004172 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004173 endclass
4174 def Lock(o: C)
4175 lockvar o.val4
4176 enddef
4177 Lock(C.new(3))
4178 END
4179 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4180
4181 # lockvar from object method arg
4182 lines =<< trim END
4183 vim9script
4184
4185 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004186 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004187 def Lock(o_any: any)
4188 lockvar o_any.val5
4189 enddef
4190 endclass
4191 var o = C.new(3)
4192 o.Lock(C.new(5))
4193 END
4194 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4195
4196 # lockvar from class method arg
4197 lines =<< trim END
4198 vim9script
4199
4200 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004201 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004202 static def Lock(o_any: any)
4203 lockvar o_any.val6
4204 enddef
4205 endclass
4206 var o = C.new(3)
4207 C.Lock(o)
4208 END
4209 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4210enddef
4211
4212" Test trying to lock a class variable from various places
4213def Test_lockvar_class_variable()
4214
4215 # lockvar bare static from object method
4216 var lines =<< trim END
4217 vim9script
4218
4219 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004220 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004221 def Lock()
4222 lockvar sval1
4223 enddef
4224 endclass
4225 var o = C.new()
4226 o.Lock()
4227 END
4228 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4229
4230 # lockvar C.static from object method
4231 lines =<< trim END
4232 vim9script
4233
4234 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004235 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004236 def Lock()
4237 lockvar C.sval2
4238 enddef
4239 endclass
4240 var o = C.new()
4241 o.Lock()
4242 END
4243 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4244
4245 # lockvar bare static from class method
4246 lines =<< trim END
4247 vim9script
4248
4249 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004250 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004251 static def Lock()
4252 lockvar sval3
4253 enddef
4254 endclass
4255 C.Lock()
4256 END
4257 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4258
4259 # lockvar C.static from class method
4260 lines =<< trim END
4261 vim9script
4262
4263 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004264 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004265 static def Lock()
4266 lockvar C.sval4
4267 enddef
4268 endclass
4269 C.Lock()
4270 END
4271 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4272
4273 # lockvar C.static from script level
4274 lines =<< trim END
4275 vim9script
4276
4277 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004278 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004279 endclass
4280 lockvar C.sval5
4281 END
4282 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4283
4284 # lockvar o.static from script level
4285 lines =<< trim END
4286 vim9script
4287
4288 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004289 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004290 endclass
4291 var o = C.new()
4292 lockvar o.sval6
4293 END
4294 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4295enddef
4296
4297" Test locking an argument to :def
4298def Test_lockvar_argument()
4299 # Lockvar a function arg
4300 var lines =<< trim END
4301 vim9script
4302
4303 def Lock(val: any)
4304 lockvar val
4305 enddef
4306
4307 var d = {a: 1, b: 2}
4308 Lock(d)
4309
4310 d->extend({c: 3})
4311 END
4312 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4313
4314 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4315 # class member in "C". This tests lval_root_is_arg.
4316 lines =<< trim END
4317 vim9script
4318
4319 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004320 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004321 endclass
4322
4323 def Lock2(sval: any)
4324 lockvar sval
4325 enddef
4326
4327 var o = C.new()
4328 Lock2(o)
4329 END
4330 v9.CheckSourceSuccess(lines)
4331
4332 # Lock a class.
4333 lines =<< trim END
4334 vim9script
4335
4336 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004337 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004338 endclass
4339
4340 def Lock2(sval: any)
4341 lockvar sval
4342 enddef
4343
4344 Lock2(C)
4345 END
Ernie Raelb077b582023-12-14 20:11:44 +01004346 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004347
4348 # Lock an object.
4349 lines =<< trim END
4350 vim9script
4351
4352 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004353 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004354 endclass
4355
4356 def Lock2(sval: any)
4357 lockvar sval
4358 enddef
4359
4360 Lock2(C.new())
4361 END
4362 v9.CheckSourceSuccess(lines)
4363
4364 # In this case (unlike previous) "lockvar sval" is a class member.
4365 lines =<< trim END
4366 vim9script
4367
4368 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004369 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004370 def Lock2()
4371 lockvar sval
4372 enddef
4373 endclass
4374
4375
4376 var o = C.new()
4377 o.Lock2()
4378 END
4379 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4380enddef
4381
4382" Test that this can be locked without error
4383def Test_lockvar_this()
4384 # lockvar this
4385 var lines =<< trim END
4386 vim9script
4387 class C
4388 def TLock()
4389 lockvar this
4390 enddef
4391 endclass
4392 var o = C.new()
4393 o.TLock()
4394 END
4395 v9.CheckSourceSuccess(lines)
4396
4397 # lockvar four (four letter word, but not this)
4398 lines =<< trim END
4399 vim9script
4400 class C
4401 def TLock4()
4402 var four: number
4403 lockvar four
4404 enddef
4405 endclass
4406 var o = C.new()
4407 o.TLock4()
4408 END
4409 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4410
4411 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4412 lines =<< trim END
4413 vim9script
4414 class C
4415 def TLock5()
4416 var this5: number
4417 lockvar this5
4418 enddef
4419 endclass
4420 var o = C.new()
4421 o.TLock5()
4422 END
4423 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4424enddef
4425
4426" Test some general lockvar cases
4427def Test_lockvar_general()
4428 # lockvar an object and a class. It does nothing
4429 var lines =<< trim END
4430 vim9script
4431 class C
4432 endclass
4433 var o = C.new()
4434 lockvar o
4435 lockvar C
4436 END
4437 v9.CheckSourceSuccess(lines)
4438
4439 # Lock a list element that's nested in an object variable from a :def
4440 lines =<< trim END
4441 vim9script
4442
4443 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004444 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004445 endclass
4446 def Lock2(obj: any)
4447 lockvar obj.val[1]
4448 enddef
4449
4450 var o = C.new()
4451 Lock2(o)
4452 o.val[0] = [9]
4453 assert_equal([ [9], [2], [3] ], o.val)
4454 try
4455 o.val[1] = [999]
4456 call assert_false(true, 'assign should have failed')
4457 catch
4458 assert_exception('E741:')
4459 endtry
4460 o.val[2] = [8]
4461 assert_equal([ [9], [2], [8] ], o.val)
4462 END
4463 v9.CheckSourceSuccess(lines)
4464
4465 # Lock a list element that's nested in an object variable from scriptlevel
4466 lines =<< trim END
4467 vim9script
4468
4469 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004470 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004471 endclass
4472
4473 var o = C.new()
4474 lockvar o.val[1]
4475 o.val[0] = [9]
4476 assert_equal([ [9], [2], [3] ], o.val)
4477 try
4478 o.val[1] = [999]
4479 call assert_false(true, 'assign should have failed')
4480 catch
4481 assert_exception('E741:')
4482 endtry
4483 o.val[2] = [8]
4484 assert_equal([ [9], [2], [8] ], o.val)
4485 END
4486 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004487
4488 # lock a script level variable from an object method
4489 lines =<< trim END
4490 vim9script
4491
4492 class C
4493 def Lock()
4494 lockvar l
4495 enddef
4496 endclass
4497
4498 var l = [1]
4499 C.new().Lock()
4500 l[0] = 11
4501 END
4502 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4503
Ernie Rael03042a22023-11-11 08:53:32 +01004504 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004505 # in an object fetched via a script level list
4506 lines =<< trim END
4507 vim9script
4508
4509 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004510 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004511 def Lock()
4512 lockvar lc[0]._v1[1]
4513 enddef
4514 endclass
4515
4516 var l = [[1], [2], [3]]
4517 var o = C.new(l)
4518 var lc: list<C> = [ o ]
4519
4520 o.Lock()
4521 l[0] = [22]
4522 l[1] = [33]
4523 END
4524 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4525
4526 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004527 # in a class that does not own the protected variable.
4528 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004529 # the same name.
4530 lines =<< trim END
4531 vim9script
4532
4533 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004534 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004535 def Lock(obj: any)
4536 lockvar lc[0]._v1[1]
4537 enddef
4538 endclass
4539
4540 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004541 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004542 endclass
4543
4544 var l = [[1], [2], [3]]
4545 var o = C.new(l)
4546 var lc: list<C> = [ o ]
4547
4548 var o2 = C2.new()
4549 o2.Lock(o)
4550 END
Ernie Rael03042a22023-11-11 08:53:32 +01004551 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004552enddef
4553
Ernie Rael9771b2a2023-10-07 22:05:40 +02004554" Test builtin islocked()
4555def Test_lockvar_islocked()
4556 # Can't lock class/object variable
4557 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004558 # Lock item of variable's value (a list item)
4559 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004560 var lines =<< trim END
4561 vim9script
4562
4563 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004564 var o0: list<list<number>> = [ [0], [1], [2]]
4565 var o1: list<list<number>> = [[10], [11], [12]]
4566 static var c0: list<list<number>> = [[20], [21], [22]]
4567 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004568 endclass
4569
4570 def LockIt(arg: any)
4571 lockvar arg
4572 enddef
4573
4574 def UnlockIt(arg: any)
4575 unlockvar arg
4576 enddef
4577
4578 var obj = C.new()
4579 #lockvar obj.o1 # can't lock something you can't write to
4580
4581 try
4582 lockvar obj.o1 # can't lock something you can't write to
4583 call assert_false(1, '"lockvar obj.o1" should have failed')
4584 catch
4585 call assert_exception('E1335:')
4586 endtry
4587
4588 LockIt(obj.o1) # but can lock it's value
4589 assert_equal(1, islocked("obj.o1"))
4590 assert_equal(1, islocked("obj.o1[0]"))
4591 assert_equal(1, islocked("obj.o1[1]"))
4592 UnlockIt(obj.o1)
4593 assert_equal(0, islocked("obj.o1"))
4594 assert_equal(0, islocked("obj.o1[0]"))
4595
4596 lockvar obj.o1[0]
4597 assert_equal(0, islocked("obj.o1"))
4598 assert_equal(1, islocked("obj.o1[0]"))
4599 assert_equal(0, islocked("obj.o1[1]"))
4600 unlockvar obj.o1[0]
4601 assert_equal(0, islocked("obj.o1"))
4602 assert_equal(0, islocked("obj.o1[0]"))
4603
4604 # Same thing, but with a static
4605
4606 try
4607 lockvar C.c1 # can't lock something you can't write to
4608 call assert_false(1, '"lockvar C.c1" should have failed')
4609 catch
4610 call assert_exception('E1335:')
4611 endtry
4612
4613 LockIt(C.c1) # but can lock it's value
4614 assert_equal(1, islocked("C.c1"))
4615 assert_equal(1, islocked("C.c1[0]"))
4616 assert_equal(1, islocked("C.c1[1]"))
4617 UnlockIt(C.c1)
4618 assert_equal(0, islocked("C.c1"))
4619 assert_equal(0, islocked("C.c1[0]"))
4620
4621 lockvar C.c1[0]
4622 assert_equal(0, islocked("C.c1"))
4623 assert_equal(1, islocked("C.c1[0]"))
4624 assert_equal(0, islocked("C.c1[1]"))
4625 unlockvar C.c1[0]
4626 assert_equal(0, islocked("C.c1"))
4627 assert_equal(0, islocked("C.c1[0]"))
4628 END
4629 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004630
4631 # Do islocked() from an object method
4632 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004633 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004634 vim9script
4635
4636 var l0o0 = [ [0], [1], [2]]
4637 var l0o1 = [ [10], [11], [12]]
4638 var l0c0 = [[120], [121], [122]]
4639 var l0c1 = [[130], [131], [132]]
4640
4641 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004642 var o0: list<list<number>> = l0o0
4643 var o1: list<list<number>> = l0o1
4644 static var c0: list<list<number>> = l0c0
4645 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004646 def Islocked(arg: string): number
4647 return islocked(arg)
4648 enddef
4649 static def SIslocked(arg: string): number
4650 return islocked(arg)
4651 enddef
4652 endclass
4653
4654 var l2o0 = [[20000], [20001], [20002]]
4655 var l2o1 = [[20010], [20011], [20012]]
4656 var l2c0 = [[20120], [20121], [20122]]
4657 var l2c1 = [[20130], [20131], [20132]]
4658
4659 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004660 var o0: list<list<number>> = l2o0
4661 var o1: list<list<number>> = l2o1
4662 static var c0: list<list<number>> = l2c0
4663 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004664 def Islocked(arg: string): number
4665 return islocked(arg)
4666 enddef
4667 static def SIslocked(arg: string): number
4668 return islocked(arg)
4669 enddef
4670 endclass
4671
4672 var obj0 = C0.new()
4673 var obj2 = C2.new()
4674
4675 var l = [ obj0, null_object, obj2 ]
4676
4677 # lock list, object func access through script var expr
4678 assert_equal(0, obj0.Islocked("l[0].o0"))
4679 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4680 lockvar l0o0
4681 assert_equal(1, obj0.Islocked("l[0].o0"))
4682 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4683
4684 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4685
4686 # lock list element, object func access through script var expr
4687 lockvar l0o1[1]
4688 assert_equal(0, obj0.Islocked("this.o1[0]"))
4689 assert_equal(1, obj0.Islocked("this.o1[1]"))
4690
4691 assert_equal(0, obj0.Islocked("this.o1"))
4692 lockvar l0o1
4693 assert_equal(1, obj0.Islocked("this.o1"))
4694 unlockvar l0o1
4695
4696 lockvar l0c1[1]
4697
4698 # static by class name member expr from same class
4699 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4700 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4701 # static by bare name member expr from same class
4702 assert_equal(0, obj0.Islocked("c1[0]"))
4703 assert_equal(1, obj0.Islocked("c1[1]"))
4704
4705 # static by class name member expr from other class
4706 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4707 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4708 # static by bare name member expr from other class
4709 assert_equal(0, obj2.Islocked("c1[0]"))
4710 assert_equal(0, obj2.Islocked("c1[1]"))
4711
4712
4713 # static by bare name in same class
4714 assert_equal(0, obj0.Islocked("c0"))
4715 lockvar l0c0
4716 assert_equal(1, obj0.Islocked("c0"))
4717
4718 #
4719 # similar stuff, but use static method
4720 #
4721
4722 unlockvar l0o0
4723
4724 # lock list, object func access through script var expr
4725 assert_equal(0, C0.SIslocked("l[0].o0"))
4726 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4727 lockvar l0o0
4728 assert_equal(1, C0.SIslocked("l[0].o0"))
4729 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4730
4731 unlockvar l0o1
4732
4733 # can't access "this" from class method
4734 try
4735 C0.SIslocked("this.o1[0]")
4736 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4737 catch
4738 call assert_exception('E121: Undefined variable: this')
4739 endtry
4740
4741 lockvar l0c1[1]
4742
4743 # static by class name member expr from same class
4744 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4745 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4746 # static by bare name member expr from same class
4747 assert_equal(0, C0.SIslocked("c1[0]"))
4748 assert_equal(1, C0.SIslocked("c1[1]"))
4749
4750 # static by class name member expr from other class
4751 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4752 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4753 # static by bare name member expr from other class
4754 assert_equal(0, C2.SIslocked("c1[0]"))
4755 assert_equal(0, C2.SIslocked("c1[1]"))
4756
4757
4758 # static by bare name in same class
4759 unlockvar l0c0
4760 assert_equal(0, C0.SIslocked("c0"))
4761 lockvar l0c0
4762 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004763 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004764 v9.CheckSourceSuccess(lines)
4765
4766 # Check islocked class/object from various places.
4767 lines =<< trim END
4768 vim9script
4769
4770 class C
4771 def Islocked(arg: string): number
4772 return islocked(arg)
4773 enddef
4774 static def SIslocked(arg: string): number
4775 return islocked(arg)
4776 enddef
4777 endclass
4778 var obj = C.new()
4779
4780 # object method
4781 assert_equal(0, obj.Islocked("this"))
4782 assert_equal(0, obj.Islocked("C"))
4783
4784 # class method
4785 ### assert_equal(0, C.SIslocked("this"))
4786 assert_equal(0, C.SIslocked("C"))
4787
4788 #script level
4789 var v: number
4790 v = islocked("C")
4791 assert_equal(0, v)
4792 v = islocked("obj")
4793 assert_equal(0, v)
4794 END
4795 v9.CheckSourceSuccess(lines)
4796enddef
4797
4798def Test_lockvar_islocked_notfound()
4799 # Try non-existent things
4800 var lines =<< trim END
4801 vim9script
4802
4803 class C
4804 def Islocked(arg: string): number
4805 return islocked(arg)
4806 enddef
4807 static def SIslocked(arg: string): number
4808 return islocked(arg)
4809 enddef
4810 endclass
4811 var obj = C.new()
4812 assert_equal(-1, obj.Islocked("anywhere"))
4813 assert_equal(-1, C.SIslocked("notanywhere"))
4814 END
4815 v9.CheckSourceSuccess(lines)
4816
4817 # Something not found of the form "name1.name2" is an error
4818 lines =<< trim END
4819 vim9script
4820
4821 islocked("one.two")
4822 END
4823 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4824
4825 lines =<< trim END
4826 vim9script
4827
4828 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004829 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004830 def Islocked(arg: string): number
4831 return islocked(arg)
4832 enddef
4833 endclass
4834 var obj = C.new()
4835 obj.Islocked("this.val.not_there"))
4836 END
4837 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4838
4839 lines =<< trim END
4840 vim9script
4841
4842 class C
4843 def Islocked(arg: string): number
4844 return islocked(arg)
4845 enddef
4846 endclass
4847 var obj = C.new()
4848 obj.Islocked("this.notobjmember")
4849 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004850 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004851
4852 # access a script variable through methods
4853 lines =<< trim END
4854 vim9script
4855
4856 var l = [1]
4857 class C
4858 def Islocked(arg: string): number
4859 return islocked(arg)
4860 enddef
4861 static def SIslocked(arg: string): number
4862 return islocked(arg)
4863 enddef
4864 endclass
4865 var obj = C.new()
4866 assert_equal(0, obj.Islocked("l"))
4867 assert_equal(0, C.SIslocked("l"))
4868 lockvar l
4869 assert_equal(1, obj.Islocked("l"))
4870 assert_equal(1, C.SIslocked("l"))
4871 END
4872 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004873enddef
4874
Ernie Rael03042a22023-11-11 08:53:32 +01004875" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004876def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004877 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004878 var lines =<< trim END
4879 vim9script
4880
4881 class A
4882 def _Foo(): number
4883 return 1234
4884 enddef
4885 endclass
4886 var a = A.new()
4887 a._Foo()
4888 END
Ernie Rael03042a22023-11-11 08:53:32 +01004889 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004890
Ernie Rael03042a22023-11-11 08:53:32 +01004891 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004892 lines =<< trim END
4893 vim9script
4894
4895 class A
4896 def _Foo(): number
4897 return 1234
4898 enddef
4899 endclass
4900 def T()
4901 var a = A.new()
4902 a._Foo()
4903 enddef
4904 T()
4905 END
Ernie Rael03042a22023-11-11 08:53:32 +01004906 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004907
Ernie Rael03042a22023-11-11 08:53:32 +01004908 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004909 lines =<< trim END
4910 vim9script
4911
4912 class A
4913 def _Foo(): number
4914 return 1234
4915 enddef
4916 def Bar(): number
4917 return this._Foo()
4918 enddef
4919 endclass
4920 var a = A.new()
4921 assert_equal(1234, a.Bar())
4922 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004923 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004924
Ernie Rael03042a22023-11-11 08:53:32 +01004925 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004926 lines =<< trim END
4927 vim9script
4928
4929 class A
4930 def _Foo(): number
4931 return 1234
4932 enddef
4933 def Bar(): number
4934 return this._Foo()
4935 enddef
4936 endclass
4937 def T()
4938 var a = A.new()
4939 assert_equal(1234, a.Bar())
4940 enddef
4941 T()
4942 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004943 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004944
Ernie Rael03042a22023-11-11 08:53:32 +01004945 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004946 lines =<< trim END
4947 vim9script
4948
4949 class A
4950 def _Foo(): number
4951 return 1234
4952 enddef
4953 def Bar(): number
4954 return _Foo()
4955 enddef
4956 endclass
4957 var a = A.new()
4958 a.Bar()
4959 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004960 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004961
Ernie Rael03042a22023-11-11 08:53:32 +01004962 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004963 lines =<< trim END
4964 vim9script
4965
4966 class A
4967 def _Foo(): number
4968 return 1234
4969 enddef
4970 endclass
4971 A._Foo()
4972 END
Ernie Rael03042a22023-11-11 08:53:32 +01004973 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004974
Ernie Rael03042a22023-11-11 08:53:32 +01004975 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004976 lines =<< trim END
4977 vim9script
4978
4979 class A
4980 def _Foo()
4981 enddef
4982 def _Foo()
4983 enddef
4984 endclass
4985 var a = A.new()
4986 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004987 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004988
Ernie Rael03042a22023-11-11 08:53:32 +01004989 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004990 lines =<< trim END
4991 vim9script
4992
4993 class A
4994 def _Foo()
4995 enddef
4996 def Foo()
4997 enddef
4998 endclass
4999 var a = A.new()
5000 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005001 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005002
Ernie Rael03042a22023-11-11 08:53:32 +01005003 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005004 lines =<< trim END
5005 vim9script
5006
5007 class A
5008 def Foo()
5009 enddef
5010 def _Foo()
5011 enddef
5012 endclass
5013 var a = A.new()
5014 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005015 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005016
Ernie Rael03042a22023-11-11 08:53:32 +01005017 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005018 lines =<< trim END
5019 vim9script
5020
5021 class A
5022 def Foo(): number
5023 return 100
5024 enddef
5025 def _Bar(): number
5026 return 200
5027 enddef
5028 def _Baz()
5029 assert_equal(100, this.Foo())
5030 assert_equal(200, this._Bar())
5031 enddef
5032 def T()
5033 this._Baz()
5034 enddef
5035 endclass
5036 var a = A.new()
5037 a.T()
5038 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005039 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005040
Ernie Rael03042a22023-11-11 08:53:32 +01005041 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005042 lines =<< trim END
5043 vim9script
5044
5045 class A
5046 def _Foo(): number
5047 return 100
5048 enddef
5049 endclass
5050 class B
5051 def Foo(): number
5052 var a = A.new()
5053 a._Foo()
5054 enddef
5055 endclass
5056 var b = B.new()
5057 b.Foo()
5058 END
Ernie Rael03042a22023-11-11 08:53:32 +01005059 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005060
Ernie Rael03042a22023-11-11 08:53:32 +01005061 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005062 lines =<< trim END
5063 vim9script
5064 class A
5065 def _Foo(): number
5066 return 1234
5067 enddef
5068 endclass
5069 class B extends A
5070 def Bar()
5071 enddef
5072 endclass
5073 class C extends B
5074 def Baz(): number
5075 return this._Foo()
5076 enddef
5077 endclass
5078 var c = C.new()
5079 assert_equal(1234, c.Baz())
5080 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005081 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005082
Ernie Rael03042a22023-11-11 08:53:32 +01005083 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005084 lines =<< trim END
5085 vim9script
5086 class A
5087 def _Foo(): number
5088 return 1234
5089 enddef
5090 endclass
5091 class B extends A
5092 def Bar()
5093 enddef
5094 endclass
5095 class C extends B
5096 def Baz(): number
5097 enddef
5098 endclass
5099 var c = C.new()
5100 assert_equal(1234, c._Foo())
5101 END
Ernie Rael03042a22023-11-11 08:53:32 +01005102 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005103
5104 # Using "_" prefix in a method name should fail outside of a class
5105 lines =<< trim END
5106 vim9script
5107 def _Foo(): number
5108 return 1234
5109 enddef
5110 var a = _Foo()
5111 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005112 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005113enddef
5114
Ernie Rael03042a22023-11-11 08:53:32 +01005115" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005116def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005117 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005118 var lines =<< trim END
5119 vim9script
5120
5121 class A
5122 static def _Foo(): number
5123 return 1234
5124 enddef
5125 endclass
5126 A._Foo()
5127 END
Ernie Rael03042a22023-11-11 08:53:32 +01005128 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005129
Ernie Rael03042a22023-11-11 08:53:32 +01005130 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005131 lines =<< trim END
5132 vim9script
5133
5134 class A
5135 static def _Foo(): number
5136 return 1234
5137 enddef
5138 endclass
5139 def T()
5140 A._Foo()
5141 enddef
5142 T()
5143 END
Ernie Rael03042a22023-11-11 08:53:32 +01005144 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005145
Ernie Rael03042a22023-11-11 08:53:32 +01005146 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005147 lines =<< trim END
5148 vim9script
5149
5150 class A
5151 static def _Foo(): number
5152 return 1234
5153 enddef
5154 endclass
5155 var a = A.new()
5156 a._Foo()
5157 END
Ernie Rael03042a22023-11-11 08:53:32 +01005158 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005159
Ernie Rael03042a22023-11-11 08:53:32 +01005160 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005161 lines =<< trim END
5162 vim9script
5163
5164 class A
5165 static def _Foo(): number
5166 return 1234
5167 enddef
5168 endclass
5169 def T()
5170 var a = A.new()
5171 a._Foo()
5172 enddef
5173 T()
5174 END
Ernie Rael03042a22023-11-11 08:53:32 +01005175 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005176
Ernie Rael03042a22023-11-11 08:53:32 +01005177 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005178 lines =<< trim END
5179 vim9script
5180
5181 class A
5182 static def _Foo(): number
5183 return 1234
5184 enddef
5185 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005186 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005187 enddef
5188 endclass
5189 var a = A.new()
5190 a.Bar()
5191 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005192 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005193
Ernie Rael03042a22023-11-11 08:53:32 +01005194 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005195 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005196 lines =<< trim END
5197 vim9script
5198
5199 class A
5200 static def _Foo1(): number
5201 return 1234
5202 enddef
5203 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005204 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005205 enddef
5206 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005207 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005208 enddef
5209 endclass
5210 var a = A.new()
5211 a.Bar()
5212 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005213 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005214
Ernie Rael03042a22023-11-11 08:53:32 +01005215 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005216 lines =<< trim END
5217 vim9script
5218
5219 class A
5220 static def _Foo()
5221 enddef
5222 static def Foo()
5223 enddef
5224 endclass
5225 var a = A.new()
5226 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005227 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005228
Ernie Rael03042a22023-11-11 08:53:32 +01005229 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005230 lines =<< trim END
5231 vim9script
5232
5233 class A
5234 static def _Foo(): number
5235 return 1234
5236 enddef
5237 endclass
5238 class B
5239 def Foo(): number
5240 return A._Foo()
5241 enddef
5242 endclass
5243 var b = B.new()
5244 assert_equal(1234, b.Foo())
5245 END
Ernie Rael03042a22023-11-11 08:53:32 +01005246 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005247
Ernie Rael03042a22023-11-11 08:53:32 +01005248 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005249 lines =<< trim END
5250 vim9script
5251 class A
5252 static def _Foo(): number
5253 return 1234
5254 enddef
5255 endclass
5256 class B extends A
5257 def Bar()
5258 enddef
5259 endclass
5260 class C extends B
5261 def Baz(): number
5262 return A._Foo()
5263 enddef
5264 endclass
5265 var c = C.new()
5266 assert_equal(1234, c.Baz())
5267 END
Ernie Rael03042a22023-11-11 08:53:32 +01005268 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005269
Ernie Rael03042a22023-11-11 08:53:32 +01005270 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005271 lines =<< trim END
5272 vim9script
5273 class A
5274 static def _Foo(): number
5275 return 1234
5276 enddef
5277 endclass
5278 class B extends A
5279 def Bar()
5280 enddef
5281 endclass
5282 class C extends B
5283 static def Baz(): number
5284 return A._Foo()
5285 enddef
5286 endclass
5287 assert_equal(1234, C.Baz())
5288 END
Ernie Rael03042a22023-11-11 08:53:32 +01005289 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005290
Ernie Rael03042a22023-11-11 08:53:32 +01005291 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005292 lines =<< trim END
5293 vim9script
5294 class A
5295 static def _Foo(): number
5296 return 1234
5297 enddef
5298 endclass
5299 class B extends A
5300 def Bar()
5301 enddef
5302 endclass
5303 class C extends B
5304 def Baz(): number
5305 enddef
5306 endclass
5307 var c = C.new()
5308 assert_equal(1234, C._Foo())
5309 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005310 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005311enddef
5312
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005313" Test for using the return value of a class/object method as a function
5314" argument.
5315def Test_objmethod_funcarg()
5316 var lines =<< trim END
5317 vim9script
5318
5319 class C
5320 def Foo(): string
5321 return 'foo'
5322 enddef
5323 endclass
5324
5325 def Bar(a: number, s: string): string
5326 return s
5327 enddef
5328
5329 def Baz(c: C)
5330 assert_equal('foo', Bar(10, c.Foo()))
5331 enddef
5332
5333 var t = C.new()
5334 Baz(t)
5335 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005336 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005337
5338 lines =<< trim END
5339 vim9script
5340
5341 class C
5342 static def Foo(): string
5343 return 'foo'
5344 enddef
5345 endclass
5346
5347 def Bar(a: number, s: string): string
5348 return s
5349 enddef
5350
5351 def Baz()
5352 assert_equal('foo', Bar(10, C.Foo()))
5353 enddef
5354
5355 Baz()
5356 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005357 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005358enddef
5359
Ernie Raelcf138d42023-09-06 20:45:03 +02005360def Test_static_inheritence()
5361 # subclasses get their own static copy
5362 var lines =<< trim END
5363 vim9script
5364
5365 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005366 static var _svar: number
5367 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005368 def new()
5369 _svar = 1
5370 this._mvar = 101
5371 enddef
5372 def AccessObject(): number
5373 return this._mvar
5374 enddef
5375 def AccessStaticThroughObject(): number
5376 return _svar
5377 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005378 endclass
5379
5380 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005381 def new()
5382 this._mvar = 102
5383 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005384 endclass
5385
5386 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005387 def new()
5388 this._mvar = 103
5389 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005390
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005391 def AccessPrivateStaticThroughClassName(): number
5392 assert_equal(1, A._svar)
5393 return 444
5394 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005395 endclass
5396
5397 var oa = A.new()
5398 var ob = B.new()
5399 var oc = C.new()
5400 assert_equal(101, oa.AccessObject())
5401 assert_equal(102, ob.AccessObject())
5402 assert_equal(103, oc.AccessObject())
5403
Ernie Rael03042a22023-11-11 08:53:32 +01005404 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005405
5406 # verify object properly resolves to correct static
5407 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005408 assert_equal(1, ob.AccessStaticThroughObject())
5409 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005410 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005411 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005412enddef
5413
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005414" Test for declaring duplicate object and class members
5415def Test_dup_member_variable()
5416 # Duplicate member variable
5417 var lines =<< trim END
5418 vim9script
5419 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005420 var val = 10
5421 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005422 endclass
5423 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005424 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005425
Ernie Rael03042a22023-11-11 08:53:32 +01005426 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005427 lines =<< trim END
5428 vim9script
5429 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005430 var _val = 10
5431 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005432 endclass
5433 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005434 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005435
5436 # Duplicate public member variable
5437 lines =<< trim END
5438 vim9script
5439 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005440 public var val = 10
5441 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005442 endclass
5443 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005444 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005445
Ernie Rael03042a22023-11-11 08:53:32 +01005446 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005447 lines =<< trim END
5448 vim9script
5449 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005450 var val = 10
5451 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005452 endclass
5453 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005454 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005455
Ernie Rael03042a22023-11-11 08:53:32 +01005456 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005457 lines =<< trim END
5458 vim9script
5459 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005460 var _val = 20
5461 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005462 endclass
5463 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005464 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005465
5466 # Duplicate class member variable
5467 lines =<< trim END
5468 vim9script
5469 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005470 static var s: string = "abc"
5471 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005472 endclass
5473 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005474 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005475
Ernie Rael03042a22023-11-11 08:53:32 +01005476 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005477 lines =<< trim END
5478 vim9script
5479 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005480 public static var s: string = "abc"
5481 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005482 endclass
5483 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005484 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005485
5486 # Duplicate class and object member variable
5487 lines =<< trim END
5488 vim9script
5489 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005490 static var val = 10
5491 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005492 def new()
5493 enddef
5494 endclass
5495 var c = C.new()
5496 assert_equal(10, C.val)
5497 assert_equal(20, c.val)
5498 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005499 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005500
5501 # Duplicate object member variable in a derived class
5502 lines =<< trim END
5503 vim9script
5504 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005505 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005506 endclass
5507 class B extends A
5508 endclass
5509 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005510 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005511 endclass
5512 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005513 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005514
Ernie Rael03042a22023-11-11 08:53:32 +01005515 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005516 lines =<< trim END
5517 vim9script
5518 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005519 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005520 endclass
5521 class B extends A
5522 endclass
5523 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005524 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005525 endclass
5526 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005527 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005528
Ernie Rael03042a22023-11-11 08:53:32 +01005529 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005530 lines =<< trim END
5531 vim9script
5532 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005533 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005534 endclass
5535 class B extends A
5536 endclass
5537 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005538 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005539 endclass
5540 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005541 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005542
5543 # Duplicate object member variable in a derived class
5544 lines =<< trim END
5545 vim9script
5546 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005547 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005548 endclass
5549 class B extends A
5550 endclass
5551 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005552 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005553 endclass
5554 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005555 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005556
5557 # Two member variables with a common prefix
5558 lines =<< trim END
5559 vim9script
5560 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005561 public static var svar2: number
5562 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005563 endclass
5564 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005565 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005566enddef
5567
Ernie Rael03042a22023-11-11 08:53:32 +01005568" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005569def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005570 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005571 var lines =<< trim END
5572 vim9script
5573 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005574 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005575 def GetVal(): number
5576 return this._val
5577 enddef
5578 endclass
5579 def T()
5580 var a = A.new()
5581 a._val = 20
5582 enddef
5583 T()
5584 END
Ernie Rael03042a22023-11-11 08:53:32 +01005585 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005586
Ernie Rael03042a22023-11-11 08:53:32 +01005587 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005588 lines =<< trim END
5589 vim9script
5590 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005591 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005592 endclass
5593 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005594 var a = A.new()
5595 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005596 enddef
5597 T()
5598 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005599 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005600
Ernie Rael03042a22023-11-11 08:53:32 +01005601 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005602 lines =<< trim END
5603 vim9script
5604 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005605 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005606 endclass
5607 def T()
5608 var a = A.new()
5609 var x = a._val
5610 enddef
5611 T()
5612 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005613 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005614
Ernie Rael03042a22023-11-11 08:53:32 +01005615 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005616 lines =<< trim END
5617 vim9script
5618 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005619 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005620 endclass
5621 def T()
5622 var a = A.new()
5623 a._val = 3
5624 enddef
5625 T()
5626 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005627 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005628
Ernie Rael03042a22023-11-11 08:53:32 +01005629 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005630 lines =<< trim END
5631 vim9script
5632 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005633 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005634 endclass
5635 def T()
5636 var x = A._val
5637 enddef
5638 T()
5639 END
Ernie Rael03042a22023-11-11 08:53:32 +01005640 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005641
Ernie Rael03042a22023-11-11 08:53:32 +01005642 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005643 lines =<< trim END
5644 vim9script
5645 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005646 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005647 endclass
5648 def T()
5649 A._val = 3
5650 enddef
5651 T()
5652 END
Ernie Rael03042a22023-11-11 08:53:32 +01005653 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005654enddef
5655
5656" Test for changing the member access of an interface in a implementation class
5657def Test_change_interface_member_access()
5658 var lines =<< trim END
5659 vim9script
5660 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005661 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005662 endinterface
5663 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005664 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005665 endclass
5666 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005667 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005668
5669 lines =<< trim END
5670 vim9script
5671 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005672 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005673 endinterface
5674 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005675 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005676 endclass
5677 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005678 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005679enddef
5680
5681" Test for trying to change a readonly member from a def function
5682def Test_readonly_member_change_in_def_func()
5683 var lines =<< trim END
5684 vim9script
5685 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005686 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005687 endclass
5688 def T()
5689 var a = A.new()
5690 a.val = 20
5691 enddef
5692 T()
5693 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005694 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005695enddef
5696
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005697" Test for reading and writing a class member from a def function
5698def Test_modify_class_member_from_def_function()
5699 var lines =<< trim END
5700 vim9script
5701 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005702 var var1: number = 10
5703 public static var var2: list<number> = [1, 2]
5704 public static var var3: dict<number> = {a: 1, b: 2}
5705 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005706 endclass
5707 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005708 assert_equal([1, 2], A.var2)
5709 assert_equal({a: 1, b: 2}, A.var3)
5710 A.var2 = [3, 4]
5711 A.var3 = {c: 3, d: 4}
5712 assert_equal([3, 4], A.var2)
5713 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005714 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005715 enddef
5716 T()
5717 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005718 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005719enddef
5720
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005721" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005722def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005723 var lines =<< trim END
5724 vim9script
5725 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005726 public static var svar1: list<number> = [1]
5727 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005728 endclass
5729
5730 A.svar1->add(3)
5731 A.svar2->add(4)
5732 assert_equal([1, 3], A.svar1)
5733 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005734
5735 def Foo()
5736 A.svar1->add(7)
5737 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005738 assert_equal([1, 3, 7], A.svar1)
5739 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005740 enddef
5741 Foo()
5742 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005743 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005744
5745 # Cannot read from a class variable using an object in script context
5746 lines =<< trim END
5747 vim9script
5748 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005749 public var var1: number
5750 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005751 endclass
5752
5753 var a = A.new()
5754 echo a.svar2
5755 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005756 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005757
5758 # Cannot write to a class variable using an object in script context
5759 lines =<< trim END
5760 vim9script
5761 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005762 public var var1: number
5763 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005764 endclass
5765
5766 var a = A.new()
5767 a.svar2 = [2]
5768 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005769 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005770
5771 # Cannot read from a class variable using an object in def method context
5772 lines =<< trim END
5773 vim9script
5774 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005775 public var var1: number
5776 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005777 endclass
5778
5779 def T()
5780 var a = A.new()
5781 echo a.svar2
5782 enddef
5783 T()
5784 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005785 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005786
5787 # Cannot write to a class variable using an object in def method context
5788 lines =<< trim END
5789 vim9script
5790 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005791 public var var1: number
5792 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005793 endclass
5794
5795 def T()
5796 var a = A.new()
5797 a.svar2 = [2]
5798 enddef
5799 T()
5800 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005801 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005802enddef
5803
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005804" Test for using a interface method using a child object
5805def Test_interface_method_from_child()
5806 var lines =<< trim END
5807 vim9script
5808
5809 interface A
5810 def Foo(): string
5811 endinterface
5812
5813 class B implements A
5814 def Foo(): string
5815 return 'foo'
5816 enddef
5817 endclass
5818
5819 class C extends B
5820 def Bar(): string
5821 return 'bar'
5822 enddef
5823 endclass
5824
5825 def T1(a: A)
5826 assert_equal('foo', a.Foo())
5827 enddef
5828
5829 def T2(b: B)
5830 assert_equal('foo', b.Foo())
5831 enddef
5832
5833 var c = C.new()
5834 T1(c)
5835 T2(c)
5836 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005837 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005838enddef
5839
5840" Test for using an interface method using a child object when it is overridden
5841" by the child class.
5842" FIXME: This test fails.
5843" def Test_interface_overridden_method_from_child()
5844" var lines =<< trim END
5845" vim9script
5846"
5847" interface A
5848" def Foo(): string
5849" endinterface
5850"
5851" class B implements A
5852" def Foo(): string
5853" return 'b-foo'
5854" enddef
5855" endclass
5856"
5857" class C extends B
5858" def Bar(): string
5859" return 'bar'
5860" enddef
5861" def Foo(): string
5862" return 'c-foo'
5863" enddef
5864" endclass
5865"
5866" def T1(a: A)
5867" assert_equal('c-foo', a.Foo())
5868" enddef
5869"
5870" def T2(b: B)
5871" assert_equal('c-foo', b.Foo())
5872" enddef
5873"
5874" var c = C.new()
5875" T1(c)
5876" T2(c)
5877" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005878" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005879" enddef
5880
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005881" Test for abstract methods
5882def Test_abstract_method()
5883 # Use two abstract methods
5884 var lines =<< trim END
5885 vim9script
5886 abstract class A
5887 def M1(): number
5888 return 10
5889 enddef
5890 abstract def M2(): number
5891 abstract def M3(): number
5892 endclass
5893 class B extends A
5894 def M2(): number
5895 return 20
5896 enddef
5897 def M3(): number
5898 return 30
5899 enddef
5900 endclass
5901 var b = B.new()
5902 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5903 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005904 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005905
5906 # Don't define an abstract method
5907 lines =<< trim END
5908 vim9script
5909 abstract class A
5910 abstract def Foo()
5911 endclass
5912 class B extends A
5913 endclass
5914 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005915 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005916
5917 # Use abstract method in a concrete class
5918 lines =<< trim END
5919 vim9script
5920 class A
5921 abstract def Foo()
5922 endclass
5923 class B extends A
5924 endclass
5925 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005926 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005927
5928 # Use abstract method in an interface
5929 lines =<< trim END
5930 vim9script
5931 interface A
5932 abstract def Foo()
5933 endinterface
5934 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005935 def Foo()
5936 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005937 endclass
5938 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005939 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5940
5941 # Use abstract static method in an interface
5942 lines =<< trim END
5943 vim9script
5944 interface A
5945 abstract static def Foo()
5946 enddef
5947 endinterface
5948 END
5949 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5950
5951 # Use abstract static variable in an interface
5952 lines =<< trim END
5953 vim9script
5954 interface A
5955 abstract static foo: number = 10
5956 endinterface
5957 END
5958 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005959
5960 # Abbreviate the "abstract" keyword
5961 lines =<< trim END
5962 vim9script
5963 class A
5964 abs def Foo()
5965 endclass
5966 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005967 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005968
5969 # Use "abstract" with a member variable
5970 lines =<< trim END
5971 vim9script
5972 abstract class A
5973 abstract this.val = 10
5974 endclass
5975 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005976 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005977
5978 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01005979 lines =<< trim END
5980 vim9script
5981 abstract class A
5982 abstract static def Foo(): number
5983 endclass
5984 END
5985 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005986
5987 # Type mismatch between abstract method and concrete method
5988 lines =<< trim END
5989 vim9script
5990 abstract class A
5991 abstract def Foo(a: string, b: number): list<number>
5992 endclass
5993 class B extends A
5994 def Foo(a: number, b: string): list<string>
5995 return []
5996 enddef
5997 endclass
5998 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005999 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 +02006000
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006001 # Invoke an abstract method from a def function
6002 lines =<< trim END
6003 vim9script
6004 abstract class A
6005 abstract def Foo(): list<number>
6006 endclass
6007 class B extends A
6008 def Foo(): list<number>
6009 return [3, 5]
6010 enddef
6011 endclass
6012 def Bar(c: B)
6013 assert_equal([3, 5], c.Foo())
6014 enddef
6015 var b = B.new()
6016 Bar(b)
6017 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006018 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006019
6020 # Use a static method in an abstract class
6021 lines =<< trim END
6022 vim9script
6023 abstract class A
6024 static def Foo(): string
6025 return 'foo'
6026 enddef
6027 endclass
6028 assert_equal('foo', A.Foo())
6029 END
6030 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006031enddef
6032
6033" Test for calling a class method from a subclass
6034def Test_class_method_call_from_subclass()
6035 # class method call from a subclass
6036 var lines =<< trim END
6037 vim9script
6038
6039 class A
6040 static def Foo()
6041 echo "foo"
6042 enddef
6043 endclass
6044
6045 class B extends A
6046 def Bar()
6047 Foo()
6048 enddef
6049 endclass
6050
6051 var b = B.new()
6052 b.Bar()
6053 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006054 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006055enddef
6056
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006057" Test for calling a class method using an object in a def function context and
6058" script context.
6059def Test_class_method_call_using_object()
6060 # script context
6061 var lines =<< trim END
6062 vim9script
6063 class A
6064 static def Foo(): list<string>
6065 return ['a', 'b']
6066 enddef
6067 def Bar()
6068 assert_equal(['a', 'b'], A.Foo())
6069 assert_equal(['a', 'b'], Foo())
6070 enddef
6071 endclass
6072
6073 def T()
6074 assert_equal(['a', 'b'], A.Foo())
6075 var t_a = A.new()
6076 t_a.Bar()
6077 enddef
6078
6079 assert_equal(['a', 'b'], A.Foo())
6080 var a = A.new()
6081 a.Bar()
6082 T()
6083 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006084 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006085
6086 # script context
6087 lines =<< trim END
6088 vim9script
6089 class A
6090 static def Foo(): string
6091 return 'foo'
6092 enddef
6093 endclass
6094
6095 var a = A.new()
6096 assert_equal('foo', a.Foo())
6097 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006098 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006099
6100 # def function context
6101 lines =<< trim END
6102 vim9script
6103 class A
6104 static def Foo(): string
6105 return 'foo'
6106 enddef
6107 endclass
6108
6109 def T()
6110 var a = A.new()
6111 assert_equal('foo', a.Foo())
6112 enddef
6113 T()
6114 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006115 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006116enddef
6117
6118def Test_class_variable()
6119 var lines =<< trim END
6120 vim9script
6121
6122 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006123 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006124 static def ClassFunc()
6125 assert_equal(10, val)
6126 enddef
6127 def ObjFunc()
6128 assert_equal(10, val)
6129 enddef
6130 endclass
6131
6132 class B extends A
6133 endclass
6134
6135 assert_equal(10, A.val)
6136 A.ClassFunc()
6137 var a = A.new()
6138 a.ObjFunc()
6139 var b = B.new()
6140 b.ObjFunc()
6141
6142 def T1(a1: A)
6143 a1.ObjFunc()
6144 A.ClassFunc()
6145 enddef
6146 T1(b)
6147
6148 A.val = 20
6149 assert_equal(20, A.val)
6150 END
6151 v9.CheckSourceSuccess(lines)
6152
6153 # Modifying a parent class variable from a child class method
6154 lines =<< trim END
6155 vim9script
6156
6157 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006158 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006159 endclass
6160
6161 class B extends A
6162 static def ClassFunc()
6163 val = 20
6164 enddef
6165 endclass
6166 B.ClassFunc()
6167 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006168 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006169
6170 # Reading a parent class variable from a child class method
6171 lines =<< trim END
6172 vim9script
6173
6174 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006175 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006176 endclass
6177
6178 class B extends A
6179 static def ClassFunc()
6180 var i = val
6181 enddef
6182 endclass
6183 B.ClassFunc()
6184 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006185 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006186
6187 # Modifying a parent class variable from a child object method
6188 lines =<< trim END
6189 vim9script
6190
6191 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006192 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006193 endclass
6194
6195 class B extends A
6196 def ObjFunc()
6197 val = 20
6198 enddef
6199 endclass
6200 var b = B.new()
6201 b.ObjFunc()
6202 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006203 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006204
6205 # Reading a parent class variable from a child object method
6206 lines =<< trim END
6207 vim9script
6208
6209 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006210 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006211 endclass
6212
6213 class B extends A
6214 def ObjFunc()
6215 var i = val
6216 enddef
6217 endclass
6218 var b = B.new()
6219 b.ObjFunc()
6220 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006221 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006222
6223 # Modifying a class variable using an object at script level
6224 lines =<< trim END
6225 vim9script
6226
6227 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006228 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006229 endclass
6230 var a = A.new()
6231 a.val = 20
6232 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006233 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006234
6235 # Reading a class variable using an object at script level
6236 lines =<< trim END
6237 vim9script
6238
6239 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006240 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006241 endclass
6242 var a = A.new()
6243 var i = a.val
6244 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006245 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006246
6247 # Modifying a class variable using an object at function level
6248 lines =<< trim END
6249 vim9script
6250
6251 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006252 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006253 endclass
6254
6255 def T()
6256 var a = A.new()
6257 a.val = 20
6258 enddef
6259 T()
6260 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006261 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006262
6263 # Reading a class variable using an object at function level
6264 lines =<< trim END
6265 vim9script
6266
6267 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006268 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006269 endclass
6270 def T()
6271 var a = A.new()
6272 var i = a.val
6273 enddef
6274 T()
6275 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006276 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006277
6278 # Use old implicit var declaration syntax (without initialization)
6279 lines =<< trim END
6280 vim9script
6281
6282 class A
6283 static val: number
6284 endclass
6285 END
6286 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6287
6288 # Use old implicit var declaration syntax (with initialization)
6289 lines =<< trim END
6290 vim9script
6291
6292 class A
6293 static val: number = 10
6294 endclass
6295 END
6296 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6297
6298 # Use old implicit var declaration syntax (type inferred)
6299 lines =<< trim END
6300 vim9script
6301
6302 class A
6303 static val = 10
6304 endclass
6305 END
6306 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6307
6308 # Missing ":var" in "var" class variable declaration (without initialization)
6309 lines =<< trim END
6310 vim9script
6311
6312 class A
6313 static var: number
6314 endclass
6315 END
6316 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6317
6318 # Missing ":var" in "var" class variable declaration (with initialization)
6319 lines =<< trim END
6320 vim9script
6321
6322 class A
6323 static var: number = 10
6324 endclass
6325 END
6326 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6327
6328 # Missing ":var" in "var" class variable declaration (type inferred)
6329 lines =<< trim END
6330 vim9script
6331
6332 class A
6333 static var = 10
6334 endclass
6335 END
6336 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6337
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006338enddef
6339
6340" Test for using a duplicate class method and class variable in a child class
6341def Test_dup_class_member()
6342 # duplicate class variable, class method and overridden object method
6343 var lines =<< trim END
6344 vim9script
6345 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006346 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006347 static def Check()
6348 assert_equal(100, sval)
6349 enddef
6350 def GetVal(): number
6351 return sval
6352 enddef
6353 endclass
6354
6355 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006356 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006357 static def Check()
6358 assert_equal(200, sval)
6359 enddef
6360 def GetVal(): number
6361 return sval
6362 enddef
6363 endclass
6364
6365 def T1(aa: A): number
6366 return aa.GetVal()
6367 enddef
6368
6369 def T2(bb: B): number
6370 return bb.GetVal()
6371 enddef
6372
6373 assert_equal(100, A.sval)
6374 assert_equal(200, B.sval)
6375 var a = A.new()
6376 assert_equal(100, a.GetVal())
6377 var b = B.new()
6378 assert_equal(200, b.GetVal())
6379 assert_equal(200, T1(b))
6380 assert_equal(200, T2(b))
6381 END
6382 v9.CheckSourceSuccess(lines)
6383
6384 # duplicate class variable and class method
6385 lines =<< trim END
6386 vim9script
6387 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006388 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006389 static def Check()
6390 assert_equal(100, sval)
6391 enddef
6392 def GetVal(): number
6393 return sval
6394 enddef
6395 endclass
6396
6397 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006398 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006399 static def Check()
6400 assert_equal(200, sval)
6401 enddef
6402 endclass
6403
6404 def T1(aa: A): number
6405 return aa.GetVal()
6406 enddef
6407
6408 def T2(bb: B): number
6409 return bb.GetVal()
6410 enddef
6411
6412 assert_equal(100, A.sval)
6413 assert_equal(200, B.sval)
6414 var a = A.new()
6415 assert_equal(100, a.GetVal())
6416 var b = B.new()
6417 assert_equal(100, b.GetVal())
6418 assert_equal(100, T1(b))
6419 assert_equal(100, T2(b))
6420 END
6421 v9.CheckSourceSuccess(lines)
6422enddef
6423
6424" Test for calling an instance method using the class
6425def Test_instance_method_call_using_class()
6426 # Invoke an object method using a class in script context
6427 var lines =<< trim END
6428 vim9script
6429 class A
6430 def Foo()
6431 echo "foo"
6432 enddef
6433 endclass
6434 A.Foo()
6435 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006436 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006437
6438 # Invoke an object method using a class in def function context
6439 lines =<< trim END
6440 vim9script
6441 class A
6442 def Foo()
6443 echo "foo"
6444 enddef
6445 endclass
6446 def T()
6447 A.Foo()
6448 enddef
6449 T()
6450 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006451 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006452enddef
6453
6454" Test for duplicate class method and instance method
6455def Test_dup_classmethod_objmethod()
6456 # Duplicate instance method
6457 var lines =<< trim END
6458 vim9script
6459 class A
6460 static def Foo()
6461 enddef
6462 def Foo()
6463 enddef
6464 endclass
6465 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006466 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006467
Ernie Rael03042a22023-11-11 08:53:32 +01006468 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006469 lines =<< trim END
6470 vim9script
6471 class A
6472 static def Foo()
6473 enddef
6474 def _Foo()
6475 enddef
6476 endclass
6477 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006478 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006479
6480 # Duplicate class method
6481 lines =<< trim END
6482 vim9script
6483 class A
6484 def Foo()
6485 enddef
6486 static def Foo()
6487 enddef
6488 endclass
6489 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006490 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006491
Ernie Rael03042a22023-11-11 08:53:32 +01006492 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006493 lines =<< trim END
6494 vim9script
6495 class A
6496 def Foo()
6497 enddef
6498 static def _Foo()
6499 enddef
6500 endclass
6501 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006502 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006503
Ernie Rael03042a22023-11-11 08:53:32 +01006504 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006505 lines =<< trim END
6506 vim9script
6507 class A
6508 def _Foo()
6509 enddef
6510 static def _Foo()
6511 enddef
6512 endclass
6513 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006514 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006515enddef
6516
6517" Test for an instance method access level comparison with parent instance
6518" methods.
6519def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006520 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006521 var lines =<< trim END
6522 vim9script
6523 class A
6524 def Foo()
6525 enddef
6526 endclass
6527 class B extends A
6528 endclass
6529 class C extends B
6530 def _Foo()
6531 enddef
6532 endclass
6533 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006534 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006535
6536 # Public method in subclass
6537 lines =<< trim END
6538 vim9script
6539 class A
6540 def _Foo()
6541 enddef
6542 endclass
6543 class B extends A
6544 endclass
6545 class C extends B
6546 def Foo()
6547 enddef
6548 endclass
6549 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006550 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006551enddef
6552
6553def Test_extend_empty_class()
6554 var lines =<< trim END
6555 vim9script
6556 class A
6557 endclass
6558 class B extends A
6559 endclass
6560 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006561 public static var rw_class_var = 1
6562 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006563 static def ClassMethod(): number
6564 return 3
6565 enddef
6566 def ObjMethod(): number
6567 return 4
6568 enddef
6569 endclass
6570 assert_equal(1, C.rw_class_var)
6571 assert_equal(3, C.ClassMethod())
6572 var c = C.new()
6573 assert_equal(2, c.rw_obj_var)
6574 assert_equal(4, c.ObjMethod())
6575 END
6576 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006577enddef
6578
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006579" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006580" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006581def Test_interface_with_unsupported_members()
6582 var lines =<< trim END
6583 vim9script
6584 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006585 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006586 endinterface
6587 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006588 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006589
6590 lines =<< trim END
6591 vim9script
6592 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006593 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006594 endinterface
6595 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006596 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006597
6598 lines =<< trim END
6599 vim9script
6600 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006601 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006602 endinterface
6603 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006604 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006605
6606 lines =<< trim END
6607 vim9script
6608 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006609 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006610 endinterface
6611 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006612 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006613
6614 lines =<< trim END
6615 vim9script
6616 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006617 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006618 endinterface
6619 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006620 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006621
6622 lines =<< trim END
6623 vim9script
6624 interface A
6625 static def Foo(d: dict<any>): list<string>
6626 endinterface
6627 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006628 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006629
6630 lines =<< trim END
6631 vim9script
6632 interface A
6633 static def _Foo(d: dict<any>): list<string>
6634 endinterface
6635 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006636 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006637
6638 lines =<< trim END
6639 vim9script
6640 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006641 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006642 endinterface
6643 END
Ernie Rael03042a22023-11-11 08:53:32 +01006644 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006645
6646 lines =<< trim END
6647 vim9script
6648 interface A
6649 def _Foo(d: dict<any>): list<string>
6650 endinterface
6651 END
Ernie Rael03042a22023-11-11 08:53:32 +01006652 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006653enddef
6654
6655" Test for extending an interface
6656def Test_extend_interface()
6657 var lines =<< trim END
6658 vim9script
6659 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006660 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006661 def Foo()
6662 endinterface
6663 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006664 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006665 def Bar()
6666 endinterface
6667 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006668 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006669 def Foo()
6670 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006671 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006672 def Bar()
6673 enddef
6674 endclass
6675 END
6676 v9.CheckSourceSuccess(lines)
6677
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006678 # extending empty interface
6679 lines =<< trim END
6680 vim9script
6681 interface A
6682 endinterface
6683 interface B extends A
6684 endinterface
6685 class C implements B
6686 endclass
6687 END
6688 v9.CheckSourceSuccess(lines)
6689
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006690 lines =<< trim END
6691 vim9script
6692 interface A
6693 def Foo()
6694 endinterface
6695 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006696 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006697 endinterface
6698 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006699 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006700 endclass
6701 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006702 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006703
6704 lines =<< trim END
6705 vim9script
6706 interface A
6707 def Foo()
6708 endinterface
6709 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006710 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006711 endinterface
6712 class C implements A, B
6713 def Foo()
6714 enddef
6715 endclass
6716 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006717 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006718
6719 # interface cannot extend a class
6720 lines =<< trim END
6721 vim9script
6722 class A
6723 endclass
6724 interface B extends A
6725 endinterface
6726 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006727 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006728
6729 # class cannot extend an interface
6730 lines =<< trim END
6731 vim9script
6732 interface A
6733 endinterface
6734 class B extends A
6735 endclass
6736 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006737 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006738
6739 # interface cannot implement another interface
6740 lines =<< trim END
6741 vim9script
6742 interface A
6743 endinterface
6744 interface B implements A
6745 endinterface
6746 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006747 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006748
6749 # interface cannot extend multiple interfaces
6750 lines =<< trim END
6751 vim9script
6752 interface A
6753 endinterface
6754 interface B
6755 endinterface
6756 interface C extends A, B
6757 endinterface
6758 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006759 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006760
6761 # Variable type in an extended interface is of different type
6762 lines =<< trim END
6763 vim9script
6764 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006765 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006766 endinterface
6767 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006768 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006769 endinterface
6770 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006771 var val1: string
6772 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006773 endinterface
6774 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006775 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006776enddef
6777
6778" Test for a child class implementing an interface when some of the methods are
6779" defined in the parent class.
6780def Test_child_class_implements_interface()
6781 var lines =<< trim END
6782 vim9script
6783
6784 interface Intf
6785 def F1(): list<list<number>>
6786 def F2(): list<list<number>>
6787 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006788 var var1: list<dict<number>>
6789 var var2: list<dict<number>>
6790 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006791 endinterface
6792
6793 class A
6794 def A1()
6795 enddef
6796 def F3(): list<list<number>>
6797 return [[3]]
6798 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006799 var v1: list<list<number>> = [[0]]
6800 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006801 endclass
6802
6803 class B extends A
6804 def B1()
6805 enddef
6806 def F2(): list<list<number>>
6807 return [[2]]
6808 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006809 var v2: list<list<number>> = [[0]]
6810 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006811 endclass
6812
6813 class C extends B implements Intf
6814 def C1()
6815 enddef
6816 def F1(): list<list<number>>
6817 return [[1]]
6818 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006819 var v3: list<list<number>> = [[0]]
6820 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006821 endclass
6822
6823 def T(if: Intf)
6824 assert_equal([[1]], if.F1())
6825 assert_equal([[2]], if.F2())
6826 assert_equal([[3]], if.F3())
6827 assert_equal([{a: 10}], if.var1)
6828 assert_equal([{b: 20}], if.var2)
6829 assert_equal([{c: 30}], if.var3)
6830 enddef
6831
6832 var c = C.new()
6833 T(c)
6834 assert_equal([[1]], c.F1())
6835 assert_equal([[2]], c.F2())
6836 assert_equal([[3]], c.F3())
6837 assert_equal([{a: 10}], c.var1)
6838 assert_equal([{b: 20}], c.var2)
6839 assert_equal([{c: 30}], c.var3)
6840 END
6841 v9.CheckSourceSuccess(lines)
6842
6843 # One of the interface methods is not found
6844 lines =<< trim END
6845 vim9script
6846
6847 interface Intf
6848 def F1()
6849 def F2()
6850 def F3()
6851 endinterface
6852
6853 class A
6854 def A1()
6855 enddef
6856 endclass
6857
6858 class B extends A
6859 def B1()
6860 enddef
6861 def F2()
6862 enddef
6863 endclass
6864
6865 class C extends B implements Intf
6866 def C1()
6867 enddef
6868 def F1()
6869 enddef
6870 endclass
6871 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006872 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006873
6874 # One of the interface methods is of different type
6875 lines =<< trim END
6876 vim9script
6877
6878 interface Intf
6879 def F1()
6880 def F2()
6881 def F3()
6882 endinterface
6883
6884 class A
6885 def F3(): number
6886 return 0
6887 enddef
6888 def A1()
6889 enddef
6890 endclass
6891
6892 class B extends A
6893 def B1()
6894 enddef
6895 def F2()
6896 enddef
6897 endclass
6898
6899 class C extends B implements Intf
6900 def C1()
6901 enddef
6902 def F1()
6903 enddef
6904 endclass
6905 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006906 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006907
6908 # One of the interface variables is not present
6909 lines =<< trim END
6910 vim9script
6911
6912 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006913 var var1: list<dict<number>>
6914 var var2: list<dict<number>>
6915 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006916 endinterface
6917
6918 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006919 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006920 endclass
6921
6922 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006923 var v2: list<list<number>> = [[0]]
6924 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006925 endclass
6926
6927 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006928 var v3: list<list<number>> = [[0]]
6929 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006930 endclass
6931 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006932 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006933
6934 # One of the interface variables is of different type
6935 lines =<< trim END
6936 vim9script
6937
6938 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006939 var var1: list<dict<number>>
6940 var var2: list<dict<number>>
6941 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006942 endinterface
6943
6944 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006945 var v1: list<list<number>> = [[0]]
6946 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006947 endclass
6948
6949 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006950 var v2: list<list<number>> = [[0]]
6951 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006952 endclass
6953
6954 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006955 var v3: list<list<number>> = [[0]]
6956 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006957 endclass
6958 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006959 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 +02006960enddef
6961
6962" Test for extending an interface with duplicate variables and methods
6963def Test_interface_extends_with_dup_members()
6964 var lines =<< trim END
6965 vim9script
6966 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006967 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006968 def Foo1(): number
6969 endinterface
6970 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006971 var n2: number
6972 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006973 def Foo2(): number
6974 def Foo1(): number
6975 endinterface
6976 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006977 var n1 = 10
6978 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006979 def Foo1(): number
6980 return 30
6981 enddef
6982 def Foo2(): number
6983 return 40
6984 enddef
6985 endclass
6986 def T1(a: A)
6987 assert_equal(10, a.n1)
6988 assert_equal(30, a.Foo1())
6989 enddef
6990 def T2(b: B)
6991 assert_equal(10, b.n1)
6992 assert_equal(20, b.n2)
6993 assert_equal(30, b.Foo1())
6994 assert_equal(40, b.Foo2())
6995 enddef
6996 var c = C.new()
6997 T1(c)
6998 T2(c)
6999 END
7000 v9.CheckSourceSuccess(lines)
7001enddef
7002
7003" Test for using "any" type for a variable in a sub-class while it has a
7004" concrete type in the interface
7005def Test_implements_using_var_type_any()
7006 var lines =<< trim END
7007 vim9script
7008 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007009 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007010 endinterface
7011 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007012 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007013 endclass
7014 var b = B.new()
7015 assert_equal([{a: '1'}, {b: '2'}], b.val)
7016 END
7017 v9.CheckSourceSuccess(lines)
7018
7019 # initialize instance variable using a different type
7020 lines =<< trim END
7021 vim9script
7022 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007023 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007024 endinterface
7025 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007026 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007027 endclass
7028 var b = B.new()
7029 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007030 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007031enddef
7032
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007033" Test for assigning to a member variable in a nested class
7034def Test_nested_object_assignment()
7035 var lines =<< trim END
7036 vim9script
7037
7038 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007039 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007040 endclass
7041
7042 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007043 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007044 endclass
7045
7046 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007047 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007048 endclass
7049
7050 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007051 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007052 endclass
7053
7054 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007055 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007056 enddef
7057
7058 var d = D.new()
7059 T(d)
7060 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007061 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007062enddef
7063
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007064" Test for calling methods using a null object
7065def Test_null_object_method_call()
7066 # Calling a object method using a null object in script context
7067 var lines =<< trim END
7068 vim9script
7069
7070 class C
7071 def Foo()
7072 assert_report('This method should not be executed')
7073 enddef
7074 endclass
7075
7076 var o: C
7077 o.Foo()
7078 END
7079 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7080
7081 # Calling a object method using a null object in def function context
7082 lines =<< trim END
7083 vim9script
7084
7085 class C
7086 def Foo()
7087 assert_report('This method should not be executed')
7088 enddef
7089 endclass
7090
7091 def T()
7092 var o: C
7093 o.Foo()
7094 enddef
7095 T()
7096 END
7097 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7098
7099 # Calling a object method through another class method using a null object in
7100 # script context
7101 lines =<< trim END
7102 vim9script
7103
7104 class C
7105 def Foo()
7106 assert_report('This method should not be executed')
7107 enddef
7108
7109 static def Bar(o_any: any)
7110 var o_typed: C = o_any
7111 o_typed.Foo()
7112 enddef
7113 endclass
7114
7115 var o: C
7116 C.Bar(o)
7117 END
7118 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7119
7120 # Calling a object method through another class method using a null object in
7121 # def function context
7122 lines =<< trim END
7123 vim9script
7124
7125 class C
7126 def Foo()
7127 assert_report('This method should not be executed')
7128 enddef
7129
7130 static def Bar(o_any: any)
7131 var o_typed: C = o_any
7132 o_typed.Foo()
7133 enddef
7134 endclass
7135
7136 def T()
7137 var o: C
7138 C.Bar(o)
7139 enddef
7140 T()
7141 END
7142 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7143enddef
7144
7145" Test for using a dict as an object member
7146def Test_dict_object_member()
7147 var lines =<< trim END
7148 vim9script
7149
7150 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007151 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007152 def GetState(): dict<number>
7153 return this.state
7154 enddef
7155 endclass
7156
7157 var ctx = Context.new()
7158 ctx.state->extend({a: 1})
7159 ctx.state['b'] = 2
7160 assert_equal({a: 1, b: 2}, ctx.GetState())
7161
7162 def F()
7163 ctx.state['c'] = 3
7164 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7165 enddef
7166 F()
7167 assert_equal(3, ctx.state.c)
7168 ctx.state.c = 4
7169 assert_equal(4, ctx.state.c)
7170 END
7171 v9.CheckSourceSuccess(lines)
7172enddef
7173
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007174" The following test was failing after 9.0.1914. This was caused by using a
7175" freed object from a previous method call.
7176def Test_freed_object_from_previous_method_call()
7177 var lines =<< trim END
7178 vim9script
7179
7180 class Context
7181 endclass
7182
7183 class Result
7184 endclass
7185
7186 def Failure(): Result
7187 return Result.new()
7188 enddef
7189
7190 def GetResult(ctx: Context): Result
7191 return Failure()
7192 enddef
7193
7194 def Test_GetResult()
7195 var ctx = Context.new()
7196 var result = GetResult(ctx)
7197 enddef
7198
7199 Test_GetResult()
7200 END
7201 v9.CheckSourceSuccess(lines)
7202enddef
7203
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007204" Test for duplicate object and class variable
7205def Test_duplicate_variable()
7206 # Object variable name is same as the class variable name
7207 var lines =<< trim END
7208 vim9script
7209 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007210 public static var sval: number
7211 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007212 endclass
7213 var a = A.new()
7214 END
7215 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7216
7217 # Duplicate variable name and calling a class method
7218 lines =<< trim END
7219 vim9script
7220 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007221 public static var sval: number
7222 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007223 def F1()
7224 echo this.sval
7225 enddef
7226 static def F2()
7227 echo sval
7228 enddef
7229 endclass
7230 A.F2()
7231 END
7232 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7233
7234 # Duplicate variable with an empty constructor
7235 lines =<< trim END
7236 vim9script
7237 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007238 public static var sval: number
7239 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007240 def new()
7241 enddef
7242 endclass
7243 var a = A.new()
7244 END
7245 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7246enddef
7247
7248" Test for using a reserved keyword as a variable name
7249def Test_reserved_varname()
7250 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7251 'null_function', 'null_list', 'null_partial', 'null_string',
7252 'null_channel', 'null_job', 'super', 'this']
7253
7254 var lines =<< trim eval END
7255 vim9script
7256 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007257 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007258 endclass
7259 var o = C.new()
7260 END
7261 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7262
7263 lines =<< trim eval END
7264 vim9script
7265 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007266 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007267 def new()
7268 enddef
7269 endclass
7270 var o = C.new()
7271 END
7272 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7273
7274 lines =<< trim eval END
7275 vim9script
7276 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007277 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007278 def new()
7279 enddef
7280 def F()
7281 echo this.{kword}
7282 enddef
7283 endclass
7284 var o = C.new()
7285 o.F()
7286 END
7287 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007288
7289 # class variable name
7290 if kword != 'this'
7291 lines =<< trim eval END
7292 vim9script
7293 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007294 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007295 endclass
7296 END
7297 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7298 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007299 endfor
7300enddef
7301
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007302" Test for checking the type of the arguments and the return value of a object
7303" method in an extended class.
7304def Test_extended_obj_method_type_check()
7305 var lines =<< trim END
7306 vim9script
7307
7308 class A
7309 endclass
7310 class B extends A
7311 endclass
7312 class C extends B
7313 endclass
7314
7315 class Foo
7316 def Doit(p: B): B
7317 return B.new()
7318 enddef
7319 endclass
7320
7321 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007322 def Doit(p: C): B
7323 return B.new()
7324 enddef
7325 endclass
7326 END
7327 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7328
7329 lines =<< trim END
7330 vim9script
7331
7332 class A
7333 endclass
7334 class B extends A
7335 endclass
7336 class C extends B
7337 endclass
7338
7339 class Foo
7340 def Doit(p: B): B
7341 return B.new()
7342 enddef
7343 endclass
7344
7345 class Bar extends Foo
7346 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007347 return C.new()
7348 enddef
7349 endclass
7350 END
7351 v9.CheckSourceSuccess(lines)
7352
7353 lines =<< trim END
7354 vim9script
7355
7356 class A
7357 endclass
7358 class B extends A
7359 endclass
7360 class C extends B
7361 endclass
7362
7363 class Foo
7364 def Doit(p: B): B
7365 return B.new()
7366 enddef
7367 endclass
7368
7369 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007370 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007371 return B.new()
7372 enddef
7373 endclass
7374 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007375 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 +02007376
7377 lines =<< trim END
7378 vim9script
7379
7380 class A
7381 endclass
7382 class B extends A
7383 endclass
7384 class C extends B
7385 endclass
7386
7387 class Foo
7388 def Doit(p: B): B
7389 return B.new()
7390 enddef
7391 endclass
7392
7393 class Bar extends Foo
7394 def Doit(p: B): A
7395 return A.new()
7396 enddef
7397 endclass
7398 END
7399 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 +02007400
7401 # check varargs type mismatch
7402 lines =<< trim END
7403 vim9script
7404
7405 class B
7406 def F(...xxx: list<any>)
7407 enddef
7408 endclass
7409 class C extends B
7410 def F(xxx: list<any>)
7411 enddef
7412 endclass
7413 END
7414 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 +02007415enddef
7416
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007417" Test type checking for class variable in assignments
7418func Test_class_variable_complex_type_check()
7419 " class variable with a specific type. Try assigning a different type at
7420 " script level.
7421 let lines =<< trim END
7422 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007423 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007424 return {}
7425 enddef
7426 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007427 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007428 endclass
7429 test_garbagecollect_now()
7430 A.Fn = "abc"
7431 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007432 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 +02007433
7434 " class variable with a specific type. Try assigning a different type at
7435 " class def method level.
7436 let lines =<< trim END
7437 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007438 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007439 return {}
7440 enddef
7441 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007442 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007443 def Bar()
7444 Fn = "abc"
7445 enddef
7446 endclass
7447 var a = A.new()
7448 test_garbagecollect_now()
7449 a.Bar()
7450 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007451 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 +02007452
7453 " class variable with a specific type. Try assigning a different type at
7454 " script def method level.
7455 let lines =<< trim END
7456 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007457 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007458 return {}
7459 enddef
7460 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007461 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007462 endclass
7463 def Bar()
7464 A.Fn = "abc"
7465 enddef
7466 test_garbagecollect_now()
7467 Bar()
7468 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007469 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 +02007470
7471 " class variable without any type. Should be set to the initialization
7472 " expression type. Try assigning a different type from script level.
7473 let lines =<< trim END
7474 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007475 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007476 return {}
7477 enddef
7478 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007479 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007480 endclass
7481 test_garbagecollect_now()
7482 A.Fn = "abc"
7483 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007484 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 +02007485
7486 " class variable without any type. Should be set to the initialization
7487 " expression type. Try assigning a different type at class def level.
7488 let lines =<< trim END
7489 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007490 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007491 return {}
7492 enddef
7493 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007494 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007495 def Bar()
7496 Fn = "abc"
7497 enddef
7498 endclass
7499 var a = A.new()
7500 test_garbagecollect_now()
7501 a.Bar()
7502 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007503 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 +02007504
7505 " class variable without any type. Should be set to the initialization
7506 " expression type. Try assigning a different type at script def level.
7507 let lines =<< trim END
7508 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007509 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007510 return {}
7511 enddef
7512 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007513 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007514 endclass
7515 def Bar()
7516 A.Fn = "abc"
7517 enddef
7518 test_garbagecollect_now()
7519 Bar()
7520 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007521 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 +02007522
7523 " class variable with 'any" type. Can be assigned different types.
7524 let lines =<< trim END
7525 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007526 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007527 return {}
7528 enddef
7529 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007530 public static var Fn: any = Foo
7531 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007532 endclass
7533 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007534 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007535 A.Fn = "abc"
7536 test_garbagecollect_now()
7537 assert_equal('string', typename(A.Fn))
7538 A.Fn2 = Foo
7539 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007540 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007541 A.Fn2 = "xyz"
7542 test_garbagecollect_now()
7543 assert_equal('string', typename(A.Fn2))
7544 END
7545 call v9.CheckSourceSuccess(lines)
7546
7547 " class variable with 'any" type. Can be assigned different types.
7548 let lines =<< trim END
7549 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007550 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007551 return {}
7552 enddef
7553 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007554 public static var Fn: any = Foo
7555 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007556
7557 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007558 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007559 Fn = "abc"
7560 assert_equal('string', typename(Fn))
7561 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007562 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007563 Fn2 = "xyz"
7564 assert_equal('string', typename(Fn2))
7565 enddef
7566 endclass
7567 var a = A.new()
7568 test_garbagecollect_now()
7569 a.Bar()
7570 test_garbagecollect_now()
7571 A.Fn = Foo
7572 a.Bar()
7573 END
7574 call v9.CheckSourceSuccess(lines)
7575
7576 " class variable with 'any" type. Can be assigned different types.
7577 let lines =<< trim END
7578 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007579 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007580 return {}
7581 enddef
7582 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007583 public static var Fn: any = Foo
7584 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007585 endclass
7586
7587 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007588 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007589 A.Fn = "abc"
7590 assert_equal('string', typename(A.Fn))
7591 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007592 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007593 A.Fn2 = "xyz"
7594 assert_equal('string', typename(A.Fn2))
7595 enddef
7596 Bar()
7597 test_garbagecollect_now()
7598 A.Fn = Foo
7599 Bar()
7600 END
7601 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007602
7603 let lines =<< trim END
7604 vim9script
7605 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007606 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007607 endclass
7608 assert_equal([0z10, 0z20], A.foo)
7609 A.foo = [0z30]
7610 assert_equal([0z30], A.foo)
7611 var a = A.foo
7612 assert_equal([0z30], a)
7613 END
7614 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007615endfunc
7616
7617" Test type checking for object variable in assignments
7618func Test_object_variable_complex_type_check()
7619 " object variable with a specific type. Try assigning a different type at
7620 " script level.
7621 let lines =<< trim END
7622 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007623 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007624 return {}
7625 enddef
7626 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007627 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007628 endclass
7629 var a = A.new()
7630 test_garbagecollect_now()
7631 a.Fn = "abc"
7632 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007633 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 +02007634
7635 " object variable with a specific type. Try assigning a different type at
7636 " object def method level.
7637 let lines =<< trim END
7638 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007639 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007640 return {}
7641 enddef
7642 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007643 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007644 def Bar()
7645 this.Fn = "abc"
7646 this.Fn = Foo
7647 enddef
7648 endclass
7649 var a = A.new()
7650 test_garbagecollect_now()
7651 a.Bar()
7652 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007653 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 +02007654
7655 " object variable with a specific type. Try assigning a different type at
7656 " script def method level.
7657 let lines =<< trim END
7658 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007659 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007660 return {}
7661 enddef
7662 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007663 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007664 endclass
7665 def Bar()
7666 var a = A.new()
7667 a.Fn = "abc"
7668 a.Fn = Foo
7669 enddef
7670 test_garbagecollect_now()
7671 Bar()
7672 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007673 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 +02007674
7675 " object variable without any type. Should be set to the initialization
7676 " expression type. Try assigning a different type from script level.
7677 let lines =<< trim END
7678 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007679 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007680 return {}
7681 enddef
7682 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007683 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007684 endclass
7685 var a = A.new()
7686 test_garbagecollect_now()
7687 a.Fn = "abc"
7688 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007689 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 +02007690
7691 " object variable without any type. Should be set to the initialization
7692 " expression type. Try assigning a different type at object def level.
7693 let lines =<< trim END
7694 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007695 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007696 return {}
7697 enddef
7698 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007699 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007700 def Bar()
7701 this.Fn = "abc"
7702 this.Fn = Foo
7703 enddef
7704 endclass
7705 var a = A.new()
7706 test_garbagecollect_now()
7707 a.Bar()
7708 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007709 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 +02007710
7711 " object variable without any type. Should be set to the initialization
7712 " expression type. Try assigning a different type at script def level.
7713 let lines =<< trim END
7714 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007715 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007716 return {}
7717 enddef
7718 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007719 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007720 endclass
7721 def Bar()
7722 var a = A.new()
7723 a.Fn = "abc"
7724 a.Fn = Foo
7725 enddef
7726 test_garbagecollect_now()
7727 Bar()
7728 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007729 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 +02007730
7731 " object variable with 'any" type. Can be assigned different types.
7732 let lines =<< trim END
7733 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007734 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007735 return {}
7736 enddef
7737 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007738 public var Fn: any = Foo
7739 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007740 endclass
7741
7742 var a = A.new()
7743 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007744 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007745 a.Fn = "abc"
7746 test_garbagecollect_now()
7747 assert_equal('string', typename(a.Fn))
7748 a.Fn2 = Foo
7749 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007750 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007751 a.Fn2 = "xyz"
7752 test_garbagecollect_now()
7753 assert_equal('string', typename(a.Fn2))
7754 END
7755 call v9.CheckSourceSuccess(lines)
7756
7757 " object variable with 'any" type. Can be assigned different types.
7758 let lines =<< trim END
7759 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007760 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007761 return {}
7762 enddef
7763 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007764 public var Fn: any = Foo
7765 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007766
7767 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007768 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007769 this.Fn = "abc"
7770 assert_equal('string', typename(this.Fn))
7771 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007772 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007773 this.Fn2 = "xyz"
7774 assert_equal('string', typename(this.Fn2))
7775 enddef
7776 endclass
7777
7778 var a = A.new()
7779 test_garbagecollect_now()
7780 a.Bar()
7781 test_garbagecollect_now()
7782 a.Fn = Foo
7783 a.Bar()
7784 END
7785 call v9.CheckSourceSuccess(lines)
7786
7787 " object variable with 'any" type. Can be assigned different types.
7788 let lines =<< trim END
7789 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007790 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007791 return {}
7792 enddef
7793 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007794 public var Fn: any = Foo
7795 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007796 endclass
7797
7798 def Bar()
7799 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007800 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007801 a.Fn = "abc"
7802 assert_equal('string', typename(a.Fn))
7803 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007804 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007805 a.Fn2 = "xyz"
7806 assert_equal('string', typename(a.Fn2))
7807 enddef
7808 test_garbagecollect_now()
7809 Bar()
7810 test_garbagecollect_now()
7811 Bar()
7812 END
7813 call v9.CheckSourceSuccess(lines)
7814endfunc
7815
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007816" Test for recursively calling an object method. This used to cause an
7817" use-after-free error.
7818def Test_recursive_object_method_call()
7819 var lines =<< trim END
7820 vim9script
7821 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007822 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007823 def Foo(): number
7824 if this.val >= 90
7825 return this.val
7826 endif
7827 this.val += 1
7828 return this.Foo()
7829 enddef
7830 endclass
7831 var a = A.new()
7832 assert_equal(90, a.Foo())
7833 END
7834 v9.CheckSourceSuccess(lines)
7835enddef
7836
7837" Test for recursively calling a class method.
7838def Test_recursive_class_method_call()
7839 var lines =<< trim END
7840 vim9script
7841 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007842 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007843 static def Foo(): number
7844 if val >= 90
7845 return val
7846 endif
7847 val += 1
7848 return Foo()
7849 enddef
7850 endclass
7851 assert_equal(90, A.Foo())
7852 END
7853 v9.CheckSourceSuccess(lines)
7854enddef
7855
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007856" Test for checking the argument types and the return type when assigning a
7857" funcref to make sure the invariant class type is used.
7858def Test_funcref_argtype_returntype_check()
7859 var lines =<< trim END
7860 vim9script
7861 class A
7862 endclass
7863 class B extends A
7864 endclass
7865
7866 def Foo(p: B): B
7867 return B.new()
7868 enddef
7869
7870 var Bar: func(A): A = Foo
7871 END
7872 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7873
7874 lines =<< trim END
7875 vim9script
7876 class A
7877 endclass
7878 class B extends A
7879 endclass
7880
7881 def Foo(p: B): B
7882 return B.new()
7883 enddef
7884
7885 def Baz()
7886 var Bar: func(A): A = Foo
7887 enddef
7888 Baz()
7889 END
7890 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7891enddef
7892
Ernie Rael96952b22023-10-17 18:15:01 +02007893def Test_funcref_argtype_invariance_check()
7894 var lines =<< trim END
7895 vim9script
7896
7897 class A
7898 endclass
7899 class B extends A
7900 endclass
7901 class C extends B
7902 endclass
7903
7904 var Func: func(B): number
7905 Func = (o: B): number => 3
7906 assert_equal(3, Func(B.new()))
7907 END
7908 v9.CheckSourceSuccess(lines)
7909
7910 lines =<< trim END
7911 vim9script
7912
7913 class A
7914 endclass
7915 class B extends A
7916 endclass
7917 class C extends B
7918 endclass
7919
7920 var Func: func(B): number
7921 Func = (o: A): number => 3
7922 END
7923 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7924
7925 lines =<< trim END
7926 vim9script
7927
7928 class A
7929 endclass
7930 class B extends A
7931 endclass
7932 class C extends B
7933 endclass
7934
7935 var Func: func(B): number
7936 Func = (o: C): number => 3
7937 END
7938 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7939enddef
7940
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007941" Test for using an operator (e.g. +) with an assignment
7942def Test_op_and_assignment()
7943 # Using += with a class variable
7944 var lines =<< trim END
7945 vim9script
7946 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007947 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007948 static def Foo(): list<number>
7949 val += [1]
7950 return val
7951 enddef
7952 endclass
7953 def Bar(): list<number>
7954 A.val += [2]
7955 return A.val
7956 enddef
7957 assert_equal([1], A.Foo())
7958 assert_equal([1, 2], Bar())
7959 A.val += [3]
7960 assert_equal([1, 2, 3], A.val)
7961 END
7962 v9.CheckSourceSuccess(lines)
7963
7964 # Using += with an object variable
7965 lines =<< trim END
7966 vim9script
7967 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007968 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007969 def Foo(): list<number>
7970 this.val += [1]
7971 return this.val
7972 enddef
7973 endclass
7974 def Bar(bar_a: A): list<number>
7975 bar_a.val += [2]
7976 return bar_a.val
7977 enddef
7978 var a = A.new()
7979 assert_equal([1], a.Foo())
7980 assert_equal([1, 2], Bar(a))
7981 a.val += [3]
7982 assert_equal([1, 2, 3], a.val)
7983 END
7984 v9.CheckSourceSuccess(lines)
7985enddef
7986
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007987" Test for using an object method as a funcref
7988def Test_object_funcref()
7989 # Using object method funcref from a def function
7990 var lines =<< trim END
7991 vim9script
7992 class A
7993 def Foo(): list<number>
7994 return [3, 2, 1]
7995 enddef
7996 endclass
7997 def Bar()
7998 var a = A.new()
7999 var Fn = a.Foo
8000 assert_equal([3, 2, 1], Fn())
8001 enddef
8002 Bar()
8003 END
8004 v9.CheckSourceSuccess(lines)
8005
8006 # Using object method funcref at the script level
8007 lines =<< trim END
8008 vim9script
8009 class A
8010 def Foo(): dict<number>
8011 return {a: 1, b: 2}
8012 enddef
8013 endclass
8014 var a = A.new()
8015 var Fn = a.Foo
8016 assert_equal({a: 1, b: 2}, Fn())
8017 END
8018 v9.CheckSourceSuccess(lines)
8019
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008020 # Using object method funcref at the script level
8021 lines =<< trim END
8022 vim9script
8023 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008024 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008025 def Foo(): number
8026 return this.val
8027 enddef
8028 endclass
8029 var a = A.new(345)
8030 var Fn = a.Foo
8031 assert_equal(345, Fn())
8032 END
8033 v9.CheckSourceSuccess(lines)
8034
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008035 # Using object method funcref from another object method
8036 lines =<< trim END
8037 vim9script
8038 class A
8039 def Foo(): list<number>
8040 return [3, 2, 1]
8041 enddef
8042 def Bar()
8043 var Fn = this.Foo
8044 assert_equal([3, 2, 1], Fn())
8045 enddef
8046 endclass
8047 var a = A.new()
8048 a.Bar()
8049 END
8050 v9.CheckSourceSuccess(lines)
8051
8052 # Using function() to get a object method funcref
8053 lines =<< trim END
8054 vim9script
8055 class A
8056 def Foo(l: list<any>): list<any>
8057 return l
8058 enddef
8059 endclass
8060 var a = A.new()
8061 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8062 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8063 END
8064 v9.CheckSourceSuccess(lines)
8065
8066 # Use an object method with a function returning a funcref and then call the
8067 # funcref.
8068 lines =<< trim END
8069 vim9script
8070
8071 def Map(F: func(number): number): func(number): number
8072 return (n: number) => F(n)
8073 enddef
8074
8075 class Math
8076 def Double(n: number): number
8077 return 2 * n
8078 enddef
8079 endclass
8080
8081 const math = Math.new()
8082 assert_equal(48, Map(math.Double)(24))
8083 END
8084 v9.CheckSourceSuccess(lines)
8085
Ernie Rael03042a22023-11-11 08:53:32 +01008086 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008087 lines =<< trim END
8088 vim9script
8089 class A
8090 def _Foo()
8091 enddef
8092 endclass
8093 def Bar()
8094 var a = A.new()
8095 var Fn = a._Foo
8096 enddef
8097 Bar()
8098 END
Ernie Rael03042a22023-11-11 08:53:32 +01008099 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008100
Ernie Rael03042a22023-11-11 08:53:32 +01008101 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008102 lines =<< trim END
8103 vim9script
8104 class A
8105 def _Foo()
8106 enddef
8107 endclass
8108 var a = A.new()
8109 var Fn = a._Foo
8110 END
Ernie Rael03042a22023-11-11 08:53:32 +01008111 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008112
Ernie Rael03042a22023-11-11 08:53:32 +01008113 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008114 lines =<< trim END
8115 vim9script
8116 class A
8117 def _Foo(): list<number>
8118 return [3, 2, 1]
8119 enddef
8120 def Bar()
8121 var Fn = this._Foo
8122 assert_equal([3, 2, 1], Fn())
8123 enddef
8124 endclass
8125 var a = A.new()
8126 a.Bar()
8127 END
8128 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008129
8130 # Using object method funcref using call()
8131 lines =<< trim END
8132 vim9script
8133 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008134 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008135 def Foo(): number
8136 return this.val
8137 enddef
8138 endclass
8139
8140 def Bar(obj: A)
8141 assert_equal(123, call(obj.Foo, []))
8142 enddef
8143
8144 var a = A.new(123)
8145 Bar(a)
8146 assert_equal(123, call(a.Foo, []))
8147 END
8148 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008149enddef
8150
8151" Test for using a class method as a funcref
8152def Test_class_funcref()
8153 # Using class method funcref in a def function
8154 var lines =<< trim END
8155 vim9script
8156 class A
8157 static def Foo(): list<number>
8158 return [3, 2, 1]
8159 enddef
8160 endclass
8161 def Bar()
8162 var Fn = A.Foo
8163 assert_equal([3, 2, 1], Fn())
8164 enddef
8165 Bar()
8166 END
8167 v9.CheckSourceSuccess(lines)
8168
8169 # Using class method funcref at script level
8170 lines =<< trim END
8171 vim9script
8172 class A
8173 static def Foo(): dict<number>
8174 return {a: 1, b: 2}
8175 enddef
8176 endclass
8177 var Fn = A.Foo
8178 assert_equal({a: 1, b: 2}, Fn())
8179 END
8180 v9.CheckSourceSuccess(lines)
8181
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008182 # Using class method funcref at the script level
8183 lines =<< trim END
8184 vim9script
8185 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008186 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008187 static def Foo(): number
8188 return val
8189 enddef
8190 endclass
8191 A.val = 567
8192 var Fn = A.Foo
8193 assert_equal(567, Fn())
8194 END
8195 v9.CheckSourceSuccess(lines)
8196
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008197 # Using function() to get a class method funcref
8198 lines =<< trim END
8199 vim9script
8200 class A
8201 static def Foo(l: list<any>): list<any>
8202 return l
8203 enddef
8204 endclass
8205 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8206 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8207 END
8208 v9.CheckSourceSuccess(lines)
8209
8210 # Using a class method funcref from another class method
8211 lines =<< trim END
8212 vim9script
8213 class A
8214 static def Foo(): list<number>
8215 return [3, 2, 1]
8216 enddef
8217 static def Bar()
8218 var Fn = Foo
8219 assert_equal([3, 2, 1], Fn())
8220 enddef
8221 endclass
8222 A.Bar()
8223 END
8224 v9.CheckSourceSuccess(lines)
8225
8226 # Use a class method with a function returning a funcref and then call the
8227 # funcref.
8228 lines =<< trim END
8229 vim9script
8230
8231 def Map(F: func(number): number): func(number): number
8232 return (n: number) => F(n)
8233 enddef
8234
8235 class Math
8236 static def StaticDouble(n: number): number
8237 return 2 * n
8238 enddef
8239 endclass
8240
8241 assert_equal(48, Map(Math.StaticDouble)(24))
8242 END
8243 v9.CheckSourceSuccess(lines)
8244
Ernie Rael03042a22023-11-11 08:53:32 +01008245 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008246 lines =<< trim END
8247 vim9script
8248 class A
8249 static def _Foo()
8250 enddef
8251 endclass
8252 def Bar()
8253 var Fn = A._Foo
8254 enddef
8255 Bar()
8256 END
Ernie Rael03042a22023-11-11 08:53:32 +01008257 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008258
Ernie Rael03042a22023-11-11 08:53:32 +01008259 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008260 lines =<< trim END
8261 vim9script
8262 class A
8263 static def _Foo()
8264 enddef
8265 endclass
8266 var Fn = A._Foo
8267 END
Ernie Rael03042a22023-11-11 08:53:32 +01008268 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008269
Ernie Rael03042a22023-11-11 08:53:32 +01008270 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008271 lines =<< trim END
8272 vim9script
8273 class A
8274 static def _Foo(): list<number>
8275 return [3, 2, 1]
8276 enddef
8277 static def Bar()
8278 var Fn = _Foo
8279 assert_equal([3, 2, 1], Fn())
8280 enddef
8281 endclass
8282 A.Bar()
8283 END
8284 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008285
8286 # Using class method funcref using call()
8287 lines =<< trim END
8288 vim9script
8289 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008290 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008291 static def Foo(): number
8292 return val
8293 enddef
8294 endclass
8295
8296 def Bar()
8297 A.val = 468
8298 assert_equal(468, call(A.Foo, []))
8299 enddef
8300 Bar()
8301 assert_equal(468, call(A.Foo, []))
8302 END
8303 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008304enddef
8305
8306" Test for using an object member as a funcref
8307def Test_object_member_funcref()
8308 # Using a funcref object variable in an object method
8309 var lines =<< trim END
8310 vim9script
8311 def Foo(n: number): number
8312 return n * 10
8313 enddef
8314
8315 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008316 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008317 def Bar()
8318 assert_equal(200, this.Cb(20))
8319 enddef
8320 endclass
8321
8322 var a = A.new()
8323 a.Bar()
8324 END
8325 v9.CheckSourceSuccess(lines)
8326
8327 # Using a funcref object variable in a def method
8328 lines =<< trim END
8329 vim9script
8330 def Foo(n: number): number
8331 return n * 10
8332 enddef
8333
8334 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008335 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008336 endclass
8337
8338 def Bar()
8339 var a = A.new()
8340 assert_equal(200, a.Cb(20))
8341 enddef
8342 Bar()
8343 END
8344 v9.CheckSourceSuccess(lines)
8345
8346 # Using a funcref object variable at script level
8347 lines =<< trim END
8348 vim9script
8349 def Foo(n: number): number
8350 return n * 10
8351 enddef
8352
8353 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008354 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008355 endclass
8356
8357 var a = A.new()
8358 assert_equal(200, a.Cb(20))
8359 END
8360 v9.CheckSourceSuccess(lines)
8361
8362 # Using a funcref object variable pointing to an object method in an object
8363 # method.
8364 lines =<< trim END
8365 vim9script
8366 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008367 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008368 def Foo(n: number): number
8369 return n * 10
8370 enddef
8371 def Bar()
8372 assert_equal(200, this.Cb(20))
8373 enddef
8374 endclass
8375
8376 var a = A.new()
8377 a.Bar()
8378 END
8379 v9.CheckSourceSuccess(lines)
8380
8381 # Using a funcref object variable pointing to an object method in a def
8382 # method.
8383 lines =<< trim END
8384 vim9script
8385 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008386 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008387 def Foo(n: number): number
8388 return n * 10
8389 enddef
8390 endclass
8391
8392 def Bar()
8393 var a = A.new()
8394 assert_equal(200, a.Cb(20))
8395 enddef
8396 Bar()
8397 END
8398 v9.CheckSourceSuccess(lines)
8399
8400 # Using a funcref object variable pointing to an object method at script
8401 # level.
8402 lines =<< trim END
8403 vim9script
8404 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008405 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008406 def Foo(n: number): number
8407 return n * 10
8408 enddef
8409 endclass
8410
8411 var a = A.new()
8412 assert_equal(200, a.Cb(20))
8413 END
8414 v9.CheckSourceSuccess(lines)
8415enddef
8416
8417" Test for using a class member as a funcref
8418def Test_class_member_funcref()
8419 # Using a funcref class variable in a class method
8420 var lines =<< trim END
8421 vim9script
8422 def Foo(n: number): number
8423 return n * 10
8424 enddef
8425
8426 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008427 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008428 static def Bar()
8429 assert_equal(200, Cb(20))
8430 enddef
8431 endclass
8432
8433 A.Bar()
8434 END
8435 v9.CheckSourceSuccess(lines)
8436
8437 # Using a funcref class variable in a def method
8438 lines =<< trim END
8439 vim9script
8440 def Foo(n: number): number
8441 return n * 10
8442 enddef
8443
8444 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008445 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008446 endclass
8447
8448 def Bar()
8449 assert_equal(200, A.Cb(20))
8450 enddef
8451 Bar()
8452 END
8453 v9.CheckSourceSuccess(lines)
8454
8455 # Using a funcref class variable at script level
8456 lines =<< trim END
8457 vim9script
8458 def Foo(n: number): number
8459 return n * 10
8460 enddef
8461
8462 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008463 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008464 endclass
8465
8466 assert_equal(200, A.Cb(20))
8467 END
8468 v9.CheckSourceSuccess(lines)
8469
8470 # Using a funcref class variable pointing to a class method in a class
8471 # method.
8472 lines =<< trim END
8473 vim9script
8474 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008475 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008476 static def Foo(n: number): number
8477 return n * 10
8478 enddef
8479 static def Init()
8480 Cb = Foo
8481 enddef
8482 static def Bar()
8483 assert_equal(200, Cb(20))
8484 enddef
8485 endclass
8486
8487 A.Init()
8488 A.Bar()
8489 END
8490 v9.CheckSourceSuccess(lines)
8491
8492 # Using a funcref class variable pointing to a class method in a def method.
8493 lines =<< trim END
8494 vim9script
8495 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008496 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008497 static def Foo(n: number): number
8498 return n * 10
8499 enddef
8500 static def Init()
8501 Cb = Foo
8502 enddef
8503 endclass
8504
8505 def Bar()
8506 A.Init()
8507 assert_equal(200, A.Cb(20))
8508 enddef
8509 Bar()
8510 END
8511 v9.CheckSourceSuccess(lines)
8512
8513 # Using a funcref class variable pointing to a class method at script level.
8514 lines =<< trim END
8515 vim9script
8516 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008517 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008518 static def Foo(n: number): number
8519 return n * 10
8520 enddef
8521 static def Init()
8522 Cb = Foo
8523 enddef
8524 endclass
8525
8526 A.Init()
8527 assert_equal(200, A.Cb(20))
8528 END
8529 v9.CheckSourceSuccess(lines)
8530enddef
8531
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008532" Test for using object methods as popup callback functions
8533def Test_objmethod_popup_callback()
8534 # Use the popup from the script level
8535 var lines =<< trim END
8536 vim9script
8537
8538 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008539 var selection: number = -1
8540 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008541
8542 def PopupFilter(id: number, key: string): bool
8543 add(this.filterkeys, key)
8544 return popup_filter_yesno(id, key)
8545 enddef
8546
8547 def PopupCb(id: number, result: number)
8548 this.selection = result ? 100 : 200
8549 enddef
8550 endclass
8551
8552 var a = A.new()
8553 feedkeys('', 'xt')
8554 var winid = popup_create('Y/N?',
8555 {filter: a.PopupFilter, callback: a.PopupCb})
8556 feedkeys('y', 'xt')
8557 popup_close(winid)
8558 assert_equal(100, a.selection)
8559 assert_equal(['y'], a.filterkeys)
8560 feedkeys('', 'xt')
8561 winid = popup_create('Y/N?',
8562 {filter: a.PopupFilter, callback: a.PopupCb})
8563 feedkeys('n', 'xt')
8564 popup_close(winid)
8565 assert_equal(200, a.selection)
8566 assert_equal(['y', 'n'], a.filterkeys)
8567 END
8568 v9.CheckSourceSuccess(lines)
8569
8570 # Use the popup from a def function
8571 lines =<< trim END
8572 vim9script
8573
8574 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008575 var selection: number = -1
8576 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008577
8578 def PopupFilter(id: number, key: string): bool
8579 add(this.filterkeys, key)
8580 return popup_filter_yesno(id, key)
8581 enddef
8582
8583 def PopupCb(id: number, result: number)
8584 this.selection = result ? 100 : 200
8585 enddef
8586 endclass
8587
8588 def Foo()
8589 var a = A.new()
8590 feedkeys('', 'xt')
8591 var winid = popup_create('Y/N?',
8592 {filter: a.PopupFilter, callback: a.PopupCb})
8593 feedkeys('y', 'xt')
8594 popup_close(winid)
8595 assert_equal(100, a.selection)
8596 assert_equal(['y'], a.filterkeys)
8597 feedkeys('', 'xt')
8598 winid = popup_create('Y/N?',
8599 {filter: a.PopupFilter, callback: a.PopupCb})
8600 feedkeys('n', 'xt')
8601 popup_close(winid)
8602 assert_equal(200, a.selection)
8603 assert_equal(['y', 'n'], a.filterkeys)
8604 enddef
8605 Foo()
8606 END
8607 v9.CheckSourceSuccess(lines)
8608enddef
8609
8610" Test for using class methods as popup callback functions
8611def Test_classmethod_popup_callback()
8612 # Use the popup from the script level
8613 var lines =<< trim END
8614 vim9script
8615
8616 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008617 static var selection: number = -1
8618 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008619
8620 static def PopupFilter(id: number, key: string): bool
8621 add(filterkeys, key)
8622 return popup_filter_yesno(id, key)
8623 enddef
8624
8625 static def PopupCb(id: number, result: number)
8626 selection = result ? 100 : 200
8627 enddef
8628 endclass
8629
8630 feedkeys('', 'xt')
8631 var winid = popup_create('Y/N?',
8632 {filter: A.PopupFilter, callback: A.PopupCb})
8633 feedkeys('y', 'xt')
8634 popup_close(winid)
8635 assert_equal(100, A.selection)
8636 assert_equal(['y'], A.filterkeys)
8637 feedkeys('', 'xt')
8638 winid = popup_create('Y/N?',
8639 {filter: A.PopupFilter, callback: A.PopupCb})
8640 feedkeys('n', 'xt')
8641 popup_close(winid)
8642 assert_equal(200, A.selection)
8643 assert_equal(['y', 'n'], A.filterkeys)
8644 END
8645 v9.CheckSourceSuccess(lines)
8646
8647 # Use the popup from a def function
8648 lines =<< trim END
8649 vim9script
8650
8651 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008652 static var selection: number = -1
8653 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008654
8655 static def PopupFilter(id: number, key: string): bool
8656 add(filterkeys, key)
8657 return popup_filter_yesno(id, key)
8658 enddef
8659
8660 static def PopupCb(id: number, result: number)
8661 selection = result ? 100 : 200
8662 enddef
8663 endclass
8664
8665 def Foo()
8666 feedkeys('', 'xt')
8667 var winid = popup_create('Y/N?',
8668 {filter: A.PopupFilter, callback: A.PopupCb})
8669 feedkeys('y', 'xt')
8670 popup_close(winid)
8671 assert_equal(100, A.selection)
8672 assert_equal(['y'], A.filterkeys)
8673 feedkeys('', 'xt')
8674 winid = popup_create('Y/N?',
8675 {filter: A.PopupFilter, callback: A.PopupCb})
8676 feedkeys('n', 'xt')
8677 popup_close(winid)
8678 assert_equal(200, A.selection)
8679 assert_equal(['y', 'n'], A.filterkeys)
8680 enddef
8681 Foo()
8682 END
8683 v9.CheckSourceSuccess(lines)
8684enddef
8685
8686" Test for using an object method as a timer callback function
8687def Test_objmethod_timer_callback()
8688 # Use the timer callback from script level
8689 var lines =<< trim END
8690 vim9script
8691
8692 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008693 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008694 def TimerCb(timerID: number)
8695 this.timerTick = 6
8696 enddef
8697 endclass
8698
8699 var a = A.new()
8700 timer_start(0, a.TimerCb)
8701 var maxWait = 5
8702 while maxWait > 0 && a.timerTick == -1
8703 :sleep 10m
8704 maxWait -= 1
8705 endwhile
8706 assert_equal(6, a.timerTick)
8707 END
8708 v9.CheckSourceSuccess(lines)
8709
8710 # Use the timer callback from a def function
8711 lines =<< trim END
8712 vim9script
8713
8714 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008715 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008716 def TimerCb(timerID: number)
8717 this.timerTick = 6
8718 enddef
8719 endclass
8720
8721 def Foo()
8722 var a = A.new()
8723 timer_start(0, a.TimerCb)
8724 var maxWait = 5
8725 while maxWait > 0 && a.timerTick == -1
8726 :sleep 10m
8727 maxWait -= 1
8728 endwhile
8729 assert_equal(6, a.timerTick)
8730 enddef
8731 Foo()
8732 END
8733 v9.CheckSourceSuccess(lines)
8734enddef
8735
8736" Test for using a class method as a timer callback function
8737def Test_classmethod_timer_callback()
8738 # Use the timer callback from script level
8739 var lines =<< trim END
8740 vim9script
8741
8742 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008743 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008744 static def TimerCb(timerID: number)
8745 timerTick = 6
8746 enddef
8747 endclass
8748
8749 timer_start(0, A.TimerCb)
8750 var maxWait = 5
8751 while maxWait > 0 && A.timerTick == -1
8752 :sleep 10m
8753 maxWait -= 1
8754 endwhile
8755 assert_equal(6, A.timerTick)
8756 END
8757 v9.CheckSourceSuccess(lines)
8758
8759 # Use the timer callback from a def function
8760 lines =<< trim END
8761 vim9script
8762
8763 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008764 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008765 static def TimerCb(timerID: number)
8766 timerTick = 6
8767 enddef
8768 endclass
8769
8770 def Foo()
8771 timer_start(0, A.TimerCb)
8772 var maxWait = 5
8773 while maxWait > 0 && A.timerTick == -1
8774 :sleep 10m
8775 maxWait -= 1
8776 endwhile
8777 assert_equal(6, A.timerTick)
8778 enddef
8779 Foo()
8780 END
8781 v9.CheckSourceSuccess(lines)
8782enddef
8783
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008784" Test for using a class variable as the first and/or second operand of a binary
8785" operator.
8786def Test_class_variable_as_operands()
8787 var lines =<< trim END
8788 vim9script
8789 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008790 static var truthy: bool = true
8791 public static var TruthyFn: func
8792 static var list: list<any> = []
8793 static var four: number = 4
8794 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008795
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008796 static def Str(): string
8797 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008798 enddef
8799
8800 static def Four(): number
8801 return four
8802 enddef
8803
8804 static def List(): list<any>
8805 return list
8806 enddef
8807
8808 static def Truthy(): bool
8809 return truthy
8810 enddef
8811
8812 def TestOps()
8813 assert_true(Tests.truthy == truthy)
8814 assert_true(truthy == Tests.truthy)
8815 assert_true(Tests.list isnot [])
8816 assert_true([] isnot Tests.list)
8817 assert_equal(2, Tests.four >> 1)
8818 assert_equal(16, 1 << Tests.four)
8819 assert_equal(8, Tests.four + four)
8820 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008821 assert_equal('hellohello', Tests.str .. str)
8822 assert_equal('hellohello', str .. Tests.str)
8823
8824 # Using class variable for list indexing
8825 var l = range(10)
8826 assert_equal(4, l[Tests.four])
8827 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8828
8829 # Using class variable for Dict key
8830 var d = {hello: 'abc'}
8831 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008832 enddef
8833 endclass
8834
8835 def TestOps2()
8836 assert_true(Tests.truthy == Tests.Truthy())
8837 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008838 assert_true(Tests.truthy == Tests.TruthyFn())
8839 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008840 assert_true(Tests.list is Tests.List())
8841 assert_true(Tests.List() is Tests.list)
8842 assert_equal(2, Tests.four >> 1)
8843 assert_equal(16, 1 << Tests.four)
8844 assert_equal(8, Tests.four + Tests.Four())
8845 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008846 assert_equal('hellohello', Tests.str .. Tests.Str())
8847 assert_equal('hellohello', Tests.Str() .. Tests.str)
8848
8849 # Using class variable for list indexing
8850 var l = range(10)
8851 assert_equal(4, l[Tests.four])
8852 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8853
8854 # Using class variable for Dict key
8855 var d = {hello: 'abc'}
8856 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008857 enddef
8858
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008859 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008860 var t = Tests.new()
8861 t.TestOps()
8862 TestOps2()
8863
8864 assert_true(Tests.truthy == Tests.Truthy())
8865 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008866 assert_true(Tests.truthy == Tests.TruthyFn())
8867 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008868 assert_true(Tests.list is Tests.List())
8869 assert_true(Tests.List() is Tests.list)
8870 assert_equal(2, Tests.four >> 1)
8871 assert_equal(16, 1 << Tests.four)
8872 assert_equal(8, Tests.four + Tests.Four())
8873 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008874 assert_equal('hellohello', Tests.str .. Tests.Str())
8875 assert_equal('hellohello', Tests.Str() .. Tests.str)
8876
8877 # Using class variable for list indexing
8878 var l = range(10)
8879 assert_equal(4, l[Tests.four])
8880 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8881
8882 # Using class variable for Dict key
8883 var d = {hello: 'abc'}
8884 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008885 END
8886 v9.CheckSourceSuccess(lines)
8887enddef
8888
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008889" Test for checking the type of the key used to access an object dict member.
8890def Test_dict_member_key_type_check()
8891 var lines =<< trim END
8892 vim9script
8893
8894 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01008895 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008896 endclass
8897
8898 class Test extends State
8899 def ObjMethodTests()
8900 var cursor: number = 0
8901 var z: number = 0
8902 [this.numbers[cursor]] = ['zero.1']
8903 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8904 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8905 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8906 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8907 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8908 [this.numbers[cursor], z] = ['zero.4', 1]
8909 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8910 [z, this.numbers[cursor]] = [1, 'zero.5']
8911 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8912 enddef
8913
8914 static def ClassMethodTests(that: State)
8915 var cursor: number = 0
8916 var z: number = 0
8917 [that.numbers[cursor]] = ['zero.1']
8918 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8919 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8920 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8921 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8922 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8923 [that.numbers[cursor], z] = ['zero.4', 1]
8924 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8925 [z, that.numbers[cursor]] = [1, 'zero.5']
8926 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8927 enddef
8928
8929 def new()
8930 enddef
8931
8932 def newMethodTests()
8933 var cursor: number = 0
8934 var z: number
8935 [this.numbers[cursor]] = ['zero.1']
8936 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8937 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8938 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8939 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8940 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8941 [this.numbers[cursor], z] = ['zero.4', 1]
8942 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8943 [z, this.numbers[cursor]] = [1, 'zero.5']
8944 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8945 enddef
8946 endclass
8947
8948 def DefFuncTests(that: Test)
8949 var cursor: number = 0
8950 var z: number
8951 [that.numbers[cursor]] = ['zero.1']
8952 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8953 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8954 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8955 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8956 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8957 [that.numbers[cursor], z] = ['zero.4', 1]
8958 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8959 [z, that.numbers[cursor]] = [1, 'zero.5']
8960 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8961 enddef
8962
8963 Test.newMethodTests()
8964 Test.new().ObjMethodTests()
8965 Test.ClassMethodTests(Test.new())
8966 DefFuncTests(Test.new())
8967
8968 const test: Test = Test.new()
8969 var cursor: number = 0
8970 [test.numbers[cursor], cursor] = ['zero', 1]
8971 [cursor, test.numbers[cursor]] = [1, 'one']
8972 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8973 END
8974 v9.CheckSourceSuccess(lines)
8975
8976 lines =<< trim END
8977 vim9script
8978
8979 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008980 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008981
8982 def new()
8983 enddef
8984
8985 def Foo()
8986 var z: number
8987 [this.numbers.a, z] = [{}, 10]
8988 enddef
8989 endclass
8990
8991 var a = A.new()
8992 a.Foo()
8993 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008994 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008995
8996 lines =<< trim END
8997 vim9script
8998
8999 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009000 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009001
9002 def new()
9003 enddef
9004
9005 def Foo()
9006 var x: string = 'a'
9007 var y: number
9008 [this.numbers[x], y] = [{}, 10]
9009 enddef
9010 endclass
9011
9012 var a = A.new()
9013 a.Foo()
9014 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009015 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009016enddef
9017
mityua5550692023-11-25 15:41:20 +01009018def Test_compile_many_def_functions_in_funcref_instr()
9019 # This used to crash Vim. This is reproducible only when run on new instance
9020 # of Vim.
9021 var lines =<< trim END
9022 vim9script
9023
9024 class A
9025 def new()
9026 this.TakeFunc(this.F00)
9027 enddef
9028
9029 def TakeFunc(F: func)
9030 enddef
9031
9032 def F00()
9033 this.F01()
9034 this.F02()
9035 this.F03()
9036 this.F04()
9037 this.F05()
9038 this.F06()
9039 this.F07()
9040 this.F08()
9041 this.F09()
9042 this.F10()
9043 this.F11()
9044 this.F12()
9045 this.F13()
9046 this.F14()
9047 this.F15()
9048 this.F16()
9049 this.F17()
9050 this.F18()
9051 this.F19()
9052 this.F20()
9053 this.F21()
9054 this.F22()
9055 this.F23()
9056 this.F24()
9057 this.F25()
9058 this.F26()
9059 this.F27()
9060 this.F28()
9061 this.F29()
9062 this.F30()
9063 this.F31()
9064 this.F32()
9065 this.F33()
9066 this.F34()
9067 this.F35()
9068 this.F36()
9069 this.F37()
9070 this.F38()
9071 this.F39()
9072 this.F40()
9073 this.F41()
9074 this.F42()
9075 this.F43()
9076 this.F44()
9077 this.F45()
9078 this.F46()
9079 this.F47()
9080 enddef
9081
9082 def F01()
9083 enddef
9084 def F02()
9085 enddef
9086 def F03()
9087 enddef
9088 def F04()
9089 enddef
9090 def F05()
9091 enddef
9092 def F06()
9093 enddef
9094 def F07()
9095 enddef
9096 def F08()
9097 enddef
9098 def F09()
9099 enddef
9100 def F10()
9101 enddef
9102 def F11()
9103 enddef
9104 def F12()
9105 enddef
9106 def F13()
9107 enddef
9108 def F14()
9109 enddef
9110 def F15()
9111 enddef
9112 def F16()
9113 enddef
9114 def F17()
9115 enddef
9116 def F18()
9117 enddef
9118 def F19()
9119 enddef
9120 def F20()
9121 enddef
9122 def F21()
9123 enddef
9124 def F22()
9125 enddef
9126 def F23()
9127 enddef
9128 def F24()
9129 enddef
9130 def F25()
9131 enddef
9132 def F26()
9133 enddef
9134 def F27()
9135 enddef
9136 def F28()
9137 enddef
9138 def F29()
9139 enddef
9140 def F30()
9141 enddef
9142 def F31()
9143 enddef
9144 def F32()
9145 enddef
9146 def F33()
9147 enddef
9148 def F34()
9149 enddef
9150 def F35()
9151 enddef
9152 def F36()
9153 enddef
9154 def F37()
9155 enddef
9156 def F38()
9157 enddef
9158 def F39()
9159 enddef
9160 def F40()
9161 enddef
9162 def F41()
9163 enddef
9164 def F42()
9165 enddef
9166 def F43()
9167 enddef
9168 def F44()
9169 enddef
9170 def F45()
9171 enddef
9172 def F46()
9173 enddef
9174 def F47()
9175 enddef
9176 endclass
9177
9178 A.new()
9179 END
9180 writefile(lines, 'Xscript', 'D')
9181 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9182 assert_equal(0, v:shell_error)
9183enddef
9184
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009185" Test for 'final' class and object variables
9186def Test_final_class_object_variable()
9187 # Test for changing a final object variable from an object function
9188 var lines =<< trim END
9189 vim9script
9190 class A
9191 final foo: string = "abc"
9192 def Foo()
9193 this.foo = "def"
9194 enddef
9195 endclass
9196 defcompile A.Foo
9197 END
9198 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9199
9200 # Test for changing a final object variable from the 'new' function
9201 lines =<< trim END
9202 vim9script
9203 class A
9204 final s1: string
9205 final s2: string
9206 def new(this.s1)
9207 this.s2 = 'def'
9208 enddef
9209 endclass
9210 var a = A.new('abc')
9211 assert_equal('abc', a.s1)
9212 assert_equal('def', a.s2)
9213 END
9214 v9.CheckSourceSuccess(lines)
9215
9216 # Test for a final class variable
9217 lines =<< trim END
9218 vim9script
9219 class A
9220 static final s1: string = "abc"
9221 endclass
9222 assert_equal('abc', A.s1)
9223 END
9224 v9.CheckSourceSuccess(lines)
9225
9226 # Test for changing a final class variable from a class function
9227 lines =<< trim END
9228 vim9script
9229 class A
9230 static final s1: string = "abc"
9231 static def Foo()
9232 s1 = "def"
9233 enddef
9234 endclass
9235 A.Foo()
9236 END
9237 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9238
9239 # Test for changing a public final class variable at script level
9240 lines =<< trim END
9241 vim9script
9242 class A
9243 public static final s1: string = "abc"
9244 endclass
9245 assert_equal('abc', A.s1)
9246 A.s1 = 'def'
9247 END
9248 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9249
9250 # Test for changing a public final class variable from a class function
9251 lines =<< trim END
9252 vim9script
9253 class A
9254 public static final s1: string = "abc"
9255 static def Foo()
9256 s1 = "def"
9257 enddef
9258 endclass
9259 A.Foo()
9260 END
9261 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9262
9263 # Test for changing a public final class variable from a function
9264 lines =<< trim END
9265 vim9script
9266 class A
9267 public static final s1: string = "abc"
9268 endclass
9269 def Foo()
9270 A.s1 = 'def'
9271 enddef
9272 defcompile
9273 END
9274 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9275
9276 # Test for using a final variable of composite type
9277 lines =<< trim END
9278 vim9script
9279 class A
9280 public final l: list<number>
9281 def new()
9282 this.l = [1, 2]
9283 enddef
9284 def Foo()
9285 this.l[0] = 3
9286 this.l->add(4)
9287 enddef
9288 endclass
9289 var a = A.new()
9290 assert_equal([1, 2], a.l)
9291 a.Foo()
9292 assert_equal([3, 2, 4], a.l)
9293 END
9294 v9.CheckSourceSuccess(lines)
9295
9296 # Test for changing a final variable of composite type from another object
9297 # function
9298 lines =<< trim END
9299 vim9script
9300 class A
9301 public final l: list<number> = [1, 2]
9302 def Foo()
9303 this.l = [3, 4]
9304 enddef
9305 endclass
9306 var a = A.new()
9307 a.Foo()
9308 END
9309 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9310
9311 # Test for modifying a final variable of composite type at script level
9312 lines =<< trim END
9313 vim9script
9314 class A
9315 public final l: list<number> = [1, 2]
9316 endclass
9317 var a = A.new()
9318 a.l[0] = 3
9319 a.l->add(4)
9320 assert_equal([3, 2, 4], a.l)
9321 END
9322 v9.CheckSourceSuccess(lines)
9323
9324 # Test for modifying a final variable of composite type from a function
9325 lines =<< trim END
9326 vim9script
9327 class A
9328 public final l: list<number> = [1, 2]
9329 endclass
9330 def Foo()
9331 var a = A.new()
9332 a.l[0] = 3
9333 a.l->add(4)
9334 assert_equal([3, 2, 4], a.l)
9335 enddef
9336 Foo()
9337 END
9338 v9.CheckSourceSuccess(lines)
9339
9340 # Test for modifying a final variable of composite type from another object
9341 # function
9342 lines =<< trim END
9343 vim9script
9344 class A
9345 public final l: list<number> = [1, 2]
9346 def Foo()
9347 this.l[0] = 3
9348 this.l->add(4)
9349 enddef
9350 endclass
9351 var a = A.new()
9352 a.Foo()
9353 assert_equal([3, 2, 4], a.l)
9354 END
9355 v9.CheckSourceSuccess(lines)
9356
9357 # Test for assigning a new value to a final variable of composite type at
9358 # script level
9359 lines =<< trim END
9360 vim9script
9361 class A
9362 public final l: list<number> = [1, 2]
9363 endclass
9364 var a = A.new()
9365 a.l = [3, 4]
9366 END
9367 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9368
9369 # Test for assigning a new value to a final variable of composite type from
9370 # another object function
9371 lines =<< trim END
9372 vim9script
9373 class A
9374 public final l: list<number> = [1, 2]
9375 def Foo()
9376 this.l = [3, 4]
9377 enddef
9378 endclass
9379 var a = A.new()
9380 a.Foo()
9381 END
9382 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9383
9384 # Test for assigning a new value to a final variable of composite type from
9385 # another function
9386 lines =<< trim END
9387 vim9script
9388 class A
9389 public final l: list<number> = [1, 2]
9390 endclass
9391 def Foo()
9392 var a = A.new()
9393 a.l = [3, 4]
9394 enddef
9395 Foo()
9396 END
9397 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9398
9399 # Error case: Use 'final' with just a variable name
9400 lines =<< trim END
9401 vim9script
9402 class A
9403 final foo
9404 endclass
9405 var a = A.new()
9406 END
9407 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9408
9409 # Error case: Use 'final' followed by 'public'
9410 lines =<< trim END
9411 vim9script
9412 class A
9413 final public foo: number
9414 endclass
9415 var a = A.new()
9416 END
9417 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9418
9419 # Error case: Use 'final' followed by 'static'
9420 lines =<< trim END
9421 vim9script
9422 class A
9423 final static foo: number
9424 endclass
9425 var a = A.new()
9426 END
9427 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9428
9429 # Error case: 'final' cannot be used in an interface
9430 lines =<< trim END
9431 vim9script
9432 interface A
9433 final foo: number = 10
9434 endinterface
9435 END
9436 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9437
9438 # Error case: 'final' not supported for an object method
9439 lines =<< trim END
9440 vim9script
9441 class A
9442 final def Foo()
9443 enddef
9444 endclass
9445 END
9446 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9447
9448 # Error case: 'final' not supported for a class method
9449 lines =<< trim END
9450 vim9script
9451 class A
9452 static final def Foo()
9453 enddef
9454 endclass
9455 END
9456 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9457enddef
9458
9459" Test for 'const' class and object variables
9460def Test_const_class_object_variable()
9461 # Test for changing a const object variable from an object function
9462 var lines =<< trim END
9463 vim9script
9464 class A
9465 const foo: string = "abc"
9466 def Foo()
9467 this.foo = "def"
9468 enddef
9469 endclass
9470 defcompile A.Foo
9471 END
9472 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9473
9474 # Test for changing a const object variable from the 'new' function
9475 lines =<< trim END
9476 vim9script
9477 class A
9478 const s1: string
9479 const s2: string
9480 def new(this.s1)
9481 this.s2 = 'def'
9482 enddef
9483 endclass
9484 var a = A.new('abc')
9485 assert_equal('abc', a.s1)
9486 assert_equal('def', a.s2)
9487 END
9488 v9.CheckSourceSuccess(lines)
9489
9490 # Test for changing a const object variable from an object method called from
9491 # the 'new' function
9492 lines =<< trim END
9493 vim9script
9494 class A
9495 const s1: string = 'abc'
9496 def new()
9497 this.ChangeStr()
9498 enddef
9499 def ChangeStr()
9500 this.s1 = 'def'
9501 enddef
9502 endclass
9503 var a = A.new()
9504 END
9505 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9506
9507 # Test for a const class variable
9508 lines =<< trim END
9509 vim9script
9510 class A
9511 static const s1: string = "abc"
9512 endclass
9513 assert_equal('abc', A.s1)
9514 END
9515 v9.CheckSourceSuccess(lines)
9516
9517 # Test for changing a const class variable from a class function
9518 lines =<< trim END
9519 vim9script
9520 class A
9521 static const s1: string = "abc"
9522 static def Foo()
9523 s1 = "def"
9524 enddef
9525 endclass
9526 A.Foo()
9527 END
9528 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9529
9530 # Test for changing a public const class variable at script level
9531 lines =<< trim END
9532 vim9script
9533 class A
9534 public static const s1: string = "abc"
9535 endclass
9536 assert_equal('abc', A.s1)
9537 A.s1 = 'def'
9538 END
9539 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9540
9541 # Test for changing a public const class variable from a class function
9542 lines =<< trim END
9543 vim9script
9544 class A
9545 public static const s1: string = "abc"
9546 static def Foo()
9547 s1 = "def"
9548 enddef
9549 endclass
9550 A.Foo()
9551 END
9552 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9553
9554 # Test for changing a public const class variable from a function
9555 lines =<< trim END
9556 vim9script
9557 class A
9558 public static const s1: string = "abc"
9559 endclass
9560 def Foo()
9561 A.s1 = 'def'
9562 enddef
9563 defcompile
9564 END
9565 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9566
9567 # Test for changing a const List item from an object function
9568 lines =<< trim END
9569 vim9script
9570 class A
9571 public const l: list<number>
9572 def new()
9573 this.l = [1, 2]
9574 enddef
9575 def Foo()
9576 this.l[0] = 3
9577 enddef
9578 endclass
9579 var a = A.new()
9580 assert_equal([1, 2], a.l)
9581 a.Foo()
9582 END
9583 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9584
9585 # Test for adding a value to a const List from an object function
9586 lines =<< trim END
9587 vim9script
9588 class A
9589 public const l: list<number>
9590 def new()
9591 this.l = [1, 2]
9592 enddef
9593 def Foo()
9594 this.l->add(3)
9595 enddef
9596 endclass
9597 var a = A.new()
9598 a.Foo()
9599 END
9600 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9601
9602 # Test for reassigning a const List from an object function
9603 lines =<< trim END
9604 vim9script
9605 class A
9606 public const l: list<number> = [1, 2]
9607 def Foo()
9608 this.l = [3, 4]
9609 enddef
9610 endclass
9611 var a = A.new()
9612 a.Foo()
9613 END
9614 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9615
9616 # Test for changing a const List item at script level
9617 lines =<< trim END
9618 vim9script
9619 class A
9620 public const l: list<number> = [1, 2]
9621 endclass
9622 var a = A.new()
9623 a.l[0] = 3
9624 END
9625 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9626
9627 # Test for adding a value to a const List item at script level
9628 lines =<< trim END
9629 vim9script
9630 class A
9631 public const l: list<number> = [1, 2]
9632 endclass
9633 var a = A.new()
9634 a.l->add(4)
9635 END
9636 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9637
9638 # Test for changing a const List item from a function
9639 lines =<< trim END
9640 vim9script
9641 class A
9642 public const l: list<number> = [1, 2]
9643 endclass
9644 def Foo()
9645 var a = A.new()
9646 a.l[0] = 3
9647 enddef
9648 Foo()
9649 END
9650 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9651
9652 # Test for adding a value to a const List item from a function
9653 lines =<< trim END
9654 vim9script
9655 class A
9656 public const l: list<number> = [1, 2]
9657 endclass
9658 def Foo()
9659 var a = A.new()
9660 a.l->add(4)
9661 enddef
9662 Foo()
9663 END
9664 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9665
9666 # Test for changing a const List item from an object method
9667 lines =<< trim END
9668 vim9script
9669 class A
9670 public const l: list<number> = [1, 2]
9671 def Foo()
9672 this.l[0] = 3
9673 enddef
9674 endclass
9675 var a = A.new()
9676 a.Foo()
9677 END
9678 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9679
9680 # Test for adding a value to a const List item from an object method
9681 lines =<< trim END
9682 vim9script
9683 class A
9684 public const l: list<number> = [1, 2]
9685 def Foo()
9686 this.l->add(4)
9687 enddef
9688 endclass
9689 var a = A.new()
9690 a.Foo()
9691 END
9692 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9693
9694 # Test for reassigning a const List object variable at script level
9695 lines =<< trim END
9696 vim9script
9697 class A
9698 public const l: list<number> = [1, 2]
9699 endclass
9700 var a = A.new()
9701 a.l = [3, 4]
9702 END
9703 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9704
9705 # Test for reassigning a const List object variable from an object method
9706 lines =<< trim END
9707 vim9script
9708 class A
9709 public const l: list<number> = [1, 2]
9710 def Foo()
9711 this.l = [3, 4]
9712 enddef
9713 endclass
9714 var a = A.new()
9715 a.Foo()
9716 END
9717 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9718
9719 # Test for reassigning a const List object variable from another function
9720 lines =<< trim END
9721 vim9script
9722 class A
9723 public const l: list<number> = [1, 2]
9724 endclass
9725 def Foo()
9726 var a = A.new()
9727 a.l = [3, 4]
9728 enddef
9729 Foo()
9730 END
9731 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9732
9733 # Error case: Use 'const' with just a variable name
9734 lines =<< trim END
9735 vim9script
9736 class A
9737 const foo
9738 endclass
9739 var a = A.new()
9740 END
9741 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9742
9743 # Error case: Use 'const' followed by 'public'
9744 lines =<< trim END
9745 vim9script
9746 class A
9747 const public foo: number
9748 endclass
9749 var a = A.new()
9750 END
9751 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9752
9753 # Error case: Use 'const' followed by 'static'
9754 lines =<< trim END
9755 vim9script
9756 class A
9757 const static foo: number
9758 endclass
9759 var a = A.new()
9760 END
9761 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9762
9763 # Error case: 'const' cannot be used in an interface
9764 lines =<< trim END
9765 vim9script
9766 interface A
9767 const foo: number = 10
9768 endinterface
9769 END
9770 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9771
9772 # Error case: 'const' not supported for an object method
9773 lines =<< trim END
9774 vim9script
9775 class A
9776 const def Foo()
9777 enddef
9778 endclass
9779 END
9780 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9781
9782 # Error case: 'const' not supported for a class method
9783 lines =<< trim END
9784 vim9script
9785 class A
9786 static const def Foo()
9787 enddef
9788 endclass
9789 END
9790 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9791enddef
9792
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009793" Test for compiling class/object methods using :defcompile
9794def Test_defcompile_class()
9795 # defcompile all the classes in the current script
9796 var lines =<< trim END
9797 vim9script
9798 class A
9799 def Foo()
9800 var i = 10
9801 enddef
9802 endclass
9803 class B
9804 def Bar()
9805 var i = 20
9806 xxx
9807 enddef
9808 endclass
9809 defcompile
9810 END
9811 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9812
9813 # defcompile a specific class
9814 lines =<< trim END
9815 vim9script
9816 class A
9817 def Foo()
9818 xxx
9819 enddef
9820 endclass
9821 class B
9822 def Bar()
9823 yyy
9824 enddef
9825 endclass
9826 defcompile B
9827 END
9828 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9829
9830 # defcompile a non-class
9831 lines =<< trim END
9832 vim9script
9833 class A
9834 def Foo()
9835 enddef
9836 endclass
9837 var X: list<number> = []
9838 defcompile X
9839 END
9840 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9841
9842 # defcompile a class twice
9843 lines =<< trim END
9844 vim9script
9845 class A
9846 def new()
9847 enddef
9848 endclass
9849 defcompile A
9850 defcompile A
9851 assert_equal('Function A.new does not need compiling', v:statusmsg)
9852 END
9853 v9.CheckSourceSuccess(lines)
9854
9855 # defcompile should not compile an imported class
9856 lines =<< trim END
9857 vim9script
9858 export class A
9859 def Foo()
9860 xxx
9861 enddef
9862 endclass
9863 END
9864 writefile(lines, 'Xdefcompileimport.vim', 'D')
9865 lines =<< trim END
9866 vim9script
9867
9868 import './Xdefcompileimport.vim'
9869 class B
9870 endclass
9871 defcompile
9872 END
9873 v9.CheckScriptSuccess(lines)
9874enddef
9875
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +01009876" Test for cases common to all the object builtin methods
9877def Test_object_builtin_method()
9878 var lines =<< trim END
9879 vim9script
9880 class A
9881 def abc()
9882 enddef
9883 endclass
9884 END
9885 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
9886
9887 for funcname in ["len", "string", "empty"]
9888 lines =<< trim eval END
9889 vim9script
9890 class A
9891 static def {funcname}(): number
9892 enddef
9893 endclass
9894 END
9895 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
9896 endfor
9897enddef
9898
9899" Test for using the empty() builtin method with an object
9900" This is a legacy function to use the test_garbagecollect_now() function.
9901func Test_object_empty()
9902 let lines =<< trim END
9903 vim9script
9904 class A
9905 def empty(): bool
9906 return true
9907 enddef
9908 endclass
9909
9910 def Foo()
9911 var afoo = A.new()
9912 assert_equal(true, empty(afoo))
9913 assert_equal(true, afoo->empty())
9914 enddef
9915
9916 var a = A.new()
9917 assert_equal(1, empty(a))
9918 assert_equal(1, a->empty())
9919 test_garbagecollect_now()
9920 assert_equal(1, empty(a))
9921 Foo()
9922 test_garbagecollect_now()
9923 Foo()
9924 END
9925 call v9.CheckSourceSuccess(lines)
9926
9927 " empty() should return 1 without a builtin method
9928 let lines =<< trim END
9929 vim9script
9930 class A
9931 endclass
9932
9933 def Foo()
9934 var afoo = A.new()
9935 assert_equal(1, empty(afoo))
9936 enddef
9937
9938 var a = A.new()
9939 assert_equal(1, empty(a))
9940 Foo()
9941 END
9942 call v9.CheckSourceSuccess(lines)
9943
9944 " Unsupported signature for the empty() method
9945 let lines =<< trim END
9946 vim9script
9947 class A
9948 def empty()
9949 enddef
9950 endclass
9951 END
9952 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
9953
9954 " Error when calling the empty() method
9955 let lines =<< trim END
9956 vim9script
9957 class A
9958 def empty(): bool
9959 throw "Failed to check emptiness"
9960 enddef
9961 endclass
9962
9963 def Foo()
9964 var afoo = A.new()
9965 var i = empty(afoo)
9966 enddef
9967
9968 var a = A.new()
9969 assert_fails('empty(a)', 'Failed to check emptiness')
9970 assert_fails('Foo()', 'Failed to check emptiness')
9971 END
9972 call v9.CheckSourceSuccess(lines)
9973
9974 " call empty() using an object from a script
9975 let lines =<< trim END
9976 vim9script
9977 class A
9978 def empty(): bool
9979 return true
9980 enddef
9981 endclass
9982 var afoo = A.new()
9983 assert_equal(true, afoo.empty())
9984 END
9985 call v9.CheckSourceSuccess(lines)
9986
9987 " call empty() using an object from a method
9988 let lines =<< trim END
9989 vim9script
9990 class A
9991 def empty(): bool
9992 return true
9993 enddef
9994 endclass
9995 def Foo()
9996 var afoo = A.new()
9997 assert_equal(true, afoo.empty())
9998 enddef
9999 Foo()
10000 END
10001 call v9.CheckSourceSuccess(lines)
10002
10003 " call empty() using "this" from an object method
10004 let lines =<< trim END
10005 vim9script
10006 class A
10007 def empty(): bool
10008 return true
10009 enddef
10010 def Foo(): bool
10011 return this.empty()
10012 enddef
10013 endclass
10014 def Bar()
10015 var abar = A.new()
10016 assert_equal(true, abar.Foo())
10017 enddef
10018 Bar()
10019 END
10020 call v9.CheckSourceSuccess(lines)
10021
10022 " Call empty() from a derived object
10023 let lines =<< trim END
10024 vim9script
10025 class A
10026 def empty(): bool
10027 return false
10028 enddef
10029 endclass
10030 class B extends A
10031 def empty(): bool
10032 return true
10033 enddef
10034 endclass
10035 def Foo(afoo: A)
10036 assert_equal(true, empty(afoo))
10037 var bfoo = B.new()
10038 assert_equal(true, empty(bfoo))
10039 enddef
10040 var b = B.new()
10041 assert_equal(1, empty(b))
10042 Foo(b)
10043 END
10044 call v9.CheckSourceSuccess(lines)
10045
10046 " Invoking empty method using an interface
10047 let lines =<< trim END
10048 vim9script
10049 interface A
10050 def empty(): bool
10051 endinterface
10052 class B implements A
10053 def empty(): bool
10054 return false
10055 enddef
10056 endclass
10057 def Foo(a: A)
10058 assert_equal(false, empty(a))
10059 enddef
10060 var b = B.new()
10061 Foo(b)
10062 END
10063 call v9.CheckSourceSuccess(lines)
10064endfunc
10065
10066" Test for using the len() builtin method with an object
10067" This is a legacy function to use the test_garbagecollect_now() function.
10068func Test_object_length()
10069 let lines =<< trim END
10070 vim9script
10071 class A
10072 var mylen: number = 0
10073 def new(n: number)
10074 this.mylen = n
10075 enddef
10076 def len(): number
10077 return this.mylen
10078 enddef
10079 endclass
10080
10081 def Foo()
10082 var afoo = A.new(12)
10083 assert_equal(12, len(afoo))
10084 assert_equal(12, afoo->len())
10085 enddef
10086
10087 var a = A.new(22)
10088 assert_equal(22, len(a))
10089 assert_equal(22, a->len())
10090 test_garbagecollect_now()
10091 assert_equal(22, len(a))
10092 Foo()
10093 test_garbagecollect_now()
10094 Foo()
10095 END
10096 call v9.CheckSourceSuccess(lines)
10097
10098 " len() should return 0 without a builtin method
10099 let lines =<< trim END
10100 vim9script
10101 class A
10102 endclass
10103
10104 def Foo()
10105 var afoo = A.new()
10106 assert_equal(0, len(afoo))
10107 enddef
10108
10109 var a = A.new()
10110 assert_equal(0, len(a))
10111 Foo()
10112 END
10113 call v9.CheckSourceSuccess(lines)
10114
10115 " Unsupported signature for the len() method
10116 let lines =<< trim END
10117 vim9script
10118 class A
10119 def len()
10120 enddef
10121 endclass
10122 END
10123 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10124
10125 " Error when calling the len() method
10126 let lines =<< trim END
10127 vim9script
10128 class A
10129 def len(): number
10130 throw "Failed to compute length"
10131 enddef
10132 endclass
10133
10134 def Foo()
10135 var afoo = A.new()
10136 var i = len(afoo)
10137 enddef
10138
10139 var a = A.new()
10140 assert_fails('len(a)', 'Failed to compute length')
10141 assert_fails('Foo()', 'Failed to compute length')
10142 END
10143 call v9.CheckSourceSuccess(lines)
10144
10145 " call len() using an object from a script
10146 let lines =<< trim END
10147 vim9script
10148 class A
10149 def len(): number
10150 return 5
10151 enddef
10152 endclass
10153 var afoo = A.new()
10154 assert_equal(5, afoo.len())
10155 END
10156 call v9.CheckSourceSuccess(lines)
10157
10158 " call len() using an object from a method
10159 let lines =<< trim END
10160 vim9script
10161 class A
10162 def len(): number
10163 return 5
10164 enddef
10165 endclass
10166 def Foo()
10167 var afoo = A.new()
10168 assert_equal(5, afoo.len())
10169 enddef
10170 Foo()
10171 END
10172 call v9.CheckSourceSuccess(lines)
10173
10174 " call len() using "this" from an object method
10175 let lines =<< trim END
10176 vim9script
10177 class A
10178 def len(): number
10179 return 8
10180 enddef
10181 def Foo(): number
10182 return this.len()
10183 enddef
10184 endclass
10185 def Bar()
10186 var abar = A.new()
10187 assert_equal(8, abar.Foo())
10188 enddef
10189 Bar()
10190 END
10191 call v9.CheckSourceSuccess(lines)
10192
10193 " Call len() from a derived object
10194 let lines =<< trim END
10195 vim9script
10196 class A
10197 def len(): number
10198 return 10
10199 enddef
10200 endclass
10201 class B extends A
10202 def len(): number
10203 return 20
10204 enddef
10205 endclass
10206 def Foo(afoo: A)
10207 assert_equal(20, len(afoo))
10208 var bfoo = B.new()
10209 assert_equal(20, len(bfoo))
10210 enddef
10211 var b = B.new()
10212 assert_equal(20, len(b))
10213 Foo(b)
10214 END
10215 call v9.CheckSourceSuccess(lines)
10216
10217 " Invoking len method using an interface
10218 let lines =<< trim END
10219 vim9script
10220 interface A
10221 def len(): number
10222 endinterface
10223 class B implements A
10224 def len(): number
10225 return 123
10226 enddef
10227 endclass
10228 def Foo(a: A)
10229 assert_equal(123, len(a))
10230 enddef
10231 var b = B.new()
10232 Foo(b)
10233 END
10234 call v9.CheckSourceSuccess(lines)
10235endfunc
10236
10237" Test for using the string() builtin method with an object
10238" This is a legacy function to use the test_garbagecollect_now() function.
10239func Test_object_string()
10240 let lines =<< trim END
10241 vim9script
10242 class A
10243 var name: string
10244 def string(): string
10245 return this.name
10246 enddef
10247 endclass
10248
10249 def Foo()
10250 var afoo = A.new("foo-A")
10251 assert_equal('foo-A', string(afoo))
10252 assert_equal('foo-A', afoo->string())
10253 enddef
10254
10255 var a = A.new("script-A")
10256 assert_equal('script-A', string(a))
10257 assert_equal('script-A', a->string())
10258 assert_equal(['script-A'], execute('echo a')->split("\n"))
10259 test_garbagecollect_now()
10260 assert_equal('script-A', string(a))
10261 Foo()
10262 test_garbagecollect_now()
10263 Foo()
10264 END
10265 call v9.CheckSourceSuccess(lines)
10266
10267 " string() should return "object of A {}" without a builtin method
10268 let lines =<< trim END
10269 vim9script
10270 class A
10271 endclass
10272
10273 def Foo()
10274 var afoo = A.new()
10275 assert_equal('object of A {}', string(afoo))
10276 enddef
10277
10278 var a = A.new()
10279 assert_equal('object of A {}', string(a))
10280 Foo()
10281 END
10282 call v9.CheckSourceSuccess(lines)
10283
10284 " Unsupported signature for the string() method
10285 let lines =<< trim END
10286 vim9script
10287 class A
10288 def string()
10289 enddef
10290 endclass
10291 END
10292 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10293
10294 " Error when calling the string() method
10295 let lines =<< trim END
10296 vim9script
10297 class A
10298 def string(): string
10299 throw "Failed to get text"
10300 enddef
10301 endclass
10302
10303 def Foo()
10304 var afoo = A.new()
10305 var i = string(afoo)
10306 enddef
10307
10308 var a = A.new()
10309 assert_fails('string(a)', 'Failed to get text')
10310 assert_fails('Foo()', 'Failed to get text')
10311 END
10312 call v9.CheckSourceSuccess(lines)
10313
10314 " call string() using an object from a script
10315 let lines =<< trim END
10316 vim9script
10317 class A
10318 def string(): string
10319 return 'A'
10320 enddef
10321 endclass
10322 var afoo = A.new()
10323 assert_equal('A', afoo.string())
10324 END
10325 call v9.CheckSourceSuccess(lines)
10326
10327 " call string() using an object from a method
10328 let lines =<< trim END
10329 vim9script
10330 class A
10331 def string(): string
10332 return 'A'
10333 enddef
10334 endclass
10335 def Foo()
10336 var afoo = A.new()
10337 assert_equal('A', afoo.string())
10338 enddef
10339 Foo()
10340 END
10341 call v9.CheckSourceSuccess(lines)
10342
10343 " call string() using "this" from an object method
10344 let lines =<< trim END
10345 vim9script
10346 class A
10347 def string(): string
10348 return 'A'
10349 enddef
10350 def Foo(): string
10351 return this.string()
10352 enddef
10353 endclass
10354 def Bar()
10355 var abar = A.new()
10356 assert_equal('A', abar.string())
10357 enddef
10358 Bar()
10359 END
10360 call v9.CheckSourceSuccess(lines)
10361
10362 " Call string() from a derived object
10363 let lines =<< trim END
10364 vim9script
10365 class A
10366 def string(): string
10367 return 'A'
10368 enddef
10369 endclass
10370 class B extends A
10371 def string(): string
10372 return 'B'
10373 enddef
10374 endclass
10375 def Foo(afoo: A)
10376 assert_equal('B', string(afoo))
10377 var bfoo = B.new()
10378 assert_equal('B', string(bfoo))
10379 enddef
10380 var b = B.new()
10381 assert_equal('B', string(b))
10382 Foo(b)
10383 END
10384 call v9.CheckSourceSuccess(lines)
10385
10386 " Invoking string method using an interface
10387 let lines =<< trim END
10388 vim9script
10389 interface A
10390 def string(): string
10391 endinterface
10392 class B implements A
10393 def string(): string
10394 return 'B'
10395 enddef
10396 endclass
10397 def Foo(a: A)
10398 assert_equal('B', string(a))
10399 enddef
10400 var b = B.new()
10401 Foo(b)
10402 END
10403 call v9.CheckSourceSuccess(lines)
10404endfunc
10405
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010406" Test for using a class in the class definition
10407def Test_Ref_Class_Within_Same_Class()
10408 var lines =<< trim END
10409 vim9script
10410 class A
10411 var n: number = 0
10412 def Equals(other: A): bool
10413 return this.n == other.n
10414 enddef
10415 endclass
10416
10417 var a1 = A.new(10)
10418 var a2 = A.new(10)
10419 var a3 = A.new(20)
10420 assert_equal(true, a1.Equals(a2))
10421 assert_equal(false, a2.Equals(a3))
10422 END
10423 v9.CheckScriptSuccess(lines)
10424
10425 lines =<< trim END
10426 vim9script
10427
10428 class Foo
10429 var num: number
10430 def Clone(): Foo
10431 return Foo.new(this.num)
10432 enddef
10433 endclass
10434
10435 var f1 = Foo.new(1)
10436
10437 def F()
10438 var f2: Foo = f1.Clone()
10439 assert_equal(false, f2 is f1)
10440 assert_equal(true, f2.num == f1.num)
10441 enddef
10442 F()
10443
10444 var f3: Foo = f1.Clone()
10445 assert_equal(false, f3 is f1)
10446 assert_equal(true, f3.num == f1.num)
10447 END
10448 v9.CheckScriptSuccess(lines)
10449
10450 # Test for trying to use a class to extend when defining the same class
10451 lines =<< trim END
10452 vim9script
10453 class A extends A
10454 endclass
10455 END
10456 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10457
10458 # Test for trying to use a class to implement when defining the same class
10459 lines =<< trim END
10460 vim9script
10461 class A implements A
10462 endclass
10463 END
10464 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10465enddef
10466
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010467" Test for using a compound operator from a lambda function in an object method
10468def Test_compound_op_in_objmethod_lambda()
10469 # Test using the "+=" operator
10470 var lines =<< trim END
10471 vim9script
10472 class A
10473 var n: number = 10
10474 def Foo()
10475 var Fn = () => {
10476 this.n += 1
10477 }
10478 Fn()
10479 enddef
10480 endclass
10481
10482 var a = A.new()
10483 a.Foo()
10484 assert_equal(11, a.n)
10485 END
10486 v9.CheckScriptSuccess(lines)
10487
10488 # Test using the "..=" operator
10489 lines =<< trim END
10490 vim9script
10491 class A
10492 var s: string = "a"
10493 def Foo()
10494 var Fn = () => {
10495 this.s ..= "a"
10496 }
10497 Fn()
10498 enddef
10499 endclass
10500
10501 var a = A.new()
10502 a.Foo()
10503 a.Foo()
10504 assert_equal("aaa", a.s)
10505 END
10506 v9.CheckScriptSuccess(lines)
10507enddef
10508
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010509" Test for using test_refcount() with a class and an object
10510def Test_class_object_refcount()
10511 var lines =<< trim END
10512 vim9script
10513 class A
10514 endclass
10515 var a: A = A.new()
10516 assert_equal(2, test_refcount(A))
10517 assert_equal(1, test_refcount(a))
10518 var b = a
10519 assert_equal(2, test_refcount(A))
10520 assert_equal(2, test_refcount(a))
10521 assert_equal(2, test_refcount(b))
10522 END
10523 v9.CheckScriptSuccess(lines)
10524enddef
10525
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010526" call a lambda function in one object from another object
10527def Test_lambda_invocation_across_classes()
10528 var lines =<< trim END
10529 vim9script
10530 class A
10531 var s: string = "foo"
10532 def GetFn(): func
10533 var Fn = (): string => {
10534 return this.s
10535 }
10536 return Fn
10537 enddef
10538 endclass
10539
10540 class B
10541 var s: string = "bar"
10542 def GetFn(): func
10543 var a = A.new()
10544 return a.GetFn()
10545 enddef
10546 endclass
10547
10548 var b = B.new()
10549 var Fn = b.GetFn()
10550 assert_equal("foo", Fn())
10551 END
10552 v9.CheckScriptSuccess(lines)
10553enddef
10554
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010555" Test for using a class member which is an object of the current class
10556def Test_current_class_object_class_member()
10557 var lines =<< trim END
10558 vim9script
10559 class A
10560 public static var obj1: A = A.new(10)
10561 var n: number
10562 endclass
10563 defcompile
10564 assert_equal(10, A.obj1.n)
10565 END
10566 v9.CheckScriptSuccess(lines)
10567enddef
10568
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020010569" Test for updating a base class variable from a base class method without the
10570" class name. This used to crash Vim (Github issue #14352).
10571def Test_use_base_class_variable_from_base_class_method()
10572 var lines =<< trim END
10573 vim9script
10574
10575 class DictKeyClass
10576 static var _obj_id_count = 1
10577 def _GenerateKey()
10578 _obj_id_count += 1
10579 enddef
10580 static def GetIdCount(): number
10581 return _obj_id_count
10582 enddef
10583 endclass
10584
10585 class C extends DictKeyClass
10586 def F()
10587 this._GenerateKey()
10588 enddef
10589 endclass
10590
10591 C.new().F()
10592 assert_equal(2, DictKeyClass.GetIdCount())
10593 END
10594 v9.CheckScriptSuccess(lines)
10595enddef
10596
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020010597" Test for accessing protected funcref object and class variables
10598def Test_protected_funcref()
10599 # protected funcref object variable
10600 var lines =<< trim END
10601 vim9script
10602 class Test1
10603 const _Id: func(any): any = (v) => v
10604 endclass
10605 var n = Test1.new()._Id(1)
10606 END
10607 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
10608
10609 # protected funcref class variable
10610 lines =<< trim END
10611 vim9script
10612 class Test2
10613 static const _Id: func(any): any = (v) => v
10614 endclass
10615 var n = Test2._Id(2)
10616 END
10617 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
10618enddef
10619
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020010620" Test for using lambda block in classes
10621def Test_lambda_block_in_class()
10622 # This used to crash Vim
10623 var lines =<< trim END
10624 vim9script
10625 class IdClass1
10626 const Id: func(number): number = (num: number): number => {
10627 # Return a ID
10628 return num * 10
10629 }
10630 endclass
10631 var id = IdClass1.new()
10632 assert_equal(20, id.Id(2))
10633 END
10634 v9.CheckScriptSuccess(lines)
10635
10636 # This used to crash Vim
10637 lines =<< trim END
10638 vim9script
10639 class IdClass2
10640 static const Id: func(number): number = (num: number): number => {
10641 # Return a ID
10642 return num * 2
10643 }
10644 endclass
10645 assert_equal(16, IdClass2.Id(8))
10646 END
10647 v9.CheckScriptSuccess(lines)
10648enddef
10649
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020010650" Test for defcompiling an abstract method
10651def Test_abstract_method_defcompile()
10652 # Compile an abstract class with abstract object methods
10653 var lines =<< trim END
10654 vim9script
10655 abstract class A
10656 abstract def Foo(): string
10657 abstract def Bar(): list<string>
10658 endclass
10659 defcompile
10660 END
10661 v9.CheckScriptSuccess(lines)
10662
10663 # Compile a concrete object method in an abstract class
10664 lines =<< trim END
10665 vim9script
10666 abstract class A
10667 abstract def Foo(): string
10668 abstract def Bar(): list<string>
10669 def Baz(): string
10670 pass
10671 enddef
10672 endclass
10673 defcompile
10674 END
10675 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10676
10677 # Compile a concrete class method in an abstract class
10678 lines =<< trim END
10679 vim9script
10680 abstract class A
10681 abstract def Foo(): string
10682 abstract def Bar(): list<string>
10683 static def Baz(): string
10684 pass
10685 enddef
10686 endclass
10687 defcompile
10688 END
10689 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10690enddef
10691
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020010692" Test for defining a class in a function
10693def Test_class_definition_in_a_function()
10694 var lines =<< trim END
10695 vim9script
10696 def Foo()
10697 class A
10698 endclass
10699 enddef
10700 defcompile
10701 END
10702 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
10703enddef
10704
Bram Moolenaar00b28d62022-12-08 15:32:33 +000010705" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker