blob: 0754af7deccd6f5d02dd5c59a7079c9904454252 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +010038 # Only the complete word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmananac773182024-04-27 11:36:12 +020070 # Additional command after "class name"
71 lines =<< trim END
72 vim9script
73 class Something | var x = 10
74 endclass
75 END
76 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
77
78 # Additional command after "object variable"
79 lines =<< trim END
80 vim9script
81 class Something
82 var l: list<number> = [] | var y = 10
83 endclass
84 END
85 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
86
87 # Additional command after "class variable"
88 lines =<< trim END
89 vim9script
90 class Something
91 static var d = {a: 10} | var y = 10
92 endclass
93 END
94 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
95
96 # Additional command after "object method"
97 lines =<< trim END
98 vim9script
99 class Something
100 def Foo() | var y = 10
101 enddef
102 endclass
103 END
104 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
105
Yegappan Lakshmananfe55c312024-04-28 09:54:09 +0200106 # Comments are allowed after an inline block
107 lines =<< trim END
108 vim9script
109 class Foo
110 static const bar = { # {{{
111 baz: 'qux'
112 } # }}}
113 endclass
114 assert_equal({baz: 'qux'}, Foo.bar)
115 END
116 v9.CheckSourceSuccess(lines)
117
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +0100118 # Try to define a class with the same name as an existing variable
119 lines =<< trim END
120 vim9script
121 var Something: list<number> = [1]
122 class Thing
123 endclass
124 interface Api
125 endinterface
126 class Something extends Thing implements Api
127 var v1: string = ''
128 def Foo()
129 enddef
130 endclass
131 END
132 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 7)
133
zeertzjqe7102202024-02-13 20:32:04 +0100134 # Use old "this." prefixed member variable declaration syntax (without initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100135 lines =<< trim END
136 vim9script
137 class Something
138 this.count: number
139 endclass
140 END
141 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
142
zeertzjqe7102202024-02-13 20:32:04 +0100143 # Use old "this." prefixed member variable declaration syntax (with initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100144 lines =<< trim END
145 vim9script
146 class Something
147 this.count: number = 42
148 endclass
149 END
150 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
151
152 # Use old "this." prefixed member variable declaration syntax (type inferred)
153 lines =<< trim END
154 vim9script
155 class Something
156 this.count = 42
157 endclass
158 END
159 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
160
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200161 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000162 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 vim9script
164 class Something
165 this
166 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000167 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100168 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000169
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200170 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000171 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200172 vim9script
173 class Something
174 this.
175 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000176 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100177 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000178
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200179 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000180 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200181 vim9script
182 class Something
183 this .count
184 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000185 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100186 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000187
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200188 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000189 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200190 vim9script
191 class Something
192 this. count
193 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000194 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100195 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000196
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200197 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000198 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200199 vim9script
200 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100201 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200202 that.count
203 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200205 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000206
Doug Kearns74da0ee2023-12-14 20:26:26 +0100207 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000208 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200209 vim9script
210 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100211 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000213 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100214 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
215
216 # Use "variable" instead of "var" for member variable declaration (with initialization)
217 lines =<< trim END
218 vim9script
219 class Something
220 variable count: number = 42
221 endclass
222 END
223 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
224
225 # Use "variable" instead of "var" for member variable declaration (type inferred)
226 lines =<< trim END
227 vim9script
228 class Something
229 variable count = 42
230 endclass
231 END
232 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000233
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200234 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000235 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200236 vim9script
237 class Something
238 def new()
239 this.state = 0
240 enddef
241 endclass
242 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000243 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200244 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000245
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200246 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000247 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200248 vim9script
249 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100250 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200251 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000252 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200253 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000254
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200255 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000256 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200257 vim9script
258 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100259 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200260 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000261 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200262 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000263
Doug Kearns74da0ee2023-12-14 20:26:26 +0100264 # Missing ":var" in a "var" member variable declaration (without initialization)
265 lines =<< trim END
266 vim9script
267 class Something
268 var: number
269 endclass
270 END
271 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
272
273 # Missing ":var" in a "var" member variable declaration (with initialization)
274 lines =<< trim END
275 vim9script
276 class Something
277 var: number = 42
278 endclass
279 END
280 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
281
282 # Missing ":var" in a "var" member variable declaration (type inferred)
283 lines =<< trim END
284 vim9script
285 class Something
286 var = 42
287 endclass
288 END
289 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
290
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200291 # Test for unsupported comment specifier
292 lines =<< trim END
293 vim9script
294 class Something
295 # comment
296 #{
297 endclass
298 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200299 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200300
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200301 # Test for using class as a bool
302 lines =<< trim END
303 vim9script
304 class A
305 endclass
306 if A
307 endif
308 END
Ernie Raele75fde62023-12-21 17:18:54 +0100309 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200310
311 # Test for using object as a bool
312 lines =<< trim END
313 vim9script
314 class A
315 endclass
316 var a = A.new()
317 if a
318 endif
319 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200320 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200321
322 # Test for using class as a float
323 lines =<< trim END
324 vim9script
325 class A
326 endclass
327 sort([1.1, A], 'f')
328 END
Ernie Raelfa831102023-12-14 20:06:39 +0100329 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200330
331 # Test for using object as a float
332 lines =<< trim END
333 vim9script
334 class A
335 endclass
336 var a = A.new()
337 sort([1.1, a], 'f')
338 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200339 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200340
341 # Test for using class as a string
342 lines =<< trim END
343 vim9script
344 class A
345 endclass
346 :exe 'call ' .. A
347 END
Ernie Raele75fde62023-12-21 17:18:54 +0100348 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200349
350 # Test for using object as a string
351 lines =<< trim END
352 vim9script
353 class A
354 endclass
355 var a = A.new()
356 :exe 'call ' .. a
357 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200358 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200359
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200360 # Test creating a class with member variables and methods, calling a object
361 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000362 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200363 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000364
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200365 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100366 var lnum: number
367 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000368
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200369 # make a nicely formatted string
370 def ToString(): string
371 return $'({this.lnum}, {this.col})'
372 enddef
373 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000374
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200375 # use the automatically generated new() method
376 var pos = TextPosition.new(2, 12)
377 assert_equal(2, pos.lnum)
378 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000379
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200380 # call an object method
381 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000382
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200383 assert_equal(v:t_class, type(TextPosition))
384 assert_equal(v:t_object, type(pos))
385 assert_equal('class<TextPosition>', typename(TextPosition))
386 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000387 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200388 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200389
390 # When referencing object methods, space cannot be used after a "."
391 lines =<< trim END
392 vim9script
393 class A
394 def Foo(): number
395 return 10
396 enddef
397 endclass
398 var a = A.new()
399 var v = a. Foo()
400 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200401 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200402
403 # Using an object without specifying a method or a member variable
404 lines =<< trim END
405 vim9script
406 class A
407 def Foo(): number
408 return 10
409 enddef
410 endclass
411 var a = A.new()
412 var v = a.
413 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200414 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200415
416 # Error when parsing the arguments of an object method.
417 lines =<< trim END
418 vim9script
419 class A
420 def Foo()
421 enddef
422 endclass
423 var a = A.new()
424 var v = a.Foo(,)
425 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200426 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200427
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200428 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200429 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200430 vim9script
431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100432 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200433 X: 1
434 }
435 endclass
436 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200437 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200438 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000439enddef
440
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200441" Tests for object/class methods in a class
442def Test_class_def_method()
443 # Using the "public" keyword when defining an object method
444 var lines =<< trim END
445 vim9script
446 class A
447 public def Foo()
448 enddef
449 endclass
450 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200451 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200452
453 # Using the "public" keyword when defining a class method
454 lines =<< trim END
455 vim9script
456 class A
457 public static def Foo()
458 enddef
459 endclass
460 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200461 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200462
Ernie Rael03042a22023-11-11 08:53:32 +0100463 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200464 lines =<< trim END
465 vim9script
466 class A
467 public def _Foo()
468 enddef
469 endclass
470 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200471 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200472
Ernie Rael03042a22023-11-11 08:53:32 +0100473 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200474 lines =<< trim END
475 vim9script
476 class A
477 public static def _Foo()
478 enddef
479 endclass
480 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200481 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200482
483 # Using a "def" keyword without an object method name
484 lines =<< trim END
485 vim9script
486 class A
487 def
488 enddef
489 endclass
490 END
491 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
492
493 # Using a "def" keyword without a class method name
494 lines =<< trim END
495 vim9script
496 class A
497 static def
498 enddef
499 endclass
500 END
501 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
502enddef
503
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000504def Test_class_defined_twice()
505 # class defined twice should fail
506 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200507 vim9script
508 class There
509 endclass
510 class There
511 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000512 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200513 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000514
515 # one class, reload same script twice is OK
516 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 vim9script
518 class There
519 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000520 END
521 writefile(lines, 'XclassTwice.vim', 'D')
522 source XclassTwice.vim
523 source XclassTwice.vim
524enddef
525
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000526def Test_returning_null_object()
527 # this was causing an internal error
528 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200529 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000530
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200531 class BufferList
532 def Current(): any
533 return null_object
534 enddef
535 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000536
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200537 var buffers = BufferList.new()
538 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000539 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200540 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000541enddef
542
Bram Moolenaard13dd302023-03-11 20:56:35 +0000543def Test_using_null_class()
544 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200545 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200547 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200548
549 # Test for using a null class as a value
550 lines =<< trim END
551 vim9script
552 echo empty(null_class)
553 END
554 v9.CheckSourceFailure(lines, 'E1405: Class "" cannot be used as a value', 2)
555
556 # Test for using a null class with string()
557 lines =<< trim END
558 vim9script
559 assert_equal('class [unknown]', string(null_class))
560 END
561 v9.CheckSourceSuccess(lines)
562
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +0200563 # Test for using a null class with type() and typename()
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200564 lines =<< trim END
565 vim9script
566 assert_equal(12, type(null_class))
567 assert_equal('class<Unknown>', typename(null_class))
568 END
569 v9.CheckSourceSuccess(lines)
570enddef
571
Bram Moolenaar657aea72023-01-27 13:16:19 +0000572def Test_class_interface_wrong_end()
573 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200574 vim9script
575 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100576 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200577 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200579 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000580
581 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200582 vim9script
583 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100584 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200585 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000586 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200587 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000588enddef
589
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000590def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200591 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000592 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200593 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000594
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200595 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100596 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200597 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200599 var state: State
600 var db = {'xyz': 789}
601 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200603 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000604
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200605 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000606 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200607 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000608
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200609 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100610 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200611 def Method1()
612 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000613 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200614 endclass
615
616 var obj: Class
617 def Func()
618 obj.Method1()
619 enddef
620 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000621 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200622 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000623
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200624 # Pass an uninitialized object variable to a "new" function and try to call an
625 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000626 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200627 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000628
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200629 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100630 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200631 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000632
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200633 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100634 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200636 def GetBackground(): string
637 return this._bg.background
638 enddef
639 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000640
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200641 var bg: Background # UNINITIALIZED
642 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200644 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000645
646 # TODO: this should not give an error but be handled at runtime
647 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200648 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000649
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200650 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100651 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200652 def Method1()
653 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000654 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200655 endclass
656
657 var obj = null_object
658 def Func()
659 obj.Method1()
660 enddef
661 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000662 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200663 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000664enddef
665
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200666" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200667def Test_null_object_assign_compare()
668 var lines =<< trim END
669 vim9script
670
671 var nullo = null_object
672 def F(): any
673 return nullo
674 enddef
675 assert_equal('object<Unknown>', typename(F()))
676
677 var o0 = F()
678 assert_true(o0 == null_object)
679 assert_true(o0 == null)
680
681 var o1: any = nullo
682 assert_true(o1 == null_object)
683 assert_true(o1 == null)
684
685 def G()
686 var x = null_object
687 enddef
688
689 class C
690 endclass
691 var o2: C
692 assert_true(o2 == null_object)
693 assert_true(o2 == null)
694
695 o2 = null_object
696 assert_true(o2 == null)
697
698 o2 = C.new()
699 assert_true(o2 != null)
700
701 o2 = null_object
702 assert_true(o2 == null)
703 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200704 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200705enddef
706
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200707" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000708def Test_class_member_initializer()
709 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200710 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000711
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200712 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100713 var lnum: number = 1
714 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000715
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200716 # constructor with only the line number
717 def new(lnum: number)
718 this.lnum = lnum
719 enddef
720 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200722 var pos = TextPosition.new(3)
723 assert_equal(3, pos.lnum)
724 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000725
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200726 var instr = execute('disassemble TextPosition.new')
727 assert_match('new\_s*' ..
728 '0 NEW TextPosition size \d\+\_s*' ..
729 '\d PUSHNR 1\_s*' ..
730 '\d STORE_THIS 0\_s*' ..
731 '\d PUSHNR 1\_s*' ..
732 '\d STORE_THIS 1\_s*' ..
733 'this.lnum = lnum\_s*' ..
734 '\d LOAD arg\[-1]\_s*' ..
735 '\d PUSHNR 0\_s*' ..
736 '\d LOAD $0\_s*' ..
737 '\d\+ STOREINDEX object\_s*' ..
738 '\d\+ RETURN object.*',
739 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000740 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200741 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000742enddef
743
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000744def Test_member_any_used_as_object()
745 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200746 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000747
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200748 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100749 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200750 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000751
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200752 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100753 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200754 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000755
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200756 def F(outer: Outer)
757 outer.inner.value = 1
758 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200760 var inner_obj = Inner.new(0)
761 var outer_obj = Outer.new(inner_obj)
762 F(outer_obj)
763 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000764 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200765 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000766
Ernie Rael03042a22023-11-11 08:53:32 +0100767 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200768 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._value = '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 Rael03042a22023-11-11 08:53:32 +0100787 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200788
789 # Try modifying a non-existing variable using an "any" object
790 lines =<< trim END
791 vim9script
792
793 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100794 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200795 endclass
796
797 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100798 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200799 endclass
800
801 def F(outer: Outer)
802 outer.inner.someval = 'b'
803 enddef
804
805 var inner_obj = Inner.new('a')
806 var outer_obj = Outer.new(inner_obj)
807 F(outer_obj)
808 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200809 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000810enddef
811
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200812" Nested assignment to a object variable which is of another class type
813def Test_assignment_nested_type()
814 var lines =<< trim END
815 vim9script
816
817 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100818 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200819 endclass
820
821 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100822 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200823 endclass
824
825 def F(outer: Outer)
826 outer.inner.value = 1
827 enddef
828
829 def Test_assign_to_nested_typed_member()
830 var inner = Inner.new(0)
831 var outer = Outer.new(inner)
832 F(outer)
833 assert_equal(1, inner.value)
834 enddef
835
836 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200837
838 var script_inner = Inner.new(0)
839 var script_outer = Outer.new(script_inner)
840 script_outer.inner.value = 1
841 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200842 END
843 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200844
845 # Assignment where target item is read only in :def
846 lines =<< trim END
847 vim9script
848
849 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100850 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200851 endclass
852
853 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100854 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200855 endclass
856
857 def F(outer: Outer)
858 outer.inner.value = 1
859 enddef
860
861 def Test_assign_to_nested_typed_member()
862 var inner = Inner.new(0)
863 var outer = Outer.new(inner)
864 F(outer)
865 assert_equal(1, inner.value)
866 enddef
867
868 Test_assign_to_nested_typed_member()
869 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200870 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200871
872 # Assignment where target item is read only script level
873 lines =<< trim END
874 vim9script
875
876 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100877 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200878 endclass
879
880 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100881 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200882 endclass
883
884 def F(outer: Outer)
885 outer.inner.value = 1
886 enddef
887
888 var script_inner = Inner.new(0)
889 var script_outer = Outer.new(script_inner)
890 script_outer.inner.value = 1
891 assert_equal(1, script_inner.value)
892 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200893 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200894enddef
895
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000896def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200897 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000898 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200899 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000900
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200901 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100902 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000903
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200904 def Add(n: number)
905 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100906 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200907 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100908
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200909 var f = Foo.new(3)
910 f.Add(17)
911 assert_equal(20, f.x)
912
913 def AddToFoo(obj: Foo)
914 obj.x += 3
915 enddef
916
917 AddToFoo(f)
918 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000919 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200920 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000921enddef
922
Bram Moolenaarf4508042023-01-15 16:54:57 +0000923def Test_list_of_objects()
924 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200925 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000926
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200927 class Foo
928 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000929 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200930 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000931
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200932 def ProcessList(fooList: list<Foo>)
933 for foo in fooList
934 foo.Add()
935 endfor
936 enddef
937
938 var l: list<Foo> = [Foo.new()]
939 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000940 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200941 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000942enddef
943
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000944def Test_expr_after_using_object()
945 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200946 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000947
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200948 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100949 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200950 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000951
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200952 def Foo(): Something
953 var v = Something.new()
954 echo 'in Foo(): ' .. typename(v)
955 return v
956 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000957
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200958 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000959 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200960 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000961enddef
962
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000963def Test_class_default_new()
964 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200965 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000966
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200967 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100968 var lnum: number = 1
969 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200970 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000971
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200972 var pos = TextPosition.new()
973 assert_equal(1, pos.lnum)
974 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000975
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200976 pos = TextPosition.new(v:none, v:none)
977 assert_equal(1, pos.lnum)
978 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000979
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200980 pos = TextPosition.new(3, 22)
981 assert_equal(3, pos.lnum)
982 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000983
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200984 pos = TextPosition.new(v:none, 33)
985 assert_equal(1, pos.lnum)
986 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000987 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200988 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000989
990 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200991 vim9script
992 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100993 var name: string
994 var age: number = 42
995 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000996
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200997 def new(this.name, this.age = v:none, this.education = v:none)
998 enddef
999 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001000
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001001 var piet = Person.new("Piet")
1002 assert_equal("Piet", piet.name)
1003 assert_equal(42, piet.age)
1004 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001005
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001006 var chris = Person.new("Chris", 4, "none")
1007 assert_equal("Chris", chris.name)
1008 assert_equal(4, chris.age)
1009 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001010 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001011 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001012
1013 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001014 vim9script
1015 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001016 var name: string
1017 var age: number = 42
1018 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +00001019
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001020 def new(this.name, this.age = v:none, this.education = v:none)
1021 enddef
1022 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001023
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001024 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +00001025 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001026 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001027
1028 # Using a specific value to initialize an instance variable in the new()
1029 # method.
1030 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001031 vim9script
1032 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001033 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001034 def new(this.val = 'a')
1035 enddef
1036 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001037 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001038 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001039enddef
1040
h-east2261c892023-08-16 21:49:54 +09001041def Test_class_new_with_object_member()
1042 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001043 vim9script
h-east2261c892023-08-16 21:49:54 +09001044
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001045 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001046 var str: string
1047 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001048 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +09001049 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001050 def newVals(this.str, this.num)
1051 enddef
1052 endclass
h-east2261c892023-08-16 21:49:54 +09001053
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001054 def Check()
1055 try
1056 var c = C.new('cats', 2)
1057 assert_equal('cats', c.str)
1058 assert_equal(2, c.num)
1059
1060 c = C.newVals('dogs', 4)
1061 assert_equal('dogs', c.str)
1062 assert_equal(4, c.num)
1063 catch
1064 assert_report($'Unexpected exception was caught: {v:exception}')
1065 endtry
1066 enddef
1067
1068 Check()
h-east2261c892023-08-16 21:49:54 +09001069 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001070 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001071
1072 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001073 vim9script
1074
1075 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 new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001079 enddef
1080 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001081
1082 def Check()
1083 try
1084 var c = C.new(1, 2)
1085 catch
1086 assert_report($'Unexpected exception was caught: {v:exception}')
1087 endtry
1088 enddef
1089
1090 Check()
h-eastdb385522023-09-28 22:18:19 +02001091 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001092 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001093
1094 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001095 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001096
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001097 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001098 var str: string
1099 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001100 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001101 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001102 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001103
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001104 def Check()
1105 try
1106 var c = C.newVals('dogs', 'apes')
1107 catch
1108 assert_report($'Unexpected exception was caught: {v:exception}')
1109 endtry
1110 enddef
1111
1112 Check()
1113 END
1114 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1115
1116 lines =<< trim END
1117 vim9script
1118
1119 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001120 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001121 def new(str: any)
1122 enddef
1123 endclass
1124
1125 def Check()
1126 try
1127 var c = C.new(1)
1128 catch
1129 assert_report($'Unexpected exception was caught: {v:exception}')
1130 endtry
1131 enddef
1132
1133 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001134 END
1135 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001136
1137 # Try using "this." argument in a class method
1138 lines =<< trim END
1139 vim9script
1140 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001141 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001142 static def Foo(this.val: number)
1143 enddef
1144 endclass
1145 END
1146 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1147
1148 # Try using "this." argument in an object method
1149 lines =<< trim END
1150 vim9script
1151 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001152 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001153 def Foo(this.val: number)
1154 enddef
1155 endclass
1156 END
1157 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001158enddef
1159
Bram Moolenaar74e12742022-12-13 21:14:28 +00001160def Test_class_object_member_inits()
1161 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001162 vim9script
1163 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001164 var lnum: number
1165 var col = 1
1166 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001167 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001168
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001169 var pos = TextPosition.new()
1170 assert_equal(0, pos.lnum)
1171 assert_equal(1, pos.col)
1172 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001173 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001174 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001175
1176 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001177 vim9script
1178 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001179 var lnum
1180 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001181 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001182 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001183 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001184
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001185 # If the type is not specified for a member, then it should be set during
1186 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001187 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001188 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001189
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001190 var init_count = 0
1191 def Init(): string
1192 init_count += 1
1193 return 'foo'
1194 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001195
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001196 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001197 var str1 = Init()
1198 var str2: string = Init()
1199 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001200 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001201
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001202 assert_equal(init_count, 0)
1203 var a = A.new()
1204 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001205 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001206 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001207
1208 # Test for initializing an object member with an unknown variable/type
1209 lines =<< trim END
1210 vim9script
1211 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001212 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001213 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001214 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001215 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001216 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001217
1218 # Test for initializing an object member with an special type
1219 lines =<< trim END
1220 vim9script
1221 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001222 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001223 endclass
1224 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001225 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001226enddef
1227
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001228" Test for instance variable access
1229def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001230 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001231 vim9script
1232 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001233 var _one = 1
1234 var two = 2
1235 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001236
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001237 def GetOne(): number
1238 return this._one
1239 enddef
1240 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001241
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001242 var trip = Triple.new()
1243 assert_equal(1, trip.GetOne())
1244 assert_equal(2, trip.two)
1245 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001246 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001247
Ernie Rael03042a22023-11-11 08:53:32 +01001248 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001249 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1250 trip.three = 33
1251 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001252
Ernie Raeld4802ec2023-10-20 11:59:00 +02001253 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001254 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001255 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001256
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001257 # Test for a public member variable name beginning with an underscore
1258 lines =<< trim END
1259 vim9script
1260 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001261 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001262 endclass
1263 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001264 v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001265
Bram Moolenaar590162c2022-12-24 21:24:06 +00001266 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001267 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001268
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001269 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001270 var make: string
1271 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001272
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001273 def new(make_arg: string)
1274 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001275 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001276
1277 def GetMake(): string
1278 return $"make = {this.make}"
1279 enddef
1280 def GetAge(): number
1281 return this.age
1282 enddef
1283 endclass
1284
1285 var c = MyCar.new("abc")
1286 assert_equal('make = abc', c.GetMake())
1287
1288 c = MyCar.new("def")
1289 assert_equal('make = def', c.GetMake())
1290
1291 var c2 = MyCar.new("123")
1292 assert_equal('make = 123', c2.GetMake())
1293
1294 def CheckCar()
1295 assert_equal("make = def", c.GetMake())
1296 assert_equal(5, c.GetAge())
1297 enddef
1298 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001299 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001300 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001301
1302 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001303 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001304
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001305 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001306 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001307
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001308 def new(make_arg: string)
1309 this.make = make_arg
1310 enddef
1311 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001312
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001313 var c = MyCar.new("abc")
1314 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001315 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001316 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001317
1318 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001319 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001320
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001321 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001322 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001323
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001324 def Add(n: number): any
1325 this.x->add(n)
1326 return this
1327 enddef
1328 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001329
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001330 echo Foo.new().Add(1).Add(2).x
1331 echo Foo.new().Add(1).Add(2)
1332 .x
1333 echo Foo.new().Add(1)
1334 .Add(2).x
1335 echo Foo.new()
1336 .Add(1).Add(2).x
1337 echo Foo.new()
1338 .Add(1)
1339 .Add(2)
1340 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001341 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001342 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001343
1344 # Test for "public" cannot be abbreviated
1345 lines =<< trim END
1346 vim9script
1347 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001348 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001349 endclass
1350 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001351 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001352
Doug Kearns74da0ee2023-12-14 20:26:26 +01001353 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001354 lines =<< trim END
1355 vim9script
1356 class Something
1357 public val = 1
1358 endclass
1359 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001360 v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001361
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001362 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001363 lines =<< trim END
1364 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001365 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001366 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001367 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001368 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001369 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001370 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001371
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001372 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001373 lines =<< trim END
1374 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001375 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001376 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001377 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001378 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001379 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001380 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001381
1382 # Modify a instance variable using the class name in a def function
1383 lines =<< trim END
1384 vim9script
1385 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001386 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001387 endclass
1388 def T()
1389 A.val = 1
1390 enddef
1391 T()
1392 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001393 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001394
1395 # Read a instance variable using the class name in a def function
1396 lines =<< trim END
1397 vim9script
1398 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001399 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001400 endclass
1401 def T()
1402 var i = A.val
1403 enddef
1404 T()
1405 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001406 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001407
1408 # Access from child class extending a class:
1409 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001410 vim9script
1411 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001412 var ro_obj_var = 10
1413 public var rw_obj_var = 20
1414 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001415 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001416
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001417 class B extends A
1418 def Foo()
1419 var x: number
1420 x = this.ro_obj_var
1421 this.ro_obj_var = 0
1422 x = this.rw_obj_var
1423 this.rw_obj_var = 0
1424 x = this._priv_obj_var
1425 this._priv_obj_var = 0
1426 enddef
1427 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001428
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001429 var b = B.new()
1430 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001431 END
1432 v9.CheckSourceSuccess(lines)
1433enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001434
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001435" Test for class variable access
1436def Test_class_variable_access()
1437 # Test for "static" cannot be abbreviated
1438 var lines =<< trim END
1439 vim9script
1440 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001441 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001442 endclass
1443 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001444 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001445
1446 # Test for "static" cannot be followed by "public".
1447 lines =<< trim END
1448 vim9script
1449 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001450 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001451 endclass
1452 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001453 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001454
1455 # A readonly class variable cannot be modified from a child class
1456 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001457 vim9script
1458 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001459 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001460 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001461
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001462 class B extends A
1463 def Foo()
1464 A.ro_class_var = 50
1465 enddef
1466 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001467
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001468 var b = B.new()
1469 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001470 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001471 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001472
Ernie Rael03042a22023-11-11 08:53:32 +01001473 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001474 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001475 vim9script
1476 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001477 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001478 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001479
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001480 class B extends A
1481 def Foo()
1482 var i = A._priv_class_var
1483 enddef
1484 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001485
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001486 var b = B.new()
1487 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001488 END
Ernie Rael03042a22023-11-11 08:53:32 +01001489 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001490
Ernie Rael03042a22023-11-11 08:53:32 +01001491 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001492 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001493 vim9script
1494 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001495 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001496 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001497
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 class B extends A
1499 def Foo()
1500 A._priv_class_var = 0
1501 enddef
1502 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001503
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001504 var b = B.new()
1505 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001506 END
Ernie Rael03042a22023-11-11 08:53:32 +01001507 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001508
1509 # Access from child class extending a class and from script context
1510 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001511 vim9script
1512 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001513 static var ro_class_var = 10
1514 public static var rw_class_var = 20
1515 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001516 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001517
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001518 class B extends A
1519 def Foo()
1520 var x: number
1521 x = A.ro_class_var
1522 assert_equal(10, x)
1523 x = A.rw_class_var
1524 assert_equal(25, x)
1525 A.rw_class_var = 20
1526 assert_equal(20, A.rw_class_var)
1527 enddef
1528 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001529
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001530 assert_equal(10, A.ro_class_var)
1531 assert_equal(20, A.rw_class_var)
1532 A.rw_class_var = 25
1533 assert_equal(25, A.rw_class_var)
1534 var b = B.new()
1535 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001536 END
1537 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001538enddef
1539
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001540def Test_class_object_compare()
1541 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001542 vim9script
1543 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001544 var nr = 0
1545 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001546 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001547 END
1548
1549 # used at the script level and in a compiled function
1550 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001551 var i1 = Item.new()
1552 assert_equal(i1, i1)
1553 assert_true(i1 is i1)
1554 var i2 = Item.new()
1555 assert_equal(i1, i2)
1556 assert_false(i1 is i2)
1557 var i3 = Item.new(0, 'xx')
1558 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001559
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001560 var io1 = Item.new(1, 'xx')
1561 assert_notequal(i1, io1)
1562 var io2 = Item.new(0, 'yy')
1563 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001564 END
1565
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001566 v9.CheckSourceSuccess(class_lines + test_lines)
1567 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001568 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001569
1570 for op in ['>', '>=', '<', '<=', '=~', '!~']
1571 var op_lines = [
1572 'var i1 = Item.new()',
1573 'var i2 = Item.new()',
1574 'echo i1 ' .. op .. ' i2',
1575 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001576 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001577 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001578 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001579 endfor
1580enddef
1581
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001582def Test_object_type()
1583 var 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
1592 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001593 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001594 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001595
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001596 var o: One = One.new()
1597 var t: Two = Two.new()
1598 var m: TwoMore = TwoMore.new()
1599 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001600
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001601 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001602 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001603 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001604
1605 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001606 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001607
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001608 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001609 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001610 endclass
1611 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001612 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001613 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001614
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001615 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001616 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001617 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001618
1619 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001620 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001621
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001622 interface One
1623 def GetMember(): number
1624 endinterface
1625 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001626 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001627 def GetMember(): number
1628 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001629 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001630 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001631
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001632 var o: One = Two.new(5)
1633 assert_equal(5, o.GetMember())
1634 END
1635 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001636
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001637 lines =<< trim END
1638 vim9script
1639
1640 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001641 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001642 endclass
1643
1644 def Ref(name: string): func(Num): Num
1645 return (arg: Num): Num => {
1646 return eval(name)(arg)
1647 }
1648 enddef
1649
1650 const Fn = Ref('Double')
1651 var Double = (m: Num): Num => Num.new(m.n * 2)
1652
1653 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001654 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001655 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001656enddef
1657
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001658def Test_class_member()
1659 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001660 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001661 vim9script
1662 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001663 var lnum = 1
1664 var col = 1
1665 static var counter = 0
1666 static var _secret = 7
1667 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001668
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001669 static def AddToCounter(nr: number)
1670 counter += nr
1671 enddef
1672 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001673
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001674 assert_equal(0, TextPos.counter)
1675 TextPos.AddToCounter(3)
1676 assert_equal(3, TextPos.counter)
1677 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001678
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001679 def GetCounter(): number
1680 return TextPos.counter
1681 enddef
1682 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001683
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001684 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1685 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1686 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001687
Ernie Rael03042a22023-11-11 08:53:32 +01001688 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1689 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001690
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001691 assert_equal(42, TextPos.anybody)
1692 TextPos.anybody = 12
1693 assert_equal(12, TextPos.anybody)
1694 TextPos.anybody += 5
1695 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001696 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001697 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001698
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001699 # example in the help
1700 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001701 vim9script
1702 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001703 var size: number
1704 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001705
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001706 def new(this.size)
1707 totalSize += this.size
1708 enddef
1709 endclass
1710 assert_equal(0, OtherThing.totalSize)
1711 var to3 = OtherThing.new(3)
1712 assert_equal(3, OtherThing.totalSize)
1713 var to7 = OtherThing.new(7)
1714 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001715 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001716 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001717
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001718 # using static class member twice
1719 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001720 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001722 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001723 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001724
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001725 static def MacroSubstitute(s: string): string
1726 return substitute(s, '{{author}}', author, 'gi')
1727 enddef
1728 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001729
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001730 assert_equal('some text', HTML.MacroSubstitute('some text'))
1731 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001732 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001733 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001734
Ernie Rael03042a22023-11-11 08:53:32 +01001735 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001736 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001737 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001738
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001739 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001740 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001741
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001742 def Add(n: number): number
1743 const F = (): number => this._x + n
1744 return F()
1745 enddef
1746 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001747
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001748 var foo = Foo.new()
1749 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001750 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001751 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001752
Ernie Rael03042a22023-11-11 08:53:32 +01001753 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001754 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001755 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001756
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001757 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001758 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001760 def Add(n: number): number
1761 var Lam = () => {
1762 this._x = this._x + n
1763 }
1764 Lam()
1765 return this._x
1766 enddef
1767 endclass
h-east2bd6a092023-05-19 19:01:17 +01001768
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001769 var foo = Foo.new()
1770 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001771 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001772 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001773
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001774 # check shadowing
1775 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001776 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001777
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001778 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001779 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001780 def Method(count: number)
1781 echo count
1782 enddef
1783 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001784
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001785 var s = Some.new()
1786 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001787 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001788 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001789
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001790 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001791 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001792 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001794 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001795 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001796 def Method(arg: number)
1797 var count = 3
1798 echo arg count
1799 enddef
1800 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001801
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001802 var s = Some.new()
1803 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001804 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001805 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001806
1807 # Test for using an invalid type for a member variable
1808 lines =<< trim END
1809 vim9script
1810 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001811 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001812 endclass
1813 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001814 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001815
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001816 # Test for setting a member on a null object
1817 lines =<< trim END
1818 vim9script
1819 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001820 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001821 endclass
1822
1823 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001824 var obj: A
1825 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001826 enddef
1827 F()
1828 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001829 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001830
1831 # Test for accessing a member on a null object
1832 lines =<< trim END
1833 vim9script
1834 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001835 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001836 endclass
1837
1838 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001839 var obj: A
1840 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001841 enddef
1842 F()
1843 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001844 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001845
1846 # Test for setting a member on a null object, at script level
1847 lines =<< trim END
1848 vim9script
1849 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001850 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001851 endclass
1852
1853 var obj: A
1854 obj.val = ""
1855 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001856 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001857
1858 # Test for accessing a member on a null object, at script level
1859 lines =<< trim END
1860 vim9script
1861 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001862 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001863 endclass
1864
1865 var obj: A
1866 echo obj.val
1867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001868 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001869
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001870 # Test for no space before or after the '=' when initializing a member
1871 # variable
1872 lines =<< trim END
1873 vim9script
1874 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001875 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001876 endclass
1877 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001878 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001879 lines =<< trim END
1880 vim9script
1881 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001882 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001883 endclass
1884 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001885 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001886
1887 # Access a non-existing member
1888 lines =<< trim END
1889 vim9script
1890 class A
1891 endclass
1892 var a = A.new()
1893 var v = a.bar
1894 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001895 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001896enddef
1897
Ernie Raele6c9aa52023-10-06 19:55:52 +02001898" These messages should show the defining class of the variable (base class),
1899" not the class that did the reference (super class)
1900def Test_defining_class_message()
1901 var lines =<< trim END
1902 vim9script
1903
1904 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001905 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001906 endclass
1907
1908 class Child extends Base
1909 endclass
1910
1911 var o = Child.new()
1912 var x = o._v1
1913 END
Ernie Rael03042a22023-11-11 08:53:32 +01001914 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001915 lines =<< trim END
1916 vim9script
1917
1918 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001919 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001920 endclass
1921
1922 class Child extends Base
1923 endclass
1924
1925 def F()
1926 var o = Child.new()
1927 var x = o._v1
1928 enddef
1929 F()
1930 END
Ernie Rael03042a22023-11-11 08:53:32 +01001931 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001932 lines =<< trim END
1933 vim9script
1934
1935 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001936 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001937 endclass
1938
1939 class Child extends Base
1940 endclass
1941
1942 var o = Child.new()
1943 o.v1 = []
1944 END
1945 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1946 lines =<< trim END
1947 vim9script
1948
1949 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001950 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001951 endclass
1952
1953 class Child extends Base
1954 endclass
1955
1956 def F()
1957 var o = Child.new()
1958 o.v1 = []
1959 enddef
1960 F()
1961 END
1962
Ernie Rael03042a22023-11-11 08:53:32 +01001963 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001964 # of the class hierarchy.
1965 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1966 lines =<< trim END
1967 vim9script
1968
1969 class Base0
1970 endclass
1971
1972 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01001973 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001974 endclass
1975
1976 class Child extends Base
1977 endclass
1978
1979 def F()
1980 var o = Child.new()
1981 var x = o._v1
1982 enddef
1983 F()
1984 END
Ernie Rael03042a22023-11-11 08:53:32 +01001985 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001986
Ernie Rael03042a22023-11-11 08:53:32 +01001987 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02001988 # of the class hierarchy.
1989 lines =<< trim END
1990 vim9script
1991
1992 class Base0
1993 endclass
1994
1995 class Base extends Base0
1996 endclass
1997
1998 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001999 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002000 endclass
2001
2002 def F()
2003 var o = Child.new()
2004 var x = o._v1
2005 enddef
2006 F()
2007 END
Ernie Rael03042a22023-11-11 08:53:32 +01002008 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002009enddef
2010
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002011func Test_class_garbagecollect()
2012 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002013 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002014
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002015 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002016 var p = [2, 3]
2017 static var pl = ['a', 'b']
2018 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002019 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002020
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002021 echo Point.pl Point.pd
2022 call test_garbagecollect_now()
2023 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002024 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002025 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002026
2027 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002028 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002029
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002030 interface View
2031 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002032
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002033 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01002034 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002035 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002036
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002037 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01002038 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002039
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002040 def new()
2041 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01002042 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002043 enddef
2044 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002045
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002046 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002047
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002048 # overwrite "view", will be garbage-collected next
2049 view = MyView.new()
2050 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002051 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002052 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002053endfunc
2054
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002055" Test interface garbage collection
2056func Test_interface_garbagecollect()
2057 let lines =<< trim END
2058 vim9script
2059
2060 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002061 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002062
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002063 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002064 endinterface
2065
2066 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002067 static var ro_class_var: number = 10
2068 public static var rw_class_var: number = 20
2069 static var _priv_class_var: number = 30
2070 var ro_obj_var: number = 40
2071 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002072
2073 static def _ClassBar(): number
2074 return _priv_class_var
2075 enddef
2076
2077 static def ClassFoo(): number
2078 return ro_class_var + rw_class_var + A._ClassBar()
2079 enddef
2080
2081 def _ObjBar(): number
2082 return this._priv_obj_var
2083 enddef
2084
2085 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002086 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002087 enddef
2088 endclass
2089
2090 assert_equal(60, A.ClassFoo())
2091 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002092 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002093 test_garbagecollect_now()
2094 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002095 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002096 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002097 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002098endfunc
2099
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002100def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002101 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002102 vim9script
2103 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002104 var value = 0
2105 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002106
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002107 def new(v: number)
2108 this.value = v
2109 ++objects
2110 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002111
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002112 static def GetCount(): number
2113 return objects
2114 enddef
2115 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002116
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002117 assert_equal(0, Value.GetCount())
2118 var v1 = Value.new(2)
2119 assert_equal(1, Value.GetCount())
2120 var v2 = Value.new(7)
2121 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002122 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002123 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002124
2125 # Test for cleaning up after a class definition failure when using class
2126 # functions.
2127 lines =<< trim END
2128 vim9script
2129 class A
2130 static def Foo()
2131 enddef
2132 aaa
2133 endclass
2134 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002135 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002136
2137 # Test for calling a class method from another class method without the class
2138 # name prefix.
2139 lines =<< trim END
2140 vim9script
2141 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002142 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002143 static def Foo(n: number)
2144 myList->add(n)
2145 enddef
2146 static def Bar()
2147 Foo(2)
2148 enddef
2149 def Baz()
2150 Foo(3)
2151 enddef
2152 endclass
2153 A.Bar()
2154 var a = A.new()
2155 a.Baz()
2156 assert_equal([1, 2, 3], A.myList)
2157 END
2158 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002159enddef
2160
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002161def Test_class_defcompile()
2162 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002163 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002164
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002165 class C
2166 def Fo(i: number): string
2167 return i
2168 enddef
2169 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002170
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002171 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002172 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002173 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002174
2175 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002176 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002177
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002178 class C
2179 static def Fc(): number
2180 return 'x'
2181 enddef
2182 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002183
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002184 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002185 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002186 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002187
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002188 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002189 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002190
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002191 class C
2192 static def new()
2193 enddef
2194 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002195
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002196 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002197 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002198 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002199
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002200 # Trying to compile a function using a non-existing class variable
2201 lines =<< trim END
2202 vim9script
2203 defcompile x.Foo()
2204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002205 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002206
2207 # Trying to compile a function using a variable which is not a class
2208 lines =<< trim END
2209 vim9script
2210 var x: number
2211 defcompile x.Foo()
2212 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002213 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002214
2215 # Trying to compile a function without specifying the name
2216 lines =<< trim END
2217 vim9script
2218 class A
2219 endclass
2220 defcompile A.
2221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002222 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002223
2224 # Trying to compile a non-existing class object member function
2225 lines =<< trim END
2226 vim9script
2227 class A
2228 endclass
2229 var a = A.new()
2230 defcompile a.Foo()
2231 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002232 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002233enddef
2234
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002235def Test_class_object_to_string()
2236 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002237 vim9script
2238 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002239 var lnum = 1
2240 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002241 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002242
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002243 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002244
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002245 var pos = TextPosition.new()
2246 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002247 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002248 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002249enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002250
Bram Moolenaar554d0312023-01-05 19:59:18 +00002251def Test_interface_basics()
2252 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002253 vim9script
2254 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002255 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002256 def GetCount(): number
2257 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002258 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002259 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002260
2261 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002262 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002263 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002264 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002265 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002266 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002267
2268 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002269 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002270
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002271 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002272 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002273 def Method(value: number)
2274 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002275 END
h-east61378a12023-04-18 19:07:29 +01002276 # The argument name and the object member name are the same, but this is not a
2277 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002278 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002279
2280 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002281 vim9script
2282 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002283 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002284 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002285 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002286 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002287
2288 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002289 vim9script
2290 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002291 var value: string
2292 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002293 def GetCount(): number
2294 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002295 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002296 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002297
2298 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002299 vim9script
2300 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002301 var value: string
2302 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002303 def GetCount(): number
2304 return 5
2305 enddef
2306 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002307 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002308 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002309
Yegappan Lakshmananac773182024-04-27 11:36:12 +02002310 # Additional commands after "interface name"
2311 lines =<< trim END
2312 vim9script
2313 interface Something | var x = 10 | var y = 20
2314 endinterface
2315 END
2316 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
2317
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002318 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002319 vim9script
2320 export interface EnterExit
2321 def Enter(): void
2322 def Exit(): void
2323 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002324 END
2325 writefile(lines, 'XdefIntf.vim', 'D')
2326
2327 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002328 vim9script
2329 import './XdefIntf.vim' as defIntf
2330 export def With(ee: defIntf.EnterExit, F: func)
2331 ee.Enter()
2332 try
2333 F()
2334 finally
2335 ee.Exit()
2336 endtry
2337 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002338 END
2339 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002340
2341 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002342 vim9script
2343 export abstract class EnterExit
2344 def Enter(): void
2345 enddef
2346 def Exit(): void
2347 enddef
2348 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002349 END
2350 writefile(imported, 'XdefIntf2.vim', 'D')
2351
2352 lines[1] = " import './XdefIntf2.vim' as defIntf"
2353 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002354enddef
2355
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002356" Test for using string() with an interface
2357def Test_interface_to_string()
2358 var lines =<< trim END
2359 vim9script
2360 interface Intf
2361 def Method(nr: number)
2362 endinterface
2363 assert_equal("interface Intf", string(Intf))
2364 END
2365 v9.CheckSourceSuccess(lines)
2366enddef
2367
Bram Moolenaar94674f22023-01-06 18:42:20 +00002368def Test_class_implements_interface()
2369 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002370 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002371
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002372 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002373 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002374 def Method(nr: number)
2375 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002376
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002377 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002378 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002379 def Method(nr: number)
2380 echo nr
2381 enddef
2382 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002383
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002384 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002385 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002386 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002387
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002388 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002389 var member = 'abc'
2390 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002391 def Method(nr: number)
2392 echo nr
2393 enddef
2394 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002395 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002396 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002397
2398 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002399 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002400
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002401 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002402 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002403 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002404
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002405 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002406 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002407 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002408 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002409 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002410
2411 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002412 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002413
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002414 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002415 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002416 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002417
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002418 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002419 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002420 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002421 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002422 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002423
2424 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002425 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002426
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002427 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002428 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002429 def Method(nr: number)
2430 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002431
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002432 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002433 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002434 def Method(nr: number)
2435 echo nr
2436 enddef
2437 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002438 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002439 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002440
2441 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002442 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002443
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002444 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002445 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002446 def Methods(nr: number)
2447 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002448
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002449 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002450 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002451 def Method(nr: number)
2452 echo nr
2453 enddef
2454 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002455 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002456 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002457
2458 # Check different order of members in class and interface works.
2459 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002460 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002461
2462 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002463 var label: string
2464 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002465 endinterface
2466
2467 # order of members is opposite of interface
2468 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002469 public var lnum: number = 5
2470 var errpos: number = 42
2471 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002472 endclass
2473
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002474 def Test()
2475 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002476
2477 assert_equal('label', result.label)
2478 assert_equal(42, result.errpos)
2479 enddef
2480
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002481 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002482 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002483 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002484
2485 # Interface name after "extends" doesn't end in a space or NUL character
2486 lines =<< trim END
2487 vim9script
2488 interface A
2489 endinterface
2490 class B extends A"
2491 endclass
2492 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002493 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002494
2495 # Trailing characters after a class name
2496 lines =<< trim END
2497 vim9script
2498 class A bbb
2499 endclass
2500 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002501 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002502
2503 # using "implements" with a non-existing class
2504 lines =<< trim END
2505 vim9script
2506 class A implements B
2507 endclass
2508 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002509 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002510
2511 # using "implements" with a regular class
2512 lines =<< trim END
2513 vim9script
2514 class A
2515 endclass
2516 class B implements A
2517 endclass
2518 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002519 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002520
2521 # using "implements" with a variable
2522 lines =<< trim END
2523 vim9script
2524 var T: number = 10
2525 class A implements T
2526 endclass
2527 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002528 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002529
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002530 # implements should be followed by a white space
2531 lines =<< trim END
2532 vim9script
2533 interface A
2534 endinterface
2535 class B implements A;
2536 endclass
2537 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002538 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002539
LemonBoyc5d27442023-08-19 13:02:35 +02002540 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002541 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002542
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002543 interface One
2544 def IsEven(nr: number): bool
2545 endinterface
2546 class Two implements One
2547 def IsEven(nr: number): string
2548 enddef
2549 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002550 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002551 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002552
2553 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002554 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002555
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002556 interface One
2557 def IsEven(nr: number): bool
2558 endinterface
2559 class Two implements One
2560 def IsEven(nr: bool): bool
2561 enddef
2562 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002563 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002564 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002565
2566 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002567 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002568
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002569 interface One
2570 def IsEven(nr: number): bool
2571 endinterface
2572 class Two implements One
2573 def IsEven(nr: number, ...extra: list<number>): bool
2574 enddef
2575 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002576 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002577 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 +02002578
2579 # access superclass interface members from subclass, mix variable order
2580 lines =<< trim END
2581 vim9script
2582
2583 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002584 var mvar1: number
2585 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002586 endinterface
2587
2588 # NOTE: the order is swapped
2589 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002590 var mvar2: number
2591 var mvar1: number
2592 public static var svar2: number
2593 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002594 def new()
2595 svar1 = 11
2596 svar2 = 12
2597 this.mvar1 = 111
2598 this.mvar2 = 112
2599 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002600 endclass
2601
2602 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002603 def new()
2604 this.mvar1 = 121
2605 this.mvar2 = 122
2606 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002607 endclass
2608
2609 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002610 def new()
2611 this.mvar1 = 131
2612 this.mvar2 = 132
2613 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002614 endclass
2615
Ernie Raelcf138d42023-09-06 20:45:03 +02002616 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002617 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002618 enddef
2619
2620 var oa = A.new()
2621 var ob = B.new()
2622 var oc = C.new()
2623
Ernie Raelcf138d42023-09-06 20:45:03 +02002624 assert_equal([111, 112], F2(oa))
2625 assert_equal([121, 122], F2(ob))
2626 assert_equal([131, 132], F2(oc))
2627 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002628 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002629
2630 # Access superclass interface members from subclass, mix variable order.
2631 # Two interfaces, one on A, one on B; each has both kinds of variables
2632 lines =<< trim END
2633 vim9script
2634
2635 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002636 var mvar1: number
2637 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002638 endinterface
2639
2640 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002641 var mvar3: number
2642 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002643 endinterface
2644
2645 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002646 public static var svar1: number
2647 public static var svar2: number
2648 var mvar1: number
2649 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002650 def new()
2651 svar1 = 11
2652 svar2 = 12
2653 this.mvar1 = 111
2654 this.mvar2 = 112
2655 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002656 endclass
2657
2658 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002659 static var svar3: number
2660 static var svar4: number
2661 var mvar3: number
2662 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002663 def new()
2664 svar3 = 23
2665 svar4 = 24
2666 this.mvar1 = 121
2667 this.mvar2 = 122
2668 this.mvar3 = 123
2669 this.mvar4 = 124
2670 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002671 endclass
2672
2673 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002674 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002675 def new()
2676 svar5 = 1001
2677 this.mvar1 = 131
2678 this.mvar2 = 132
2679 this.mvar3 = 133
2680 this.mvar4 = 134
2681 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002682 endclass
2683
Ernie Raelcf138d42023-09-06 20:45:03 +02002684 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002685 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002686 enddef
2687
Ernie Raelcf138d42023-09-06 20:45:03 +02002688 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002689 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002690 enddef
2691
Ernie Raelcf138d42023-09-06 20:45:03 +02002692 var oa = A.new()
2693 var ob = B.new()
2694 var oc = C.new()
2695
Ernie Raelcf138d42023-09-06 20:45:03 +02002696 assert_equal([[111, 112]], [F2(oa)])
2697 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2698 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002699 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002700 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002701
2702 # Using two interface names without a space after the ","
2703 lines =<< trim END
2704 vim9script
2705 interface A
2706 endinterface
2707 interface B
2708 endinterface
2709 class C implements A,B
2710 endclass
2711 END
2712 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2713
2714 # No interface name after a comma
2715 lines =<< trim END
2716 vim9script
2717 interface A
2718 endinterface
2719 class B implements A,
2720 endclass
2721 END
2722 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2723
2724 # No interface name after implements
2725 lines =<< trim END
2726 vim9script
2727 class A implements
2728 endclass
2729 END
2730 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002731enddef
2732
Bram Moolenaard0200c82023-01-28 15:19:40 +00002733def Test_call_interface_method()
2734 var lines =<< trim END
2735 vim9script
2736 interface Base
2737 def Enter(): void
2738 endinterface
2739
2740 class Child implements Base
2741 def Enter(): void
2742 g:result ..= 'child'
2743 enddef
2744 endclass
2745
2746 def F(obj: Base)
2747 obj.Enter()
2748 enddef
2749
2750 g:result = ''
2751 F(Child.new())
2752 assert_equal('child', g:result)
2753 unlet g:result
2754 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002755 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002756
2757 lines =<< trim END
2758 vim9script
2759 class Base
2760 def Enter(): void
2761 g:result ..= 'base'
2762 enddef
2763 endclass
2764
2765 class Child extends Base
2766 def Enter(): void
2767 g:result ..= 'child'
2768 enddef
2769 endclass
2770
2771 def F(obj: Base)
2772 obj.Enter()
2773 enddef
2774
2775 g:result = ''
2776 F(Child.new())
2777 assert_equal('child', g:result)
2778 unlet g:result
2779 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002780 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002781
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002782 # method of interface returns a value
2783 lines =<< trim END
2784 vim9script
2785 interface Base
2786 def Enter(): string
2787 endinterface
2788
2789 class Child implements Base
2790 def Enter(): string
2791 g:result ..= 'child'
2792 return "/resource"
2793 enddef
2794 endclass
2795
2796 def F(obj: Base)
2797 var r = obj.Enter()
2798 g:result ..= r
2799 enddef
2800
2801 g:result = ''
2802 F(Child.new())
2803 assert_equal('child/resource', g:result)
2804 unlet g:result
2805 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002806 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002807
2808 lines =<< trim END
2809 vim9script
2810 class Base
2811 def Enter(): string
2812 return null_string
2813 enddef
2814 endclass
2815
2816 class Child extends Base
2817 def Enter(): string
2818 g:result ..= 'child'
2819 return "/resource"
2820 enddef
2821 endclass
2822
2823 def F(obj: Base)
2824 var r = obj.Enter()
2825 g:result ..= r
2826 enddef
2827
2828 g:result = ''
2829 F(Child.new())
2830 assert_equal('child/resource', g:result)
2831 unlet g:result
2832 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002833 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002834
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002835 # No class that implements the interface.
2836 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002837 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002838
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002839 interface IWithEE
2840 def Enter(): any
2841 def Exit(): void
2842 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002843
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002844 def With1(ee: IWithEE, F: func)
2845 var r = ee.Enter()
2846 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002847
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002848 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002849 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002850 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002851enddef
2852
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002853def Test_class_used_as_type()
2854 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002855 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002856
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002857 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002858 var x = 0
2859 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002860 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002861
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002862 var p: Point
2863 p = Point.new(2, 33)
2864 assert_equal(2, p.x)
2865 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002866 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002867 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002868
2869 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002870 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002871
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002872 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002873 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002874 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002875
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002876 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002877 var x = 0
2878 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002879 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002880
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002881 var p: Point
2882 p = Point.new(2, 33)
2883 var hx = p
2884 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002885 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002886 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002887
2888 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002889 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002890
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002891 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002892 var x = 0
2893 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002894 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002895
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002896 var p: Point
2897 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002898 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002899 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002900enddef
2901
Bram Moolenaar83677162023-01-08 19:54:10 +00002902def Test_class_extends()
2903 var 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 def GetOne(): number
2908 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002909 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002910 endclass
2911 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002912 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002913 def GetTotal(): number
2914 return this.one + this.two
2915 enddef
2916 endclass
2917 var o = Child.new()
2918 assert_equal(1, o.one)
2919 assert_equal(2, o.two)
2920 assert_equal(1, o.GetOne())
2921 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002922 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002923 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002924
2925 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002926 vim9script
2927 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002928 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002929 endclass
2930 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002931 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002932 endclass
2933 var o = Child.new(3, 44)
2934 assert_equal(3, o.one)
2935 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002936 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002937 v9.CheckSourceSuccess(lines)
2938
2939 lines =<< trim END
2940 vim9script
2941 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002942 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002943 endclass
2944 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002945 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002946 endclass
2947 END
2948 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2949
2950 lines =<< trim END
2951 vim9script
2952 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01002953 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002954 endclass
2955 END
2956 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2957
2958 lines =<< trim END
2959 vim9script
2960 var SomeVar = 99
2961 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01002962 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002963 endclass
2964 END
2965 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2966
2967 lines =<< trim END
2968 vim9script
2969 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002970 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002971 def ToString(): string
2972 return this.name
2973 enddef
2974 endclass
2975
2976 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002977 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002978 def ToString(): string
2979 return super.ToString() .. ': ' .. this.age
2980 enddef
2981 endclass
2982
2983 var o = Child.new('John', 42)
2984 assert_equal('John: 42', o.ToString())
2985 END
2986 v9.CheckSourceSuccess(lines)
2987
2988 lines =<< trim END
2989 vim9script
2990 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002991 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002992 def ToString(): number
2993 return this.age
2994 enddef
2995 def ToString(): string
2996 return this.age
2997 enddef
2998 endclass
2999 END
3000 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
3001
3002 lines =<< trim END
3003 vim9script
3004 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003005 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003006 def ToString(): string
3007 return super .ToString() .. ': ' .. this.age
3008 enddef
3009 endclass
3010 var o = Child.new(42)
3011 echo o.ToString()
3012 END
3013 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
3014
3015 lines =<< trim END
3016 vim9script
3017 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003018 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003019 def ToString(): string
3020 return this.name
3021 enddef
3022 endclass
3023
3024 var age = 42
3025 def ToString(): string
3026 return super.ToString() .. ': ' .. age
3027 enddef
3028 echo ToString()
3029 END
3030 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
3031
3032 lines =<< trim END
3033 vim9script
3034 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003035 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003036 def ToString(): string
3037 return super.ToString() .. ': ' .. this.age
3038 enddef
3039 endclass
3040 var o = Child.new(42)
3041 echo o.ToString()
3042 END
3043 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
3044
3045 lines =<< trim END
3046 vim9script
3047 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003048 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003049 static def ToString(): string
3050 return 'Base class'
3051 enddef
3052 endclass
3053
3054 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003055 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003056 def ToString(): string
3057 return Base.ToString() .. ': ' .. this.age
3058 enddef
3059 endclass
3060
3061 var o = Child.new('John', 42)
3062 assert_equal('Base class: 42', o.ToString())
3063 END
3064 v9.CheckSourceSuccess(lines)
3065
3066 lines =<< trim END
3067 vim9script
3068 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003069 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003070 def new(init: number)
3071 this.value = number + 1
3072 enddef
3073 endclass
3074 class Child extends Base
3075 def new()
3076 this.new(3)
3077 enddef
3078 endclass
3079 var c = Child.new()
3080 END
3081 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003082
3083 # base class with more than one object member
3084 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003085 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003086
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003087 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003088 var success: bool
3089 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003090 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003091
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003092 class Success extends Result
3093 def new(this.value = v:none)
3094 this.success = true
3095 enddef
3096 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003097
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003098 var v = Success.new('asdf')
3099 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003100 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003101 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003102
3103 # class name after "extends" doesn't end in a space or NUL character
3104 lines =<< trim END
3105 vim9script
3106 class A
3107 endclass
3108 class B extends A"
3109 endclass
3110 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003111 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003112enddef
3113
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003114def Test_using_base_class()
3115 var lines =<< trim END
3116 vim9script
3117
3118 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003119 def Enter(): any
3120 return null
3121 enddef
3122 def Exit(resource: any): void
3123 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003124 endclass
3125
3126 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003127 def Enter(): any
3128 return 42
3129 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003130
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003131 def Exit(resource: number): void
3132 g:result ..= '/exit'
3133 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003134 endclass
3135
3136 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003137 var r = ee.Enter()
3138 try
3139 g:result ..= r
3140 finally
3141 g:result ..= '/finally'
3142 ee.Exit(r)
3143 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003144 enddef
3145
3146 g:result = ''
3147 With(ChildEE.new())
3148 assert_equal('42/finally/exit', g:result)
3149 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003150 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003151 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003152
3153 # Using super, Child invokes Base method which has optional arg. #12471
3154 lines =<< trim END
3155 vim9script
3156
3157 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003158 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003159 def Method(arg = 0)
3160 this.success = true
3161 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003162 endclass
3163
3164 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003165 def new()
3166 super.Method()
3167 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003168 endclass
3169
3170 var obj = Child.new()
3171 assert_equal(true, obj.success)
3172 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003173 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003174enddef
3175
Bram Moolenaara86655a2023-01-12 17:06:27 +00003176def Test_class_import()
3177 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003178 vim9script
3179 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003180 var kind: string
3181 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003182 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003183 END
3184 writefile(lines, 'Xanimal.vim', 'D')
3185
3186 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003187 vim9script
3188 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003189
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003190 var a: animal.Animal
3191 a = animal.Animal.new('fish', 'Eric')
3192 assert_equal('fish', a.kind)
3193 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003194
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003195 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3196 assert_equal('cat', b.kind)
3197 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003198 END
3199 v9.CheckScriptSuccess(lines)
3200enddef
3201
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003202" Test for importing a class into a legacy script and calling the class method
3203def Test_class_method_from_legacy_script()
3204 var lines =<< trim END
3205 vim9script
3206 export class A
3207 static var name: string = 'a'
3208 static def SetName(n: string)
3209 name = n
3210 enddef
3211 endclass
3212 END
3213 writefile(lines, 'Xvim9export.vim', 'D')
3214
3215 lines =<< trim END
3216 import './Xvim9export.vim' as vim9
3217
3218 call s:vim9.A.SetName('b')
3219 call assert_equal('b', s:vim9.A.name)
3220 END
3221 v9.CheckScriptSuccess(lines)
3222enddef
3223
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003224" Test for implementing an imported interface
3225def Test_implement_imported_interface()
3226 var lines =<< trim END
3227 vim9script
3228 export interface Imp_Intf1
3229 def Fn1(): number
3230 endinterface
3231 export interface Imp_Intf2
3232 def Fn2(): number
3233 endinterface
3234 END
3235 writefile(lines, 'Ximportinterface.vim', 'D')
3236
3237 lines =<< trim END
3238 vim9script
3239 import './Ximportinterface.vim' as Xintf
3240
3241 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3242 def Fn1(): number
3243 return 10
3244 enddef
3245 def Fn2(): number
3246 return 20
3247 enddef
3248 endclass
3249 var a = A.new()
3250 assert_equal(10, a.Fn1())
3251 assert_equal(20, a.Fn2())
3252 END
3253 v9.CheckScriptSuccess(lines)
3254enddef
3255
3256" Test for extending an imported class
3257def Test_extend_imported_class()
3258 var lines =<< trim END
3259 vim9script
3260 export class Imp_C1
3261 def Fn1(): number
3262 return 5
3263 enddef
3264 endclass
3265 END
3266 writefile(lines, 'Xextendimportclass.vim', 'D')
3267
3268 lines =<< trim END
3269 vim9script
3270 import './Xextendimportclass.vim' as XClass
3271
3272 class A extends XClass.Imp_C1
3273 endclass
3274 var a = A.new()
3275 assert_equal(5, a.Fn1())
3276 END
3277 v9.CheckScriptSuccess(lines)
3278enddef
3279
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003280def Test_abstract_class()
3281 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003282 vim9script
3283 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003284 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003285 endclass
3286 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003287 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003288 endclass
3289 var p: Base = Person.new('Peter', 42)
3290 assert_equal('Peter', p.name)
3291 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003292 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003293 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003294
3295 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003296 vim9script
3297 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003298 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003299 endclass
3300 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003301 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003302 endclass
3303 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003304 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003305 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003306
3307 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003308 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003309 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003310 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003311 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003312 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003313
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003314 # Additional commands after "abstract class"
3315 lines =<< trim END
3316 vim9script
3317 abstract class Something | var x = []
3318 endclass
3319 END
3320 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3321
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003322 # Abstract class cannot have a "new" function
3323 lines =<< trim END
3324 vim9script
3325 abstract class Base
3326 def new()
3327 enddef
3328 endclass
3329 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003330 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003331
3332 # extending an abstract class with class methods and variables
3333 lines =<< trim END
3334 vim9script
3335 abstract class A
3336 static var s: string = 'vim'
3337 static def Fn(): list<number>
3338 return [10]
3339 enddef
3340 endclass
3341 class B extends A
3342 endclass
3343 var b = B.new()
3344 assert_equal('vim', A.s)
3345 assert_equal([10], A.Fn())
3346 END
3347 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003348enddef
3349
Bram Moolenaar486fc252023-01-18 14:51:07 +00003350def Test_closure_in_class()
3351 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003352 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003353
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003354 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003355 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003356
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003357 def new()
3358 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3359 enddef
3360 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003361
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003362 Foo.new()
3363 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003364 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003365 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003366enddef
3367
Ernie Rael9ed53752023-12-11 17:40:46 +01003368def Test_construct_object_from_legacy()
3369 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003370 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003371 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003372
Ernie Rael9ed53752023-12-11 17:40:46 +01003373 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003374
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003375 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003376 def new(arg: string)
3377 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003378 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003379 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003380
Ernie Rael9ed53752023-12-11 17:40:46 +01003381 export def CreateA(...args: list<any>): A
3382 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003383 enddef
3384
Ernie Rael9ed53752023-12-11 17:40:46 +01003385 g:P = CreateA
3386 legacy call g:P('some_arg')
3387 assert_equal(true, newCalled)
3388 unlet g:P
3389 END
3390 v9.CheckSourceSuccess(lines)
3391
3392 lines =<< trim END
3393 vim9script
3394
3395 var newCalled = false
3396
3397 class A
3398 static def CreateA(options = {}): any
3399 return A.new()
3400 enddef
3401 def new()
3402 newCalled = true
3403 enddef
3404 endclass
3405
3406 g:P = A.CreateA
3407 legacy call g:P()
3408 assert_equal(true, newCalled)
3409 unlet g:P
3410 END
3411 v9.CheckSourceSuccess(lines)
3412
3413 # This also tests invoking "new()" with "call"
3414 lines =<< trim END
3415 vim9script
3416
3417 var createdObject: any
3418
3419 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003420 var val1: number
3421 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003422 static def CreateA(...args: list<any>): any
3423 createdObject = call(A.new, args)
3424 return createdObject
3425 enddef
3426 endclass
3427
3428 g:P = A.CreateA
3429 legacy call g:P(3, 5)
3430 assert_equal(3, createdObject.val1)
3431 assert_equal(5, createdObject.val2)
3432 legacy call g:P()
3433 assert_equal(0, createdObject.val1)
3434 assert_equal(0, createdObject.val2)
3435 legacy call g:P(7)
3436 assert_equal(7, createdObject.val1)
3437 assert_equal(0, createdObject.val2)
3438 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003439 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003440 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003441enddef
3442
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003443def Test_defer_with_object()
3444 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003445 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003446
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003447 class CWithEE
3448 def Enter()
3449 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003450 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003451 def Exit()
3452 g:result ..= "exited"
3453 enddef
3454 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003455
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003456 def With(ee: CWithEE, F: func)
3457 ee.Enter()
3458 defer ee.Exit()
3459 F()
3460 enddef
3461
3462 g:result = ''
3463 var obj = CWithEE.new()
3464 obj->With(() => {
3465 g:result ..= "called/"
3466 })
3467 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003468 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003469 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003470 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003471
3472 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003473 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003474
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003475 class BaseWithEE
3476 def Enter()
3477 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003478 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003479 def Exit()
3480 g:result ..= "exited-base"
3481 enddef
3482 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003483
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003484 class CWithEE extends BaseWithEE
3485 def Enter()
3486 g:result ..= "entered-child/"
3487 enddef
3488 def Exit()
3489 g:result ..= "exited-child"
3490 enddef
3491 endclass
3492
3493 def With(ee: BaseWithEE, F: func)
3494 ee.Enter()
3495 defer ee.Exit()
3496 F()
3497 enddef
3498
3499 g:result = ''
3500 var obj = CWithEE.new()
3501 obj->With(() => {
3502 g:result ..= "called/"
3503 })
3504 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003505 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003506 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003507 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003508enddef
3509
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003510" The following test used to crash Vim (Github issue #12676)
3511def Test_extends_method_crashes_vim()
3512 var lines =<< trim END
3513 vim9script
3514
3515 class Observer
3516 endclass
3517
3518 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003519 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003520
3521 def Set(v: any)
3522 if v != this.value
3523 this.value = v
3524 endif
3525 enddef
3526
3527 def Register(observer: Observer)
3528 enddef
3529 endclass
3530
3531 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003532 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003533 endclass
3534
3535 def Observe(obj: Property, who: Observer)
3536 obj.Register(who)
3537 enddef
3538
3539 var p = Bool.new(false)
3540 var myObserver = Observer.new()
3541
3542 Observe(p, myObserver)
3543
3544 p.Set(true)
3545 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003546 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003547enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003548
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003549" Test for calling a method in a class that is extended
3550def Test_call_method_in_extended_class()
3551 var lines =<< trim END
3552 vim9script
3553
3554 var prop_init_called = false
3555 var prop_register_called = false
3556
3557 class Property
3558 def Init()
3559 prop_init_called = true
3560 enddef
3561
3562 def Register()
3563 prop_register_called = true
3564 enddef
3565 endclass
3566
3567 class Bool extends Property
3568 endclass
3569
3570 def Observe(obj: Property)
3571 obj.Register()
3572 enddef
3573
3574 var p = Property.new()
3575 Observe(p)
3576
3577 p.Init()
3578 assert_true(prop_init_called)
3579 assert_true(prop_register_called)
3580 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003581 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003582enddef
3583
LemonBoyafe04662023-08-23 21:08:11 +02003584def Test_instanceof()
3585 var lines =<< trim END
3586 vim9script
3587
3588 class Base1
3589 endclass
3590
3591 class Base2 extends Base1
3592 endclass
3593
3594 interface Intf1
3595 endinterface
3596
3597 class Mix1 implements Intf1
3598 endclass
3599
3600 class Base3 extends Mix1
3601 endclass
3602
Ernie Rael2025af12023-12-12 16:58:00 +01003603 type AliasBase1 = Base1
3604 type AliasBase2 = Base2
3605 type AliasIntf1 = Intf1
3606 type AliasMix1 = Mix1
3607
LemonBoyafe04662023-08-23 21:08:11 +02003608 var b1 = Base1.new()
3609 var b2 = Base2.new()
3610 var b3 = Base3.new()
3611
3612 assert_true(instanceof(b1, Base1))
3613 assert_true(instanceof(b2, Base1))
3614 assert_false(instanceof(b1, Base2))
3615 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003616 assert_true(instanceof(b3, Base1, Base2, Intf1))
3617
3618 assert_true(instanceof(b1, AliasBase1))
3619 assert_true(instanceof(b2, AliasBase1))
3620 assert_false(instanceof(b1, AliasBase2))
3621 assert_true(instanceof(b3, AliasMix1))
3622 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003623
3624 def Foo()
3625 var a1 = Base1.new()
3626 var a2 = Base2.new()
3627 var a3 = Base3.new()
3628
3629 assert_true(instanceof(a1, Base1))
3630 assert_true(instanceof(a2, Base1))
3631 assert_false(instanceof(a1, Base2))
3632 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003633 assert_true(instanceof(a3, Base1, Base2, Intf1))
3634
3635 assert_true(instanceof(a1, AliasBase1))
3636 assert_true(instanceof(a2, AliasBase1))
3637 assert_false(instanceof(a1, AliasBase2))
3638 assert_true(instanceof(a3, AliasMix1))
3639 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003640 enddef
3641 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003642
3643 var o_null: Base1
3644 assert_false(instanceof(o_null, Base1))
3645
LemonBoyafe04662023-08-23 21:08:11 +02003646 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003647 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003648
3649 lines =<< trim END
3650 vim9script
3651
3652 class Base1
3653 endclass
3654 instanceof(Base1.new())
3655 END
3656 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3657
3658 lines =<< trim END
3659 vim9script
3660
3661 class Base1
3662 endclass
3663 def F()
3664 instanceof(Base1.new())
3665 enddef
3666 F()
3667 END
3668 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3669
3670 lines =<< trim END
3671 vim9script
3672
3673 class Base1
3674 endclass
3675
3676 class Base2
3677 endclass
3678
3679 var o = Base2.new()
3680 instanceof(o, Base1, Base2, 3)
3681 END
3682 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3683
3684 lines =<< trim END
3685 vim9script
3686
3687 class Base1
3688 endclass
3689
3690 class Base2
3691 endclass
3692
3693 def F()
3694 var o = Base2.new()
3695 instanceof(o, Base1, Base2, 3)
3696 enddef
3697 F()
3698 END
3699 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003700enddef
3701
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003702" Test for calling a method in the parent class that is extended partially.
3703" This used to fail with the 'E118: Too many arguments for function: Text' error
3704" message (Github issue #12524).
3705def Test_call_method_in_parent_class()
3706 var lines =<< trim END
3707 vim9script
3708
3709 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003710 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003711
3712 def SetY(lnum: number)
3713 this._lnum = lnum
3714 enddef
3715
3716 def Text(): string
3717 return ''
3718 enddef
3719 endclass
3720
3721 class Foo extends Widget
3722 def Text(): string
3723 return '<Foo>'
3724 enddef
3725 endclass
3726
3727 def Stack(w1: Widget, w2: Widget): list<Widget>
3728 w1.SetY(1)
3729 w2.SetY(2)
3730 return [w1, w2]
3731 enddef
3732
3733 var foo1 = Foo.new()
3734 var foo2 = Foo.new()
3735 var l = Stack(foo1, foo2)
3736 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003737 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003738enddef
3739
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003740" Test for calling methods from three levels of classes
3741def Test_multi_level_method_call()
3742 var lines =<< trim END
3743 vim9script
3744
3745 var A_func1: number = 0
3746 var A_func2: number = 0
3747 var A_func3: number = 0
3748 var B_func2: number = 0
3749 var B_func3: number = 0
3750 var C_func3: number = 0
3751
3752 class A
3753 def Func1()
3754 A_func1 += 1
3755 enddef
3756
3757 def Func2()
3758 A_func2 += 1
3759 enddef
3760
3761 def Func3()
3762 A_func3 += 1
3763 enddef
3764 endclass
3765
3766 class B extends A
3767 def Func2()
3768 B_func2 += 1
3769 enddef
3770
3771 def Func3()
3772 B_func3 += 1
3773 enddef
3774 endclass
3775
3776 class C extends B
3777 def Func3()
3778 C_func3 += 1
3779 enddef
3780 endclass
3781
3782 def A_CallFuncs(a: A)
3783 a.Func1()
3784 a.Func2()
3785 a.Func3()
3786 enddef
3787
3788 def B_CallFuncs(b: B)
3789 b.Func1()
3790 b.Func2()
3791 b.Func3()
3792 enddef
3793
3794 def C_CallFuncs(c: C)
3795 c.Func1()
3796 c.Func2()
3797 c.Func3()
3798 enddef
3799
3800 var cobj = C.new()
3801 A_CallFuncs(cobj)
3802 B_CallFuncs(cobj)
3803 C_CallFuncs(cobj)
3804 assert_equal(3, A_func1)
3805 assert_equal(0, A_func2)
3806 assert_equal(0, A_func3)
3807 assert_equal(3, B_func2)
3808 assert_equal(0, B_func3)
3809 assert_equal(3, C_func3)
3810 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003811 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003812enddef
3813
3814" Test for using members from three levels of classes
3815def Test_multi_level_member_access()
3816 var lines =<< trim END
3817 vim9script
3818
3819 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003820 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003821 endclass
3822
3823 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003824 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003825 endclass
3826
3827 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003828 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003829 endclass
3830
3831 def A_members(a: A)
3832 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003833 enddef
3834
3835 def B_members(b: B)
3836 b.val1 += 1
3837 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003838 enddef
3839
3840 def C_members(c: C)
3841 c.val1 += 1
3842 c.val2 += 1
3843 c.val3 += 1
3844 enddef
3845
3846 var cobj = C.new()
3847 A_members(cobj)
3848 B_members(cobj)
3849 C_members(cobj)
3850 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003851 assert_equal(2, cobj.val2)
3852 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003853 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003854 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003855enddef
3856
LemonBoy0ffc17a2023-08-20 18:09:11 +02003857" Test expansion of <stack> with class methods.
3858def Test_stack_expansion_with_methods()
3859 var lines =<< trim END
3860 vim9script
3861
3862 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003863 def M1()
3864 F0()
3865 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003866 endclass
3867
3868 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02003869 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02003870 enddef
3871
3872 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003873 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003874 enddef
3875
3876 F()
3877 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003878 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003879enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003880
3881" Test the return type of the new() constructor
3882def Test_new_return_type()
3883 # new() uses the default return type and there is no return statement
3884 var lines =<< trim END
3885 vim9script
3886
3887 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003888 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003889
3890 def new(this._bufnr)
3891 if !bufexists(this._bufnr)
3892 this._bufnr = -1
3893 endif
3894 enddef
3895 endclass
3896
3897 var c = C.new(12345)
3898 assert_equal('object<C>', typename(c))
3899
3900 var v1: C
3901 v1 = C.new(12345)
3902 assert_equal('object<C>', typename(v1))
3903
3904 def F()
3905 var v2: C
3906 v2 = C.new(12345)
3907 assert_equal('object<C>', typename(v2))
3908 enddef
3909 F()
3910 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003911 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003912
3913 # new() uses the default return type and an empty 'return' statement
3914 lines =<< trim END
3915 vim9script
3916
3917 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003918 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003919
3920 def new(this._bufnr)
3921 if !bufexists(this._bufnr)
3922 this._bufnr = -1
3923 return
3924 endif
3925 enddef
3926 endclass
3927
3928 var c = C.new(12345)
3929 assert_equal('object<C>', typename(c))
3930
3931 var v1: C
3932 v1 = C.new(12345)
3933 assert_equal('object<C>', typename(v1))
3934
3935 def F()
3936 var v2: C
3937 v2 = C.new(12345)
3938 assert_equal('object<C>', typename(v2))
3939 enddef
3940 F()
3941 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003942 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003943
3944 # new() uses "any" return type and returns "this"
3945 lines =<< trim END
3946 vim9script
3947
3948 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003949 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003950
3951 def new(this._bufnr): any
3952 if !bufexists(this._bufnr)
3953 this._bufnr = -1
3954 return this
3955 endif
3956 enddef
3957 endclass
3958 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003959 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003960
3961 # new() uses 'Dict' return type and returns a Dict
3962 lines =<< trim END
3963 vim9script
3964
3965 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003966 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003967
3968 def new(): dict<any>
3969 this._state = {}
3970 return this._state
3971 enddef
3972 endclass
3973
3974 var c = C.new()
3975 assert_equal('object<C>', typename(c))
3976 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003977 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003978enddef
3979
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003980" Test for checking a member initialization type at run time.
3981def Test_runtime_type_check_for_member_init()
3982 var lines =<< trim END
3983 vim9script
3984
3985 var retnum: bool = false
3986
3987 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003988 retnum = !retnum
3989 if retnum
3990 return 1
3991 else
3992 return "hello"
3993 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003994 enddef
3995
3996 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003997 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003998 endclass
3999
4000 var c1 = C.new()
4001 var c2 = C.new()
4002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004003 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004004enddef
4005
4006" Test for locking a variable referring to an object and reassigning to another
4007" object.
Ernie Raelee865f32023-09-29 19:53:55 +02004008def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004009 var lines =<< trim END
4010 vim9script
4011
4012 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004013 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004014 def new(this.val)
4015 enddef
4016 endclass
4017
4018 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
4019 lockvar 2 some_dict
4020
4021 var current: C
4022 current = some_dict['c']
4023 assert_equal(3, current.val)
4024 current = some_dict['b']
4025 assert_equal(2, current.val)
4026
4027 def F()
4028 current = some_dict['c']
4029 enddef
4030
4031 def G()
4032 current = some_dict['b']
4033 enddef
4034
4035 F()
4036 assert_equal(3, current.val)
4037 G()
4038 assert_equal(2, current.val)
4039 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004040 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004041enddef
4042
Ernie Raelee865f32023-09-29 19:53:55 +02004043" Test trying to lock an object variable from various places
4044def Test_lockvar_object_variable()
4045 # An object variable lockvar has several cases:
4046 # object method, scriptlevel, scriplevel from :def, :def arg
4047 # method arg, static method arg.
4048 # Also different depths
4049
Ernie Raelee865f32023-09-29 19:53:55 +02004050 #
4051 # lockvar of read-only object variable
4052 #
4053
4054 # read-only lockvar from object method
4055 var lines =<< trim END
4056 vim9script
4057
4058 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004059 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004060 def Lock()
4061 lockvar this.val1
4062 enddef
4063 endclass
4064 var o = C.new(3)
4065 o.Lock()
4066 END
Ernie Rael64885642023-10-04 20:16:22 +02004067 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004068
4069 # read-only lockvar from scriptlevel
4070 lines =<< trim END
4071 vim9script
4072
4073 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004074 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004075 endclass
4076 var o = C.new(3)
4077 lockvar o.val2
4078 END
4079 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4080
4081 # read-only lockvar of scriptlevel variable from def
4082 lines =<< trim END
4083 vim9script
4084
4085 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004086 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004087 endclass
4088 var o = C.new(3)
4089 def Lock()
4090 lockvar o.val3
4091 enddef
4092 Lock()
4093 END
4094 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4095
4096 # read-only lockvar of def argument variable
4097 lines =<< trim END
4098 vim9script
4099
4100 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004101 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004102 endclass
4103 def Lock(o: C)
4104 lockvar o.val4
4105 enddef
4106 Lock(C.new(3))
4107 END
4108 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4109
4110 # TODO: the following tests use type "any" for argument. Need a run time
4111 # check for access. Probably OK as is for now.
4112
4113 # read-only lockvar from object method arg
4114 lines =<< trim END
4115 vim9script
4116
4117 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004118 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004119 def Lock(o_any: any)
4120 lockvar o_any.val5
4121 enddef
4122 endclass
4123 var o = C.new(3)
4124 o.Lock(C.new(5))
4125 END
Ernie Rael64885642023-10-04 20:16:22 +02004126 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004127
4128 # read-only lockvar from class method arg
4129 lines =<< trim END
4130 vim9script
4131
4132 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004133 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004134 static def Lock(o_any: any)
4135 lockvar o_any.val6
4136 enddef
4137 endclass
4138 var o = C.new(3)
4139 C.Lock(o)
4140 END
Ernie Rael64885642023-10-04 20:16:22 +02004141 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004142
4143 #
4144 # lockvar of public object variable
4145 #
4146
4147 # lockvar from object method
4148 lines =<< trim END
4149 vim9script
4150
4151 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004152 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004153 def Lock()
4154 lockvar this.val1
4155 enddef
4156 endclass
4157 var o = C.new(3)
4158 o.Lock()
4159 END
4160 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4161
4162 # lockvar from scriptlevel
4163 lines =<< trim END
4164 vim9script
4165
4166 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004167 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004168 endclass
4169 var o = C.new(3)
4170 lockvar o.val2
4171 END
4172 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4173
4174 # lockvar of scriptlevel variable from def
4175 lines =<< trim END
4176 vim9script
4177
4178 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004179 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004180 endclass
4181 var o = C.new(3)
4182 def Lock()
4183 lockvar o.val3
4184 enddef
4185 Lock()
4186 END
4187 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4188
4189 # lockvar of def argument variable
4190 lines =<< trim END
4191 vim9script
4192
4193 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004194 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004195 endclass
4196 def Lock(o: C)
4197 lockvar o.val4
4198 enddef
4199 Lock(C.new(3))
4200 END
4201 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4202
4203 # lockvar from object method arg
4204 lines =<< trim END
4205 vim9script
4206
4207 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004208 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004209 def Lock(o_any: any)
4210 lockvar o_any.val5
4211 enddef
4212 endclass
4213 var o = C.new(3)
4214 o.Lock(C.new(5))
4215 END
4216 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4217
4218 # lockvar from class method arg
4219 lines =<< trim END
4220 vim9script
4221
4222 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004223 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004224 static def Lock(o_any: any)
4225 lockvar o_any.val6
4226 enddef
4227 endclass
4228 var o = C.new(3)
4229 C.Lock(o)
4230 END
4231 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4232enddef
4233
4234" Test trying to lock a class variable from various places
4235def Test_lockvar_class_variable()
4236
4237 # lockvar bare static from object method
4238 var lines =<< trim END
4239 vim9script
4240
4241 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004242 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004243 def Lock()
4244 lockvar sval1
4245 enddef
4246 endclass
4247 var o = C.new()
4248 o.Lock()
4249 END
4250 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4251
4252 # lockvar C.static from object method
4253 lines =<< trim END
4254 vim9script
4255
4256 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004257 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004258 def Lock()
4259 lockvar C.sval2
4260 enddef
4261 endclass
4262 var o = C.new()
4263 o.Lock()
4264 END
4265 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4266
4267 # lockvar bare static from class method
4268 lines =<< trim END
4269 vim9script
4270
4271 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004272 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004273 static def Lock()
4274 lockvar sval3
4275 enddef
4276 endclass
4277 C.Lock()
4278 END
4279 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4280
4281 # lockvar C.static from class method
4282 lines =<< trim END
4283 vim9script
4284
4285 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004286 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004287 static def Lock()
4288 lockvar C.sval4
4289 enddef
4290 endclass
4291 C.Lock()
4292 END
4293 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4294
4295 # lockvar C.static from script level
4296 lines =<< trim END
4297 vim9script
4298
4299 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004300 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004301 endclass
4302 lockvar C.sval5
4303 END
4304 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4305
4306 # lockvar o.static from script level
4307 lines =<< trim END
4308 vim9script
4309
4310 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004311 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004312 endclass
4313 var o = C.new()
4314 lockvar o.sval6
4315 END
4316 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4317enddef
4318
4319" Test locking an argument to :def
4320def Test_lockvar_argument()
4321 # Lockvar a function arg
4322 var lines =<< trim END
4323 vim9script
4324
4325 def Lock(val: any)
4326 lockvar val
4327 enddef
4328
4329 var d = {a: 1, b: 2}
4330 Lock(d)
4331
4332 d->extend({c: 3})
4333 END
4334 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4335
4336 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4337 # class member in "C". This tests lval_root_is_arg.
4338 lines =<< trim END
4339 vim9script
4340
4341 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004342 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004343 endclass
4344
4345 def Lock2(sval: any)
4346 lockvar sval
4347 enddef
4348
4349 var o = C.new()
4350 Lock2(o)
4351 END
4352 v9.CheckSourceSuccess(lines)
4353
4354 # Lock a class.
4355 lines =<< trim END
4356 vim9script
4357
4358 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004359 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004360 endclass
4361
4362 def Lock2(sval: any)
4363 lockvar sval
4364 enddef
4365
4366 Lock2(C)
4367 END
Ernie Raelb077b582023-12-14 20:11:44 +01004368 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004369
4370 # Lock an object.
4371 lines =<< trim END
4372 vim9script
4373
4374 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004375 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004376 endclass
4377
4378 def Lock2(sval: any)
4379 lockvar sval
4380 enddef
4381
4382 Lock2(C.new())
4383 END
4384 v9.CheckSourceSuccess(lines)
4385
4386 # In this case (unlike previous) "lockvar sval" is a class member.
4387 lines =<< trim END
4388 vim9script
4389
4390 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004391 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004392 def Lock2()
4393 lockvar sval
4394 enddef
4395 endclass
4396
4397
4398 var o = C.new()
4399 o.Lock2()
4400 END
4401 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4402enddef
4403
4404" Test that this can be locked without error
4405def Test_lockvar_this()
4406 # lockvar this
4407 var lines =<< trim END
4408 vim9script
4409 class C
4410 def TLock()
4411 lockvar this
4412 enddef
4413 endclass
4414 var o = C.new()
4415 o.TLock()
4416 END
4417 v9.CheckSourceSuccess(lines)
4418
4419 # lockvar four (four letter word, but not this)
4420 lines =<< trim END
4421 vim9script
4422 class C
4423 def TLock4()
4424 var four: number
4425 lockvar four
4426 enddef
4427 endclass
4428 var o = C.new()
4429 o.TLock4()
4430 END
4431 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4432
4433 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4434 lines =<< trim END
4435 vim9script
4436 class C
4437 def TLock5()
4438 var this5: number
4439 lockvar this5
4440 enddef
4441 endclass
4442 var o = C.new()
4443 o.TLock5()
4444 END
4445 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4446enddef
4447
4448" Test some general lockvar cases
4449def Test_lockvar_general()
4450 # lockvar an object and a class. It does nothing
4451 var lines =<< trim END
4452 vim9script
4453 class C
4454 endclass
4455 var o = C.new()
4456 lockvar o
4457 lockvar C
4458 END
4459 v9.CheckSourceSuccess(lines)
4460
4461 # Lock a list element that's nested in an object variable from a :def
4462 lines =<< trim END
4463 vim9script
4464
4465 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004466 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004467 endclass
4468 def Lock2(obj: any)
4469 lockvar obj.val[1]
4470 enddef
4471
4472 var o = C.new()
4473 Lock2(o)
4474 o.val[0] = [9]
4475 assert_equal([ [9], [2], [3] ], o.val)
4476 try
4477 o.val[1] = [999]
4478 call assert_false(true, 'assign should have failed')
4479 catch
4480 assert_exception('E741:')
4481 endtry
4482 o.val[2] = [8]
4483 assert_equal([ [9], [2], [8] ], o.val)
4484 END
4485 v9.CheckSourceSuccess(lines)
4486
4487 # Lock a list element that's nested in an object variable from scriptlevel
4488 lines =<< trim END
4489 vim9script
4490
4491 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004492 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004493 endclass
4494
4495 var o = C.new()
4496 lockvar o.val[1]
4497 o.val[0] = [9]
4498 assert_equal([ [9], [2], [3] ], o.val)
4499 try
4500 o.val[1] = [999]
4501 call assert_false(true, 'assign should have failed')
4502 catch
4503 assert_exception('E741:')
4504 endtry
4505 o.val[2] = [8]
4506 assert_equal([ [9], [2], [8] ], o.val)
4507 END
4508 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004509
4510 # lock a script level variable from an object method
4511 lines =<< trim END
4512 vim9script
4513
4514 class C
4515 def Lock()
4516 lockvar l
4517 enddef
4518 endclass
4519
4520 var l = [1]
4521 C.new().Lock()
4522 l[0] = 11
4523 END
4524 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4525
Ernie Rael03042a22023-11-11 08:53:32 +01004526 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004527 # in an object fetched via a script level list
4528 lines =<< trim END
4529 vim9script
4530
4531 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004532 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004533 def Lock()
4534 lockvar lc[0]._v1[1]
4535 enddef
4536 endclass
4537
4538 var l = [[1], [2], [3]]
4539 var o = C.new(l)
4540 var lc: list<C> = [ o ]
4541
4542 o.Lock()
4543 l[0] = [22]
4544 l[1] = [33]
4545 END
4546 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4547
4548 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004549 # in a class that does not own the protected variable.
4550 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004551 # the same name.
4552 lines =<< trim END
4553 vim9script
4554
4555 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004556 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004557 def Lock(obj: any)
4558 lockvar lc[0]._v1[1]
4559 enddef
4560 endclass
4561
4562 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004563 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004564 endclass
4565
4566 var l = [[1], [2], [3]]
4567 var o = C.new(l)
4568 var lc: list<C> = [ o ]
4569
4570 var o2 = C2.new()
4571 o2.Lock(o)
4572 END
Ernie Rael03042a22023-11-11 08:53:32 +01004573 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004574enddef
4575
Ernie Rael9771b2a2023-10-07 22:05:40 +02004576" Test builtin islocked()
4577def Test_lockvar_islocked()
4578 # Can't lock class/object variable
4579 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004580 # Lock item of variable's value (a list item)
4581 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004582 var lines =<< trim END
4583 vim9script
4584
4585 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004586 var o0: list<list<number>> = [ [0], [1], [2]]
4587 var o1: list<list<number>> = [[10], [11], [12]]
4588 static var c0: list<list<number>> = [[20], [21], [22]]
4589 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004590 endclass
4591
4592 def LockIt(arg: any)
4593 lockvar arg
4594 enddef
4595
4596 def UnlockIt(arg: any)
4597 unlockvar arg
4598 enddef
4599
4600 var obj = C.new()
4601 #lockvar obj.o1 # can't lock something you can't write to
4602
4603 try
4604 lockvar obj.o1 # can't lock something you can't write to
4605 call assert_false(1, '"lockvar obj.o1" should have failed')
4606 catch
4607 call assert_exception('E1335:')
4608 endtry
4609
4610 LockIt(obj.o1) # but can lock it's value
4611 assert_equal(1, islocked("obj.o1"))
4612 assert_equal(1, islocked("obj.o1[0]"))
4613 assert_equal(1, islocked("obj.o1[1]"))
4614 UnlockIt(obj.o1)
4615 assert_equal(0, islocked("obj.o1"))
4616 assert_equal(0, islocked("obj.o1[0]"))
4617
4618 lockvar obj.o1[0]
4619 assert_equal(0, islocked("obj.o1"))
4620 assert_equal(1, islocked("obj.o1[0]"))
4621 assert_equal(0, islocked("obj.o1[1]"))
4622 unlockvar obj.o1[0]
4623 assert_equal(0, islocked("obj.o1"))
4624 assert_equal(0, islocked("obj.o1[0]"))
4625
4626 # Same thing, but with a static
4627
4628 try
4629 lockvar C.c1 # can't lock something you can't write to
4630 call assert_false(1, '"lockvar C.c1" should have failed')
4631 catch
4632 call assert_exception('E1335:')
4633 endtry
4634
4635 LockIt(C.c1) # but can lock it's value
4636 assert_equal(1, islocked("C.c1"))
4637 assert_equal(1, islocked("C.c1[0]"))
4638 assert_equal(1, islocked("C.c1[1]"))
4639 UnlockIt(C.c1)
4640 assert_equal(0, islocked("C.c1"))
4641 assert_equal(0, islocked("C.c1[0]"))
4642
4643 lockvar C.c1[0]
4644 assert_equal(0, islocked("C.c1"))
4645 assert_equal(1, islocked("C.c1[0]"))
4646 assert_equal(0, islocked("C.c1[1]"))
4647 unlockvar C.c1[0]
4648 assert_equal(0, islocked("C.c1"))
4649 assert_equal(0, islocked("C.c1[0]"))
4650 END
4651 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004652
4653 # Do islocked() from an object method
4654 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004655 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004656 vim9script
4657
4658 var l0o0 = [ [0], [1], [2]]
4659 var l0o1 = [ [10], [11], [12]]
4660 var l0c0 = [[120], [121], [122]]
4661 var l0c1 = [[130], [131], [132]]
4662
4663 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004664 var o0: list<list<number>> = l0o0
4665 var o1: list<list<number>> = l0o1
4666 static var c0: list<list<number>> = l0c0
4667 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004668 def Islocked(arg: string): number
4669 return islocked(arg)
4670 enddef
4671 static def SIslocked(arg: string): number
4672 return islocked(arg)
4673 enddef
4674 endclass
4675
4676 var l2o0 = [[20000], [20001], [20002]]
4677 var l2o1 = [[20010], [20011], [20012]]
4678 var l2c0 = [[20120], [20121], [20122]]
4679 var l2c1 = [[20130], [20131], [20132]]
4680
4681 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004682 var o0: list<list<number>> = l2o0
4683 var o1: list<list<number>> = l2o1
4684 static var c0: list<list<number>> = l2c0
4685 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004686 def Islocked(arg: string): number
4687 return islocked(arg)
4688 enddef
4689 static def SIslocked(arg: string): number
4690 return islocked(arg)
4691 enddef
4692 endclass
4693
4694 var obj0 = C0.new()
4695 var obj2 = C2.new()
4696
4697 var l = [ obj0, null_object, obj2 ]
4698
4699 # lock list, object func access through script var expr
4700 assert_equal(0, obj0.Islocked("l[0].o0"))
4701 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4702 lockvar l0o0
4703 assert_equal(1, obj0.Islocked("l[0].o0"))
4704 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4705
4706 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4707
4708 # lock list element, object func access through script var expr
4709 lockvar l0o1[1]
4710 assert_equal(0, obj0.Islocked("this.o1[0]"))
4711 assert_equal(1, obj0.Islocked("this.o1[1]"))
4712
4713 assert_equal(0, obj0.Islocked("this.o1"))
4714 lockvar l0o1
4715 assert_equal(1, obj0.Islocked("this.o1"))
4716 unlockvar l0o1
4717
4718 lockvar l0c1[1]
4719
4720 # static by class name member expr from same class
4721 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4722 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4723 # static by bare name member expr from same class
4724 assert_equal(0, obj0.Islocked("c1[0]"))
4725 assert_equal(1, obj0.Islocked("c1[1]"))
4726
4727 # static by class name member expr from other class
4728 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4729 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4730 # static by bare name member expr from other class
4731 assert_equal(0, obj2.Islocked("c1[0]"))
4732 assert_equal(0, obj2.Islocked("c1[1]"))
4733
4734
4735 # static by bare name in same class
4736 assert_equal(0, obj0.Islocked("c0"))
4737 lockvar l0c0
4738 assert_equal(1, obj0.Islocked("c0"))
4739
4740 #
4741 # similar stuff, but use static method
4742 #
4743
4744 unlockvar l0o0
4745
4746 # lock list, object func access through script var expr
4747 assert_equal(0, C0.SIslocked("l[0].o0"))
4748 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4749 lockvar l0o0
4750 assert_equal(1, C0.SIslocked("l[0].o0"))
4751 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4752
4753 unlockvar l0o1
4754
4755 # can't access "this" from class method
4756 try
4757 C0.SIslocked("this.o1[0]")
4758 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4759 catch
4760 call assert_exception('E121: Undefined variable: this')
4761 endtry
4762
4763 lockvar l0c1[1]
4764
4765 # static by class name member expr from same class
4766 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4767 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4768 # static by bare name member expr from same class
4769 assert_equal(0, C0.SIslocked("c1[0]"))
4770 assert_equal(1, C0.SIslocked("c1[1]"))
4771
4772 # static by class name member expr from other class
4773 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4774 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4775 # static by bare name member expr from other class
4776 assert_equal(0, C2.SIslocked("c1[0]"))
4777 assert_equal(0, C2.SIslocked("c1[1]"))
4778
4779
4780 # static by bare name in same class
4781 unlockvar l0c0
4782 assert_equal(0, C0.SIslocked("c0"))
4783 lockvar l0c0
4784 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004785 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004786 v9.CheckSourceSuccess(lines)
4787
4788 # Check islocked class/object from various places.
4789 lines =<< trim END
4790 vim9script
4791
4792 class C
4793 def Islocked(arg: string): number
4794 return islocked(arg)
4795 enddef
4796 static def SIslocked(arg: string): number
4797 return islocked(arg)
4798 enddef
4799 endclass
4800 var obj = C.new()
4801
4802 # object method
4803 assert_equal(0, obj.Islocked("this"))
4804 assert_equal(0, obj.Islocked("C"))
4805
4806 # class method
4807 ### assert_equal(0, C.SIslocked("this"))
4808 assert_equal(0, C.SIslocked("C"))
4809
4810 #script level
4811 var v: number
4812 v = islocked("C")
4813 assert_equal(0, v)
4814 v = islocked("obj")
4815 assert_equal(0, v)
4816 END
4817 v9.CheckSourceSuccess(lines)
4818enddef
4819
4820def Test_lockvar_islocked_notfound()
4821 # Try non-existent things
4822 var lines =<< trim END
4823 vim9script
4824
4825 class C
4826 def Islocked(arg: string): number
4827 return islocked(arg)
4828 enddef
4829 static def SIslocked(arg: string): number
4830 return islocked(arg)
4831 enddef
4832 endclass
4833 var obj = C.new()
4834 assert_equal(-1, obj.Islocked("anywhere"))
4835 assert_equal(-1, C.SIslocked("notanywhere"))
4836 END
4837 v9.CheckSourceSuccess(lines)
4838
4839 # Something not found of the form "name1.name2" is an error
4840 lines =<< trim END
4841 vim9script
4842
4843 islocked("one.two")
4844 END
4845 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4846
4847 lines =<< trim END
4848 vim9script
4849
4850 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004851 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004852 def Islocked(arg: string): number
4853 return islocked(arg)
4854 enddef
4855 endclass
4856 var obj = C.new()
4857 obj.Islocked("this.val.not_there"))
4858 END
4859 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4860
4861 lines =<< trim END
4862 vim9script
4863
4864 class C
4865 def Islocked(arg: string): number
4866 return islocked(arg)
4867 enddef
4868 endclass
4869 var obj = C.new()
4870 obj.Islocked("this.notobjmember")
4871 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004872 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004873
4874 # access a script variable through methods
4875 lines =<< trim END
4876 vim9script
4877
4878 var l = [1]
4879 class C
4880 def Islocked(arg: string): number
4881 return islocked(arg)
4882 enddef
4883 static def SIslocked(arg: string): number
4884 return islocked(arg)
4885 enddef
4886 endclass
4887 var obj = C.new()
4888 assert_equal(0, obj.Islocked("l"))
4889 assert_equal(0, C.SIslocked("l"))
4890 lockvar l
4891 assert_equal(1, obj.Islocked("l"))
4892 assert_equal(1, C.SIslocked("l"))
4893 END
4894 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004895enddef
4896
Ernie Rael03042a22023-11-11 08:53:32 +01004897" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004898def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004899 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004900 var lines =<< trim END
4901 vim9script
4902
4903 class A
4904 def _Foo(): number
4905 return 1234
4906 enddef
4907 endclass
4908 var a = A.new()
4909 a._Foo()
4910 END
Ernie Rael03042a22023-11-11 08:53:32 +01004911 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004912
Ernie Rael03042a22023-11-11 08:53:32 +01004913 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004914 lines =<< trim END
4915 vim9script
4916
4917 class A
4918 def _Foo(): number
4919 return 1234
4920 enddef
4921 endclass
4922 def T()
4923 var a = A.new()
4924 a._Foo()
4925 enddef
4926 T()
4927 END
Ernie Rael03042a22023-11-11 08:53:32 +01004928 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004929
Ernie Rael03042a22023-11-11 08:53:32 +01004930 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004931 lines =<< trim END
4932 vim9script
4933
4934 class A
4935 def _Foo(): number
4936 return 1234
4937 enddef
4938 def Bar(): number
4939 return this._Foo()
4940 enddef
4941 endclass
4942 var a = A.new()
4943 assert_equal(1234, a.Bar())
4944 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004945 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004946
Ernie Rael03042a22023-11-11 08:53:32 +01004947 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004948 lines =<< trim END
4949 vim9script
4950
4951 class A
4952 def _Foo(): number
4953 return 1234
4954 enddef
4955 def Bar(): number
4956 return this._Foo()
4957 enddef
4958 endclass
4959 def T()
4960 var a = A.new()
4961 assert_equal(1234, a.Bar())
4962 enddef
4963 T()
4964 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004965 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004966
Ernie Rael03042a22023-11-11 08:53:32 +01004967 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004968 lines =<< trim END
4969 vim9script
4970
4971 class A
4972 def _Foo(): number
4973 return 1234
4974 enddef
4975 def Bar(): number
4976 return _Foo()
4977 enddef
4978 endclass
4979 var a = A.new()
4980 a.Bar()
4981 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004982 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004983
Ernie Rael03042a22023-11-11 08:53:32 +01004984 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004985 lines =<< trim END
4986 vim9script
4987
4988 class A
4989 def _Foo(): number
4990 return 1234
4991 enddef
4992 endclass
4993 A._Foo()
4994 END
Ernie Rael03042a22023-11-11 08:53:32 +01004995 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004996
Ernie Rael03042a22023-11-11 08:53:32 +01004997 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004998 lines =<< trim END
4999 vim9script
5000
5001 class A
5002 def _Foo()
5003 enddef
5004 def _Foo()
5005 enddef
5006 endclass
5007 var a = A.new()
5008 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005009 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005010
Ernie Rael03042a22023-11-11 08:53:32 +01005011 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005012 lines =<< trim END
5013 vim9script
5014
5015 class A
5016 def _Foo()
5017 enddef
5018 def Foo()
5019 enddef
5020 endclass
5021 var a = A.new()
5022 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005023 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005024
Ernie Rael03042a22023-11-11 08:53:32 +01005025 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005026 lines =<< trim END
5027 vim9script
5028
5029 class A
5030 def Foo()
5031 enddef
5032 def _Foo()
5033 enddef
5034 endclass
5035 var a = A.new()
5036 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005037 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005038
Ernie Rael03042a22023-11-11 08:53:32 +01005039 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005040 lines =<< trim END
5041 vim9script
5042
5043 class A
5044 def Foo(): number
5045 return 100
5046 enddef
5047 def _Bar(): number
5048 return 200
5049 enddef
5050 def _Baz()
5051 assert_equal(100, this.Foo())
5052 assert_equal(200, this._Bar())
5053 enddef
5054 def T()
5055 this._Baz()
5056 enddef
5057 endclass
5058 var a = A.new()
5059 a.T()
5060 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005061 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005062
Ernie Rael03042a22023-11-11 08:53:32 +01005063 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005064 lines =<< trim END
5065 vim9script
5066
5067 class A
5068 def _Foo(): number
5069 return 100
5070 enddef
5071 endclass
5072 class B
5073 def Foo(): number
5074 var a = A.new()
5075 a._Foo()
5076 enddef
5077 endclass
5078 var b = B.new()
5079 b.Foo()
5080 END
Ernie Rael03042a22023-11-11 08:53:32 +01005081 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
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 method
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 return this._Foo()
5098 enddef
5099 endclass
5100 var c = C.new()
5101 assert_equal(1234, c.Baz())
5102 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005103 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005104
Ernie Rael03042a22023-11-11 08:53:32 +01005105 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005106 lines =<< trim END
5107 vim9script
5108 class A
5109 def _Foo(): number
5110 return 1234
5111 enddef
5112 endclass
5113 class B extends A
5114 def Bar()
5115 enddef
5116 endclass
5117 class C extends B
5118 def Baz(): number
5119 enddef
5120 endclass
5121 var c = C.new()
5122 assert_equal(1234, c._Foo())
5123 END
Ernie Rael03042a22023-11-11 08:53:32 +01005124 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005125
5126 # Using "_" prefix in a method name should fail outside of a class
5127 lines =<< trim END
5128 vim9script
5129 def _Foo(): number
5130 return 1234
5131 enddef
5132 var a = _Foo()
5133 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005134 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005135enddef
5136
Ernie Rael03042a22023-11-11 08:53:32 +01005137" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005138def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005139 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005140 var lines =<< trim END
5141 vim9script
5142
5143 class A
5144 static def _Foo(): number
5145 return 1234
5146 enddef
5147 endclass
5148 A._Foo()
5149 END
Ernie Rael03042a22023-11-11 08:53:32 +01005150 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005151
Ernie Rael03042a22023-11-11 08:53:32 +01005152 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005153 lines =<< trim END
5154 vim9script
5155
5156 class A
5157 static def _Foo(): number
5158 return 1234
5159 enddef
5160 endclass
5161 def T()
5162 A._Foo()
5163 enddef
5164 T()
5165 END
Ernie Rael03042a22023-11-11 08:53:32 +01005166 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005167
Ernie Rael03042a22023-11-11 08:53:32 +01005168 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005169 lines =<< trim END
5170 vim9script
5171
5172 class A
5173 static def _Foo(): number
5174 return 1234
5175 enddef
5176 endclass
5177 var a = A.new()
5178 a._Foo()
5179 END
Ernie Rael03042a22023-11-11 08:53:32 +01005180 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005181
Ernie Rael03042a22023-11-11 08:53:32 +01005182 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005183 lines =<< trim END
5184 vim9script
5185
5186 class A
5187 static def _Foo(): number
5188 return 1234
5189 enddef
5190 endclass
5191 def T()
5192 var a = A.new()
5193 a._Foo()
5194 enddef
5195 T()
5196 END
Ernie Rael03042a22023-11-11 08:53:32 +01005197 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005198
Ernie Rael03042a22023-11-11 08:53:32 +01005199 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005200 lines =<< trim END
5201 vim9script
5202
5203 class A
5204 static def _Foo(): number
5205 return 1234
5206 enddef
5207 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005208 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005209 enddef
5210 endclass
5211 var a = A.new()
5212 a.Bar()
5213 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005214 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005215
Ernie Rael03042a22023-11-11 08:53:32 +01005216 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005217 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005218 lines =<< trim END
5219 vim9script
5220
5221 class A
5222 static def _Foo1(): number
5223 return 1234
5224 enddef
5225 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005226 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005227 enddef
5228 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005229 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005230 enddef
5231 endclass
5232 var a = A.new()
5233 a.Bar()
5234 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005235 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005236
Ernie Rael03042a22023-11-11 08:53:32 +01005237 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005238 lines =<< trim END
5239 vim9script
5240
5241 class A
5242 static def _Foo()
5243 enddef
5244 static def Foo()
5245 enddef
5246 endclass
5247 var a = A.new()
5248 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005249 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005250
Ernie Rael03042a22023-11-11 08:53:32 +01005251 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005252 lines =<< trim END
5253 vim9script
5254
5255 class A
5256 static def _Foo(): number
5257 return 1234
5258 enddef
5259 endclass
5260 class B
5261 def Foo(): number
5262 return A._Foo()
5263 enddef
5264 endclass
5265 var b = B.new()
5266 assert_equal(1234, b.Foo())
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 object 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 def Baz(): number
5284 return A._Foo()
5285 enddef
5286 endclass
5287 var c = C.new()
5288 assert_equal(1234, c.Baz())
5289 END
Ernie Rael03042a22023-11-11 08:53:32 +01005290 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005291
Ernie Rael03042a22023-11-11 08:53:32 +01005292 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005293 lines =<< trim END
5294 vim9script
5295 class A
5296 static def _Foo(): number
5297 return 1234
5298 enddef
5299 endclass
5300 class B extends A
5301 def Bar()
5302 enddef
5303 endclass
5304 class C extends B
5305 static def Baz(): number
5306 return A._Foo()
5307 enddef
5308 endclass
5309 assert_equal(1234, C.Baz())
5310 END
Ernie Rael03042a22023-11-11 08:53:32 +01005311 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005312
Ernie Rael03042a22023-11-11 08:53:32 +01005313 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005314 lines =<< trim END
5315 vim9script
5316 class A
5317 static def _Foo(): number
5318 return 1234
5319 enddef
5320 endclass
5321 class B extends A
5322 def Bar()
5323 enddef
5324 endclass
5325 class C extends B
5326 def Baz(): number
5327 enddef
5328 endclass
5329 var c = C.new()
5330 assert_equal(1234, C._Foo())
5331 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005332 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005333enddef
5334
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005335" Test for using the return value of a class/object method as a function
5336" argument.
5337def Test_objmethod_funcarg()
5338 var lines =<< trim END
5339 vim9script
5340
5341 class C
5342 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(c: C)
5352 assert_equal('foo', Bar(10, c.Foo()))
5353 enddef
5354
5355 var t = C.new()
5356 Baz(t)
5357 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005358 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005359
5360 lines =<< trim END
5361 vim9script
5362
5363 class C
5364 static def Foo(): string
5365 return 'foo'
5366 enddef
5367 endclass
5368
5369 def Bar(a: number, s: string): string
5370 return s
5371 enddef
5372
5373 def Baz()
5374 assert_equal('foo', Bar(10, C.Foo()))
5375 enddef
5376
5377 Baz()
5378 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005379 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005380enddef
5381
Ernie Raelcf138d42023-09-06 20:45:03 +02005382def Test_static_inheritence()
5383 # subclasses get their own static copy
5384 var lines =<< trim END
5385 vim9script
5386
5387 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005388 static var _svar: number
5389 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005390 def new()
5391 _svar = 1
5392 this._mvar = 101
5393 enddef
5394 def AccessObject(): number
5395 return this._mvar
5396 enddef
5397 def AccessStaticThroughObject(): number
5398 return _svar
5399 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005400 endclass
5401
5402 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005403 def new()
5404 this._mvar = 102
5405 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005406 endclass
5407
5408 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005409 def new()
5410 this._mvar = 103
5411 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005412
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005413 def AccessPrivateStaticThroughClassName(): number
5414 assert_equal(1, A._svar)
5415 return 444
5416 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005417 endclass
5418
5419 var oa = A.new()
5420 var ob = B.new()
5421 var oc = C.new()
5422 assert_equal(101, oa.AccessObject())
5423 assert_equal(102, ob.AccessObject())
5424 assert_equal(103, oc.AccessObject())
5425
Ernie Rael03042a22023-11-11 08:53:32 +01005426 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005427
5428 # verify object properly resolves to correct static
5429 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005430 assert_equal(1, ob.AccessStaticThroughObject())
5431 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005432 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005433 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005434enddef
5435
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005436" Test for declaring duplicate object and class members
5437def Test_dup_member_variable()
5438 # Duplicate member variable
5439 var lines =<< trim END
5440 vim9script
5441 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005442 var val = 10
5443 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005444 endclass
5445 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005446 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005447
Ernie Rael03042a22023-11-11 08:53:32 +01005448 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005449 lines =<< trim END
5450 vim9script
5451 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005452 var _val = 10
5453 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005454 endclass
5455 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005456 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005457
5458 # Duplicate public member variable
5459 lines =<< trim END
5460 vim9script
5461 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005462 public var val = 10
5463 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005464 endclass
5465 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005466 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005467
Ernie Rael03042a22023-11-11 08:53:32 +01005468 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005469 lines =<< trim END
5470 vim9script
5471 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005472 var val = 10
5473 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005474 endclass
5475 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005476 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005477
Ernie Rael03042a22023-11-11 08:53:32 +01005478 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005479 lines =<< trim END
5480 vim9script
5481 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005482 var _val = 20
5483 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005484 endclass
5485 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005486 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005487
5488 # Duplicate class member variable
5489 lines =<< trim END
5490 vim9script
5491 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005492 static var s: string = "abc"
5493 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005494 endclass
5495 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005496 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005497
Ernie Rael03042a22023-11-11 08:53:32 +01005498 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005499 lines =<< trim END
5500 vim9script
5501 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005502 public static var s: string = "abc"
5503 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005504 endclass
5505 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005506 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005507
5508 # Duplicate class and object member variable
5509 lines =<< trim END
5510 vim9script
5511 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005512 static var val = 10
5513 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005514 def new()
5515 enddef
5516 endclass
5517 var c = C.new()
5518 assert_equal(10, C.val)
5519 assert_equal(20, c.val)
5520 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005521 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005522
5523 # Duplicate object member variable in a derived class
5524 lines =<< trim END
5525 vim9script
5526 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005527 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005528 endclass
5529 class B extends A
5530 endclass
5531 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005532 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005533 endclass
5534 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005535 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005536
Ernie Rael03042a22023-11-11 08:53:32 +01005537 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005538 lines =<< trim END
5539 vim9script
5540 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005541 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005542 endclass
5543 class B extends A
5544 endclass
5545 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005546 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005547 endclass
5548 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005549 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005550
Ernie Rael03042a22023-11-11 08:53:32 +01005551 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005552 lines =<< trim END
5553 vim9script
5554 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005555 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005556 endclass
5557 class B extends A
5558 endclass
5559 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005560 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005561 endclass
5562 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005563 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005564
5565 # Duplicate object member variable in a derived class
5566 lines =<< trim END
5567 vim9script
5568 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005569 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005570 endclass
5571 class B extends A
5572 endclass
5573 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005574 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005575 endclass
5576 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005577 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005578
5579 # Two member variables with a common prefix
5580 lines =<< trim END
5581 vim9script
5582 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005583 public static var svar2: number
5584 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005585 endclass
5586 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005587 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005588enddef
5589
Ernie Rael03042a22023-11-11 08:53:32 +01005590" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005591def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005592 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005593 var lines =<< trim END
5594 vim9script
5595 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005596 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005597 def GetVal(): number
5598 return this._val
5599 enddef
5600 endclass
5601 def T()
5602 var a = A.new()
5603 a._val = 20
5604 enddef
5605 T()
5606 END
Ernie Rael03042a22023-11-11 08:53:32 +01005607 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005608
Ernie Rael03042a22023-11-11 08:53:32 +01005609 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005610 lines =<< trim END
5611 vim9script
5612 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005613 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005614 endclass
5615 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005616 var a = A.new()
5617 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005618 enddef
5619 T()
5620 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005621 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005622
Ernie Rael03042a22023-11-11 08:53:32 +01005623 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005624 lines =<< trim END
5625 vim9script
5626 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005627 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005628 endclass
5629 def T()
5630 var a = A.new()
5631 var x = a._val
5632 enddef
5633 T()
5634 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005635 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005636
Ernie Rael03042a22023-11-11 08:53:32 +01005637 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005638 lines =<< trim END
5639 vim9script
5640 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005641 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005642 endclass
5643 def T()
5644 var a = A.new()
5645 a._val = 3
5646 enddef
5647 T()
5648 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005649 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005650
Ernie Rael03042a22023-11-11 08:53:32 +01005651 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005652 lines =<< trim END
5653 vim9script
5654 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005655 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005656 endclass
5657 def T()
5658 var x = A._val
5659 enddef
5660 T()
5661 END
Ernie Rael03042a22023-11-11 08:53:32 +01005662 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005663
Ernie Rael03042a22023-11-11 08:53:32 +01005664 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005665 lines =<< trim END
5666 vim9script
5667 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005668 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005669 endclass
5670 def T()
5671 A._val = 3
5672 enddef
5673 T()
5674 END
Ernie Rael03042a22023-11-11 08:53:32 +01005675 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005676enddef
5677
5678" Test for changing the member access of an interface in a implementation class
5679def Test_change_interface_member_access()
5680 var lines =<< trim END
5681 vim9script
5682 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005683 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005684 endinterface
5685 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005686 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005687 endclass
5688 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005689 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005690
5691 lines =<< trim END
5692 vim9script
5693 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005694 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005695 endinterface
5696 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005697 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005698 endclass
5699 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005700 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005701enddef
5702
5703" Test for trying to change a readonly member from a def function
5704def Test_readonly_member_change_in_def_func()
5705 var lines =<< trim END
5706 vim9script
5707 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005708 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005709 endclass
5710 def T()
5711 var a = A.new()
5712 a.val = 20
5713 enddef
5714 T()
5715 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005716 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005717enddef
5718
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005719" Test for reading and writing a class member from a def function
5720def Test_modify_class_member_from_def_function()
5721 var lines =<< trim END
5722 vim9script
5723 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005724 var var1: number = 10
5725 public static var var2: list<number> = [1, 2]
5726 public static var var3: dict<number> = {a: 1, b: 2}
5727 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005728 endclass
5729 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005730 assert_equal([1, 2], A.var2)
5731 assert_equal({a: 1, b: 2}, A.var3)
5732 A.var2 = [3, 4]
5733 A.var3 = {c: 3, d: 4}
5734 assert_equal([3, 4], A.var2)
5735 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005736 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005737 enddef
5738 T()
5739 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005740 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005741enddef
5742
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005743" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005744def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005745 var lines =<< trim END
5746 vim9script
5747 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005748 public static var svar1: list<number> = [1]
5749 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005750 endclass
5751
5752 A.svar1->add(3)
5753 A.svar2->add(4)
5754 assert_equal([1, 3], A.svar1)
5755 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005756
5757 def Foo()
5758 A.svar1->add(7)
5759 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005760 assert_equal([1, 3, 7], A.svar1)
5761 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005762 enddef
5763 Foo()
5764 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005765 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005766
5767 # Cannot read from a class variable using an object in script context
5768 lines =<< trim END
5769 vim9script
5770 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005771 public var var1: number
5772 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005773 endclass
5774
5775 var a = A.new()
5776 echo a.svar2
5777 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005778 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005779
5780 # Cannot write to a class variable using an object in script context
5781 lines =<< trim END
5782 vim9script
5783 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005784 public var var1: number
5785 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005786 endclass
5787
5788 var a = A.new()
5789 a.svar2 = [2]
5790 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005791 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005792
5793 # Cannot read from a class variable using an object in def method context
5794 lines =<< trim END
5795 vim9script
5796 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005797 public var var1: number
5798 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005799 endclass
5800
5801 def T()
5802 var a = A.new()
5803 echo a.svar2
5804 enddef
5805 T()
5806 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005807 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005808
5809 # Cannot write to a class variable using an object in def method context
5810 lines =<< trim END
5811 vim9script
5812 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005813 public var var1: number
5814 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005815 endclass
5816
5817 def T()
5818 var a = A.new()
5819 a.svar2 = [2]
5820 enddef
5821 T()
5822 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005823 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005824enddef
5825
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005826" Test for using a interface method using a child object
5827def Test_interface_method_from_child()
5828 var lines =<< trim END
5829 vim9script
5830
5831 interface A
5832 def Foo(): string
5833 endinterface
5834
5835 class B implements A
5836 def Foo(): string
5837 return 'foo'
5838 enddef
5839 endclass
5840
5841 class C extends B
5842 def Bar(): string
5843 return 'bar'
5844 enddef
5845 endclass
5846
5847 def T1(a: A)
5848 assert_equal('foo', a.Foo())
5849 enddef
5850
5851 def T2(b: B)
5852 assert_equal('foo', b.Foo())
5853 enddef
5854
5855 var c = C.new()
5856 T1(c)
5857 T2(c)
5858 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005859 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005860enddef
5861
5862" Test for using an interface method using a child object when it is overridden
5863" by the child class.
5864" FIXME: This test fails.
5865" def Test_interface_overridden_method_from_child()
5866" var lines =<< trim END
5867" vim9script
5868"
5869" interface A
5870" def Foo(): string
5871" endinterface
5872"
5873" class B implements A
5874" def Foo(): string
5875" return 'b-foo'
5876" enddef
5877" endclass
5878"
5879" class C extends B
5880" def Bar(): string
5881" return 'bar'
5882" enddef
5883" def Foo(): string
5884" return 'c-foo'
5885" enddef
5886" endclass
5887"
5888" def T1(a: A)
5889" assert_equal('c-foo', a.Foo())
5890" enddef
5891"
5892" def T2(b: B)
5893" assert_equal('c-foo', b.Foo())
5894" enddef
5895"
5896" var c = C.new()
5897" T1(c)
5898" T2(c)
5899" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005900" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005901" enddef
5902
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005903" Test for abstract methods
5904def Test_abstract_method()
5905 # Use two abstract methods
5906 var lines =<< trim END
5907 vim9script
5908 abstract class A
5909 def M1(): number
5910 return 10
5911 enddef
5912 abstract def M2(): number
5913 abstract def M3(): number
5914 endclass
5915 class B extends A
5916 def M2(): number
5917 return 20
5918 enddef
5919 def M3(): number
5920 return 30
5921 enddef
5922 endclass
5923 var b = B.new()
5924 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5925 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005926 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005927
5928 # Don't define an abstract method
5929 lines =<< trim END
5930 vim9script
5931 abstract class A
5932 abstract def Foo()
5933 endclass
5934 class B extends A
5935 endclass
5936 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005937 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005938
5939 # Use abstract method in a concrete class
5940 lines =<< trim END
5941 vim9script
5942 class A
5943 abstract def Foo()
5944 endclass
5945 class B extends A
5946 endclass
5947 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005948 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005949
5950 # Use abstract method in an interface
5951 lines =<< trim END
5952 vim9script
5953 interface A
5954 abstract def Foo()
5955 endinterface
5956 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005957 def Foo()
5958 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005959 endclass
5960 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005961 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5962
5963 # Use abstract static method in an interface
5964 lines =<< trim END
5965 vim9script
5966 interface A
5967 abstract static def Foo()
5968 enddef
5969 endinterface
5970 END
5971 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5972
5973 # Use abstract static variable in an interface
5974 lines =<< trim END
5975 vim9script
5976 interface A
5977 abstract static foo: number = 10
5978 endinterface
5979 END
5980 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005981
5982 # Abbreviate the "abstract" keyword
5983 lines =<< trim END
5984 vim9script
5985 class A
5986 abs def Foo()
5987 endclass
5988 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005989 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005990
5991 # Use "abstract" with a member variable
5992 lines =<< trim END
5993 vim9script
5994 abstract class A
5995 abstract this.val = 10
5996 endclass
5997 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005998 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005999
6000 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01006001 lines =<< trim END
6002 vim9script
6003 abstract class A
6004 abstract static def Foo(): number
6005 endclass
6006 END
6007 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006008
6009 # Type mismatch between abstract method and concrete method
6010 lines =<< trim END
6011 vim9script
6012 abstract class A
6013 abstract def Foo(a: string, b: number): list<number>
6014 endclass
6015 class B extends A
6016 def Foo(a: number, b: string): list<string>
6017 return []
6018 enddef
6019 endclass
6020 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006021 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 +02006022
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006023 # Invoke an abstract method from a def function
6024 lines =<< trim END
6025 vim9script
6026 abstract class A
6027 abstract def Foo(): list<number>
6028 endclass
6029 class B extends A
6030 def Foo(): list<number>
6031 return [3, 5]
6032 enddef
6033 endclass
6034 def Bar(c: B)
6035 assert_equal([3, 5], c.Foo())
6036 enddef
6037 var b = B.new()
6038 Bar(b)
6039 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006040 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006041
6042 # Use a static method in an abstract class
6043 lines =<< trim END
6044 vim9script
6045 abstract class A
6046 static def Foo(): string
6047 return 'foo'
6048 enddef
6049 endclass
6050 assert_equal('foo', A.Foo())
6051 END
6052 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006053enddef
6054
6055" Test for calling a class method from a subclass
6056def Test_class_method_call_from_subclass()
6057 # class method call from a subclass
6058 var lines =<< trim END
6059 vim9script
6060
6061 class A
6062 static def Foo()
6063 echo "foo"
6064 enddef
6065 endclass
6066
6067 class B extends A
6068 def Bar()
6069 Foo()
6070 enddef
6071 endclass
6072
6073 var b = B.new()
6074 b.Bar()
6075 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006076 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006077enddef
6078
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006079" Test for calling a class method using an object in a def function context and
6080" script context.
6081def Test_class_method_call_using_object()
6082 # script context
6083 var lines =<< trim END
6084 vim9script
6085 class A
6086 static def Foo(): list<string>
6087 return ['a', 'b']
6088 enddef
6089 def Bar()
6090 assert_equal(['a', 'b'], A.Foo())
6091 assert_equal(['a', 'b'], Foo())
6092 enddef
6093 endclass
6094
6095 def T()
6096 assert_equal(['a', 'b'], A.Foo())
6097 var t_a = A.new()
6098 t_a.Bar()
6099 enddef
6100
6101 assert_equal(['a', 'b'], A.Foo())
6102 var a = A.new()
6103 a.Bar()
6104 T()
6105 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006106 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006107
6108 # script context
6109 lines =<< trim END
6110 vim9script
6111 class A
6112 static def Foo(): string
6113 return 'foo'
6114 enddef
6115 endclass
6116
6117 var a = A.new()
6118 assert_equal('foo', a.Foo())
6119 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006120 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006121
6122 # def function context
6123 lines =<< trim END
6124 vim9script
6125 class A
6126 static def Foo(): string
6127 return 'foo'
6128 enddef
6129 endclass
6130
6131 def T()
6132 var a = A.new()
6133 assert_equal('foo', a.Foo())
6134 enddef
6135 T()
6136 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006137 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006138enddef
6139
6140def Test_class_variable()
6141 var lines =<< trim END
6142 vim9script
6143
6144 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006145 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006146 static def ClassFunc()
6147 assert_equal(10, val)
6148 enddef
6149 def ObjFunc()
6150 assert_equal(10, val)
6151 enddef
6152 endclass
6153
6154 class B extends A
6155 endclass
6156
6157 assert_equal(10, A.val)
6158 A.ClassFunc()
6159 var a = A.new()
6160 a.ObjFunc()
6161 var b = B.new()
6162 b.ObjFunc()
6163
6164 def T1(a1: A)
6165 a1.ObjFunc()
6166 A.ClassFunc()
6167 enddef
6168 T1(b)
6169
6170 A.val = 20
6171 assert_equal(20, A.val)
6172 END
6173 v9.CheckSourceSuccess(lines)
6174
6175 # Modifying a parent class variable from a child class method
6176 lines =<< trim END
6177 vim9script
6178
6179 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006180 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006181 endclass
6182
6183 class B extends A
6184 static def ClassFunc()
6185 val = 20
6186 enddef
6187 endclass
6188 B.ClassFunc()
6189 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006190 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006191
6192 # Reading a parent class variable from a child class method
6193 lines =<< trim END
6194 vim9script
6195
6196 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006197 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006198 endclass
6199
6200 class B extends A
6201 static def ClassFunc()
6202 var i = val
6203 enddef
6204 endclass
6205 B.ClassFunc()
6206 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006207 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006208
6209 # Modifying a parent class variable from a child object method
6210 lines =<< trim END
6211 vim9script
6212
6213 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006214 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006215 endclass
6216
6217 class B extends A
6218 def ObjFunc()
6219 val = 20
6220 enddef
6221 endclass
6222 var b = B.new()
6223 b.ObjFunc()
6224 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006225 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006226
6227 # Reading a parent class variable from a child object method
6228 lines =<< trim END
6229 vim9script
6230
6231 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006232 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006233 endclass
6234
6235 class B extends A
6236 def ObjFunc()
6237 var i = val
6238 enddef
6239 endclass
6240 var b = B.new()
6241 b.ObjFunc()
6242 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006243 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006244
6245 # Modifying a class variable using an object at script level
6246 lines =<< trim END
6247 vim9script
6248
6249 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006250 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006251 endclass
6252 var a = A.new()
6253 a.val = 20
6254 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006255 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006256
6257 # Reading a class variable using an object at script level
6258 lines =<< trim END
6259 vim9script
6260
6261 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006262 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006263 endclass
6264 var a = A.new()
6265 var i = a.val
6266 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006267 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006268
6269 # Modifying a class variable using an object at function level
6270 lines =<< trim END
6271 vim9script
6272
6273 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006274 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006275 endclass
6276
6277 def T()
6278 var a = A.new()
6279 a.val = 20
6280 enddef
6281 T()
6282 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006283 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006284
6285 # Reading a class variable using an object at function level
6286 lines =<< trim END
6287 vim9script
6288
6289 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006290 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006291 endclass
6292 def T()
6293 var a = A.new()
6294 var i = a.val
6295 enddef
6296 T()
6297 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006298 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006299
6300 # Use old implicit var declaration syntax (without initialization)
6301 lines =<< trim END
6302 vim9script
6303
6304 class A
6305 static val: number
6306 endclass
6307 END
6308 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6309
6310 # Use old implicit var declaration syntax (with initialization)
6311 lines =<< trim END
6312 vim9script
6313
6314 class A
6315 static val: number = 10
6316 endclass
6317 END
6318 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6319
6320 # Use old implicit var declaration syntax (type inferred)
6321 lines =<< trim END
6322 vim9script
6323
6324 class A
6325 static val = 10
6326 endclass
6327 END
6328 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6329
6330 # Missing ":var" in "var" class variable declaration (without initialization)
6331 lines =<< trim END
6332 vim9script
6333
6334 class A
6335 static var: number
6336 endclass
6337 END
6338 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6339
6340 # Missing ":var" in "var" class variable declaration (with initialization)
6341 lines =<< trim END
6342 vim9script
6343
6344 class A
6345 static var: number = 10
6346 endclass
6347 END
6348 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6349
6350 # Missing ":var" in "var" class variable declaration (type inferred)
6351 lines =<< trim END
6352 vim9script
6353
6354 class A
6355 static var = 10
6356 endclass
6357 END
6358 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6359
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006360enddef
6361
6362" Test for using a duplicate class method and class variable in a child class
6363def Test_dup_class_member()
6364 # duplicate class variable, class method and overridden object method
6365 var lines =<< trim END
6366 vim9script
6367 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006368 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006369 static def Check()
6370 assert_equal(100, sval)
6371 enddef
6372 def GetVal(): number
6373 return sval
6374 enddef
6375 endclass
6376
6377 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006378 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006379 static def Check()
6380 assert_equal(200, sval)
6381 enddef
6382 def GetVal(): number
6383 return sval
6384 enddef
6385 endclass
6386
6387 def T1(aa: A): number
6388 return aa.GetVal()
6389 enddef
6390
6391 def T2(bb: B): number
6392 return bb.GetVal()
6393 enddef
6394
6395 assert_equal(100, A.sval)
6396 assert_equal(200, B.sval)
6397 var a = A.new()
6398 assert_equal(100, a.GetVal())
6399 var b = B.new()
6400 assert_equal(200, b.GetVal())
6401 assert_equal(200, T1(b))
6402 assert_equal(200, T2(b))
6403 END
6404 v9.CheckSourceSuccess(lines)
6405
6406 # duplicate class variable and class method
6407 lines =<< trim END
6408 vim9script
6409 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006410 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006411 static def Check()
6412 assert_equal(100, sval)
6413 enddef
6414 def GetVal(): number
6415 return sval
6416 enddef
6417 endclass
6418
6419 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006420 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006421 static def Check()
6422 assert_equal(200, sval)
6423 enddef
6424 endclass
6425
6426 def T1(aa: A): number
6427 return aa.GetVal()
6428 enddef
6429
6430 def T2(bb: B): number
6431 return bb.GetVal()
6432 enddef
6433
6434 assert_equal(100, A.sval)
6435 assert_equal(200, B.sval)
6436 var a = A.new()
6437 assert_equal(100, a.GetVal())
6438 var b = B.new()
6439 assert_equal(100, b.GetVal())
6440 assert_equal(100, T1(b))
6441 assert_equal(100, T2(b))
6442 END
6443 v9.CheckSourceSuccess(lines)
6444enddef
6445
6446" Test for calling an instance method using the class
6447def Test_instance_method_call_using_class()
6448 # Invoke an object method using a class in script context
6449 var lines =<< trim END
6450 vim9script
6451 class A
6452 def Foo()
6453 echo "foo"
6454 enddef
6455 endclass
6456 A.Foo()
6457 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006458 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006459
6460 # Invoke an object method using a class in def function context
6461 lines =<< trim END
6462 vim9script
6463 class A
6464 def Foo()
6465 echo "foo"
6466 enddef
6467 endclass
6468 def T()
6469 A.Foo()
6470 enddef
6471 T()
6472 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006473 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006474enddef
6475
6476" Test for duplicate class method and instance method
6477def Test_dup_classmethod_objmethod()
6478 # Duplicate instance method
6479 var lines =<< trim END
6480 vim9script
6481 class A
6482 static def Foo()
6483 enddef
6484 def Foo()
6485 enddef
6486 endclass
6487 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006488 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006489
Ernie Rael03042a22023-11-11 08:53:32 +01006490 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006491 lines =<< trim END
6492 vim9script
6493 class A
6494 static def Foo()
6495 enddef
6496 def _Foo()
6497 enddef
6498 endclass
6499 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006500 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006501
6502 # Duplicate class method
6503 lines =<< trim END
6504 vim9script
6505 class A
6506 def Foo()
6507 enddef
6508 static def Foo()
6509 enddef
6510 endclass
6511 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006512 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006513
Ernie Rael03042a22023-11-11 08:53:32 +01006514 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006515 lines =<< trim END
6516 vim9script
6517 class A
6518 def Foo()
6519 enddef
6520 static def _Foo()
6521 enddef
6522 endclass
6523 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006524 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006525
Ernie Rael03042a22023-11-11 08:53:32 +01006526 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006527 lines =<< trim END
6528 vim9script
6529 class A
6530 def _Foo()
6531 enddef
6532 static def _Foo()
6533 enddef
6534 endclass
6535 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006536 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006537enddef
6538
6539" Test for an instance method access level comparison with parent instance
6540" methods.
6541def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006542 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006543 var lines =<< trim END
6544 vim9script
6545 class A
6546 def Foo()
6547 enddef
6548 endclass
6549 class B extends A
6550 endclass
6551 class C extends B
6552 def _Foo()
6553 enddef
6554 endclass
6555 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006556 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006557
6558 # Public method in subclass
6559 lines =<< trim END
6560 vim9script
6561 class A
6562 def _Foo()
6563 enddef
6564 endclass
6565 class B extends A
6566 endclass
6567 class C extends B
6568 def Foo()
6569 enddef
6570 endclass
6571 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006572 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006573enddef
6574
6575def Test_extend_empty_class()
6576 var lines =<< trim END
6577 vim9script
6578 class A
6579 endclass
6580 class B extends A
6581 endclass
6582 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006583 public static var rw_class_var = 1
6584 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006585 static def ClassMethod(): number
6586 return 3
6587 enddef
6588 def ObjMethod(): number
6589 return 4
6590 enddef
6591 endclass
6592 assert_equal(1, C.rw_class_var)
6593 assert_equal(3, C.ClassMethod())
6594 var c = C.new()
6595 assert_equal(2, c.rw_obj_var)
6596 assert_equal(4, c.ObjMethod())
6597 END
6598 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006599enddef
6600
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006601" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006602" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006603def Test_interface_with_unsupported_members()
6604 var lines =<< trim END
6605 vim9script
6606 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006607 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006608 endinterface
6609 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006610 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006611
6612 lines =<< trim END
6613 vim9script
6614 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006615 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006616 endinterface
6617 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006618 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006619
6620 lines =<< trim END
6621 vim9script
6622 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006623 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006624 endinterface
6625 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006626 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006627
6628 lines =<< trim END
6629 vim9script
6630 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006631 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006632 endinterface
6633 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006634 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006635
6636 lines =<< trim END
6637 vim9script
6638 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006639 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006640 endinterface
6641 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006642 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006643
6644 lines =<< trim END
6645 vim9script
6646 interface A
6647 static def Foo(d: dict<any>): list<string>
6648 endinterface
6649 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006650 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006651
6652 lines =<< trim END
6653 vim9script
6654 interface A
6655 static def _Foo(d: dict<any>): list<string>
6656 endinterface
6657 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006658 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006659
6660 lines =<< trim END
6661 vim9script
6662 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006663 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006664 endinterface
6665 END
Ernie Rael03042a22023-11-11 08:53:32 +01006666 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006667
6668 lines =<< trim END
6669 vim9script
6670 interface A
6671 def _Foo(d: dict<any>): list<string>
6672 endinterface
6673 END
Ernie Rael03042a22023-11-11 08:53:32 +01006674 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006675enddef
6676
6677" Test for extending an interface
6678def Test_extend_interface()
6679 var lines =<< trim END
6680 vim9script
6681 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006682 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006683 def Foo()
6684 endinterface
6685 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006686 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006687 def Bar()
6688 endinterface
6689 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006690 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006691 def Foo()
6692 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006693 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006694 def Bar()
6695 enddef
6696 endclass
6697 END
6698 v9.CheckSourceSuccess(lines)
6699
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006700 # extending empty interface
6701 lines =<< trim END
6702 vim9script
6703 interface A
6704 endinterface
6705 interface B extends A
6706 endinterface
6707 class C implements B
6708 endclass
6709 END
6710 v9.CheckSourceSuccess(lines)
6711
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006712 lines =<< trim END
6713 vim9script
6714 interface A
6715 def Foo()
6716 endinterface
6717 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006718 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006719 endinterface
6720 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006721 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006722 endclass
6723 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006724 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006725
6726 lines =<< trim END
6727 vim9script
6728 interface A
6729 def Foo()
6730 endinterface
6731 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006732 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006733 endinterface
6734 class C implements A, B
6735 def Foo()
6736 enddef
6737 endclass
6738 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006739 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006740
6741 # interface cannot extend a class
6742 lines =<< trim END
6743 vim9script
6744 class A
6745 endclass
6746 interface B extends A
6747 endinterface
6748 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006749 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006750
6751 # class cannot extend an interface
6752 lines =<< trim END
6753 vim9script
6754 interface A
6755 endinterface
6756 class B extends A
6757 endclass
6758 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006759 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006760
6761 # interface cannot implement another interface
6762 lines =<< trim END
6763 vim9script
6764 interface A
6765 endinterface
6766 interface B implements A
6767 endinterface
6768 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006769 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006770
6771 # interface cannot extend multiple interfaces
6772 lines =<< trim END
6773 vim9script
6774 interface A
6775 endinterface
6776 interface B
6777 endinterface
6778 interface C extends A, B
6779 endinterface
6780 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006781 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006782
6783 # Variable type in an extended interface is of different type
6784 lines =<< trim END
6785 vim9script
6786 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006787 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006788 endinterface
6789 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006790 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006791 endinterface
6792 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006793 var val1: string
6794 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006795 endinterface
6796 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006797 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006798enddef
6799
6800" Test for a child class implementing an interface when some of the methods are
6801" defined in the parent class.
6802def Test_child_class_implements_interface()
6803 var lines =<< trim END
6804 vim9script
6805
6806 interface Intf
6807 def F1(): list<list<number>>
6808 def F2(): list<list<number>>
6809 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006810 var var1: list<dict<number>>
6811 var var2: list<dict<number>>
6812 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006813 endinterface
6814
6815 class A
6816 def A1()
6817 enddef
6818 def F3(): list<list<number>>
6819 return [[3]]
6820 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006821 var v1: list<list<number>> = [[0]]
6822 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006823 endclass
6824
6825 class B extends A
6826 def B1()
6827 enddef
6828 def F2(): list<list<number>>
6829 return [[2]]
6830 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006831 var v2: list<list<number>> = [[0]]
6832 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006833 endclass
6834
6835 class C extends B implements Intf
6836 def C1()
6837 enddef
6838 def F1(): list<list<number>>
6839 return [[1]]
6840 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006841 var v3: list<list<number>> = [[0]]
6842 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006843 endclass
6844
6845 def T(if: Intf)
6846 assert_equal([[1]], if.F1())
6847 assert_equal([[2]], if.F2())
6848 assert_equal([[3]], if.F3())
6849 assert_equal([{a: 10}], if.var1)
6850 assert_equal([{b: 20}], if.var2)
6851 assert_equal([{c: 30}], if.var3)
6852 enddef
6853
6854 var c = C.new()
6855 T(c)
6856 assert_equal([[1]], c.F1())
6857 assert_equal([[2]], c.F2())
6858 assert_equal([[3]], c.F3())
6859 assert_equal([{a: 10}], c.var1)
6860 assert_equal([{b: 20}], c.var2)
6861 assert_equal([{c: 30}], c.var3)
6862 END
6863 v9.CheckSourceSuccess(lines)
6864
6865 # One of the interface methods is not found
6866 lines =<< trim END
6867 vim9script
6868
6869 interface Intf
6870 def F1()
6871 def F2()
6872 def F3()
6873 endinterface
6874
6875 class A
6876 def A1()
6877 enddef
6878 endclass
6879
6880 class B extends A
6881 def B1()
6882 enddef
6883 def F2()
6884 enddef
6885 endclass
6886
6887 class C extends B implements Intf
6888 def C1()
6889 enddef
6890 def F1()
6891 enddef
6892 endclass
6893 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006894 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006895
6896 # One of the interface methods is of different type
6897 lines =<< trim END
6898 vim9script
6899
6900 interface Intf
6901 def F1()
6902 def F2()
6903 def F3()
6904 endinterface
6905
6906 class A
6907 def F3(): number
6908 return 0
6909 enddef
6910 def A1()
6911 enddef
6912 endclass
6913
6914 class B extends A
6915 def B1()
6916 enddef
6917 def F2()
6918 enddef
6919 endclass
6920
6921 class C extends B implements Intf
6922 def C1()
6923 enddef
6924 def F1()
6925 enddef
6926 endclass
6927 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006928 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006929
6930 # One of the interface variables is not present
6931 lines =<< trim END
6932 vim9script
6933
6934 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006935 var var1: list<dict<number>>
6936 var var2: list<dict<number>>
6937 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006938 endinterface
6939
6940 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006941 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006942 endclass
6943
6944 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006945 var v2: list<list<number>> = [[0]]
6946 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006947 endclass
6948
6949 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006950 var v3: list<list<number>> = [[0]]
6951 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006952 endclass
6953 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006954 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006955
6956 # One of the interface variables is of different type
6957 lines =<< trim END
6958 vim9script
6959
6960 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006961 var var1: list<dict<number>>
6962 var var2: list<dict<number>>
6963 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006964 endinterface
6965
6966 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006967 var v1: list<list<number>> = [[0]]
6968 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006969 endclass
6970
6971 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006972 var v2: list<list<number>> = [[0]]
6973 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006974 endclass
6975
6976 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006977 var v3: list<list<number>> = [[0]]
6978 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006979 endclass
6980 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006981 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 +02006982enddef
6983
6984" Test for extending an interface with duplicate variables and methods
6985def Test_interface_extends_with_dup_members()
6986 var lines =<< trim END
6987 vim9script
6988 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006989 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006990 def Foo1(): number
6991 endinterface
6992 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006993 var n2: number
6994 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006995 def Foo2(): number
6996 def Foo1(): number
6997 endinterface
6998 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006999 var n1 = 10
7000 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007001 def Foo1(): number
7002 return 30
7003 enddef
7004 def Foo2(): number
7005 return 40
7006 enddef
7007 endclass
7008 def T1(a: A)
7009 assert_equal(10, a.n1)
7010 assert_equal(30, a.Foo1())
7011 enddef
7012 def T2(b: B)
7013 assert_equal(10, b.n1)
7014 assert_equal(20, b.n2)
7015 assert_equal(30, b.Foo1())
7016 assert_equal(40, b.Foo2())
7017 enddef
7018 var c = C.new()
7019 T1(c)
7020 T2(c)
7021 END
7022 v9.CheckSourceSuccess(lines)
7023enddef
7024
7025" Test for using "any" type for a variable in a sub-class while it has a
7026" concrete type in the interface
7027def Test_implements_using_var_type_any()
7028 var lines =<< trim END
7029 vim9script
7030 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007031 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007032 endinterface
7033 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007034 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007035 endclass
7036 var b = B.new()
7037 assert_equal([{a: '1'}, {b: '2'}], b.val)
7038 END
7039 v9.CheckSourceSuccess(lines)
7040
7041 # initialize instance variable using a different type
7042 lines =<< trim END
7043 vim9script
7044 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007045 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007046 endinterface
7047 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007048 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007049 endclass
7050 var b = B.new()
7051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007052 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007053enddef
7054
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007055" Test for assigning to a member variable in a nested class
7056def Test_nested_object_assignment()
7057 var lines =<< trim END
7058 vim9script
7059
7060 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007061 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007062 endclass
7063
7064 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007065 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007066 endclass
7067
7068 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007069 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007070 endclass
7071
7072 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007073 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007074 endclass
7075
7076 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007077 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007078 enddef
7079
7080 var d = D.new()
7081 T(d)
7082 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007083 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007084enddef
7085
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007086" Test for calling methods using a null object
7087def Test_null_object_method_call()
7088 # Calling a object method using a null object in script context
7089 var lines =<< trim END
7090 vim9script
7091
7092 class C
7093 def Foo()
7094 assert_report('This method should not be executed')
7095 enddef
7096 endclass
7097
7098 var o: C
7099 o.Foo()
7100 END
7101 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7102
7103 # Calling a object method using a null object in def function context
7104 lines =<< trim END
7105 vim9script
7106
7107 class C
7108 def Foo()
7109 assert_report('This method should not be executed')
7110 enddef
7111 endclass
7112
7113 def T()
7114 var o: C
7115 o.Foo()
7116 enddef
7117 T()
7118 END
7119 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7120
7121 # Calling a object method through another class method using a null object in
7122 # script context
7123 lines =<< trim END
7124 vim9script
7125
7126 class C
7127 def Foo()
7128 assert_report('This method should not be executed')
7129 enddef
7130
7131 static def Bar(o_any: any)
7132 var o_typed: C = o_any
7133 o_typed.Foo()
7134 enddef
7135 endclass
7136
7137 var o: C
7138 C.Bar(o)
7139 END
7140 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7141
7142 # Calling a object method through another class method using a null object in
7143 # def function context
7144 lines =<< trim END
7145 vim9script
7146
7147 class C
7148 def Foo()
7149 assert_report('This method should not be executed')
7150 enddef
7151
7152 static def Bar(o_any: any)
7153 var o_typed: C = o_any
7154 o_typed.Foo()
7155 enddef
7156 endclass
7157
7158 def T()
7159 var o: C
7160 C.Bar(o)
7161 enddef
7162 T()
7163 END
7164 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7165enddef
7166
7167" Test for using a dict as an object member
7168def Test_dict_object_member()
7169 var lines =<< trim END
7170 vim9script
7171
7172 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007173 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007174 def GetState(): dict<number>
7175 return this.state
7176 enddef
7177 endclass
7178
7179 var ctx = Context.new()
7180 ctx.state->extend({a: 1})
7181 ctx.state['b'] = 2
7182 assert_equal({a: 1, b: 2}, ctx.GetState())
7183
7184 def F()
7185 ctx.state['c'] = 3
7186 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7187 enddef
7188 F()
7189 assert_equal(3, ctx.state.c)
7190 ctx.state.c = 4
7191 assert_equal(4, ctx.state.c)
7192 END
7193 v9.CheckSourceSuccess(lines)
7194enddef
7195
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007196" The following test was failing after 9.0.1914. This was caused by using a
7197" freed object from a previous method call.
7198def Test_freed_object_from_previous_method_call()
7199 var lines =<< trim END
7200 vim9script
7201
7202 class Context
7203 endclass
7204
7205 class Result
7206 endclass
7207
7208 def Failure(): Result
7209 return Result.new()
7210 enddef
7211
7212 def GetResult(ctx: Context): Result
7213 return Failure()
7214 enddef
7215
7216 def Test_GetResult()
7217 var ctx = Context.new()
7218 var result = GetResult(ctx)
7219 enddef
7220
7221 Test_GetResult()
7222 END
7223 v9.CheckSourceSuccess(lines)
7224enddef
7225
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007226" Test for duplicate object and class variable
7227def Test_duplicate_variable()
7228 # Object variable name is same as the class variable name
7229 var lines =<< trim END
7230 vim9script
7231 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007232 public static var sval: number
7233 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007234 endclass
7235 var a = A.new()
7236 END
7237 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7238
7239 # Duplicate variable name and calling a class method
7240 lines =<< trim END
7241 vim9script
7242 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007243 public static var sval: number
7244 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007245 def F1()
7246 echo this.sval
7247 enddef
7248 static def F2()
7249 echo sval
7250 enddef
7251 endclass
7252 A.F2()
7253 END
7254 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7255
7256 # Duplicate variable with an empty constructor
7257 lines =<< trim END
7258 vim9script
7259 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007260 public static var sval: number
7261 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007262 def new()
7263 enddef
7264 endclass
7265 var a = A.new()
7266 END
7267 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7268enddef
7269
7270" Test for using a reserved keyword as a variable name
7271def Test_reserved_varname()
7272 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7273 'null_function', 'null_list', 'null_partial', 'null_string',
7274 'null_channel', 'null_job', 'super', 'this']
7275
7276 var lines =<< trim eval END
7277 vim9script
7278 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007279 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007280 endclass
7281 var o = C.new()
7282 END
7283 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7284
7285 lines =<< trim eval END
7286 vim9script
7287 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007288 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007289 def new()
7290 enddef
7291 endclass
7292 var o = C.new()
7293 END
7294 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7295
7296 lines =<< trim eval END
7297 vim9script
7298 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007299 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007300 def new()
7301 enddef
7302 def F()
7303 echo this.{kword}
7304 enddef
7305 endclass
7306 var o = C.new()
7307 o.F()
7308 END
7309 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007310
7311 # class variable name
7312 if kword != 'this'
7313 lines =<< trim eval END
7314 vim9script
7315 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007316 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007317 endclass
7318 END
7319 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7320 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007321 endfor
7322enddef
7323
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007324" Test for checking the type of the arguments and the return value of a object
7325" method in an extended class.
7326def Test_extended_obj_method_type_check()
7327 var lines =<< trim END
7328 vim9script
7329
7330 class A
7331 endclass
7332 class B extends A
7333 endclass
7334 class C extends B
7335 endclass
7336
7337 class Foo
7338 def Doit(p: B): B
7339 return B.new()
7340 enddef
7341 endclass
7342
7343 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007344 def Doit(p: C): B
7345 return B.new()
7346 enddef
7347 endclass
7348 END
7349 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7350
7351 lines =<< trim END
7352 vim9script
7353
7354 class A
7355 endclass
7356 class B extends A
7357 endclass
7358 class C extends B
7359 endclass
7360
7361 class Foo
7362 def Doit(p: B): B
7363 return B.new()
7364 enddef
7365 endclass
7366
7367 class Bar extends Foo
7368 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007369 return C.new()
7370 enddef
7371 endclass
7372 END
7373 v9.CheckSourceSuccess(lines)
7374
7375 lines =<< trim END
7376 vim9script
7377
7378 class A
7379 endclass
7380 class B extends A
7381 endclass
7382 class C extends B
7383 endclass
7384
7385 class Foo
7386 def Doit(p: B): B
7387 return B.new()
7388 enddef
7389 endclass
7390
7391 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007392 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007393 return B.new()
7394 enddef
7395 endclass
7396 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007397 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 +02007398
7399 lines =<< trim END
7400 vim9script
7401
7402 class A
7403 endclass
7404 class B extends A
7405 endclass
7406 class C extends B
7407 endclass
7408
7409 class Foo
7410 def Doit(p: B): B
7411 return B.new()
7412 enddef
7413 endclass
7414
7415 class Bar extends Foo
7416 def Doit(p: B): A
7417 return A.new()
7418 enddef
7419 endclass
7420 END
7421 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 +02007422
7423 # check varargs type mismatch
7424 lines =<< trim END
7425 vim9script
7426
7427 class B
7428 def F(...xxx: list<any>)
7429 enddef
7430 endclass
7431 class C extends B
7432 def F(xxx: list<any>)
7433 enddef
7434 endclass
7435 END
7436 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 +02007437enddef
7438
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007439" Test type checking for class variable in assignments
7440func Test_class_variable_complex_type_check()
7441 " class variable with a specific type. Try assigning a different type at
7442 " script level.
7443 let lines =<< trim END
7444 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007445 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007446 return {}
7447 enddef
7448 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007449 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007450 endclass
7451 test_garbagecollect_now()
7452 A.Fn = "abc"
7453 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007454 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 +02007455
7456 " class variable with a specific type. Try assigning a different type at
7457 " class def method level.
7458 let lines =<< trim END
7459 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007460 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007461 return {}
7462 enddef
7463 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007464 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007465 def Bar()
7466 Fn = "abc"
7467 enddef
7468 endclass
7469 var a = A.new()
7470 test_garbagecollect_now()
7471 a.Bar()
7472 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007473 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 +02007474
7475 " class variable with a specific type. Try assigning a different type at
7476 " script def method level.
7477 let lines =<< trim END
7478 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007479 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007480 return {}
7481 enddef
7482 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007483 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007484 endclass
7485 def Bar()
7486 A.Fn = "abc"
7487 enddef
7488 test_garbagecollect_now()
7489 Bar()
7490 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007491 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 +02007492
7493 " class variable without any type. Should be set to the initialization
7494 " expression type. Try assigning a different type from script level.
7495 let lines =<< trim END
7496 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007497 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007498 return {}
7499 enddef
7500 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007501 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007502 endclass
7503 test_garbagecollect_now()
7504 A.Fn = "abc"
7505 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007506 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 +02007507
7508 " class variable without any type. Should be set to the initialization
7509 " expression type. Try assigning a different type at class def level.
7510 let lines =<< trim END
7511 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007512 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007513 return {}
7514 enddef
7515 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007516 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007517 def Bar()
7518 Fn = "abc"
7519 enddef
7520 endclass
7521 var a = A.new()
7522 test_garbagecollect_now()
7523 a.Bar()
7524 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007525 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 +02007526
7527 " class variable without any type. Should be set to the initialization
7528 " expression type. Try assigning a different type at script def level.
7529 let lines =<< trim END
7530 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007531 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007532 return {}
7533 enddef
7534 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007535 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007536 endclass
7537 def Bar()
7538 A.Fn = "abc"
7539 enddef
7540 test_garbagecollect_now()
7541 Bar()
7542 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007543 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 +02007544
7545 " class variable with 'any" type. Can be assigned different types.
7546 let lines =<< trim END
7547 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007548 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007549 return {}
7550 enddef
7551 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007552 public static var Fn: any = Foo
7553 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007554 endclass
7555 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007556 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007557 A.Fn = "abc"
7558 test_garbagecollect_now()
7559 assert_equal('string', typename(A.Fn))
7560 A.Fn2 = Foo
7561 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007562 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007563 A.Fn2 = "xyz"
7564 test_garbagecollect_now()
7565 assert_equal('string', typename(A.Fn2))
7566 END
7567 call v9.CheckSourceSuccess(lines)
7568
7569 " class variable with 'any" type. Can be assigned different types.
7570 let lines =<< trim END
7571 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007572 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007573 return {}
7574 enddef
7575 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007576 public static var Fn: any = Foo
7577 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007578
7579 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007580 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007581 Fn = "abc"
7582 assert_equal('string', typename(Fn))
7583 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007584 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007585 Fn2 = "xyz"
7586 assert_equal('string', typename(Fn2))
7587 enddef
7588 endclass
7589 var a = A.new()
7590 test_garbagecollect_now()
7591 a.Bar()
7592 test_garbagecollect_now()
7593 A.Fn = Foo
7594 a.Bar()
7595 END
7596 call v9.CheckSourceSuccess(lines)
7597
7598 " class variable with 'any" type. Can be assigned different types.
7599 let lines =<< trim END
7600 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007601 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007602 return {}
7603 enddef
7604 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007605 public static var Fn: any = Foo
7606 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007607 endclass
7608
7609 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007610 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007611 A.Fn = "abc"
7612 assert_equal('string', typename(A.Fn))
7613 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007614 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007615 A.Fn2 = "xyz"
7616 assert_equal('string', typename(A.Fn2))
7617 enddef
7618 Bar()
7619 test_garbagecollect_now()
7620 A.Fn = Foo
7621 Bar()
7622 END
7623 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007624
7625 let lines =<< trim END
7626 vim9script
7627 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007628 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007629 endclass
7630 assert_equal([0z10, 0z20], A.foo)
7631 A.foo = [0z30]
7632 assert_equal([0z30], A.foo)
7633 var a = A.foo
7634 assert_equal([0z30], a)
7635 END
7636 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007637endfunc
7638
7639" Test type checking for object variable in assignments
7640func Test_object_variable_complex_type_check()
7641 " object variable with a specific type. Try assigning a different type at
7642 " script level.
7643 let lines =<< trim END
7644 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007645 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007646 return {}
7647 enddef
7648 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007649 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007650 endclass
7651 var a = A.new()
7652 test_garbagecollect_now()
7653 a.Fn = "abc"
7654 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007655 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 +02007656
7657 " object variable with a specific type. Try assigning a different type at
7658 " object def method level.
7659 let lines =<< trim END
7660 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007661 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007662 return {}
7663 enddef
7664 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007665 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007666 def Bar()
7667 this.Fn = "abc"
7668 this.Fn = Foo
7669 enddef
7670 endclass
7671 var a = A.new()
7672 test_garbagecollect_now()
7673 a.Bar()
7674 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007675 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 +02007676
7677 " object variable with a specific type. Try assigning a different type at
7678 " script def method level.
7679 let lines =<< trim END
7680 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007681 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007682 return {}
7683 enddef
7684 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007685 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007686 endclass
7687 def Bar()
7688 var a = A.new()
7689 a.Fn = "abc"
7690 a.Fn = Foo
7691 enddef
7692 test_garbagecollect_now()
7693 Bar()
7694 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007695 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 +02007696
7697 " object variable without any type. Should be set to the initialization
7698 " expression type. Try assigning a different type from script level.
7699 let lines =<< trim END
7700 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007701 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007702 return {}
7703 enddef
7704 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007705 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007706 endclass
7707 var a = A.new()
7708 test_garbagecollect_now()
7709 a.Fn = "abc"
7710 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007711 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 +02007712
7713 " object variable without any type. Should be set to the initialization
7714 " expression type. Try assigning a different type at object def level.
7715 let lines =<< trim END
7716 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007717 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007718 return {}
7719 enddef
7720 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007721 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007722 def Bar()
7723 this.Fn = "abc"
7724 this.Fn = Foo
7725 enddef
7726 endclass
7727 var a = A.new()
7728 test_garbagecollect_now()
7729 a.Bar()
7730 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007731 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 +02007732
7733 " object variable without any type. Should be set to the initialization
7734 " expression type. Try assigning a different type at script def level.
7735 let lines =<< trim END
7736 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007737 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007738 return {}
7739 enddef
7740 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007741 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007742 endclass
7743 def Bar()
7744 var a = A.new()
7745 a.Fn = "abc"
7746 a.Fn = Foo
7747 enddef
7748 test_garbagecollect_now()
7749 Bar()
7750 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007751 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 +02007752
7753 " object variable with 'any" type. Can be assigned different types.
7754 let lines =<< trim END
7755 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007756 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007757 return {}
7758 enddef
7759 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007760 public var Fn: any = Foo
7761 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007762 endclass
7763
7764 var a = A.new()
7765 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007766 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007767 a.Fn = "abc"
7768 test_garbagecollect_now()
7769 assert_equal('string', typename(a.Fn))
7770 a.Fn2 = Foo
7771 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007772 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007773 a.Fn2 = "xyz"
7774 test_garbagecollect_now()
7775 assert_equal('string', typename(a.Fn2))
7776 END
7777 call v9.CheckSourceSuccess(lines)
7778
7779 " object variable with 'any" type. Can be assigned different types.
7780 let lines =<< trim END
7781 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007782 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007783 return {}
7784 enddef
7785 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007786 public var Fn: any = Foo
7787 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007788
7789 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007790 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007791 this.Fn = "abc"
7792 assert_equal('string', typename(this.Fn))
7793 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007794 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007795 this.Fn2 = "xyz"
7796 assert_equal('string', typename(this.Fn2))
7797 enddef
7798 endclass
7799
7800 var a = A.new()
7801 test_garbagecollect_now()
7802 a.Bar()
7803 test_garbagecollect_now()
7804 a.Fn = Foo
7805 a.Bar()
7806 END
7807 call v9.CheckSourceSuccess(lines)
7808
7809 " object variable with 'any" type. Can be assigned different types.
7810 let lines =<< trim END
7811 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007812 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007813 return {}
7814 enddef
7815 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007816 public var Fn: any = Foo
7817 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007818 endclass
7819
7820 def Bar()
7821 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007822 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007823 a.Fn = "abc"
7824 assert_equal('string', typename(a.Fn))
7825 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007826 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007827 a.Fn2 = "xyz"
7828 assert_equal('string', typename(a.Fn2))
7829 enddef
7830 test_garbagecollect_now()
7831 Bar()
7832 test_garbagecollect_now()
7833 Bar()
7834 END
7835 call v9.CheckSourceSuccess(lines)
7836endfunc
7837
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007838" Test for recursively calling an object method. This used to cause an
7839" use-after-free error.
7840def Test_recursive_object_method_call()
7841 var lines =<< trim END
7842 vim9script
7843 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007844 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007845 def Foo(): number
7846 if this.val >= 90
7847 return this.val
7848 endif
7849 this.val += 1
7850 return this.Foo()
7851 enddef
7852 endclass
7853 var a = A.new()
7854 assert_equal(90, a.Foo())
7855 END
7856 v9.CheckSourceSuccess(lines)
7857enddef
7858
7859" Test for recursively calling a class method.
7860def Test_recursive_class_method_call()
7861 var lines =<< trim END
7862 vim9script
7863 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007864 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007865 static def Foo(): number
7866 if val >= 90
7867 return val
7868 endif
7869 val += 1
7870 return Foo()
7871 enddef
7872 endclass
7873 assert_equal(90, A.Foo())
7874 END
7875 v9.CheckSourceSuccess(lines)
7876enddef
7877
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007878" Test for checking the argument types and the return type when assigning a
7879" funcref to make sure the invariant class type is used.
7880def Test_funcref_argtype_returntype_check()
7881 var lines =<< trim END
7882 vim9script
7883 class A
7884 endclass
7885 class B extends A
7886 endclass
7887
7888 def Foo(p: B): B
7889 return B.new()
7890 enddef
7891
7892 var Bar: func(A): A = Foo
7893 END
7894 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7895
7896 lines =<< trim END
7897 vim9script
7898 class A
7899 endclass
7900 class B extends A
7901 endclass
7902
7903 def Foo(p: B): B
7904 return B.new()
7905 enddef
7906
7907 def Baz()
7908 var Bar: func(A): A = Foo
7909 enddef
7910 Baz()
7911 END
7912 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7913enddef
7914
Ernie Rael96952b22023-10-17 18:15:01 +02007915def Test_funcref_argtype_invariance_check()
7916 var lines =<< trim END
7917 vim9script
7918
7919 class A
7920 endclass
7921 class B extends A
7922 endclass
7923 class C extends B
7924 endclass
7925
7926 var Func: func(B): number
7927 Func = (o: B): number => 3
7928 assert_equal(3, Func(B.new()))
7929 END
7930 v9.CheckSourceSuccess(lines)
7931
7932 lines =<< trim END
7933 vim9script
7934
7935 class A
7936 endclass
7937 class B extends A
7938 endclass
7939 class C extends B
7940 endclass
7941
7942 var Func: func(B): number
7943 Func = (o: A): number => 3
7944 END
7945 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7946
7947 lines =<< trim END
7948 vim9script
7949
7950 class A
7951 endclass
7952 class B extends A
7953 endclass
7954 class C extends B
7955 endclass
7956
7957 var Func: func(B): number
7958 Func = (o: C): number => 3
7959 END
7960 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7961enddef
7962
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007963" Test for using an operator (e.g. +) with an assignment
7964def Test_op_and_assignment()
7965 # Using += with a class variable
7966 var lines =<< trim END
7967 vim9script
7968 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007969 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007970 static def Foo(): list<number>
7971 val += [1]
7972 return val
7973 enddef
7974 endclass
7975 def Bar(): list<number>
7976 A.val += [2]
7977 return A.val
7978 enddef
7979 assert_equal([1], A.Foo())
7980 assert_equal([1, 2], Bar())
7981 A.val += [3]
7982 assert_equal([1, 2, 3], A.val)
7983 END
7984 v9.CheckSourceSuccess(lines)
7985
7986 # Using += with an object variable
7987 lines =<< trim END
7988 vim9script
7989 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007990 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007991 def Foo(): list<number>
7992 this.val += [1]
7993 return this.val
7994 enddef
7995 endclass
7996 def Bar(bar_a: A): list<number>
7997 bar_a.val += [2]
7998 return bar_a.val
7999 enddef
8000 var a = A.new()
8001 assert_equal([1], a.Foo())
8002 assert_equal([1, 2], Bar(a))
8003 a.val += [3]
8004 assert_equal([1, 2, 3], a.val)
8005 END
8006 v9.CheckSourceSuccess(lines)
8007enddef
8008
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008009" Test for using an object method as a funcref
8010def Test_object_funcref()
8011 # Using object method funcref from a def function
8012 var lines =<< trim END
8013 vim9script
8014 class A
8015 def Foo(): list<number>
8016 return [3, 2, 1]
8017 enddef
8018 endclass
8019 def Bar()
8020 var a = A.new()
8021 var Fn = a.Foo
8022 assert_equal([3, 2, 1], Fn())
8023 enddef
8024 Bar()
8025 END
8026 v9.CheckSourceSuccess(lines)
8027
8028 # Using object method funcref at the script level
8029 lines =<< trim END
8030 vim9script
8031 class A
8032 def Foo(): dict<number>
8033 return {a: 1, b: 2}
8034 enddef
8035 endclass
8036 var a = A.new()
8037 var Fn = a.Foo
8038 assert_equal({a: 1, b: 2}, Fn())
8039 END
8040 v9.CheckSourceSuccess(lines)
8041
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008042 # Using object method funcref at the script level
8043 lines =<< trim END
8044 vim9script
8045 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008046 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008047 def Foo(): number
8048 return this.val
8049 enddef
8050 endclass
8051 var a = A.new(345)
8052 var Fn = a.Foo
8053 assert_equal(345, Fn())
8054 END
8055 v9.CheckSourceSuccess(lines)
8056
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008057 # Using object method funcref from another object method
8058 lines =<< trim END
8059 vim9script
8060 class A
8061 def Foo(): list<number>
8062 return [3, 2, 1]
8063 enddef
8064 def Bar()
8065 var Fn = this.Foo
8066 assert_equal([3, 2, 1], Fn())
8067 enddef
8068 endclass
8069 var a = A.new()
8070 a.Bar()
8071 END
8072 v9.CheckSourceSuccess(lines)
8073
8074 # Using function() to get a object method funcref
8075 lines =<< trim END
8076 vim9script
8077 class A
8078 def Foo(l: list<any>): list<any>
8079 return l
8080 enddef
8081 endclass
8082 var a = A.new()
8083 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8084 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8085 END
8086 v9.CheckSourceSuccess(lines)
8087
8088 # Use an object method with a function returning a funcref and then call the
8089 # funcref.
8090 lines =<< trim END
8091 vim9script
8092
8093 def Map(F: func(number): number): func(number): number
8094 return (n: number) => F(n)
8095 enddef
8096
8097 class Math
8098 def Double(n: number): number
8099 return 2 * n
8100 enddef
8101 endclass
8102
8103 const math = Math.new()
8104 assert_equal(48, Map(math.Double)(24))
8105 END
8106 v9.CheckSourceSuccess(lines)
8107
Ernie Rael03042a22023-11-11 08:53:32 +01008108 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008109 lines =<< trim END
8110 vim9script
8111 class A
8112 def _Foo()
8113 enddef
8114 endclass
8115 def Bar()
8116 var a = A.new()
8117 var Fn = a._Foo
8118 enddef
8119 Bar()
8120 END
Ernie Rael03042a22023-11-11 08:53:32 +01008121 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008122
Ernie Rael03042a22023-11-11 08:53:32 +01008123 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008124 lines =<< trim END
8125 vim9script
8126 class A
8127 def _Foo()
8128 enddef
8129 endclass
8130 var a = A.new()
8131 var Fn = a._Foo
8132 END
Ernie Rael03042a22023-11-11 08:53:32 +01008133 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008134
Ernie Rael03042a22023-11-11 08:53:32 +01008135 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008136 lines =<< trim END
8137 vim9script
8138 class A
8139 def _Foo(): list<number>
8140 return [3, 2, 1]
8141 enddef
8142 def Bar()
8143 var Fn = this._Foo
8144 assert_equal([3, 2, 1], Fn())
8145 enddef
8146 endclass
8147 var a = A.new()
8148 a.Bar()
8149 END
8150 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008151
8152 # Using object method funcref using call()
8153 lines =<< trim END
8154 vim9script
8155 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008156 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008157 def Foo(): number
8158 return this.val
8159 enddef
8160 endclass
8161
8162 def Bar(obj: A)
8163 assert_equal(123, call(obj.Foo, []))
8164 enddef
8165
8166 var a = A.new(123)
8167 Bar(a)
8168 assert_equal(123, call(a.Foo, []))
8169 END
8170 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008171enddef
8172
8173" Test for using a class method as a funcref
8174def Test_class_funcref()
8175 # Using class method funcref in a def function
8176 var lines =<< trim END
8177 vim9script
8178 class A
8179 static def Foo(): list<number>
8180 return [3, 2, 1]
8181 enddef
8182 endclass
8183 def Bar()
8184 var Fn = A.Foo
8185 assert_equal([3, 2, 1], Fn())
8186 enddef
8187 Bar()
8188 END
8189 v9.CheckSourceSuccess(lines)
8190
8191 # Using class method funcref at script level
8192 lines =<< trim END
8193 vim9script
8194 class A
8195 static def Foo(): dict<number>
8196 return {a: 1, b: 2}
8197 enddef
8198 endclass
8199 var Fn = A.Foo
8200 assert_equal({a: 1, b: 2}, Fn())
8201 END
8202 v9.CheckSourceSuccess(lines)
8203
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008204 # Using class method funcref at the script level
8205 lines =<< trim END
8206 vim9script
8207 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008208 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008209 static def Foo(): number
8210 return val
8211 enddef
8212 endclass
8213 A.val = 567
8214 var Fn = A.Foo
8215 assert_equal(567, Fn())
8216 END
8217 v9.CheckSourceSuccess(lines)
8218
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008219 # Using function() to get a class method funcref
8220 lines =<< trim END
8221 vim9script
8222 class A
8223 static def Foo(l: list<any>): list<any>
8224 return l
8225 enddef
8226 endclass
8227 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8228 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8229 END
8230 v9.CheckSourceSuccess(lines)
8231
8232 # Using a class method funcref from another class method
8233 lines =<< trim END
8234 vim9script
8235 class A
8236 static def Foo(): list<number>
8237 return [3, 2, 1]
8238 enddef
8239 static def Bar()
8240 var Fn = Foo
8241 assert_equal([3, 2, 1], Fn())
8242 enddef
8243 endclass
8244 A.Bar()
8245 END
8246 v9.CheckSourceSuccess(lines)
8247
8248 # Use a class method with a function returning a funcref and then call the
8249 # funcref.
8250 lines =<< trim END
8251 vim9script
8252
8253 def Map(F: func(number): number): func(number): number
8254 return (n: number) => F(n)
8255 enddef
8256
8257 class Math
8258 static def StaticDouble(n: number): number
8259 return 2 * n
8260 enddef
8261 endclass
8262
8263 assert_equal(48, Map(Math.StaticDouble)(24))
8264 END
8265 v9.CheckSourceSuccess(lines)
8266
Ernie Rael03042a22023-11-11 08:53:32 +01008267 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008268 lines =<< trim END
8269 vim9script
8270 class A
8271 static def _Foo()
8272 enddef
8273 endclass
8274 def Bar()
8275 var Fn = A._Foo
8276 enddef
8277 Bar()
8278 END
Ernie Rael03042a22023-11-11 08:53:32 +01008279 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008280
Ernie Rael03042a22023-11-11 08:53:32 +01008281 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008282 lines =<< trim END
8283 vim9script
8284 class A
8285 static def _Foo()
8286 enddef
8287 endclass
8288 var Fn = A._Foo
8289 END
Ernie Rael03042a22023-11-11 08:53:32 +01008290 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008291
Ernie Rael03042a22023-11-11 08:53:32 +01008292 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008293 lines =<< trim END
8294 vim9script
8295 class A
8296 static def _Foo(): list<number>
8297 return [3, 2, 1]
8298 enddef
8299 static def Bar()
8300 var Fn = _Foo
8301 assert_equal([3, 2, 1], Fn())
8302 enddef
8303 endclass
8304 A.Bar()
8305 END
8306 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008307
8308 # Using class method funcref using call()
8309 lines =<< trim END
8310 vim9script
8311 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008312 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008313 static def Foo(): number
8314 return val
8315 enddef
8316 endclass
8317
8318 def Bar()
8319 A.val = 468
8320 assert_equal(468, call(A.Foo, []))
8321 enddef
8322 Bar()
8323 assert_equal(468, call(A.Foo, []))
8324 END
8325 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008326enddef
8327
8328" Test for using an object member as a funcref
8329def Test_object_member_funcref()
8330 # Using a funcref object variable in an object method
8331 var lines =<< trim END
8332 vim9script
8333 def Foo(n: number): number
8334 return n * 10
8335 enddef
8336
8337 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008338 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008339 def Bar()
8340 assert_equal(200, this.Cb(20))
8341 enddef
8342 endclass
8343
8344 var a = A.new()
8345 a.Bar()
8346 END
8347 v9.CheckSourceSuccess(lines)
8348
8349 # Using a funcref object variable in a def method
8350 lines =<< trim END
8351 vim9script
8352 def Foo(n: number): number
8353 return n * 10
8354 enddef
8355
8356 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008357 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008358 endclass
8359
8360 def Bar()
8361 var a = A.new()
8362 assert_equal(200, a.Cb(20))
8363 enddef
8364 Bar()
8365 END
8366 v9.CheckSourceSuccess(lines)
8367
8368 # Using a funcref object variable at script level
8369 lines =<< trim END
8370 vim9script
8371 def Foo(n: number): number
8372 return n * 10
8373 enddef
8374
8375 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008376 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008377 endclass
8378
8379 var a = A.new()
8380 assert_equal(200, a.Cb(20))
8381 END
8382 v9.CheckSourceSuccess(lines)
8383
8384 # Using a funcref object variable pointing to an object method in an object
8385 # method.
8386 lines =<< trim END
8387 vim9script
8388 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008389 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008390 def Foo(n: number): number
8391 return n * 10
8392 enddef
8393 def Bar()
8394 assert_equal(200, this.Cb(20))
8395 enddef
8396 endclass
8397
8398 var a = A.new()
8399 a.Bar()
8400 END
8401 v9.CheckSourceSuccess(lines)
8402
8403 # Using a funcref object variable pointing to an object method in a def
8404 # method.
8405 lines =<< trim END
8406 vim9script
8407 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008408 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008409 def Foo(n: number): number
8410 return n * 10
8411 enddef
8412 endclass
8413
8414 def Bar()
8415 var a = A.new()
8416 assert_equal(200, a.Cb(20))
8417 enddef
8418 Bar()
8419 END
8420 v9.CheckSourceSuccess(lines)
8421
8422 # Using a funcref object variable pointing to an object method at script
8423 # level.
8424 lines =<< trim END
8425 vim9script
8426 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008427 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008428 def Foo(n: number): number
8429 return n * 10
8430 enddef
8431 endclass
8432
8433 var a = A.new()
8434 assert_equal(200, a.Cb(20))
8435 END
8436 v9.CheckSourceSuccess(lines)
8437enddef
8438
8439" Test for using a class member as a funcref
8440def Test_class_member_funcref()
8441 # Using a funcref class variable in a class method
8442 var lines =<< trim END
8443 vim9script
8444 def Foo(n: number): number
8445 return n * 10
8446 enddef
8447
8448 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008449 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008450 static def Bar()
8451 assert_equal(200, Cb(20))
8452 enddef
8453 endclass
8454
8455 A.Bar()
8456 END
8457 v9.CheckSourceSuccess(lines)
8458
8459 # Using a funcref class variable in a def method
8460 lines =<< trim END
8461 vim9script
8462 def Foo(n: number): number
8463 return n * 10
8464 enddef
8465
8466 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008467 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008468 endclass
8469
8470 def Bar()
8471 assert_equal(200, A.Cb(20))
8472 enddef
8473 Bar()
8474 END
8475 v9.CheckSourceSuccess(lines)
8476
8477 # Using a funcref class variable at script level
8478 lines =<< trim END
8479 vim9script
8480 def Foo(n: number): number
8481 return n * 10
8482 enddef
8483
8484 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008485 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008486 endclass
8487
8488 assert_equal(200, A.Cb(20))
8489 END
8490 v9.CheckSourceSuccess(lines)
8491
8492 # Using a funcref class variable pointing to a class method in a class
8493 # method.
8494 lines =<< trim END
8495 vim9script
8496 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008497 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008498 static def Foo(n: number): number
8499 return n * 10
8500 enddef
8501 static def Init()
8502 Cb = Foo
8503 enddef
8504 static def Bar()
8505 assert_equal(200, Cb(20))
8506 enddef
8507 endclass
8508
8509 A.Init()
8510 A.Bar()
8511 END
8512 v9.CheckSourceSuccess(lines)
8513
8514 # Using a funcref class variable pointing to a class method in a def method.
8515 lines =<< trim END
8516 vim9script
8517 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008518 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008519 static def Foo(n: number): number
8520 return n * 10
8521 enddef
8522 static def Init()
8523 Cb = Foo
8524 enddef
8525 endclass
8526
8527 def Bar()
8528 A.Init()
8529 assert_equal(200, A.Cb(20))
8530 enddef
8531 Bar()
8532 END
8533 v9.CheckSourceSuccess(lines)
8534
8535 # Using a funcref class variable pointing to a class method at script level.
8536 lines =<< trim END
8537 vim9script
8538 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008539 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008540 static def Foo(n: number): number
8541 return n * 10
8542 enddef
8543 static def Init()
8544 Cb = Foo
8545 enddef
8546 endclass
8547
8548 A.Init()
8549 assert_equal(200, A.Cb(20))
8550 END
8551 v9.CheckSourceSuccess(lines)
8552enddef
8553
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008554" Test for using object methods as popup callback functions
8555def Test_objmethod_popup_callback()
8556 # Use the popup from the script level
8557 var lines =<< trim END
8558 vim9script
8559
8560 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008561 var selection: number = -1
8562 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008563
8564 def PopupFilter(id: number, key: string): bool
8565 add(this.filterkeys, key)
8566 return popup_filter_yesno(id, key)
8567 enddef
8568
8569 def PopupCb(id: number, result: number)
8570 this.selection = result ? 100 : 200
8571 enddef
8572 endclass
8573
8574 var a = A.new()
8575 feedkeys('', 'xt')
8576 var winid = popup_create('Y/N?',
8577 {filter: a.PopupFilter, callback: a.PopupCb})
8578 feedkeys('y', 'xt')
8579 popup_close(winid)
8580 assert_equal(100, a.selection)
8581 assert_equal(['y'], a.filterkeys)
8582 feedkeys('', 'xt')
8583 winid = popup_create('Y/N?',
8584 {filter: a.PopupFilter, callback: a.PopupCb})
8585 feedkeys('n', 'xt')
8586 popup_close(winid)
8587 assert_equal(200, a.selection)
8588 assert_equal(['y', 'n'], a.filterkeys)
8589 END
8590 v9.CheckSourceSuccess(lines)
8591
8592 # Use the popup from a def function
8593 lines =<< trim END
8594 vim9script
8595
8596 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008597 var selection: number = -1
8598 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008599
8600 def PopupFilter(id: number, key: string): bool
8601 add(this.filterkeys, key)
8602 return popup_filter_yesno(id, key)
8603 enddef
8604
8605 def PopupCb(id: number, result: number)
8606 this.selection = result ? 100 : 200
8607 enddef
8608 endclass
8609
8610 def Foo()
8611 var a = A.new()
8612 feedkeys('', 'xt')
8613 var winid = popup_create('Y/N?',
8614 {filter: a.PopupFilter, callback: a.PopupCb})
8615 feedkeys('y', 'xt')
8616 popup_close(winid)
8617 assert_equal(100, a.selection)
8618 assert_equal(['y'], a.filterkeys)
8619 feedkeys('', 'xt')
8620 winid = popup_create('Y/N?',
8621 {filter: a.PopupFilter, callback: a.PopupCb})
8622 feedkeys('n', 'xt')
8623 popup_close(winid)
8624 assert_equal(200, a.selection)
8625 assert_equal(['y', 'n'], a.filterkeys)
8626 enddef
8627 Foo()
8628 END
8629 v9.CheckSourceSuccess(lines)
8630enddef
8631
8632" Test for using class methods as popup callback functions
8633def Test_classmethod_popup_callback()
8634 # Use the popup from the script level
8635 var lines =<< trim END
8636 vim9script
8637
8638 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008639 static var selection: number = -1
8640 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008641
8642 static def PopupFilter(id: number, key: string): bool
8643 add(filterkeys, key)
8644 return popup_filter_yesno(id, key)
8645 enddef
8646
8647 static def PopupCb(id: number, result: number)
8648 selection = result ? 100 : 200
8649 enddef
8650 endclass
8651
8652 feedkeys('', 'xt')
8653 var winid = popup_create('Y/N?',
8654 {filter: A.PopupFilter, callback: A.PopupCb})
8655 feedkeys('y', 'xt')
8656 popup_close(winid)
8657 assert_equal(100, A.selection)
8658 assert_equal(['y'], A.filterkeys)
8659 feedkeys('', 'xt')
8660 winid = popup_create('Y/N?',
8661 {filter: A.PopupFilter, callback: A.PopupCb})
8662 feedkeys('n', 'xt')
8663 popup_close(winid)
8664 assert_equal(200, A.selection)
8665 assert_equal(['y', 'n'], A.filterkeys)
8666 END
8667 v9.CheckSourceSuccess(lines)
8668
8669 # Use the popup from a def function
8670 lines =<< trim END
8671 vim9script
8672
8673 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008674 static var selection: number = -1
8675 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008676
8677 static def PopupFilter(id: number, key: string): bool
8678 add(filterkeys, key)
8679 return popup_filter_yesno(id, key)
8680 enddef
8681
8682 static def PopupCb(id: number, result: number)
8683 selection = result ? 100 : 200
8684 enddef
8685 endclass
8686
8687 def Foo()
8688 feedkeys('', 'xt')
8689 var winid = popup_create('Y/N?',
8690 {filter: A.PopupFilter, callback: A.PopupCb})
8691 feedkeys('y', 'xt')
8692 popup_close(winid)
8693 assert_equal(100, A.selection)
8694 assert_equal(['y'], A.filterkeys)
8695 feedkeys('', 'xt')
8696 winid = popup_create('Y/N?',
8697 {filter: A.PopupFilter, callback: A.PopupCb})
8698 feedkeys('n', 'xt')
8699 popup_close(winid)
8700 assert_equal(200, A.selection)
8701 assert_equal(['y', 'n'], A.filterkeys)
8702 enddef
8703 Foo()
8704 END
8705 v9.CheckSourceSuccess(lines)
8706enddef
8707
8708" Test for using an object method as a timer callback function
8709def Test_objmethod_timer_callback()
8710 # Use the timer callback from script level
8711 var 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 var a = A.new()
8722 timer_start(0, a.TimerCb)
8723 var maxWait = 5
8724 while maxWait > 0 && a.timerTick == -1
8725 :sleep 10m
8726 maxWait -= 1
8727 endwhile
8728 assert_equal(6, a.timerTick)
8729 END
8730 v9.CheckSourceSuccess(lines)
8731
8732 # Use the timer callback from a def function
8733 lines =<< trim END
8734 vim9script
8735
8736 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008737 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008738 def TimerCb(timerID: number)
8739 this.timerTick = 6
8740 enddef
8741 endclass
8742
8743 def Foo()
8744 var a = A.new()
8745 timer_start(0, a.TimerCb)
8746 var maxWait = 5
8747 while maxWait > 0 && a.timerTick == -1
8748 :sleep 10m
8749 maxWait -= 1
8750 endwhile
8751 assert_equal(6, a.timerTick)
8752 enddef
8753 Foo()
8754 END
8755 v9.CheckSourceSuccess(lines)
8756enddef
8757
8758" Test for using a class method as a timer callback function
8759def Test_classmethod_timer_callback()
8760 # Use the timer callback from script level
8761 var lines =<< trim END
8762 vim9script
8763
8764 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008765 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008766 static def TimerCb(timerID: number)
8767 timerTick = 6
8768 enddef
8769 endclass
8770
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 END
8779 v9.CheckSourceSuccess(lines)
8780
8781 # Use the timer callback from a def function
8782 lines =<< trim END
8783 vim9script
8784
8785 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008786 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008787 static def TimerCb(timerID: number)
8788 timerTick = 6
8789 enddef
8790 endclass
8791
8792 def Foo()
8793 timer_start(0, A.TimerCb)
8794 var maxWait = 5
8795 while maxWait > 0 && A.timerTick == -1
8796 :sleep 10m
8797 maxWait -= 1
8798 endwhile
8799 assert_equal(6, A.timerTick)
8800 enddef
8801 Foo()
8802 END
8803 v9.CheckSourceSuccess(lines)
8804enddef
8805
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008806" Test for using a class variable as the first and/or second operand of a binary
8807" operator.
8808def Test_class_variable_as_operands()
8809 var lines =<< trim END
8810 vim9script
8811 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008812 static var truthy: bool = true
8813 public static var TruthyFn: func
8814 static var list: list<any> = []
8815 static var four: number = 4
8816 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008817
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008818 static def Str(): string
8819 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008820 enddef
8821
8822 static def Four(): number
8823 return four
8824 enddef
8825
8826 static def List(): list<any>
8827 return list
8828 enddef
8829
8830 static def Truthy(): bool
8831 return truthy
8832 enddef
8833
8834 def TestOps()
8835 assert_true(Tests.truthy == truthy)
8836 assert_true(truthy == Tests.truthy)
8837 assert_true(Tests.list isnot [])
8838 assert_true([] isnot Tests.list)
8839 assert_equal(2, Tests.four >> 1)
8840 assert_equal(16, 1 << Tests.four)
8841 assert_equal(8, Tests.four + four)
8842 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008843 assert_equal('hellohello', Tests.str .. str)
8844 assert_equal('hellohello', str .. Tests.str)
8845
8846 # Using class variable for list indexing
8847 var l = range(10)
8848 assert_equal(4, l[Tests.four])
8849 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8850
8851 # Using class variable for Dict key
8852 var d = {hello: 'abc'}
8853 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008854 enddef
8855 endclass
8856
8857 def TestOps2()
8858 assert_true(Tests.truthy == Tests.Truthy())
8859 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008860 assert_true(Tests.truthy == Tests.TruthyFn())
8861 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008862 assert_true(Tests.list is Tests.List())
8863 assert_true(Tests.List() is Tests.list)
8864 assert_equal(2, Tests.four >> 1)
8865 assert_equal(16, 1 << Tests.four)
8866 assert_equal(8, Tests.four + Tests.Four())
8867 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008868 assert_equal('hellohello', Tests.str .. Tests.Str())
8869 assert_equal('hellohello', Tests.Str() .. Tests.str)
8870
8871 # Using class variable for list indexing
8872 var l = range(10)
8873 assert_equal(4, l[Tests.four])
8874 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8875
8876 # Using class variable for Dict key
8877 var d = {hello: 'abc'}
8878 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008879 enddef
8880
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008881 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008882 var t = Tests.new()
8883 t.TestOps()
8884 TestOps2()
8885
8886 assert_true(Tests.truthy == Tests.Truthy())
8887 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008888 assert_true(Tests.truthy == Tests.TruthyFn())
8889 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008890 assert_true(Tests.list is Tests.List())
8891 assert_true(Tests.List() is Tests.list)
8892 assert_equal(2, Tests.four >> 1)
8893 assert_equal(16, 1 << Tests.four)
8894 assert_equal(8, Tests.four + Tests.Four())
8895 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008896 assert_equal('hellohello', Tests.str .. Tests.Str())
8897 assert_equal('hellohello', Tests.Str() .. Tests.str)
8898
8899 # Using class variable for list indexing
8900 var l = range(10)
8901 assert_equal(4, l[Tests.four])
8902 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8903
8904 # Using class variable for Dict key
8905 var d = {hello: 'abc'}
8906 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008907 END
8908 v9.CheckSourceSuccess(lines)
8909enddef
8910
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008911" Test for checking the type of the key used to access an object dict member.
8912def Test_dict_member_key_type_check()
8913 var lines =<< trim END
8914 vim9script
8915
8916 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01008917 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008918 endclass
8919
8920 class Test extends State
8921 def ObjMethodTests()
8922 var cursor: number = 0
8923 var z: number = 0
8924 [this.numbers[cursor]] = ['zero.1']
8925 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8926 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8927 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8928 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8929 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8930 [this.numbers[cursor], z] = ['zero.4', 1]
8931 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8932 [z, this.numbers[cursor]] = [1, 'zero.5']
8933 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8934 enddef
8935
8936 static def ClassMethodTests(that: State)
8937 var cursor: number = 0
8938 var z: number = 0
8939 [that.numbers[cursor]] = ['zero.1']
8940 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8941 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8942 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8943 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8944 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8945 [that.numbers[cursor], z] = ['zero.4', 1]
8946 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8947 [z, that.numbers[cursor]] = [1, 'zero.5']
8948 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8949 enddef
8950
8951 def new()
8952 enddef
8953
8954 def newMethodTests()
8955 var cursor: number = 0
8956 var z: number
8957 [this.numbers[cursor]] = ['zero.1']
8958 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8959 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8960 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8961 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8962 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8963 [this.numbers[cursor], z] = ['zero.4', 1]
8964 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8965 [z, this.numbers[cursor]] = [1, 'zero.5']
8966 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8967 enddef
8968 endclass
8969
8970 def DefFuncTests(that: Test)
8971 var cursor: number = 0
8972 var z: number
8973 [that.numbers[cursor]] = ['zero.1']
8974 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8975 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8976 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8977 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8978 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8979 [that.numbers[cursor], z] = ['zero.4', 1]
8980 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8981 [z, that.numbers[cursor]] = [1, 'zero.5']
8982 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8983 enddef
8984
8985 Test.newMethodTests()
8986 Test.new().ObjMethodTests()
8987 Test.ClassMethodTests(Test.new())
8988 DefFuncTests(Test.new())
8989
8990 const test: Test = Test.new()
8991 var cursor: number = 0
8992 [test.numbers[cursor], cursor] = ['zero', 1]
8993 [cursor, test.numbers[cursor]] = [1, 'one']
8994 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8995 END
8996 v9.CheckSourceSuccess(lines)
8997
8998 lines =<< trim END
8999 vim9script
9000
9001 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009002 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009003
9004 def new()
9005 enddef
9006
9007 def Foo()
9008 var z: number
9009 [this.numbers.a, z] = [{}, 10]
9010 enddef
9011 endclass
9012
9013 var a = A.new()
9014 a.Foo()
9015 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009016 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009017
9018 lines =<< trim END
9019 vim9script
9020
9021 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009022 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009023
9024 def new()
9025 enddef
9026
9027 def Foo()
9028 var x: string = 'a'
9029 var y: number
9030 [this.numbers[x], y] = [{}, 10]
9031 enddef
9032 endclass
9033
9034 var a = A.new()
9035 a.Foo()
9036 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009037 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009038enddef
9039
mityua5550692023-11-25 15:41:20 +01009040def Test_compile_many_def_functions_in_funcref_instr()
9041 # This used to crash Vim. This is reproducible only when run on new instance
9042 # of Vim.
9043 var lines =<< trim END
9044 vim9script
9045
9046 class A
9047 def new()
9048 this.TakeFunc(this.F00)
9049 enddef
9050
9051 def TakeFunc(F: func)
9052 enddef
9053
9054 def F00()
9055 this.F01()
9056 this.F02()
9057 this.F03()
9058 this.F04()
9059 this.F05()
9060 this.F06()
9061 this.F07()
9062 this.F08()
9063 this.F09()
9064 this.F10()
9065 this.F11()
9066 this.F12()
9067 this.F13()
9068 this.F14()
9069 this.F15()
9070 this.F16()
9071 this.F17()
9072 this.F18()
9073 this.F19()
9074 this.F20()
9075 this.F21()
9076 this.F22()
9077 this.F23()
9078 this.F24()
9079 this.F25()
9080 this.F26()
9081 this.F27()
9082 this.F28()
9083 this.F29()
9084 this.F30()
9085 this.F31()
9086 this.F32()
9087 this.F33()
9088 this.F34()
9089 this.F35()
9090 this.F36()
9091 this.F37()
9092 this.F38()
9093 this.F39()
9094 this.F40()
9095 this.F41()
9096 this.F42()
9097 this.F43()
9098 this.F44()
9099 this.F45()
9100 this.F46()
9101 this.F47()
9102 enddef
9103
9104 def F01()
9105 enddef
9106 def F02()
9107 enddef
9108 def F03()
9109 enddef
9110 def F04()
9111 enddef
9112 def F05()
9113 enddef
9114 def F06()
9115 enddef
9116 def F07()
9117 enddef
9118 def F08()
9119 enddef
9120 def F09()
9121 enddef
9122 def F10()
9123 enddef
9124 def F11()
9125 enddef
9126 def F12()
9127 enddef
9128 def F13()
9129 enddef
9130 def F14()
9131 enddef
9132 def F15()
9133 enddef
9134 def F16()
9135 enddef
9136 def F17()
9137 enddef
9138 def F18()
9139 enddef
9140 def F19()
9141 enddef
9142 def F20()
9143 enddef
9144 def F21()
9145 enddef
9146 def F22()
9147 enddef
9148 def F23()
9149 enddef
9150 def F24()
9151 enddef
9152 def F25()
9153 enddef
9154 def F26()
9155 enddef
9156 def F27()
9157 enddef
9158 def F28()
9159 enddef
9160 def F29()
9161 enddef
9162 def F30()
9163 enddef
9164 def F31()
9165 enddef
9166 def F32()
9167 enddef
9168 def F33()
9169 enddef
9170 def F34()
9171 enddef
9172 def F35()
9173 enddef
9174 def F36()
9175 enddef
9176 def F37()
9177 enddef
9178 def F38()
9179 enddef
9180 def F39()
9181 enddef
9182 def F40()
9183 enddef
9184 def F41()
9185 enddef
9186 def F42()
9187 enddef
9188 def F43()
9189 enddef
9190 def F44()
9191 enddef
9192 def F45()
9193 enddef
9194 def F46()
9195 enddef
9196 def F47()
9197 enddef
9198 endclass
9199
9200 A.new()
9201 END
9202 writefile(lines, 'Xscript', 'D')
9203 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9204 assert_equal(0, v:shell_error)
9205enddef
9206
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009207" Test for 'final' class and object variables
9208def Test_final_class_object_variable()
9209 # Test for changing a final object variable from an object function
9210 var lines =<< trim END
9211 vim9script
9212 class A
9213 final foo: string = "abc"
9214 def Foo()
9215 this.foo = "def"
9216 enddef
9217 endclass
9218 defcompile A.Foo
9219 END
9220 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9221
9222 # Test for changing a final object variable from the 'new' function
9223 lines =<< trim END
9224 vim9script
9225 class A
9226 final s1: string
9227 final s2: string
9228 def new(this.s1)
9229 this.s2 = 'def'
9230 enddef
9231 endclass
9232 var a = A.new('abc')
9233 assert_equal('abc', a.s1)
9234 assert_equal('def', a.s2)
9235 END
9236 v9.CheckSourceSuccess(lines)
9237
9238 # Test for a final class variable
9239 lines =<< trim END
9240 vim9script
9241 class A
9242 static final s1: string = "abc"
9243 endclass
9244 assert_equal('abc', A.s1)
9245 END
9246 v9.CheckSourceSuccess(lines)
9247
9248 # Test for changing a final class variable from a class function
9249 lines =<< trim END
9250 vim9script
9251 class A
9252 static final s1: string = "abc"
9253 static def Foo()
9254 s1 = "def"
9255 enddef
9256 endclass
9257 A.Foo()
9258 END
9259 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9260
9261 # Test for changing a public final class variable at script level
9262 lines =<< trim END
9263 vim9script
9264 class A
9265 public static final s1: string = "abc"
9266 endclass
9267 assert_equal('abc', A.s1)
9268 A.s1 = 'def'
9269 END
9270 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9271
9272 # Test for changing a public final class variable from a class function
9273 lines =<< trim END
9274 vim9script
9275 class A
9276 public static final s1: string = "abc"
9277 static def Foo()
9278 s1 = "def"
9279 enddef
9280 endclass
9281 A.Foo()
9282 END
9283 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9284
9285 # Test for changing a public final class variable from a function
9286 lines =<< trim END
9287 vim9script
9288 class A
9289 public static final s1: string = "abc"
9290 endclass
9291 def Foo()
9292 A.s1 = 'def'
9293 enddef
9294 defcompile
9295 END
9296 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9297
9298 # Test for using a final variable of composite type
9299 lines =<< trim END
9300 vim9script
9301 class A
9302 public final l: list<number>
9303 def new()
9304 this.l = [1, 2]
9305 enddef
9306 def Foo()
9307 this.l[0] = 3
9308 this.l->add(4)
9309 enddef
9310 endclass
9311 var a = A.new()
9312 assert_equal([1, 2], a.l)
9313 a.Foo()
9314 assert_equal([3, 2, 4], a.l)
9315 END
9316 v9.CheckSourceSuccess(lines)
9317
9318 # Test for changing a final variable of composite type from another object
9319 # function
9320 lines =<< trim END
9321 vim9script
9322 class A
9323 public final l: list<number> = [1, 2]
9324 def Foo()
9325 this.l = [3, 4]
9326 enddef
9327 endclass
9328 var a = A.new()
9329 a.Foo()
9330 END
9331 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9332
9333 # Test for modifying a final variable of composite type at script level
9334 lines =<< trim END
9335 vim9script
9336 class A
9337 public final l: list<number> = [1, 2]
9338 endclass
9339 var a = A.new()
9340 a.l[0] = 3
9341 a.l->add(4)
9342 assert_equal([3, 2, 4], a.l)
9343 END
9344 v9.CheckSourceSuccess(lines)
9345
9346 # Test for modifying a final variable of composite type from a function
9347 lines =<< trim END
9348 vim9script
9349 class A
9350 public final l: list<number> = [1, 2]
9351 endclass
9352 def Foo()
9353 var a = A.new()
9354 a.l[0] = 3
9355 a.l->add(4)
9356 assert_equal([3, 2, 4], a.l)
9357 enddef
9358 Foo()
9359 END
9360 v9.CheckSourceSuccess(lines)
9361
9362 # Test for modifying a final variable of composite type from another object
9363 # function
9364 lines =<< trim END
9365 vim9script
9366 class A
9367 public final l: list<number> = [1, 2]
9368 def Foo()
9369 this.l[0] = 3
9370 this.l->add(4)
9371 enddef
9372 endclass
9373 var a = A.new()
9374 a.Foo()
9375 assert_equal([3, 2, 4], a.l)
9376 END
9377 v9.CheckSourceSuccess(lines)
9378
9379 # Test for assigning a new value to a final variable of composite type at
9380 # script level
9381 lines =<< trim END
9382 vim9script
9383 class A
9384 public final l: list<number> = [1, 2]
9385 endclass
9386 var a = A.new()
9387 a.l = [3, 4]
9388 END
9389 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9390
9391 # Test for assigning a new value to a final variable of composite type from
9392 # another object function
9393 lines =<< trim END
9394 vim9script
9395 class A
9396 public final l: list<number> = [1, 2]
9397 def Foo()
9398 this.l = [3, 4]
9399 enddef
9400 endclass
9401 var a = A.new()
9402 a.Foo()
9403 END
9404 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9405
9406 # Test for assigning a new value to a final variable of composite type from
9407 # another function
9408 lines =<< trim END
9409 vim9script
9410 class A
9411 public final l: list<number> = [1, 2]
9412 endclass
9413 def Foo()
9414 var a = A.new()
9415 a.l = [3, 4]
9416 enddef
9417 Foo()
9418 END
9419 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9420
9421 # Error case: Use 'final' with just a variable name
9422 lines =<< trim END
9423 vim9script
9424 class A
9425 final foo
9426 endclass
9427 var a = A.new()
9428 END
9429 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9430
9431 # Error case: Use 'final' followed by 'public'
9432 lines =<< trim END
9433 vim9script
9434 class A
9435 final public foo: number
9436 endclass
9437 var a = A.new()
9438 END
9439 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9440
9441 # Error case: Use 'final' followed by 'static'
9442 lines =<< trim END
9443 vim9script
9444 class A
9445 final static foo: number
9446 endclass
9447 var a = A.new()
9448 END
9449 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9450
9451 # Error case: 'final' cannot be used in an interface
9452 lines =<< trim END
9453 vim9script
9454 interface A
9455 final foo: number = 10
9456 endinterface
9457 END
9458 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9459
9460 # Error case: 'final' not supported for an object method
9461 lines =<< trim END
9462 vim9script
9463 class A
9464 final def Foo()
9465 enddef
9466 endclass
9467 END
9468 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9469
9470 # Error case: 'final' not supported for a class method
9471 lines =<< trim END
9472 vim9script
9473 class A
9474 static final def Foo()
9475 enddef
9476 endclass
9477 END
9478 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9479enddef
9480
9481" Test for 'const' class and object variables
9482def Test_const_class_object_variable()
9483 # Test for changing a const object variable from an object function
9484 var lines =<< trim END
9485 vim9script
9486 class A
9487 const foo: string = "abc"
9488 def Foo()
9489 this.foo = "def"
9490 enddef
9491 endclass
9492 defcompile A.Foo
9493 END
9494 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9495
9496 # Test for changing a const object variable from the 'new' function
9497 lines =<< trim END
9498 vim9script
9499 class A
9500 const s1: string
9501 const s2: string
9502 def new(this.s1)
9503 this.s2 = 'def'
9504 enddef
9505 endclass
9506 var a = A.new('abc')
9507 assert_equal('abc', a.s1)
9508 assert_equal('def', a.s2)
9509 END
9510 v9.CheckSourceSuccess(lines)
9511
9512 # Test for changing a const object variable from an object method called from
9513 # the 'new' function
9514 lines =<< trim END
9515 vim9script
9516 class A
9517 const s1: string = 'abc'
9518 def new()
9519 this.ChangeStr()
9520 enddef
9521 def ChangeStr()
9522 this.s1 = 'def'
9523 enddef
9524 endclass
9525 var a = A.new()
9526 END
9527 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9528
9529 # Test for a const class variable
9530 lines =<< trim END
9531 vim9script
9532 class A
9533 static const s1: string = "abc"
9534 endclass
9535 assert_equal('abc', A.s1)
9536 END
9537 v9.CheckSourceSuccess(lines)
9538
9539 # Test for changing a const class variable from a class function
9540 lines =<< trim END
9541 vim9script
9542 class A
9543 static const s1: string = "abc"
9544 static def Foo()
9545 s1 = "def"
9546 enddef
9547 endclass
9548 A.Foo()
9549 END
9550 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9551
9552 # Test for changing a public const class variable at script level
9553 lines =<< trim END
9554 vim9script
9555 class A
9556 public static const s1: string = "abc"
9557 endclass
9558 assert_equal('abc', A.s1)
9559 A.s1 = 'def'
9560 END
9561 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9562
9563 # Test for changing a public const class variable from a class function
9564 lines =<< trim END
9565 vim9script
9566 class A
9567 public static const s1: string = "abc"
9568 static def Foo()
9569 s1 = "def"
9570 enddef
9571 endclass
9572 A.Foo()
9573 END
9574 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9575
9576 # Test for changing a public const class variable from a function
9577 lines =<< trim END
9578 vim9script
9579 class A
9580 public static const s1: string = "abc"
9581 endclass
9582 def Foo()
9583 A.s1 = 'def'
9584 enddef
9585 defcompile
9586 END
9587 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9588
9589 # Test for changing a const List item from an object function
9590 lines =<< trim END
9591 vim9script
9592 class A
9593 public const l: list<number>
9594 def new()
9595 this.l = [1, 2]
9596 enddef
9597 def Foo()
9598 this.l[0] = 3
9599 enddef
9600 endclass
9601 var a = A.new()
9602 assert_equal([1, 2], a.l)
9603 a.Foo()
9604 END
9605 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9606
9607 # Test for adding a value to a const List from an object function
9608 lines =<< trim END
9609 vim9script
9610 class A
9611 public const l: list<number>
9612 def new()
9613 this.l = [1, 2]
9614 enddef
9615 def Foo()
9616 this.l->add(3)
9617 enddef
9618 endclass
9619 var a = A.new()
9620 a.Foo()
9621 END
9622 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9623
9624 # Test for reassigning a const List from an object function
9625 lines =<< trim END
9626 vim9script
9627 class A
9628 public const l: list<number> = [1, 2]
9629 def Foo()
9630 this.l = [3, 4]
9631 enddef
9632 endclass
9633 var a = A.new()
9634 a.Foo()
9635 END
9636 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9637
9638 # Test for changing a const List item at script level
9639 lines =<< trim END
9640 vim9script
9641 class A
9642 public const l: list<number> = [1, 2]
9643 endclass
9644 var a = A.new()
9645 a.l[0] = 3
9646 END
9647 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9648
9649 # Test for adding a value to a const List item at script level
9650 lines =<< trim END
9651 vim9script
9652 class A
9653 public const l: list<number> = [1, 2]
9654 endclass
9655 var a = A.new()
9656 a.l->add(4)
9657 END
9658 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9659
9660 # Test for changing a const List item from a function
9661 lines =<< trim END
9662 vim9script
9663 class A
9664 public const l: list<number> = [1, 2]
9665 endclass
9666 def Foo()
9667 var a = A.new()
9668 a.l[0] = 3
9669 enddef
9670 Foo()
9671 END
9672 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9673
9674 # Test for adding a value to a const List item from a function
9675 lines =<< trim END
9676 vim9script
9677 class A
9678 public const l: list<number> = [1, 2]
9679 endclass
9680 def Foo()
9681 var a = A.new()
9682 a.l->add(4)
9683 enddef
9684 Foo()
9685 END
9686 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9687
9688 # Test for changing a const List item from an object method
9689 lines =<< trim END
9690 vim9script
9691 class A
9692 public const l: list<number> = [1, 2]
9693 def Foo()
9694 this.l[0] = 3
9695 enddef
9696 endclass
9697 var a = A.new()
9698 a.Foo()
9699 END
9700 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9701
9702 # Test for adding a value to a const List item from an object method
9703 lines =<< trim END
9704 vim9script
9705 class A
9706 public const l: list<number> = [1, 2]
9707 def Foo()
9708 this.l->add(4)
9709 enddef
9710 endclass
9711 var a = A.new()
9712 a.Foo()
9713 END
9714 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9715
9716 # Test for reassigning a const List object variable at script level
9717 lines =<< trim END
9718 vim9script
9719 class A
9720 public const l: list<number> = [1, 2]
9721 endclass
9722 var a = A.new()
9723 a.l = [3, 4]
9724 END
9725 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9726
9727 # Test for reassigning a const List object variable from an object method
9728 lines =<< trim END
9729 vim9script
9730 class A
9731 public const l: list<number> = [1, 2]
9732 def Foo()
9733 this.l = [3, 4]
9734 enddef
9735 endclass
9736 var a = A.new()
9737 a.Foo()
9738 END
9739 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9740
9741 # Test for reassigning a const List object variable from another function
9742 lines =<< trim END
9743 vim9script
9744 class A
9745 public const l: list<number> = [1, 2]
9746 endclass
9747 def Foo()
9748 var a = A.new()
9749 a.l = [3, 4]
9750 enddef
9751 Foo()
9752 END
9753 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9754
9755 # Error case: Use 'const' with just a variable name
9756 lines =<< trim END
9757 vim9script
9758 class A
9759 const foo
9760 endclass
9761 var a = A.new()
9762 END
9763 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9764
9765 # Error case: Use 'const' followed by 'public'
9766 lines =<< trim END
9767 vim9script
9768 class A
9769 const public foo: number
9770 endclass
9771 var a = A.new()
9772 END
9773 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9774
9775 # Error case: Use 'const' followed by 'static'
9776 lines =<< trim END
9777 vim9script
9778 class A
9779 const static foo: number
9780 endclass
9781 var a = A.new()
9782 END
9783 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9784
9785 # Error case: 'const' cannot be used in an interface
9786 lines =<< trim END
9787 vim9script
9788 interface A
9789 const foo: number = 10
9790 endinterface
9791 END
9792 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9793
9794 # Error case: 'const' not supported for an object method
9795 lines =<< trim END
9796 vim9script
9797 class A
9798 const def Foo()
9799 enddef
9800 endclass
9801 END
9802 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9803
9804 # Error case: 'const' not supported for a class method
9805 lines =<< trim END
9806 vim9script
9807 class A
9808 static const def Foo()
9809 enddef
9810 endclass
9811 END
9812 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9813enddef
9814
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009815" Test for compiling class/object methods using :defcompile
9816def Test_defcompile_class()
9817 # defcompile all the classes in the current script
9818 var lines =<< trim END
9819 vim9script
9820 class A
9821 def Foo()
9822 var i = 10
9823 enddef
9824 endclass
9825 class B
9826 def Bar()
9827 var i = 20
9828 xxx
9829 enddef
9830 endclass
9831 defcompile
9832 END
9833 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9834
9835 # defcompile a specific class
9836 lines =<< trim END
9837 vim9script
9838 class A
9839 def Foo()
9840 xxx
9841 enddef
9842 endclass
9843 class B
9844 def Bar()
9845 yyy
9846 enddef
9847 endclass
9848 defcompile B
9849 END
9850 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9851
9852 # defcompile a non-class
9853 lines =<< trim END
9854 vim9script
9855 class A
9856 def Foo()
9857 enddef
9858 endclass
9859 var X: list<number> = []
9860 defcompile X
9861 END
9862 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9863
9864 # defcompile a class twice
9865 lines =<< trim END
9866 vim9script
9867 class A
9868 def new()
9869 enddef
9870 endclass
9871 defcompile A
9872 defcompile A
9873 assert_equal('Function A.new does not need compiling', v:statusmsg)
9874 END
9875 v9.CheckSourceSuccess(lines)
9876
9877 # defcompile should not compile an imported class
9878 lines =<< trim END
9879 vim9script
9880 export class A
9881 def Foo()
9882 xxx
9883 enddef
9884 endclass
9885 END
9886 writefile(lines, 'Xdefcompileimport.vim', 'D')
9887 lines =<< trim END
9888 vim9script
9889
9890 import './Xdefcompileimport.vim'
9891 class B
9892 endclass
9893 defcompile
9894 END
9895 v9.CheckScriptSuccess(lines)
9896enddef
9897
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +01009898" Test for cases common to all the object builtin methods
9899def Test_object_builtin_method()
9900 var lines =<< trim END
9901 vim9script
9902 class A
9903 def abc()
9904 enddef
9905 endclass
9906 END
9907 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
9908
9909 for funcname in ["len", "string", "empty"]
9910 lines =<< trim eval END
9911 vim9script
9912 class A
9913 static def {funcname}(): number
9914 enddef
9915 endclass
9916 END
9917 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
9918 endfor
9919enddef
9920
9921" Test for using the empty() builtin method with an object
9922" This is a legacy function to use the test_garbagecollect_now() function.
9923func Test_object_empty()
9924 let lines =<< trim END
9925 vim9script
9926 class A
9927 def empty(): bool
9928 return true
9929 enddef
9930 endclass
9931
9932 def Foo()
9933 var afoo = A.new()
9934 assert_equal(true, empty(afoo))
9935 assert_equal(true, afoo->empty())
9936 enddef
9937
9938 var a = A.new()
9939 assert_equal(1, empty(a))
9940 assert_equal(1, a->empty())
9941 test_garbagecollect_now()
9942 assert_equal(1, empty(a))
9943 Foo()
9944 test_garbagecollect_now()
9945 Foo()
9946 END
9947 call v9.CheckSourceSuccess(lines)
9948
9949 " empty() should return 1 without a builtin method
9950 let lines =<< trim END
9951 vim9script
9952 class A
9953 endclass
9954
9955 def Foo()
9956 var afoo = A.new()
9957 assert_equal(1, empty(afoo))
9958 enddef
9959
9960 var a = A.new()
9961 assert_equal(1, empty(a))
9962 Foo()
9963 END
9964 call v9.CheckSourceSuccess(lines)
9965
9966 " Unsupported signature for the empty() method
9967 let lines =<< trim END
9968 vim9script
9969 class A
9970 def empty()
9971 enddef
9972 endclass
9973 END
9974 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
9975
9976 " Error when calling the empty() method
9977 let lines =<< trim END
9978 vim9script
9979 class A
9980 def empty(): bool
9981 throw "Failed to check emptiness"
9982 enddef
9983 endclass
9984
9985 def Foo()
9986 var afoo = A.new()
9987 var i = empty(afoo)
9988 enddef
9989
9990 var a = A.new()
9991 assert_fails('empty(a)', 'Failed to check emptiness')
9992 assert_fails('Foo()', 'Failed to check emptiness')
9993 END
9994 call v9.CheckSourceSuccess(lines)
9995
9996 " call empty() using an object from a script
9997 let lines =<< trim END
9998 vim9script
9999 class A
10000 def empty(): bool
10001 return true
10002 enddef
10003 endclass
10004 var afoo = A.new()
10005 assert_equal(true, afoo.empty())
10006 END
10007 call v9.CheckSourceSuccess(lines)
10008
10009 " call empty() using an object from a method
10010 let lines =<< trim END
10011 vim9script
10012 class A
10013 def empty(): bool
10014 return true
10015 enddef
10016 endclass
10017 def Foo()
10018 var afoo = A.new()
10019 assert_equal(true, afoo.empty())
10020 enddef
10021 Foo()
10022 END
10023 call v9.CheckSourceSuccess(lines)
10024
10025 " call empty() using "this" from an object method
10026 let lines =<< trim END
10027 vim9script
10028 class A
10029 def empty(): bool
10030 return true
10031 enddef
10032 def Foo(): bool
10033 return this.empty()
10034 enddef
10035 endclass
10036 def Bar()
10037 var abar = A.new()
10038 assert_equal(true, abar.Foo())
10039 enddef
10040 Bar()
10041 END
10042 call v9.CheckSourceSuccess(lines)
10043
10044 " Call empty() from a derived object
10045 let lines =<< trim END
10046 vim9script
10047 class A
10048 def empty(): bool
10049 return false
10050 enddef
10051 endclass
10052 class B extends A
10053 def empty(): bool
10054 return true
10055 enddef
10056 endclass
10057 def Foo(afoo: A)
10058 assert_equal(true, empty(afoo))
10059 var bfoo = B.new()
10060 assert_equal(true, empty(bfoo))
10061 enddef
10062 var b = B.new()
10063 assert_equal(1, empty(b))
10064 Foo(b)
10065 END
10066 call v9.CheckSourceSuccess(lines)
10067
10068 " Invoking empty method using an interface
10069 let lines =<< trim END
10070 vim9script
10071 interface A
10072 def empty(): bool
10073 endinterface
10074 class B implements A
10075 def empty(): bool
10076 return false
10077 enddef
10078 endclass
10079 def Foo(a: A)
10080 assert_equal(false, empty(a))
10081 enddef
10082 var b = B.new()
10083 Foo(b)
10084 END
10085 call v9.CheckSourceSuccess(lines)
10086endfunc
10087
10088" Test for using the len() builtin method with an object
10089" This is a legacy function to use the test_garbagecollect_now() function.
10090func Test_object_length()
10091 let lines =<< trim END
10092 vim9script
10093 class A
10094 var mylen: number = 0
10095 def new(n: number)
10096 this.mylen = n
10097 enddef
10098 def len(): number
10099 return this.mylen
10100 enddef
10101 endclass
10102
10103 def Foo()
10104 var afoo = A.new(12)
10105 assert_equal(12, len(afoo))
10106 assert_equal(12, afoo->len())
10107 enddef
10108
10109 var a = A.new(22)
10110 assert_equal(22, len(a))
10111 assert_equal(22, a->len())
10112 test_garbagecollect_now()
10113 assert_equal(22, len(a))
10114 Foo()
10115 test_garbagecollect_now()
10116 Foo()
10117 END
10118 call v9.CheckSourceSuccess(lines)
10119
10120 " len() should return 0 without a builtin method
10121 let lines =<< trim END
10122 vim9script
10123 class A
10124 endclass
10125
10126 def Foo()
10127 var afoo = A.new()
10128 assert_equal(0, len(afoo))
10129 enddef
10130
10131 var a = A.new()
10132 assert_equal(0, len(a))
10133 Foo()
10134 END
10135 call v9.CheckSourceSuccess(lines)
10136
10137 " Unsupported signature for the len() method
10138 let lines =<< trim END
10139 vim9script
10140 class A
10141 def len()
10142 enddef
10143 endclass
10144 END
10145 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10146
10147 " Error when calling the len() method
10148 let lines =<< trim END
10149 vim9script
10150 class A
10151 def len(): number
10152 throw "Failed to compute length"
10153 enddef
10154 endclass
10155
10156 def Foo()
10157 var afoo = A.new()
10158 var i = len(afoo)
10159 enddef
10160
10161 var a = A.new()
10162 assert_fails('len(a)', 'Failed to compute length')
10163 assert_fails('Foo()', 'Failed to compute length')
10164 END
10165 call v9.CheckSourceSuccess(lines)
10166
10167 " call len() using an object from a script
10168 let lines =<< trim END
10169 vim9script
10170 class A
10171 def len(): number
10172 return 5
10173 enddef
10174 endclass
10175 var afoo = A.new()
10176 assert_equal(5, afoo.len())
10177 END
10178 call v9.CheckSourceSuccess(lines)
10179
10180 " call len() using an object from a method
10181 let lines =<< trim END
10182 vim9script
10183 class A
10184 def len(): number
10185 return 5
10186 enddef
10187 endclass
10188 def Foo()
10189 var afoo = A.new()
10190 assert_equal(5, afoo.len())
10191 enddef
10192 Foo()
10193 END
10194 call v9.CheckSourceSuccess(lines)
10195
10196 " call len() using "this" from an object method
10197 let lines =<< trim END
10198 vim9script
10199 class A
10200 def len(): number
10201 return 8
10202 enddef
10203 def Foo(): number
10204 return this.len()
10205 enddef
10206 endclass
10207 def Bar()
10208 var abar = A.new()
10209 assert_equal(8, abar.Foo())
10210 enddef
10211 Bar()
10212 END
10213 call v9.CheckSourceSuccess(lines)
10214
10215 " Call len() from a derived object
10216 let lines =<< trim END
10217 vim9script
10218 class A
10219 def len(): number
10220 return 10
10221 enddef
10222 endclass
10223 class B extends A
10224 def len(): number
10225 return 20
10226 enddef
10227 endclass
10228 def Foo(afoo: A)
10229 assert_equal(20, len(afoo))
10230 var bfoo = B.new()
10231 assert_equal(20, len(bfoo))
10232 enddef
10233 var b = B.new()
10234 assert_equal(20, len(b))
10235 Foo(b)
10236 END
10237 call v9.CheckSourceSuccess(lines)
10238
10239 " Invoking len method using an interface
10240 let lines =<< trim END
10241 vim9script
10242 interface A
10243 def len(): number
10244 endinterface
10245 class B implements A
10246 def len(): number
10247 return 123
10248 enddef
10249 endclass
10250 def Foo(a: A)
10251 assert_equal(123, len(a))
10252 enddef
10253 var b = B.new()
10254 Foo(b)
10255 END
10256 call v9.CheckSourceSuccess(lines)
10257endfunc
10258
10259" Test for using the string() builtin method with an object
10260" This is a legacy function to use the test_garbagecollect_now() function.
10261func Test_object_string()
10262 let lines =<< trim END
10263 vim9script
10264 class A
10265 var name: string
10266 def string(): string
10267 return this.name
10268 enddef
10269 endclass
10270
10271 def Foo()
10272 var afoo = A.new("foo-A")
10273 assert_equal('foo-A', string(afoo))
10274 assert_equal('foo-A', afoo->string())
10275 enddef
10276
10277 var a = A.new("script-A")
10278 assert_equal('script-A', string(a))
10279 assert_equal('script-A', a->string())
10280 assert_equal(['script-A'], execute('echo a')->split("\n"))
10281 test_garbagecollect_now()
10282 assert_equal('script-A', string(a))
10283 Foo()
10284 test_garbagecollect_now()
10285 Foo()
10286 END
10287 call v9.CheckSourceSuccess(lines)
10288
10289 " string() should return "object of A {}" without a builtin method
10290 let lines =<< trim END
10291 vim9script
10292 class A
10293 endclass
10294
10295 def Foo()
10296 var afoo = A.new()
10297 assert_equal('object of A {}', string(afoo))
10298 enddef
10299
10300 var a = A.new()
10301 assert_equal('object of A {}', string(a))
10302 Foo()
10303 END
10304 call v9.CheckSourceSuccess(lines)
10305
10306 " Unsupported signature for the string() method
10307 let lines =<< trim END
10308 vim9script
10309 class A
10310 def string()
10311 enddef
10312 endclass
10313 END
10314 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10315
10316 " Error when calling the string() method
10317 let lines =<< trim END
10318 vim9script
10319 class A
10320 def string(): string
10321 throw "Failed to get text"
10322 enddef
10323 endclass
10324
10325 def Foo()
10326 var afoo = A.new()
10327 var i = string(afoo)
10328 enddef
10329
10330 var a = A.new()
10331 assert_fails('string(a)', 'Failed to get text')
10332 assert_fails('Foo()', 'Failed to get text')
10333 END
10334 call v9.CheckSourceSuccess(lines)
10335
10336 " call string() using an object from a script
10337 let lines =<< trim END
10338 vim9script
10339 class A
10340 def string(): string
10341 return 'A'
10342 enddef
10343 endclass
10344 var afoo = A.new()
10345 assert_equal('A', afoo.string())
10346 END
10347 call v9.CheckSourceSuccess(lines)
10348
10349 " call string() using an object from a method
10350 let lines =<< trim END
10351 vim9script
10352 class A
10353 def string(): string
10354 return 'A'
10355 enddef
10356 endclass
10357 def Foo()
10358 var afoo = A.new()
10359 assert_equal('A', afoo.string())
10360 enddef
10361 Foo()
10362 END
10363 call v9.CheckSourceSuccess(lines)
10364
10365 " call string() using "this" from an object method
10366 let lines =<< trim END
10367 vim9script
10368 class A
10369 def string(): string
10370 return 'A'
10371 enddef
10372 def Foo(): string
10373 return this.string()
10374 enddef
10375 endclass
10376 def Bar()
10377 var abar = A.new()
10378 assert_equal('A', abar.string())
10379 enddef
10380 Bar()
10381 END
10382 call v9.CheckSourceSuccess(lines)
10383
10384 " Call string() from a derived object
10385 let lines =<< trim END
10386 vim9script
10387 class A
10388 def string(): string
10389 return 'A'
10390 enddef
10391 endclass
10392 class B extends A
10393 def string(): string
10394 return 'B'
10395 enddef
10396 endclass
10397 def Foo(afoo: A)
10398 assert_equal('B', string(afoo))
10399 var bfoo = B.new()
10400 assert_equal('B', string(bfoo))
10401 enddef
10402 var b = B.new()
10403 assert_equal('B', string(b))
10404 Foo(b)
10405 END
10406 call v9.CheckSourceSuccess(lines)
10407
10408 " Invoking string method using an interface
10409 let lines =<< trim END
10410 vim9script
10411 interface A
10412 def string(): string
10413 endinterface
10414 class B implements A
10415 def string(): string
10416 return 'B'
10417 enddef
10418 endclass
10419 def Foo(a: A)
10420 assert_equal('B', string(a))
10421 enddef
10422 var b = B.new()
10423 Foo(b)
10424 END
10425 call v9.CheckSourceSuccess(lines)
10426endfunc
10427
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010428" Test for using a class in the class definition
10429def Test_Ref_Class_Within_Same_Class()
10430 var lines =<< trim END
10431 vim9script
10432 class A
10433 var n: number = 0
10434 def Equals(other: A): bool
10435 return this.n == other.n
10436 enddef
10437 endclass
10438
10439 var a1 = A.new(10)
10440 var a2 = A.new(10)
10441 var a3 = A.new(20)
10442 assert_equal(true, a1.Equals(a2))
10443 assert_equal(false, a2.Equals(a3))
10444 END
10445 v9.CheckScriptSuccess(lines)
10446
10447 lines =<< trim END
10448 vim9script
10449
10450 class Foo
10451 var num: number
10452 def Clone(): Foo
10453 return Foo.new(this.num)
10454 enddef
10455 endclass
10456
10457 var f1 = Foo.new(1)
10458
10459 def F()
10460 var f2: Foo = f1.Clone()
10461 assert_equal(false, f2 is f1)
10462 assert_equal(true, f2.num == f1.num)
10463 enddef
10464 F()
10465
10466 var f3: Foo = f1.Clone()
10467 assert_equal(false, f3 is f1)
10468 assert_equal(true, f3.num == f1.num)
10469 END
10470 v9.CheckScriptSuccess(lines)
10471
10472 # Test for trying to use a class to extend when defining the same class
10473 lines =<< trim END
10474 vim9script
10475 class A extends A
10476 endclass
10477 END
10478 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10479
10480 # Test for trying to use a class to implement when defining the same class
10481 lines =<< trim END
10482 vim9script
10483 class A implements A
10484 endclass
10485 END
10486 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10487enddef
10488
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010489" Test for using a compound operator from a lambda function in an object method
10490def Test_compound_op_in_objmethod_lambda()
10491 # Test using the "+=" operator
10492 var lines =<< trim END
10493 vim9script
10494 class A
10495 var n: number = 10
10496 def Foo()
10497 var Fn = () => {
10498 this.n += 1
10499 }
10500 Fn()
10501 enddef
10502 endclass
10503
10504 var a = A.new()
10505 a.Foo()
10506 assert_equal(11, a.n)
10507 END
10508 v9.CheckScriptSuccess(lines)
10509
10510 # Test using the "..=" operator
10511 lines =<< trim END
10512 vim9script
10513 class A
10514 var s: string = "a"
10515 def Foo()
10516 var Fn = () => {
10517 this.s ..= "a"
10518 }
10519 Fn()
10520 enddef
10521 endclass
10522
10523 var a = A.new()
10524 a.Foo()
10525 a.Foo()
10526 assert_equal("aaa", a.s)
10527 END
10528 v9.CheckScriptSuccess(lines)
10529enddef
10530
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010531" Test for using test_refcount() with a class and an object
10532def Test_class_object_refcount()
10533 var lines =<< trim END
10534 vim9script
10535 class A
10536 endclass
10537 var a: A = A.new()
10538 assert_equal(2, test_refcount(A))
10539 assert_equal(1, test_refcount(a))
10540 var b = a
10541 assert_equal(2, test_refcount(A))
10542 assert_equal(2, test_refcount(a))
10543 assert_equal(2, test_refcount(b))
10544 END
10545 v9.CheckScriptSuccess(lines)
10546enddef
10547
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010548" call a lambda function in one object from another object
10549def Test_lambda_invocation_across_classes()
10550 var lines =<< trim END
10551 vim9script
10552 class A
10553 var s: string = "foo"
10554 def GetFn(): func
10555 var Fn = (): string => {
10556 return this.s
10557 }
10558 return Fn
10559 enddef
10560 endclass
10561
10562 class B
10563 var s: string = "bar"
10564 def GetFn(): func
10565 var a = A.new()
10566 return a.GetFn()
10567 enddef
10568 endclass
10569
10570 var b = B.new()
10571 var Fn = b.GetFn()
10572 assert_equal("foo", Fn())
10573 END
10574 v9.CheckScriptSuccess(lines)
10575enddef
10576
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010577" Test for using a class member which is an object of the current class
10578def Test_current_class_object_class_member()
10579 var lines =<< trim END
10580 vim9script
10581 class A
10582 public static var obj1: A = A.new(10)
10583 var n: number
10584 endclass
10585 defcompile
10586 assert_equal(10, A.obj1.n)
10587 END
10588 v9.CheckScriptSuccess(lines)
10589enddef
10590
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020010591" Test for updating a base class variable from a base class method without the
10592" class name. This used to crash Vim (Github issue #14352).
10593def Test_use_base_class_variable_from_base_class_method()
10594 var lines =<< trim END
10595 vim9script
10596
10597 class DictKeyClass
10598 static var _obj_id_count = 1
10599 def _GenerateKey()
10600 _obj_id_count += 1
10601 enddef
10602 static def GetIdCount(): number
10603 return _obj_id_count
10604 enddef
10605 endclass
10606
10607 class C extends DictKeyClass
10608 def F()
10609 this._GenerateKey()
10610 enddef
10611 endclass
10612
10613 C.new().F()
10614 assert_equal(2, DictKeyClass.GetIdCount())
10615 END
10616 v9.CheckScriptSuccess(lines)
10617enddef
10618
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020010619" Test for accessing protected funcref object and class variables
10620def Test_protected_funcref()
10621 # protected funcref object variable
10622 var lines =<< trim END
10623 vim9script
10624 class Test1
10625 const _Id: func(any): any = (v) => v
10626 endclass
10627 var n = Test1.new()._Id(1)
10628 END
10629 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
10630
10631 # protected funcref class variable
10632 lines =<< trim END
10633 vim9script
10634 class Test2
10635 static const _Id: func(any): any = (v) => v
10636 endclass
10637 var n = Test2._Id(2)
10638 END
10639 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
10640enddef
10641
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020010642" Test for using lambda block in classes
10643def Test_lambda_block_in_class()
10644 # This used to crash Vim
10645 var lines =<< trim END
10646 vim9script
10647 class IdClass1
10648 const Id: func(number): number = (num: number): number => {
10649 # Return a ID
10650 return num * 10
10651 }
10652 endclass
10653 var id = IdClass1.new()
10654 assert_equal(20, id.Id(2))
10655 END
10656 v9.CheckScriptSuccess(lines)
10657
10658 # This used to crash Vim
10659 lines =<< trim END
10660 vim9script
10661 class IdClass2
10662 static const Id: func(number): number = (num: number): number => {
10663 # Return a ID
10664 return num * 2
10665 }
10666 endclass
10667 assert_equal(16, IdClass2.Id(8))
10668 END
10669 v9.CheckScriptSuccess(lines)
10670enddef
10671
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020010672" Test for defcompiling an abstract method
10673def Test_abstract_method_defcompile()
10674 # Compile an abstract class with abstract object methods
10675 var lines =<< trim END
10676 vim9script
10677 abstract class A
10678 abstract def Foo(): string
10679 abstract def Bar(): list<string>
10680 endclass
10681 defcompile
10682 END
10683 v9.CheckScriptSuccess(lines)
10684
10685 # Compile a concrete object method in an abstract class
10686 lines =<< trim END
10687 vim9script
10688 abstract class A
10689 abstract def Foo(): string
10690 abstract def Bar(): list<string>
10691 def Baz(): string
10692 pass
10693 enddef
10694 endclass
10695 defcompile
10696 END
10697 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10698
10699 # Compile a concrete class method in an abstract class
10700 lines =<< trim END
10701 vim9script
10702 abstract class A
10703 abstract def Foo(): string
10704 abstract def Bar(): list<string>
10705 static def Baz(): string
10706 pass
10707 enddef
10708 endclass
10709 defcompile
10710 END
10711 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10712enddef
10713
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020010714" Test for defining a class in a function
10715def Test_class_definition_in_a_function()
10716 var lines =<< trim END
10717 vim9script
10718 def Foo()
10719 class A
10720 endclass
10721 enddef
10722 defcompile
10723 END
10724 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
10725enddef
10726
Bram Moolenaar00b28d62022-12-08 15:32:33 +000010727" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker