blob: b2ef0db98e738cae56ab18d320a96fb487e93817 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +010038 # Only the complete word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmananac773182024-04-27 11:36:12 +020070 # Additional command after "class name"
71 lines =<< trim END
72 vim9script
73 class Something | var x = 10
74 endclass
75 END
76 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
77
78 # Additional command after "object variable"
79 lines =<< trim END
80 vim9script
81 class Something
82 var l: list<number> = [] | var y = 10
83 endclass
84 END
85 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
86
87 # Additional command after "class variable"
88 lines =<< trim END
89 vim9script
90 class Something
91 static var d = {a: 10} | var y = 10
92 endclass
93 END
94 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
95
96 # Additional command after "object method"
97 lines =<< trim END
98 vim9script
99 class Something
100 def Foo() | var y = 10
101 enddef
102 endclass
103 END
104 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
105
Yegappan Lakshmananfe55c312024-04-28 09:54:09 +0200106 # Comments are allowed after an inline block
107 lines =<< trim END
108 vim9script
109 class Foo
110 static const bar = { # {{{
111 baz: 'qux'
112 } # }}}
113 endclass
114 assert_equal({baz: 'qux'}, Foo.bar)
115 END
116 v9.CheckSourceSuccess(lines)
117
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +0100118 # Try to define a class with the same name as an existing variable
119 lines =<< trim END
120 vim9script
121 var Something: list<number> = [1]
122 class Thing
123 endclass
124 interface Api
125 endinterface
126 class Something extends Thing implements Api
127 var v1: string = ''
128 def Foo()
129 enddef
130 endclass
131 END
132 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 7)
133
zeertzjqe7102202024-02-13 20:32:04 +0100134 # Use old "this." prefixed member variable declaration syntax (without initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100135 lines =<< trim END
136 vim9script
137 class Something
138 this.count: number
139 endclass
140 END
141 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
142
zeertzjqe7102202024-02-13 20:32:04 +0100143 # Use old "this." prefixed member variable declaration syntax (with initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100144 lines =<< trim END
145 vim9script
146 class Something
147 this.count: number = 42
148 endclass
149 END
150 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
151
152 # Use old "this." prefixed member variable declaration syntax (type inferred)
153 lines =<< trim END
154 vim9script
155 class Something
156 this.count = 42
157 endclass
158 END
159 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
160
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200161 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000162 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 vim9script
164 class Something
165 this
166 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000167 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100168 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000169
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200170 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000171 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200172 vim9script
173 class Something
174 this.
175 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000176 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100177 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000178
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200179 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000180 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200181 vim9script
182 class Something
183 this .count
184 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000185 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100186 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000187
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200188 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000189 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200190 vim9script
191 class Something
192 this. count
193 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000194 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100195 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000196
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200197 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000198 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200199 vim9script
200 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100201 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200202 that.count
203 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200205 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000206
Doug Kearns74da0ee2023-12-14 20:26:26 +0100207 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000208 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200209 vim9script
210 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100211 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000213 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100214 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
215
216 # Use "variable" instead of "var" for member variable declaration (with initialization)
217 lines =<< trim END
218 vim9script
219 class Something
220 variable count: number = 42
221 endclass
222 END
223 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
224
225 # Use "variable" instead of "var" for member variable declaration (type inferred)
226 lines =<< trim END
227 vim9script
228 class Something
229 variable count = 42
230 endclass
231 END
232 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000233
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200234 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000235 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200236 vim9script
237 class Something
238 def new()
239 this.state = 0
240 enddef
241 endclass
242 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000243 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200244 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000245
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200246 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000247 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200248 vim9script
249 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100250 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200251 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000252 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200253 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000254
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200255 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000256 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200257 vim9script
258 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100259 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200260 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000261 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200262 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000263
Doug Kearns74da0ee2023-12-14 20:26:26 +0100264 # Missing ":var" in a "var" member variable declaration (without initialization)
265 lines =<< trim END
266 vim9script
267 class Something
268 var: number
269 endclass
270 END
271 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
272
273 # Missing ":var" in a "var" member variable declaration (with initialization)
274 lines =<< trim END
275 vim9script
276 class Something
277 var: number = 42
278 endclass
279 END
280 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
281
282 # Missing ":var" in a "var" member variable declaration (type inferred)
283 lines =<< trim END
284 vim9script
285 class Something
286 var = 42
287 endclass
288 END
289 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
290
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200291 # Test for unsupported comment specifier
292 lines =<< trim END
293 vim9script
294 class Something
295 # comment
296 #{
297 endclass
298 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200299 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200300
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200301 # Test for using class as a bool
302 lines =<< trim END
303 vim9script
304 class A
305 endclass
306 if A
307 endif
308 END
Ernie Raele75fde62023-12-21 17:18:54 +0100309 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200310
311 # Test for using object as a bool
312 lines =<< trim END
313 vim9script
314 class A
315 endclass
316 var a = A.new()
317 if a
318 endif
319 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200320 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200321
322 # Test for using class as a float
323 lines =<< trim END
324 vim9script
325 class A
326 endclass
327 sort([1.1, A], 'f')
328 END
Ernie Raelfa831102023-12-14 20:06:39 +0100329 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200330
331 # Test for using object as a float
332 lines =<< trim END
333 vim9script
334 class A
335 endclass
336 var a = A.new()
337 sort([1.1, a], 'f')
338 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200339 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200340
341 # Test for using class as a string
342 lines =<< trim END
343 vim9script
344 class A
345 endclass
346 :exe 'call ' .. A
347 END
Ernie Raele75fde62023-12-21 17:18:54 +0100348 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200349
350 # Test for using object as a string
351 lines =<< trim END
352 vim9script
353 class A
354 endclass
355 var a = A.new()
356 :exe 'call ' .. a
357 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200358 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200359
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200360 # Test creating a class with member variables and methods, calling a object
361 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000362 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200363 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000364
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200365 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100366 var lnum: number
367 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000368
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200369 # make a nicely formatted string
370 def ToString(): string
371 return $'({this.lnum}, {this.col})'
372 enddef
373 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000374
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200375 # use the automatically generated new() method
376 var pos = TextPosition.new(2, 12)
377 assert_equal(2, pos.lnum)
378 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000379
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200380 # call an object method
381 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000382
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200383 assert_equal(v:t_class, type(TextPosition))
384 assert_equal(v:t_object, type(pos))
385 assert_equal('class<TextPosition>', typename(TextPosition))
386 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000387 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200388 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200389
390 # When referencing object methods, space cannot be used after a "."
391 lines =<< trim END
392 vim9script
393 class A
394 def Foo(): number
395 return 10
396 enddef
397 endclass
398 var a = A.new()
399 var v = a. Foo()
400 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200401 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200402
403 # Using an object without specifying a method or a member variable
404 lines =<< trim END
405 vim9script
406 class A
407 def Foo(): number
408 return 10
409 enddef
410 endclass
411 var a = A.new()
412 var v = a.
413 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200414 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200415
416 # Error when parsing the arguments of an object method.
417 lines =<< trim END
418 vim9script
419 class A
420 def Foo()
421 enddef
422 endclass
423 var a = A.new()
424 var v = a.Foo(,)
425 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200426 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200427
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200428 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200429 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200430 vim9script
431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100432 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200433 X: 1
434 }
435 endclass
436 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200437 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200438 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000439enddef
440
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200441" Tests for object/class methods in a class
442def Test_class_def_method()
443 # Using the "public" keyword when defining an object method
444 var lines =<< trim END
445 vim9script
446 class A
447 public def Foo()
448 enddef
449 endclass
450 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200451 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200452
453 # Using the "public" keyword when defining a class method
454 lines =<< trim END
455 vim9script
456 class A
457 public static def Foo()
458 enddef
459 endclass
460 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200461 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200462
Ernie Rael03042a22023-11-11 08:53:32 +0100463 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200464 lines =<< trim END
465 vim9script
466 class A
467 public def _Foo()
468 enddef
469 endclass
470 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200471 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200472
Ernie Rael03042a22023-11-11 08:53:32 +0100473 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200474 lines =<< trim END
475 vim9script
476 class A
477 public static def _Foo()
478 enddef
479 endclass
480 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200481 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200482
483 # Using a "def" keyword without an object method name
484 lines =<< trim END
485 vim9script
486 class A
487 def
488 enddef
489 endclass
490 END
491 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
492
493 # Using a "def" keyword without a class method name
494 lines =<< trim END
495 vim9script
496 class A
497 static def
498 enddef
499 endclass
500 END
501 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
502enddef
503
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000504def Test_class_defined_twice()
505 # class defined twice should fail
506 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200507 vim9script
508 class There
509 endclass
510 class There
511 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000512 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200513 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000514
515 # one class, reload same script twice is OK
516 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 vim9script
518 class There
519 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000520 END
521 writefile(lines, 'XclassTwice.vim', 'D')
522 source XclassTwice.vim
523 source XclassTwice.vim
524enddef
525
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000526def Test_returning_null_object()
527 # this was causing an internal error
528 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200529 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000530
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200531 class BufferList
532 def Current(): any
533 return null_object
534 enddef
535 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000536
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200537 var buffers = BufferList.new()
538 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000539 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200540 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000541enddef
542
Bram Moolenaard13dd302023-03-11 20:56:35 +0000543def Test_using_null_class()
544 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200545 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200547 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200548
549 # Test for using a null class as a value
550 lines =<< trim END
551 vim9script
552 echo empty(null_class)
553 END
554 v9.CheckSourceFailure(lines, 'E1405: Class "" cannot be used as a value', 2)
555
556 # Test for using a null class with string()
557 lines =<< trim END
558 vim9script
559 assert_equal('class [unknown]', string(null_class))
560 END
561 v9.CheckSourceSuccess(lines)
562
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +0200563 # Test for using a null class with type() and typename()
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200564 lines =<< trim END
565 vim9script
566 assert_equal(12, type(null_class))
567 assert_equal('class<Unknown>', typename(null_class))
568 END
569 v9.CheckSourceSuccess(lines)
570enddef
571
Bram Moolenaar657aea72023-01-27 13:16:19 +0000572def Test_class_interface_wrong_end()
573 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200574 vim9script
575 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100576 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200577 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200579 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000580
581 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200582 vim9script
583 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100584 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200585 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000586 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200587 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000588enddef
589
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000590def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200591 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000592 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200593 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000594
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200595 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100596 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200597 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200599 var state: State
600 var db = {'xyz': 789}
601 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200603 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000604
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200605 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000606 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200607 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000608
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200609 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100610 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200611 def Method1()
612 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000613 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200614 endclass
615
616 var obj: Class
617 def Func()
618 obj.Method1()
619 enddef
620 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000621 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200622 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000623
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200624 # Pass an uninitialized object variable to a "new" function and try to call an
625 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000626 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200627 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000628
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200629 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100630 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200631 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000632
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200633 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100634 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200636 def GetBackground(): string
637 return this._bg.background
638 enddef
639 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000640
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200641 var bg: Background # UNINITIALIZED
642 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200644 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000645
646 # TODO: this should not give an error but be handled at runtime
647 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200648 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000649
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200650 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100651 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200652 def Method1()
653 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000654 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200655 endclass
656
657 var obj = null_object
658 def Func()
659 obj.Method1()
660 enddef
661 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000662 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200663 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Ernie Raelbe828252024-07-26 18:37:02 +0200664
665 # Reference a object variable through a null class object which is stored in a
666 # variable of type "any".
667 lines =<< trim END
668 vim9script
669
670 def Z()
671 var o: any = null_object
672 o.v = 4
673 enddef
674 Z()
675 END
676 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
677
678 # Do "echom" of a null object variable.
679 lines =<< trim END
680 vim9script
681
682 def X()
683 var x = null_object
684 echom x
685 enddef
686 X()
687 END
688 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 2)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000689enddef
690
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200691" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200692def Test_null_object_assign_compare()
693 var lines =<< trim END
694 vim9script
695
696 var nullo = null_object
697 def F(): any
698 return nullo
699 enddef
700 assert_equal('object<Unknown>', typename(F()))
701
702 var o0 = F()
703 assert_true(o0 == null_object)
704 assert_true(o0 == null)
705
706 var o1: any = nullo
707 assert_true(o1 == null_object)
708 assert_true(o1 == null)
709
710 def G()
711 var x = null_object
712 enddef
713
714 class C
715 endclass
716 var o2: C
717 assert_true(o2 == null_object)
718 assert_true(o2 == null)
719
720 o2 = null_object
721 assert_true(o2 == null)
722
723 o2 = C.new()
724 assert_true(o2 != null)
725
726 o2 = null_object
727 assert_true(o2 == null)
728 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200729 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200730enddef
731
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200732" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000733def Test_class_member_initializer()
734 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200735 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000736
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200737 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100738 var lnum: number = 1
739 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000740
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200741 # constructor with only the line number
742 def new(lnum: number)
743 this.lnum = lnum
744 enddef
745 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000746
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200747 var pos = TextPosition.new(3)
748 assert_equal(3, pos.lnum)
749 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000750
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200751 var instr = execute('disassemble TextPosition.new')
752 assert_match('new\_s*' ..
753 '0 NEW TextPosition size \d\+\_s*' ..
754 '\d PUSHNR 1\_s*' ..
755 '\d STORE_THIS 0\_s*' ..
756 '\d PUSHNR 1\_s*' ..
757 '\d STORE_THIS 1\_s*' ..
758 'this.lnum = lnum\_s*' ..
759 '\d LOAD arg\[-1]\_s*' ..
760 '\d PUSHNR 0\_s*' ..
761 '\d LOAD $0\_s*' ..
762 '\d\+ STOREINDEX object\_s*' ..
763 '\d\+ RETURN object.*',
764 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000765 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200766 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000767enddef
768
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000769def Test_member_any_used_as_object()
770 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200771 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000772
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200773 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100774 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200775 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000776
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200777 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100778 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200779 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000780
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200781 def F(outer: Outer)
782 outer.inner.value = 1
783 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000784
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200785 var inner_obj = Inner.new(0)
786 var outer_obj = Outer.new(inner_obj)
787 F(outer_obj)
788 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000789 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200790 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000791
Ernie Rael03042a22023-11-11 08:53:32 +0100792 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200793 lines =<< trim END
794 vim9script
795
796 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100797 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200798 endclass
799
800 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100801 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200802 endclass
803
804 def F(outer: Outer)
805 outer.inner._value = 'b'
806 enddef
807
808 var inner_obj = Inner.new('a')
809 var outer_obj = Outer.new(inner_obj)
810 F(outer_obj)
811 END
Ernie Rael03042a22023-11-11 08:53:32 +0100812 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200813
814 # Try modifying a non-existing variable using an "any" object
815 lines =<< trim END
816 vim9script
817
818 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100819 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200820 endclass
821
822 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100823 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200824 endclass
825
826 def F(outer: Outer)
827 outer.inner.someval = 'b'
828 enddef
829
830 var inner_obj = Inner.new('a')
831 var outer_obj = Outer.new(inner_obj)
832 F(outer_obj)
833 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200834 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000835enddef
836
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200837" Nested assignment to a object variable which is of another class type
838def Test_assignment_nested_type()
839 var lines =<< trim END
840 vim9script
841
842 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100843 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200844 endclass
845
846 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100847 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200848 endclass
849
850 def F(outer: Outer)
851 outer.inner.value = 1
852 enddef
853
854 def Test_assign_to_nested_typed_member()
855 var inner = Inner.new(0)
856 var outer = Outer.new(inner)
857 F(outer)
858 assert_equal(1, inner.value)
859 enddef
860
861 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200862
863 var script_inner = Inner.new(0)
864 var script_outer = Outer.new(script_inner)
865 script_outer.inner.value = 1
866 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200867 END
868 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200869
870 # Assignment where target item is read only in :def
871 lines =<< trim END
872 vim9script
873
874 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100875 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200876 endclass
877
878 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100879 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200880 endclass
881
882 def F(outer: Outer)
883 outer.inner.value = 1
884 enddef
885
886 def Test_assign_to_nested_typed_member()
887 var inner = Inner.new(0)
888 var outer = Outer.new(inner)
889 F(outer)
890 assert_equal(1, inner.value)
891 enddef
892
893 Test_assign_to_nested_typed_member()
894 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200895 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200896
897 # Assignment where target item is read only script level
898 lines =<< trim END
899 vim9script
900
901 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100902 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200903 endclass
904
905 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100906 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200907 endclass
908
909 def F(outer: Outer)
910 outer.inner.value = 1
911 enddef
912
913 var script_inner = Inner.new(0)
914 var script_outer = Outer.new(script_inner)
915 script_outer.inner.value = 1
916 assert_equal(1, script_inner.value)
917 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200918 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200919enddef
920
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000921def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200922 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000923 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200924 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000925
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200926 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100927 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000928
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200929 def Add(n: number)
930 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100931 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200932 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100933
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200934 var f = Foo.new(3)
935 f.Add(17)
936 assert_equal(20, f.x)
937
938 def AddToFoo(obj: Foo)
939 obj.x += 3
940 enddef
941
942 AddToFoo(f)
943 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000944 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200945 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000946enddef
947
Bram Moolenaarf4508042023-01-15 16:54:57 +0000948def Test_list_of_objects()
949 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200950 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000951
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200952 class Foo
953 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000954 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200955 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000956
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200957 def ProcessList(fooList: list<Foo>)
958 for foo in fooList
959 foo.Add()
960 endfor
961 enddef
962
963 var l: list<Foo> = [Foo.new()]
964 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000965 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200966 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000967enddef
968
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000969def Test_expr_after_using_object()
970 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200971 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000972
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200973 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100974 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200975 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000976
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200977 def Foo(): Something
978 var v = Something.new()
979 echo 'in Foo(): ' .. typename(v)
980 return v
981 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000982
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200983 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000984 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200985 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000986enddef
987
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000988def Test_class_default_new()
989 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200990 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000991
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200992 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100993 var lnum: number = 1
994 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200995 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000996
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200997 var pos = TextPosition.new()
998 assert_equal(1, pos.lnum)
999 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001000
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001001 pos = TextPosition.new(v:none, v:none)
1002 assert_equal(1, pos.lnum)
1003 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001004
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001005 pos = TextPosition.new(3, 22)
1006 assert_equal(3, pos.lnum)
1007 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001008
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001009 pos = TextPosition.new(v:none, 33)
1010 assert_equal(1, pos.lnum)
1011 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001012 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001013 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001014
1015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001016 vim9script
1017 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001018 var name: string
1019 var age: number = 42
1020 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001022 def new(this.name, this.age = v:none, this.education = v:none)
1023 enddef
1024 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001025
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001026 var piet = Person.new("Piet")
1027 assert_equal("Piet", piet.name)
1028 assert_equal(42, piet.age)
1029 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001030
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001031 var chris = Person.new("Chris", 4, "none")
1032 assert_equal("Chris", chris.name)
1033 assert_equal(4, chris.age)
1034 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001035 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001036 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001037
1038 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001039 vim9script
1040 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001041 var name: string
1042 var age: number = 42
1043 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +00001044
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001045 def new(this.name, this.age = v:none, this.education = v:none)
1046 enddef
1047 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001048
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001049 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +00001050 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001051 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001052
1053 # Using a specific value to initialize an instance variable in the new()
1054 # method.
1055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001056 vim9script
1057 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001058 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001059 def new(this.val = 'a')
1060 enddef
1061 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001062 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001063 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001064enddef
1065
h-east2261c892023-08-16 21:49:54 +09001066def Test_class_new_with_object_member()
1067 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001068 vim9script
h-east2261c892023-08-16 21:49:54 +09001069
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001070 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001071 var str: string
1072 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001073 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +09001074 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001075 def newVals(this.str, this.num)
1076 enddef
1077 endclass
h-east2261c892023-08-16 21:49:54 +09001078
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001079 def Check()
1080 try
1081 var c = C.new('cats', 2)
1082 assert_equal('cats', c.str)
1083 assert_equal(2, c.num)
1084
1085 c = C.newVals('dogs', 4)
1086 assert_equal('dogs', c.str)
1087 assert_equal(4, c.num)
1088 catch
1089 assert_report($'Unexpected exception was caught: {v:exception}')
1090 endtry
1091 enddef
1092
1093 Check()
h-east2261c892023-08-16 21:49:54 +09001094 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001095 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001096
1097 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001098 vim9script
1099
1100 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001101 var str: string
1102 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001103 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001104 enddef
1105 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001106
1107 def Check()
1108 try
1109 var c = C.new(1, 2)
1110 catch
1111 assert_report($'Unexpected exception was caught: {v:exception}')
1112 endtry
1113 enddef
1114
1115 Check()
h-eastdb385522023-09-28 22:18:19 +02001116 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001117 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001118
1119 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001120 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001121
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001122 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001123 var str: string
1124 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001125 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001126 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001127 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001128
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001129 def Check()
1130 try
1131 var c = C.newVals('dogs', 'apes')
1132 catch
1133 assert_report($'Unexpected exception was caught: {v:exception}')
1134 endtry
1135 enddef
1136
1137 Check()
1138 END
1139 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1140
1141 lines =<< trim END
1142 vim9script
1143
1144 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001145 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001146 def new(str: any)
1147 enddef
1148 endclass
1149
1150 def Check()
1151 try
1152 var c = C.new(1)
1153 catch
1154 assert_report($'Unexpected exception was caught: {v:exception}')
1155 endtry
1156 enddef
1157
1158 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001159 END
1160 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001161
1162 # Try using "this." argument in a class method
1163 lines =<< trim END
1164 vim9script
1165 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001166 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001167 static def Foo(this.val: number)
1168 enddef
1169 endclass
1170 END
1171 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1172
1173 # Try using "this." argument in an object method
1174 lines =<< trim END
1175 vim9script
1176 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001177 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001178 def Foo(this.val: number)
1179 enddef
1180 endclass
1181 END
1182 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001183enddef
1184
Bram Moolenaar74e12742022-12-13 21:14:28 +00001185def Test_class_object_member_inits()
1186 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001187 vim9script
1188 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001189 var lnum: number
1190 var col = 1
1191 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001192 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001193
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001194 var pos = TextPosition.new()
1195 assert_equal(0, pos.lnum)
1196 assert_equal(1, pos.col)
1197 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001198 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001199 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001200
1201 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001202 vim9script
1203 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001204 var lnum
1205 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001206 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001207 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001208 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001209
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001210 # If the type is not specified for a member, then it should be set during
1211 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001212 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001213 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001214
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001215 var init_count = 0
1216 def Init(): string
1217 init_count += 1
1218 return 'foo'
1219 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001220
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001221 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001222 var str1 = Init()
1223 var str2: string = Init()
1224 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001225 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001226
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001227 assert_equal(init_count, 0)
1228 var a = A.new()
1229 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001230 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001231 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001232
1233 # Test for initializing an object member with an unknown variable/type
1234 lines =<< trim END
1235 vim9script
1236 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001237 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001238 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001239 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001240 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001241 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001242
1243 # Test for initializing an object member with an special type
1244 lines =<< trim END
1245 vim9script
1246 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001247 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001248 endclass
1249 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001250 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001251enddef
1252
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001253" Test for instance variable access
1254def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001255 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001256 vim9script
1257 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001258 var _one = 1
1259 var two = 2
1260 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001261
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001262 def GetOne(): number
1263 return this._one
1264 enddef
1265 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001266
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001267 var trip = Triple.new()
1268 assert_equal(1, trip.GetOne())
1269 assert_equal(2, trip.two)
1270 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001271 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001272
Ernie Rael03042a22023-11-11 08:53:32 +01001273 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001274 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1275 trip.three = 33
1276 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001277
Ernie Raeld4802ec2023-10-20 11:59:00 +02001278 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001279 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001280 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001281
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001282 # Test for a public member variable name beginning with an underscore
1283 lines =<< trim END
1284 vim9script
1285 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001286 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001287 endclass
1288 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001289 v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001290
Bram Moolenaar590162c2022-12-24 21:24:06 +00001291 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001292 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001293
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001294 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001295 var make: string
1296 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001297
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001298 def new(make_arg: string)
1299 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001300 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001301
1302 def GetMake(): string
1303 return $"make = {this.make}"
1304 enddef
1305 def GetAge(): number
1306 return this.age
1307 enddef
1308 endclass
1309
1310 var c = MyCar.new("abc")
1311 assert_equal('make = abc', c.GetMake())
1312
1313 c = MyCar.new("def")
1314 assert_equal('make = def', c.GetMake())
1315
1316 var c2 = MyCar.new("123")
1317 assert_equal('make = 123', c2.GetMake())
1318
1319 def CheckCar()
1320 assert_equal("make = def", c.GetMake())
1321 assert_equal(5, c.GetAge())
1322 enddef
1323 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001324 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001325 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001326
1327 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001328 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001329
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001330 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001331 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001332
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001333 def new(make_arg: string)
1334 this.make = make_arg
1335 enddef
1336 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001337
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001338 var c = MyCar.new("abc")
1339 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001340 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001341 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001342
1343 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001344 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001345
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001346 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001347 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001348
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001349 def Add(n: number): any
1350 this.x->add(n)
1351 return this
1352 enddef
1353 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001354
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001355 echo Foo.new().Add(1).Add(2).x
1356 echo Foo.new().Add(1).Add(2)
1357 .x
1358 echo Foo.new().Add(1)
1359 .Add(2).x
1360 echo Foo.new()
1361 .Add(1).Add(2).x
1362 echo Foo.new()
1363 .Add(1)
1364 .Add(2)
1365 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001366 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001367 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001368
1369 # Test for "public" cannot be abbreviated
1370 lines =<< trim END
1371 vim9script
1372 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001373 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001374 endclass
1375 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001376 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001377
Doug Kearns74da0ee2023-12-14 20:26:26 +01001378 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001379 lines =<< trim END
1380 vim9script
1381 class Something
1382 public val = 1
1383 endclass
1384 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001385 v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001386
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001387 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001388 lines =<< trim END
1389 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001390 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001391 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001392 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001393 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001394 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001395 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001396
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001397 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001398 lines =<< trim END
1399 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001400 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001401 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001402 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001403 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001404 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001405 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001406
1407 # Modify a instance variable using the class name in a def function
1408 lines =<< trim END
1409 vim9script
1410 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001411 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001412 endclass
1413 def T()
1414 A.val = 1
1415 enddef
1416 T()
1417 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001418 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001419
1420 # Read a instance variable using the class name in a def function
1421 lines =<< trim END
1422 vim9script
1423 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001424 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001425 endclass
1426 def T()
1427 var i = A.val
1428 enddef
1429 T()
1430 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001431 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001432
1433 # Access from child class extending a class:
1434 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001435 vim9script
1436 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001437 var ro_obj_var = 10
1438 public var rw_obj_var = 20
1439 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001440 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001441
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001442 class B extends A
1443 def Foo()
1444 var x: number
1445 x = this.ro_obj_var
1446 this.ro_obj_var = 0
1447 x = this.rw_obj_var
1448 this.rw_obj_var = 0
1449 x = this._priv_obj_var
1450 this._priv_obj_var = 0
1451 enddef
1452 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001453
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001454 var b = B.new()
1455 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001456 END
1457 v9.CheckSourceSuccess(lines)
1458enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001459
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001460" Test for class variable access
1461def Test_class_variable_access()
1462 # Test for "static" cannot be abbreviated
1463 var lines =<< trim END
1464 vim9script
1465 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001466 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001467 endclass
1468 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001469 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001470
1471 # Test for "static" cannot be followed by "public".
1472 lines =<< trim END
1473 vim9script
1474 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001475 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001476 endclass
1477 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001478 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001479
1480 # A readonly class variable cannot be modified from a child class
1481 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001482 vim9script
1483 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001484 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001485 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001486
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001487 class B extends A
1488 def Foo()
1489 A.ro_class_var = 50
1490 enddef
1491 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001492
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001493 var b = B.new()
1494 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001495 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001496 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001497
Ernie Rael03042a22023-11-11 08:53:32 +01001498 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001499 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001500 vim9script
1501 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001502 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001503 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001504
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001505 class B extends A
1506 def Foo()
1507 var i = A._priv_class_var
1508 enddef
1509 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001510
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001511 var b = B.new()
1512 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001513 END
Ernie Rael03042a22023-11-11 08:53:32 +01001514 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001515
Ernie Rael03042a22023-11-11 08:53:32 +01001516 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001517 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001518 vim9script
1519 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001520 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001521 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001522
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001523 class B extends A
1524 def Foo()
1525 A._priv_class_var = 0
1526 enddef
1527 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001528
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001529 var b = B.new()
1530 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001531 END
Ernie Rael03042a22023-11-11 08:53:32 +01001532 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001533
1534 # Access from child class extending a class and from script context
1535 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001536 vim9script
1537 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001538 static var ro_class_var = 10
1539 public static var rw_class_var = 20
1540 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001541 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001542
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001543 class B extends A
1544 def Foo()
1545 var x: number
1546 x = A.ro_class_var
1547 assert_equal(10, x)
1548 x = A.rw_class_var
1549 assert_equal(25, x)
1550 A.rw_class_var = 20
1551 assert_equal(20, A.rw_class_var)
1552 enddef
1553 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001554
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001555 assert_equal(10, A.ro_class_var)
1556 assert_equal(20, A.rw_class_var)
1557 A.rw_class_var = 25
1558 assert_equal(25, A.rw_class_var)
1559 var b = B.new()
1560 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001561 END
1562 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001563enddef
1564
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001565def Test_class_object_compare()
1566 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001567 vim9script
1568 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001569 var nr = 0
1570 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001571 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001572 END
1573
1574 # used at the script level and in a compiled function
1575 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001576 var i1 = Item.new()
1577 assert_equal(i1, i1)
1578 assert_true(i1 is i1)
1579 var i2 = Item.new()
1580 assert_equal(i1, i2)
1581 assert_false(i1 is i2)
1582 var i3 = Item.new(0, 'xx')
1583 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001584
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001585 var io1 = Item.new(1, 'xx')
1586 assert_notequal(i1, io1)
1587 var io2 = Item.new(0, 'yy')
1588 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001589 END
1590
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001591 v9.CheckSourceSuccess(class_lines + test_lines)
1592 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001593 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001594
1595 for op in ['>', '>=', '<', '<=', '=~', '!~']
1596 var op_lines = [
1597 'var i1 = Item.new()',
1598 'var i2 = Item.new()',
1599 'echo i1 ' .. op .. ' i2',
1600 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001601 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001602 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001603 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001604 endfor
1605enddef
1606
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001607def Test_object_type()
1608 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001609 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001610
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001611 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001612 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001613 endclass
1614 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001615 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001616 endclass
1617 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001618 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001619 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001620
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001621 var o: One = One.new()
1622 var t: Two = Two.new()
1623 var m: TwoMore = TwoMore.new()
1624 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001625
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001626 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001627 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001628 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001629
1630 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001631 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001632
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001633 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001634 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001635 endclass
1636 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001637 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001638 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001639
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001640 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001641 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001642 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001643
1644 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001645 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001646
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001647 interface One
1648 def GetMember(): number
1649 endinterface
1650 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001651 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001652 def GetMember(): number
1653 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001654 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001655 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001656
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001657 var o: One = Two.new(5)
1658 assert_equal(5, o.GetMember())
1659 END
1660 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001661
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001662 lines =<< trim END
1663 vim9script
1664
1665 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001666 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001667 endclass
1668
1669 def Ref(name: string): func(Num): Num
1670 return (arg: Num): Num => {
1671 return eval(name)(arg)
1672 }
1673 enddef
1674
1675 const Fn = Ref('Double')
1676 var Double = (m: Num): Num => Num.new(m.n * 2)
1677
1678 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001679 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001680 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001681enddef
1682
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001683def Test_class_member()
1684 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001685 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001686 vim9script
1687 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001688 var lnum = 1
1689 var col = 1
1690 static var counter = 0
1691 static var _secret = 7
1692 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001693
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001694 static def AddToCounter(nr: number)
1695 counter += nr
1696 enddef
1697 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001698
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001699 assert_equal(0, TextPos.counter)
1700 TextPos.AddToCounter(3)
1701 assert_equal(3, TextPos.counter)
1702 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001703
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001704 def GetCounter(): number
1705 return TextPos.counter
1706 enddef
1707 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001708
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001709 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1710 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1711 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001712
Ernie Rael03042a22023-11-11 08:53:32 +01001713 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1714 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001715
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001716 assert_equal(42, TextPos.anybody)
1717 TextPos.anybody = 12
1718 assert_equal(12, TextPos.anybody)
1719 TextPos.anybody += 5
1720 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001721 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001722 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001723
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001724 # example in the help
1725 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001726 vim9script
1727 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001728 var size: number
1729 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001730
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001731 def new(this.size)
1732 totalSize += this.size
1733 enddef
1734 endclass
1735 assert_equal(0, OtherThing.totalSize)
1736 var to3 = OtherThing.new(3)
1737 assert_equal(3, OtherThing.totalSize)
1738 var to7 = OtherThing.new(7)
1739 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001740 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001741 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001742
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001743 # using static class member twice
1744 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001745 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001746
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001747 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001748 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001749
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001750 static def MacroSubstitute(s: string): string
1751 return substitute(s, '{{author}}', author, 'gi')
1752 enddef
1753 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001754
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001755 assert_equal('some text', HTML.MacroSubstitute('some text'))
1756 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001757 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001758 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001759
Ernie Rael03042a22023-11-11 08:53:32 +01001760 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001761 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001762 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001763
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001764 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001765 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001766
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001767 def Add(n: number): number
1768 const F = (): number => this._x + n
1769 return F()
1770 enddef
1771 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001772
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001773 var foo = Foo.new()
1774 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001775 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001776 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001777
Ernie Rael03042a22023-11-11 08:53:32 +01001778 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001779 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001780 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001781
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001782 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001783 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001784
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001785 def Add(n: number): number
1786 var Lam = () => {
1787 this._x = this._x + n
1788 }
1789 Lam()
1790 return this._x
1791 enddef
1792 endclass
h-east2bd6a092023-05-19 19:01:17 +01001793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001794 var foo = Foo.new()
1795 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001796 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001797 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001798
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001799 # check shadowing
1800 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001801 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001802
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001803 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001804 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001805 def Method(count: number)
1806 echo count
1807 enddef
1808 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001809
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001810 var s = Some.new()
1811 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001812 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001813 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001814
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001815 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001816 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001817 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001818
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001819 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001820 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001821 def Method(arg: number)
1822 var count = 3
1823 echo arg count
1824 enddef
1825 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001826
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001827 var s = Some.new()
1828 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001829 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001830 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001831
1832 # Test for using an invalid type for a member variable
1833 lines =<< trim END
1834 vim9script
1835 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001836 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001837 endclass
1838 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001839 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001840
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001841 # Test for setting a member on a null object
1842 lines =<< trim END
1843 vim9script
1844 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001845 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001846 endclass
1847
1848 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001849 var obj: A
1850 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001851 enddef
1852 F()
1853 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001854 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001855
1856 # Test for accessing a member on a null object
1857 lines =<< trim END
1858 vim9script
1859 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001860 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001861 endclass
1862
1863 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001864 var obj: A
1865 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001866 enddef
1867 F()
1868 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001869 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001870
1871 # Test for setting a member on a null object, at script level
1872 lines =<< trim END
1873 vim9script
1874 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001875 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001876 endclass
1877
1878 var obj: A
1879 obj.val = ""
1880 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001881 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001882
1883 # Test for accessing a member on a null object, at script level
1884 lines =<< trim END
1885 vim9script
1886 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001887 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001888 endclass
1889
1890 var obj: A
1891 echo obj.val
1892 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001893 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001894
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001895 # Test for no space before or after the '=' when initializing a member
1896 # variable
1897 lines =<< trim END
1898 vim9script
1899 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001900 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001901 endclass
1902 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001903 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001904 lines =<< trim END
1905 vim9script
1906 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001907 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001908 endclass
1909 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001910 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001911
1912 # Access a non-existing member
1913 lines =<< trim END
1914 vim9script
1915 class A
1916 endclass
1917 var a = A.new()
1918 var v = a.bar
1919 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001920 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001921enddef
1922
Ernie Raele6c9aa52023-10-06 19:55:52 +02001923" These messages should show the defining class of the variable (base class),
1924" not the class that did the reference (super class)
1925def Test_defining_class_message()
1926 var lines =<< trim END
1927 vim9script
1928
1929 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001930 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001931 endclass
1932
1933 class Child extends Base
1934 endclass
1935
1936 var o = Child.new()
1937 var x = o._v1
1938 END
Ernie Rael03042a22023-11-11 08:53:32 +01001939 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001940 lines =<< trim END
1941 vim9script
1942
1943 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001944 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001945 endclass
1946
1947 class Child extends Base
1948 endclass
1949
1950 def F()
1951 var o = Child.new()
1952 var x = o._v1
1953 enddef
1954 F()
1955 END
Ernie Rael03042a22023-11-11 08:53:32 +01001956 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001957 lines =<< trim END
1958 vim9script
1959
1960 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001961 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001962 endclass
1963
1964 class Child extends Base
1965 endclass
1966
1967 var o = Child.new()
1968 o.v1 = []
1969 END
1970 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1971 lines =<< trim END
1972 vim9script
1973
1974 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001975 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001976 endclass
1977
1978 class Child extends Base
1979 endclass
1980
1981 def F()
1982 var o = Child.new()
1983 o.v1 = []
1984 enddef
1985 F()
1986 END
1987
Ernie Rael03042a22023-11-11 08:53:32 +01001988 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001989 # of the class hierarchy.
1990 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1991 lines =<< trim END
1992 vim9script
1993
1994 class Base0
1995 endclass
1996
1997 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01001998 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001999 endclass
2000
2001 class Child extends Base
2002 endclass
2003
2004 def F()
2005 var o = Child.new()
2006 var x = o._v1
2007 enddef
2008 F()
2009 END
Ernie Rael03042a22023-11-11 08:53:32 +01002010 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002011
Ernie Rael03042a22023-11-11 08:53:32 +01002012 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02002013 # of the class hierarchy.
2014 lines =<< trim END
2015 vim9script
2016
2017 class Base0
2018 endclass
2019
2020 class Base extends Base0
2021 endclass
2022
2023 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002024 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002025 endclass
2026
2027 def F()
2028 var o = Child.new()
2029 var x = o._v1
2030 enddef
2031 F()
2032 END
Ernie Rael03042a22023-11-11 08:53:32 +01002033 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002034enddef
2035
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002036func Test_class_garbagecollect()
2037 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002038 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002039
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002040 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002041 var p = [2, 3]
2042 static var pl = ['a', 'b']
2043 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002044 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002045
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002046 echo Point.pl Point.pd
2047 call test_garbagecollect_now()
2048 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002049 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002050 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002051
2052 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002053 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002054
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002055 interface View
2056 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002057
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002058 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01002059 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002060 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002061
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002062 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01002063 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002064
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002065 def new()
2066 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01002067 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002068 enddef
2069 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002070
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002071 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002072
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002073 # overwrite "view", will be garbage-collected next
2074 view = MyView.new()
2075 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002076 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002077 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002078endfunc
2079
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002080" Test interface garbage collection
2081func Test_interface_garbagecollect()
2082 let lines =<< trim END
2083 vim9script
2084
2085 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002086 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002087
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002088 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002089 endinterface
2090
2091 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002092 static var ro_class_var: number = 10
2093 public static var rw_class_var: number = 20
2094 static var _priv_class_var: number = 30
2095 var ro_obj_var: number = 40
2096 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002097
2098 static def _ClassBar(): number
2099 return _priv_class_var
2100 enddef
2101
2102 static def ClassFoo(): number
2103 return ro_class_var + rw_class_var + A._ClassBar()
2104 enddef
2105
2106 def _ObjBar(): number
2107 return this._priv_obj_var
2108 enddef
2109
2110 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002111 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002112 enddef
2113 endclass
2114
2115 assert_equal(60, A.ClassFoo())
2116 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002117 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002118 test_garbagecollect_now()
2119 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002120 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002121 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002122 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002123endfunc
2124
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002125def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002126 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002127 vim9script
2128 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002129 var value = 0
2130 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002131
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002132 def new(v: number)
2133 this.value = v
2134 ++objects
2135 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002136
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002137 static def GetCount(): number
2138 return objects
2139 enddef
2140 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002141
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002142 assert_equal(0, Value.GetCount())
2143 var v1 = Value.new(2)
2144 assert_equal(1, Value.GetCount())
2145 var v2 = Value.new(7)
2146 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002147 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002148 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002149
2150 # Test for cleaning up after a class definition failure when using class
2151 # functions.
2152 lines =<< trim END
2153 vim9script
2154 class A
2155 static def Foo()
2156 enddef
2157 aaa
2158 endclass
2159 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002160 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002161
2162 # Test for calling a class method from another class method without the class
2163 # name prefix.
2164 lines =<< trim END
2165 vim9script
2166 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002167 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002168 static def Foo(n: number)
2169 myList->add(n)
2170 enddef
2171 static def Bar()
2172 Foo(2)
2173 enddef
2174 def Baz()
2175 Foo(3)
2176 enddef
2177 endclass
2178 A.Bar()
2179 var a = A.new()
2180 a.Baz()
2181 assert_equal([1, 2, 3], A.myList)
2182 END
2183 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002184enddef
2185
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002186def Test_class_defcompile()
2187 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002188 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002189
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002190 class C
2191 def Fo(i: number): string
2192 return i
2193 enddef
2194 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002195
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002196 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002197 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002198 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002199
2200 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002201 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 class C
2204 static def Fc(): number
2205 return 'x'
2206 enddef
2207 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002208
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002209 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002210 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002211 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002212
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002213 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002214 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002215
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002216 class C
2217 static def new()
2218 enddef
2219 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002220
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002221 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002222 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002223 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002224
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002225 # Trying to compile a function using a non-existing class variable
2226 lines =<< trim END
2227 vim9script
2228 defcompile x.Foo()
2229 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002230 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002231
2232 # Trying to compile a function using a variable which is not a class
2233 lines =<< trim END
2234 vim9script
2235 var x: number
2236 defcompile x.Foo()
2237 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002238 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002239
2240 # Trying to compile a function without specifying the name
2241 lines =<< trim END
2242 vim9script
2243 class A
2244 endclass
2245 defcompile A.
2246 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002247 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002248
2249 # Trying to compile a non-existing class object member function
2250 lines =<< trim END
2251 vim9script
2252 class A
2253 endclass
2254 var a = A.new()
2255 defcompile a.Foo()
2256 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002257 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002258enddef
2259
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002260def Test_class_object_to_string()
2261 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002262 vim9script
2263 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002264 var lnum = 1
2265 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002266 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002267
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002268 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002269
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002270 var pos = TextPosition.new()
2271 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002272 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002273 v9.CheckSourceSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +02002274
2275 # check string() with object nesting
2276 lines =<< trim END
2277 vim9script
2278 class C
2279 var nest1: C
2280 var nest2: C
2281 def Init(n1: C, n2: C)
2282 this.nest1 = n1
2283 this.nest2 = n2
2284 enddef
2285 endclass
2286
2287 var o1 = C.new()
2288 var o2 = C.new()
2289 o1.Init(o1, o2)
2290 o2.Init(o2, o1)
2291
2292 # The following previously put's vim into an infinite loop.
2293
2294 var expect = "object of C {nest1: object of C {...}, nest2: object of C {nest1: object of C {...}, nest2: object of C {...}}}"
2295 assert_equal(expect, string(o1))
2296 END
2297 v9.CheckSourceSuccess(lines)
2298
2299 lines =<< trim END
2300 vim9script
2301
2302 class B
2303 endclass
2304
2305 class C
2306 var b: B
2307 var c: C
2308 endclass
2309
2310 var o1 = C.new(B.new(), C.new(B.new()))
2311 var expect = "object of C {b: object of B {}, c: object of C {b: object of B {}, c: object of [unknown]}}"
2312 assert_equal(expect, string(o1))
2313 END
2314 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002315enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002316
Bram Moolenaar554d0312023-01-05 19:59:18 +00002317def Test_interface_basics()
2318 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002319 vim9script
2320 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002321 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002322 def GetCount(): number
2323 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002324 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002325 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002326
2327 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002328 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002329 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002330 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002331 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002332 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002333
2334 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002335 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002336
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002337 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002338 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002339 def Method(value: number)
2340 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002341 END
h-east61378a12023-04-18 19:07:29 +01002342 # The argument name and the object member name are the same, but this is not a
2343 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002344 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002345
2346 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002347 vim9script
2348 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002349 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002350 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002351 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002352 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002353
2354 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002355 vim9script
2356 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002357 var value: string
2358 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002359 def GetCount(): number
2360 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002361 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002362 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002363
2364 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002365 vim9script
2366 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002367 var value: string
2368 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002369 def GetCount(): number
2370 return 5
2371 enddef
2372 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002373 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002374 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002375
Yegappan Lakshmananac773182024-04-27 11:36:12 +02002376 # Additional commands after "interface name"
2377 lines =<< trim END
2378 vim9script
2379 interface Something | var x = 10 | var y = 20
2380 endinterface
2381 END
2382 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
2383
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002384 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002385 vim9script
2386 export interface EnterExit
2387 def Enter(): void
2388 def Exit(): void
2389 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002390 END
2391 writefile(lines, 'XdefIntf.vim', 'D')
2392
2393 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002394 vim9script
2395 import './XdefIntf.vim' as defIntf
2396 export def With(ee: defIntf.EnterExit, F: func)
2397 ee.Enter()
2398 try
2399 F()
2400 finally
2401 ee.Exit()
2402 endtry
2403 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002404 END
2405 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002406
2407 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002408 vim9script
2409 export abstract class EnterExit
2410 def Enter(): void
2411 enddef
2412 def Exit(): void
2413 enddef
2414 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002415 END
2416 writefile(imported, 'XdefIntf2.vim', 'D')
2417
2418 lines[1] = " import './XdefIntf2.vim' as defIntf"
2419 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002420enddef
2421
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002422" Test for using string() with an interface
2423def Test_interface_to_string()
2424 var lines =<< trim END
2425 vim9script
2426 interface Intf
2427 def Method(nr: number)
2428 endinterface
2429 assert_equal("interface Intf", string(Intf))
2430 END
2431 v9.CheckSourceSuccess(lines)
2432enddef
2433
Bram Moolenaar94674f22023-01-06 18:42:20 +00002434def Test_class_implements_interface()
2435 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002436 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002437
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002438 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002439 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002440 def Method(nr: number)
2441 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002442
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002443 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002444 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002445 def Method(nr: number)
2446 echo nr
2447 enddef
2448 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002449
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002450 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002451 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002452 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002453
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002454 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002455 var member = 'abc'
2456 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002457 def Method(nr: number)
2458 echo nr
2459 enddef
2460 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002461 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002462 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002463
2464 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002465 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002466
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002467 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002468 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002469 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002470
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002471 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002472 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002473 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002474 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002475 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002476
2477 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002478 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002479
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002480 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002481 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002482 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002483
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002484 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002485 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002486 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002487 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002488 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002489
2490 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002491 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002492
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002493 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002494 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002495 def Method(nr: number)
2496 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002497
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002498 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002499 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002500 def Method(nr: number)
2501 echo nr
2502 enddef
2503 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002504 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002505 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002506
2507 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002508 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002509
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002510 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002511 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002512 def Methods(nr: number)
2513 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002514
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002515 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002516 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002517 def Method(nr: number)
2518 echo nr
2519 enddef
2520 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002521 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002522 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002523
2524 # Check different order of members in class and interface works.
2525 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002526 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002527
2528 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002529 var label: string
2530 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002531 endinterface
2532
2533 # order of members is opposite of interface
2534 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002535 public var lnum: number = 5
2536 var errpos: number = 42
2537 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002538 endclass
2539
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002540 def Test()
2541 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002542
2543 assert_equal('label', result.label)
2544 assert_equal(42, result.errpos)
2545 enddef
2546
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002547 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002548 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002549 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002550
2551 # Interface name after "extends" doesn't end in a space or NUL character
2552 lines =<< trim END
2553 vim9script
2554 interface A
2555 endinterface
2556 class B extends A"
2557 endclass
2558 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002559 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002560
2561 # Trailing characters after a class name
2562 lines =<< trim END
2563 vim9script
2564 class A bbb
2565 endclass
2566 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002567 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002568
2569 # using "implements" with a non-existing class
2570 lines =<< trim END
2571 vim9script
2572 class A implements B
2573 endclass
2574 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002575 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002576
2577 # using "implements" with a regular class
2578 lines =<< trim END
2579 vim9script
2580 class A
2581 endclass
2582 class B implements A
2583 endclass
2584 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002585 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002586
2587 # using "implements" with a variable
2588 lines =<< trim END
2589 vim9script
2590 var T: number = 10
2591 class A implements T
2592 endclass
2593 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002594 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002595
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002596 # implements should be followed by a white space
2597 lines =<< trim END
2598 vim9script
2599 interface A
2600 endinterface
2601 class B implements A;
2602 endclass
2603 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002604 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002605
LemonBoyc5d27442023-08-19 13:02:35 +02002606 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002607 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002608
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002609 interface One
2610 def IsEven(nr: number): bool
2611 endinterface
2612 class Two implements One
2613 def IsEven(nr: number): string
2614 enddef
2615 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002616 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002617 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002618
2619 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002620 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002621
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002622 interface One
2623 def IsEven(nr: number): bool
2624 endinterface
2625 class Two implements One
2626 def IsEven(nr: bool): bool
2627 enddef
2628 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002629 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002630 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002631
2632 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002633 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002634
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002635 interface One
2636 def IsEven(nr: number): bool
2637 endinterface
2638 class Two implements One
2639 def IsEven(nr: number, ...extra: list<number>): bool
2640 enddef
2641 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002642 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002643 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 +02002644
2645 # access superclass interface members from subclass, mix variable order
2646 lines =<< trim END
2647 vim9script
2648
2649 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002650 var mvar1: number
2651 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002652 endinterface
2653
2654 # NOTE: the order is swapped
2655 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002656 var mvar2: number
2657 var mvar1: number
2658 public static var svar2: number
2659 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002660 def new()
2661 svar1 = 11
2662 svar2 = 12
2663 this.mvar1 = 111
2664 this.mvar2 = 112
2665 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002666 endclass
2667
2668 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002669 def new()
2670 this.mvar1 = 121
2671 this.mvar2 = 122
2672 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002673 endclass
2674
2675 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002676 def new()
2677 this.mvar1 = 131
2678 this.mvar2 = 132
2679 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002680 endclass
2681
Ernie Raelcf138d42023-09-06 20:45:03 +02002682 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002683 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002684 enddef
2685
2686 var oa = A.new()
2687 var ob = B.new()
2688 var oc = C.new()
2689
Ernie Raelcf138d42023-09-06 20:45:03 +02002690 assert_equal([111, 112], F2(oa))
2691 assert_equal([121, 122], F2(ob))
2692 assert_equal([131, 132], F2(oc))
2693 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002694 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002695
2696 # Access superclass interface members from subclass, mix variable order.
2697 # Two interfaces, one on A, one on B; each has both kinds of variables
2698 lines =<< trim END
2699 vim9script
2700
2701 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002702 var mvar1: number
2703 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002704 endinterface
2705
2706 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002707 var mvar3: number
2708 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002709 endinterface
2710
2711 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002712 public static var svar1: number
2713 public static var svar2: number
2714 var mvar1: number
2715 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002716 def new()
2717 svar1 = 11
2718 svar2 = 12
2719 this.mvar1 = 111
2720 this.mvar2 = 112
2721 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002722 endclass
2723
2724 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002725 static var svar3: number
2726 static var svar4: number
2727 var mvar3: number
2728 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002729 def new()
2730 svar3 = 23
2731 svar4 = 24
2732 this.mvar1 = 121
2733 this.mvar2 = 122
2734 this.mvar3 = 123
2735 this.mvar4 = 124
2736 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002737 endclass
2738
2739 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002740 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002741 def new()
2742 svar5 = 1001
2743 this.mvar1 = 131
2744 this.mvar2 = 132
2745 this.mvar3 = 133
2746 this.mvar4 = 134
2747 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002748 endclass
2749
Ernie Raelcf138d42023-09-06 20:45:03 +02002750 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002751 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002752 enddef
2753
Ernie Raelcf138d42023-09-06 20:45:03 +02002754 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002755 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002756 enddef
2757
Ernie Raelcf138d42023-09-06 20:45:03 +02002758 var oa = A.new()
2759 var ob = B.new()
2760 var oc = C.new()
2761
Ernie Raelcf138d42023-09-06 20:45:03 +02002762 assert_equal([[111, 112]], [F2(oa)])
2763 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2764 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002765 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002766 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002767
2768 # Using two interface names without a space after the ","
2769 lines =<< trim END
2770 vim9script
2771 interface A
2772 endinterface
2773 interface B
2774 endinterface
2775 class C implements A,B
2776 endclass
2777 END
2778 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2779
2780 # No interface name after a comma
2781 lines =<< trim END
2782 vim9script
2783 interface A
2784 endinterface
2785 class B implements A,
2786 endclass
2787 END
2788 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2789
2790 # No interface name after implements
2791 lines =<< trim END
2792 vim9script
2793 class A implements
2794 endclass
2795 END
2796 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002797enddef
2798
Bram Moolenaard0200c82023-01-28 15:19:40 +00002799def Test_call_interface_method()
2800 var lines =<< trim END
2801 vim9script
2802 interface Base
2803 def Enter(): void
2804 endinterface
2805
2806 class Child implements Base
2807 def Enter(): void
2808 g:result ..= 'child'
2809 enddef
2810 endclass
2811
2812 def F(obj: Base)
2813 obj.Enter()
2814 enddef
2815
2816 g:result = ''
2817 F(Child.new())
2818 assert_equal('child', g:result)
2819 unlet g:result
2820 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002821 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002822
2823 lines =<< trim END
2824 vim9script
2825 class Base
2826 def Enter(): void
2827 g:result ..= 'base'
2828 enddef
2829 endclass
2830
2831 class Child extends Base
2832 def Enter(): void
2833 g:result ..= 'child'
2834 enddef
2835 endclass
2836
2837 def F(obj: Base)
2838 obj.Enter()
2839 enddef
2840
2841 g:result = ''
2842 F(Child.new())
2843 assert_equal('child', g:result)
2844 unlet g:result
2845 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002846 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002847
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002848 # method of interface returns a value
2849 lines =<< trim END
2850 vim9script
2851 interface Base
2852 def Enter(): string
2853 endinterface
2854
2855 class Child implements Base
2856 def Enter(): string
2857 g:result ..= 'child'
2858 return "/resource"
2859 enddef
2860 endclass
2861
2862 def F(obj: Base)
2863 var r = obj.Enter()
2864 g:result ..= r
2865 enddef
2866
2867 g:result = ''
2868 F(Child.new())
2869 assert_equal('child/resource', g:result)
2870 unlet g:result
2871 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002872 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002873
2874 lines =<< trim END
2875 vim9script
2876 class Base
2877 def Enter(): string
2878 return null_string
2879 enddef
2880 endclass
2881
2882 class Child extends Base
2883 def Enter(): string
2884 g:result ..= 'child'
2885 return "/resource"
2886 enddef
2887 endclass
2888
2889 def F(obj: Base)
2890 var r = obj.Enter()
2891 g:result ..= r
2892 enddef
2893
2894 g:result = ''
2895 F(Child.new())
2896 assert_equal('child/resource', g:result)
2897 unlet g:result
2898 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002899 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002900
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002901 # No class that implements the interface.
2902 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002903 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002904
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002905 interface IWithEE
2906 def Enter(): any
2907 def Exit(): void
2908 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002909
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002910 def With1(ee: IWithEE, F: func)
2911 var r = ee.Enter()
2912 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002913
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002914 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002915 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002916 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002917enddef
2918
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002919def Test_class_used_as_type()
2920 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002921 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002922
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002923 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002924 var x = 0
2925 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002926 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002927
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002928 var p: Point
2929 p = Point.new(2, 33)
2930 assert_equal(2, p.x)
2931 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002932 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002933 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002934
2935 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002936 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002937
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002938 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002939 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002940 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002941
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002942 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002943 var x = 0
2944 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002945 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002946
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002947 var p: Point
2948 p = Point.new(2, 33)
2949 var hx = p
2950 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002951 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002952 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002953
2954 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002955 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002956
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002957 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002958 var x = 0
2959 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002960 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002961
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002962 var p: Point
2963 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002964 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002965 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002966enddef
2967
Bram Moolenaar83677162023-01-08 19:54:10 +00002968def Test_class_extends()
2969 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002970 vim9script
2971 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002972 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002973 def GetOne(): number
2974 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002975 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002976 endclass
2977 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002978 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002979 def GetTotal(): number
2980 return this.one + this.two
2981 enddef
2982 endclass
2983 var o = Child.new()
2984 assert_equal(1, o.one)
2985 assert_equal(2, o.two)
2986 assert_equal(1, o.GetOne())
2987 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002988 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002989 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002990
2991 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002992 vim9script
2993 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002994 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002995 endclass
2996 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002997 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002998 endclass
2999 var o = Child.new(3, 44)
3000 assert_equal(3, o.one)
3001 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00003002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003003 v9.CheckSourceSuccess(lines)
3004
3005 lines =<< trim END
3006 vim9script
3007 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003008 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003009 endclass
3010 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003011 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003012 endclass
3013 END
3014 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
3015
3016 lines =<< trim END
3017 vim9script
3018 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01003019 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003020 endclass
3021 END
3022 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
3023
3024 lines =<< trim END
3025 vim9script
3026 var SomeVar = 99
3027 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01003028 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003029 endclass
3030 END
3031 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
3032
3033 lines =<< trim END
3034 vim9script
3035 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003036 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003037 def ToString(): string
3038 return this.name
3039 enddef
3040 endclass
3041
3042 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003043 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003044 def ToString(): string
3045 return super.ToString() .. ': ' .. this.age
3046 enddef
3047 endclass
3048
3049 var o = Child.new('John', 42)
3050 assert_equal('John: 42', o.ToString())
3051 END
3052 v9.CheckSourceSuccess(lines)
3053
3054 lines =<< trim END
3055 vim9script
3056 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003057 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003058 def ToString(): number
3059 return this.age
3060 enddef
3061 def ToString(): string
3062 return this.age
3063 enddef
3064 endclass
3065 END
3066 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
3067
3068 lines =<< trim END
3069 vim9script
3070 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003071 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003072 def ToString(): string
3073 return super .ToString() .. ': ' .. this.age
3074 enddef
3075 endclass
3076 var o = Child.new(42)
3077 echo o.ToString()
3078 END
3079 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
3080
3081 lines =<< trim END
3082 vim9script
3083 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003084 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003085 def ToString(): string
3086 return this.name
3087 enddef
3088 endclass
3089
3090 var age = 42
3091 def ToString(): string
3092 return super.ToString() .. ': ' .. age
3093 enddef
3094 echo ToString()
3095 END
3096 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
3097
3098 lines =<< trim END
3099 vim9script
3100 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003101 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003102 def ToString(): string
3103 return super.ToString() .. ': ' .. this.age
3104 enddef
3105 endclass
3106 var o = Child.new(42)
3107 echo o.ToString()
3108 END
3109 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
3110
3111 lines =<< trim END
3112 vim9script
3113 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003114 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003115 static def ToString(): string
3116 return 'Base class'
3117 enddef
3118 endclass
3119
3120 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003121 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003122 def ToString(): string
3123 return Base.ToString() .. ': ' .. this.age
3124 enddef
3125 endclass
3126
3127 var o = Child.new('John', 42)
3128 assert_equal('Base class: 42', o.ToString())
3129 END
3130 v9.CheckSourceSuccess(lines)
3131
3132 lines =<< trim END
3133 vim9script
3134 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003135 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003136 def new(init: number)
3137 this.value = number + 1
3138 enddef
3139 endclass
3140 class Child extends Base
3141 def new()
3142 this.new(3)
3143 enddef
3144 endclass
3145 var c = Child.new()
3146 END
3147 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003148
3149 # base class with more than one object member
3150 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003151 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003152
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003153 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003154 var success: bool
3155 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003156 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003157
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003158 class Success extends Result
3159 def new(this.value = v:none)
3160 this.success = true
3161 enddef
3162 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003163
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003164 var v = Success.new('asdf')
3165 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003166 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003167 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003168
3169 # class name after "extends" doesn't end in a space or NUL character
3170 lines =<< trim END
3171 vim9script
3172 class A
3173 endclass
3174 class B extends A"
3175 endclass
3176 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003177 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003178enddef
3179
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003180def Test_using_base_class()
3181 var lines =<< trim END
3182 vim9script
3183
3184 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003185 def Enter(): any
3186 return null
3187 enddef
3188 def Exit(resource: any): void
3189 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003190 endclass
3191
3192 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003193 def Enter(): any
3194 return 42
3195 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003196
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003197 def Exit(resource: number): void
3198 g:result ..= '/exit'
3199 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003200 endclass
3201
3202 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003203 var r = ee.Enter()
3204 try
3205 g:result ..= r
3206 finally
3207 g:result ..= '/finally'
3208 ee.Exit(r)
3209 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003210 enddef
3211
3212 g:result = ''
3213 With(ChildEE.new())
3214 assert_equal('42/finally/exit', g:result)
3215 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003216 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003217 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003218
3219 # Using super, Child invokes Base method which has optional arg. #12471
3220 lines =<< trim END
3221 vim9script
3222
3223 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003224 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003225 def Method(arg = 0)
3226 this.success = true
3227 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003228 endclass
3229
3230 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003231 def new()
3232 super.Method()
3233 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003234 endclass
3235
3236 var obj = Child.new()
3237 assert_equal(true, obj.success)
3238 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003239 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003240enddef
3241
Bram Moolenaara86655a2023-01-12 17:06:27 +00003242def Test_class_import()
3243 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003244 vim9script
3245 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003246 var kind: string
3247 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003248 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003249 END
3250 writefile(lines, 'Xanimal.vim', 'D')
3251
3252 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003253 vim9script
3254 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003255
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003256 var a: animal.Animal
3257 a = animal.Animal.new('fish', 'Eric')
3258 assert_equal('fish', a.kind)
3259 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003260
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003261 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3262 assert_equal('cat', b.kind)
3263 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003264 END
3265 v9.CheckScriptSuccess(lines)
3266enddef
3267
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003268" Test for importing a class into a legacy script and calling the class method
3269def Test_class_method_from_legacy_script()
3270 var lines =<< trim END
3271 vim9script
3272 export class A
3273 static var name: string = 'a'
3274 static def SetName(n: string)
3275 name = n
3276 enddef
3277 endclass
3278 END
3279 writefile(lines, 'Xvim9export.vim', 'D')
3280
3281 lines =<< trim END
3282 import './Xvim9export.vim' as vim9
3283
3284 call s:vim9.A.SetName('b')
3285 call assert_equal('b', s:vim9.A.name)
3286 END
3287 v9.CheckScriptSuccess(lines)
3288enddef
3289
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003290" Test for implementing an imported interface
3291def Test_implement_imported_interface()
3292 var lines =<< trim END
3293 vim9script
3294 export interface Imp_Intf1
3295 def Fn1(): number
3296 endinterface
3297 export interface Imp_Intf2
3298 def Fn2(): number
3299 endinterface
3300 END
3301 writefile(lines, 'Ximportinterface.vim', 'D')
3302
3303 lines =<< trim END
3304 vim9script
3305 import './Ximportinterface.vim' as Xintf
3306
3307 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3308 def Fn1(): number
3309 return 10
3310 enddef
3311 def Fn2(): number
3312 return 20
3313 enddef
3314 endclass
3315 var a = A.new()
3316 assert_equal(10, a.Fn1())
3317 assert_equal(20, a.Fn2())
3318 END
3319 v9.CheckScriptSuccess(lines)
3320enddef
3321
3322" Test for extending an imported class
3323def Test_extend_imported_class()
3324 var lines =<< trim END
3325 vim9script
3326 export class Imp_C1
3327 def Fn1(): number
3328 return 5
3329 enddef
3330 endclass
3331 END
3332 writefile(lines, 'Xextendimportclass.vim', 'D')
3333
3334 lines =<< trim END
3335 vim9script
3336 import './Xextendimportclass.vim' as XClass
3337
3338 class A extends XClass.Imp_C1
3339 endclass
3340 var a = A.new()
3341 assert_equal(5, a.Fn1())
3342 END
3343 v9.CheckScriptSuccess(lines)
3344enddef
3345
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003346def Test_abstract_class()
3347 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003348 vim9script
3349 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003350 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003351 endclass
3352 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003353 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003354 endclass
3355 var p: Base = Person.new('Peter', 42)
3356 assert_equal('Peter', p.name)
3357 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003358 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003359 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003360
3361 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003362 vim9script
3363 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003364 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003365 endclass
3366 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003367 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003368 endclass
3369 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003370 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003371 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003372
3373 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003374 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003375 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003376 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003377 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003378 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003379
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003380 # Additional commands after "abstract class"
3381 lines =<< trim END
3382 vim9script
3383 abstract class Something | var x = []
3384 endclass
3385 END
3386 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3387
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003388 # Abstract class cannot have a "new" function
3389 lines =<< trim END
3390 vim9script
3391 abstract class Base
3392 def new()
3393 enddef
3394 endclass
3395 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003396 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003397
3398 # extending an abstract class with class methods and variables
3399 lines =<< trim END
3400 vim9script
3401 abstract class A
3402 static var s: string = 'vim'
3403 static def Fn(): list<number>
3404 return [10]
3405 enddef
3406 endclass
3407 class B extends A
3408 endclass
3409 var b = B.new()
3410 assert_equal('vim', A.s)
3411 assert_equal([10], A.Fn())
3412 END
3413 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003414enddef
3415
Bram Moolenaar486fc252023-01-18 14:51:07 +00003416def Test_closure_in_class()
3417 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003418 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003419
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003420 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003421 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003422
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003423 def new()
3424 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3425 enddef
3426 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003427
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003428 Foo.new()
3429 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003430 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003431 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003432enddef
3433
Ernie Rael9ed53752023-12-11 17:40:46 +01003434def Test_construct_object_from_legacy()
3435 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003436 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003437 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003438
Ernie Rael9ed53752023-12-11 17:40:46 +01003439 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003440
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003441 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003442 def new(arg: string)
3443 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003444 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003445 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003446
Ernie Rael9ed53752023-12-11 17:40:46 +01003447 export def CreateA(...args: list<any>): A
3448 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003449 enddef
3450
Ernie Rael9ed53752023-12-11 17:40:46 +01003451 g:P = CreateA
3452 legacy call g:P('some_arg')
3453 assert_equal(true, newCalled)
3454 unlet g:P
3455 END
3456 v9.CheckSourceSuccess(lines)
3457
3458 lines =<< trim END
3459 vim9script
3460
3461 var newCalled = false
3462
3463 class A
3464 static def CreateA(options = {}): any
3465 return A.new()
3466 enddef
3467 def new()
3468 newCalled = true
3469 enddef
3470 endclass
3471
3472 g:P = A.CreateA
3473 legacy call g:P()
3474 assert_equal(true, newCalled)
3475 unlet g:P
3476 END
3477 v9.CheckSourceSuccess(lines)
3478
3479 # This also tests invoking "new()" with "call"
3480 lines =<< trim END
3481 vim9script
3482
3483 var createdObject: any
3484
3485 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003486 var val1: number
3487 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003488 static def CreateA(...args: list<any>): any
3489 createdObject = call(A.new, args)
3490 return createdObject
3491 enddef
3492 endclass
3493
3494 g:P = A.CreateA
3495 legacy call g:P(3, 5)
3496 assert_equal(3, createdObject.val1)
3497 assert_equal(5, createdObject.val2)
3498 legacy call g:P()
3499 assert_equal(0, createdObject.val1)
3500 assert_equal(0, createdObject.val2)
3501 legacy call g:P(7)
3502 assert_equal(7, createdObject.val1)
3503 assert_equal(0, createdObject.val2)
3504 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003505 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003506 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003507enddef
3508
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003509def Test_defer_with_object()
3510 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003511 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003512
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003513 class CWithEE
3514 def Enter()
3515 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003516 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003517 def Exit()
3518 g:result ..= "exited"
3519 enddef
3520 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003521
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003522 def With(ee: CWithEE, F: func)
3523 ee.Enter()
3524 defer ee.Exit()
3525 F()
3526 enddef
3527
3528 g:result = ''
3529 var obj = CWithEE.new()
3530 obj->With(() => {
3531 g:result ..= "called/"
3532 })
3533 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003534 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003535 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003536 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003537
3538 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003539 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003540
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003541 class BaseWithEE
3542 def Enter()
3543 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003544 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003545 def Exit()
3546 g:result ..= "exited-base"
3547 enddef
3548 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003549
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003550 class CWithEE extends BaseWithEE
3551 def Enter()
3552 g:result ..= "entered-child/"
3553 enddef
3554 def Exit()
3555 g:result ..= "exited-child"
3556 enddef
3557 endclass
3558
3559 def With(ee: BaseWithEE, F: func)
3560 ee.Enter()
3561 defer ee.Exit()
3562 F()
3563 enddef
3564
3565 g:result = ''
3566 var obj = CWithEE.new()
3567 obj->With(() => {
3568 g:result ..= "called/"
3569 })
3570 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003571 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003572 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003573 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003574enddef
3575
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003576" The following test used to crash Vim (Github issue #12676)
3577def Test_extends_method_crashes_vim()
3578 var lines =<< trim END
3579 vim9script
3580
3581 class Observer
3582 endclass
3583
3584 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003585 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003586
3587 def Set(v: any)
3588 if v != this.value
3589 this.value = v
3590 endif
3591 enddef
3592
3593 def Register(observer: Observer)
3594 enddef
3595 endclass
3596
3597 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003598 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003599 endclass
3600
3601 def Observe(obj: Property, who: Observer)
3602 obj.Register(who)
3603 enddef
3604
3605 var p = Bool.new(false)
3606 var myObserver = Observer.new()
3607
3608 Observe(p, myObserver)
3609
3610 p.Set(true)
3611 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003612 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003613enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003614
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003615" Test for calling a method in a class that is extended
3616def Test_call_method_in_extended_class()
3617 var lines =<< trim END
3618 vim9script
3619
3620 var prop_init_called = false
3621 var prop_register_called = false
3622
3623 class Property
3624 def Init()
3625 prop_init_called = true
3626 enddef
3627
3628 def Register()
3629 prop_register_called = true
3630 enddef
3631 endclass
3632
3633 class Bool extends Property
3634 endclass
3635
3636 def Observe(obj: Property)
3637 obj.Register()
3638 enddef
3639
3640 var p = Property.new()
3641 Observe(p)
3642
3643 p.Init()
3644 assert_true(prop_init_called)
3645 assert_true(prop_register_called)
3646 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003647 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003648enddef
3649
LemonBoyafe04662023-08-23 21:08:11 +02003650def Test_instanceof()
3651 var lines =<< trim END
3652 vim9script
3653
3654 class Base1
3655 endclass
3656
3657 class Base2 extends Base1
3658 endclass
3659
3660 interface Intf1
3661 endinterface
3662
3663 class Mix1 implements Intf1
3664 endclass
3665
3666 class Base3 extends Mix1
3667 endclass
3668
Ernie Rael2025af12023-12-12 16:58:00 +01003669 type AliasBase1 = Base1
3670 type AliasBase2 = Base2
3671 type AliasIntf1 = Intf1
3672 type AliasMix1 = Mix1
3673
LemonBoyafe04662023-08-23 21:08:11 +02003674 var b1 = Base1.new()
3675 var b2 = Base2.new()
3676 var b3 = Base3.new()
3677
3678 assert_true(instanceof(b1, Base1))
3679 assert_true(instanceof(b2, Base1))
3680 assert_false(instanceof(b1, Base2))
3681 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003682 assert_true(instanceof(b3, Base1, Base2, Intf1))
3683
3684 assert_true(instanceof(b1, AliasBase1))
3685 assert_true(instanceof(b2, AliasBase1))
3686 assert_false(instanceof(b1, AliasBase2))
3687 assert_true(instanceof(b3, AliasMix1))
3688 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003689
3690 def Foo()
3691 var a1 = Base1.new()
3692 var a2 = Base2.new()
3693 var a3 = Base3.new()
3694
3695 assert_true(instanceof(a1, Base1))
3696 assert_true(instanceof(a2, Base1))
3697 assert_false(instanceof(a1, Base2))
3698 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003699 assert_true(instanceof(a3, Base1, Base2, Intf1))
3700
3701 assert_true(instanceof(a1, AliasBase1))
3702 assert_true(instanceof(a2, AliasBase1))
3703 assert_false(instanceof(a1, AliasBase2))
3704 assert_true(instanceof(a3, AliasMix1))
3705 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003706 enddef
3707 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003708
3709 var o_null: Base1
3710 assert_false(instanceof(o_null, Base1))
3711
LemonBoyafe04662023-08-23 21:08:11 +02003712 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003713 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003714
3715 lines =<< trim END
3716 vim9script
3717
3718 class Base1
3719 endclass
3720 instanceof(Base1.new())
3721 END
3722 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3723
3724 lines =<< trim END
3725 vim9script
3726
3727 class Base1
3728 endclass
3729 def F()
3730 instanceof(Base1.new())
3731 enddef
3732 F()
3733 END
3734 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3735
3736 lines =<< trim END
3737 vim9script
3738
3739 class Base1
3740 endclass
3741
3742 class Base2
3743 endclass
3744
3745 var o = Base2.new()
3746 instanceof(o, Base1, Base2, 3)
3747 END
3748 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3749
3750 lines =<< trim END
3751 vim9script
3752
3753 class Base1
3754 endclass
3755
3756 class Base2
3757 endclass
3758
3759 def F()
3760 var o = Base2.new()
3761 instanceof(o, Base1, Base2, 3)
3762 enddef
3763 F()
3764 END
3765 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003766enddef
3767
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003768" Test for calling a method in the parent class that is extended partially.
3769" This used to fail with the 'E118: Too many arguments for function: Text' error
3770" message (Github issue #12524).
3771def Test_call_method_in_parent_class()
3772 var lines =<< trim END
3773 vim9script
3774
3775 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003776 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003777
3778 def SetY(lnum: number)
3779 this._lnum = lnum
3780 enddef
3781
3782 def Text(): string
3783 return ''
3784 enddef
3785 endclass
3786
3787 class Foo extends Widget
3788 def Text(): string
3789 return '<Foo>'
3790 enddef
3791 endclass
3792
3793 def Stack(w1: Widget, w2: Widget): list<Widget>
3794 w1.SetY(1)
3795 w2.SetY(2)
3796 return [w1, w2]
3797 enddef
3798
3799 var foo1 = Foo.new()
3800 var foo2 = Foo.new()
3801 var l = Stack(foo1, foo2)
3802 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003803 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003804enddef
3805
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003806" Test for calling methods from three levels of classes
3807def Test_multi_level_method_call()
3808 var lines =<< trim END
3809 vim9script
3810
3811 var A_func1: number = 0
3812 var A_func2: number = 0
3813 var A_func3: number = 0
3814 var B_func2: number = 0
3815 var B_func3: number = 0
3816 var C_func3: number = 0
3817
3818 class A
3819 def Func1()
3820 A_func1 += 1
3821 enddef
3822
3823 def Func2()
3824 A_func2 += 1
3825 enddef
3826
3827 def Func3()
3828 A_func3 += 1
3829 enddef
3830 endclass
3831
3832 class B extends A
3833 def Func2()
3834 B_func2 += 1
3835 enddef
3836
3837 def Func3()
3838 B_func3 += 1
3839 enddef
3840 endclass
3841
3842 class C extends B
3843 def Func3()
3844 C_func3 += 1
3845 enddef
3846 endclass
3847
3848 def A_CallFuncs(a: A)
3849 a.Func1()
3850 a.Func2()
3851 a.Func3()
3852 enddef
3853
3854 def B_CallFuncs(b: B)
3855 b.Func1()
3856 b.Func2()
3857 b.Func3()
3858 enddef
3859
3860 def C_CallFuncs(c: C)
3861 c.Func1()
3862 c.Func2()
3863 c.Func3()
3864 enddef
3865
3866 var cobj = C.new()
3867 A_CallFuncs(cobj)
3868 B_CallFuncs(cobj)
3869 C_CallFuncs(cobj)
3870 assert_equal(3, A_func1)
3871 assert_equal(0, A_func2)
3872 assert_equal(0, A_func3)
3873 assert_equal(3, B_func2)
3874 assert_equal(0, B_func3)
3875 assert_equal(3, C_func3)
3876 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003877 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003878enddef
3879
3880" Test for using members from three levels of classes
3881def Test_multi_level_member_access()
3882 var lines =<< trim END
3883 vim9script
3884
3885 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003886 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003887 endclass
3888
3889 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003890 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003891 endclass
3892
3893 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003894 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003895 endclass
3896
3897 def A_members(a: A)
3898 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003899 enddef
3900
3901 def B_members(b: B)
3902 b.val1 += 1
3903 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003904 enddef
3905
3906 def C_members(c: C)
3907 c.val1 += 1
3908 c.val2 += 1
3909 c.val3 += 1
3910 enddef
3911
3912 var cobj = C.new()
3913 A_members(cobj)
3914 B_members(cobj)
3915 C_members(cobj)
3916 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003917 assert_equal(2, cobj.val2)
3918 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003919 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003920 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003921enddef
3922
LemonBoy0ffc17a2023-08-20 18:09:11 +02003923" Test expansion of <stack> with class methods.
3924def Test_stack_expansion_with_methods()
3925 var lines =<< trim END
3926 vim9script
3927
3928 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003929 def M1()
3930 F0()
3931 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003932 endclass
3933
3934 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02003935 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02003936 enddef
3937
3938 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003939 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003940 enddef
3941
3942 F()
3943 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003944 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003945enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003946
3947" Test the return type of the new() constructor
3948def Test_new_return_type()
3949 # new() uses the default return type and there is no return statement
3950 var lines =<< trim END
3951 vim9script
3952
3953 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003954 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003955
3956 def new(this._bufnr)
3957 if !bufexists(this._bufnr)
3958 this._bufnr = -1
3959 endif
3960 enddef
3961 endclass
3962
3963 var c = C.new(12345)
3964 assert_equal('object<C>', typename(c))
3965
3966 var v1: C
3967 v1 = C.new(12345)
3968 assert_equal('object<C>', typename(v1))
3969
3970 def F()
3971 var v2: C
3972 v2 = C.new(12345)
3973 assert_equal('object<C>', typename(v2))
3974 enddef
3975 F()
3976 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003977 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003978
3979 # new() uses the default return type and an empty 'return' statement
3980 lines =<< trim END
3981 vim9script
3982
3983 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003984 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003985
3986 def new(this._bufnr)
3987 if !bufexists(this._bufnr)
3988 this._bufnr = -1
3989 return
3990 endif
3991 enddef
3992 endclass
3993
3994 var c = C.new(12345)
3995 assert_equal('object<C>', typename(c))
3996
3997 var v1: C
3998 v1 = C.new(12345)
3999 assert_equal('object<C>', typename(v1))
4000
4001 def F()
4002 var v2: C
4003 v2 = C.new(12345)
4004 assert_equal('object<C>', typename(v2))
4005 enddef
4006 F()
4007 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004008 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004009
4010 # new() uses "any" return type and returns "this"
4011 lines =<< trim END
4012 vim9script
4013
4014 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004015 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004016
4017 def new(this._bufnr): any
4018 if !bufexists(this._bufnr)
4019 this._bufnr = -1
4020 return this
4021 endif
4022 enddef
4023 endclass
4024 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004025 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004026
4027 # new() uses 'Dict' return type and returns a Dict
4028 lines =<< trim END
4029 vim9script
4030
4031 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004032 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004033
4034 def new(): dict<any>
4035 this._state = {}
4036 return this._state
4037 enddef
4038 endclass
4039
4040 var c = C.new()
4041 assert_equal('object<C>', typename(c))
4042 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004043 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004044enddef
4045
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004046" Test for checking a member initialization type at run time.
4047def Test_runtime_type_check_for_member_init()
4048 var lines =<< trim END
4049 vim9script
4050
4051 var retnum: bool = false
4052
4053 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004054 retnum = !retnum
4055 if retnum
4056 return 1
4057 else
4058 return "hello"
4059 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004060 enddef
4061
4062 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004063 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004064 endclass
4065
4066 var c1 = C.new()
4067 var c2 = C.new()
4068 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004069 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004070enddef
4071
4072" Test for locking a variable referring to an object and reassigning to another
4073" object.
Ernie Raelee865f32023-09-29 19:53:55 +02004074def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004075 var lines =<< trim END
4076 vim9script
4077
4078 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004079 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004080 def new(this.val)
4081 enddef
4082 endclass
4083
4084 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
4085 lockvar 2 some_dict
4086
4087 var current: C
4088 current = some_dict['c']
4089 assert_equal(3, current.val)
4090 current = some_dict['b']
4091 assert_equal(2, current.val)
4092
4093 def F()
4094 current = some_dict['c']
4095 enddef
4096
4097 def G()
4098 current = some_dict['b']
4099 enddef
4100
4101 F()
4102 assert_equal(3, current.val)
4103 G()
4104 assert_equal(2, current.val)
4105 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004106 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004107enddef
4108
Ernie Raelee865f32023-09-29 19:53:55 +02004109" Test trying to lock an object variable from various places
4110def Test_lockvar_object_variable()
4111 # An object variable lockvar has several cases:
4112 # object method, scriptlevel, scriplevel from :def, :def arg
4113 # method arg, static method arg.
4114 # Also different depths
4115
Ernie Raelee865f32023-09-29 19:53:55 +02004116 #
4117 # lockvar of read-only object variable
4118 #
4119
4120 # read-only lockvar from object method
4121 var lines =<< trim END
4122 vim9script
4123
4124 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004125 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004126 def Lock()
4127 lockvar this.val1
4128 enddef
4129 endclass
4130 var o = C.new(3)
4131 o.Lock()
4132 END
Ernie Rael64885642023-10-04 20:16:22 +02004133 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004134
4135 # read-only lockvar from scriptlevel
4136 lines =<< trim END
4137 vim9script
4138
4139 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004140 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004141 endclass
4142 var o = C.new(3)
4143 lockvar o.val2
4144 END
4145 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4146
4147 # read-only lockvar of scriptlevel variable from def
4148 lines =<< trim END
4149 vim9script
4150
4151 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004152 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004153 endclass
4154 var o = C.new(3)
4155 def Lock()
4156 lockvar o.val3
4157 enddef
4158 Lock()
4159 END
4160 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4161
4162 # read-only lockvar of def argument variable
4163 lines =<< trim END
4164 vim9script
4165
4166 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004167 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004168 endclass
4169 def Lock(o: C)
4170 lockvar o.val4
4171 enddef
4172 Lock(C.new(3))
4173 END
4174 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4175
4176 # TODO: the following tests use type "any" for argument. Need a run time
4177 # check for access. Probably OK as is for now.
4178
4179 # read-only lockvar from object method arg
4180 lines =<< trim END
4181 vim9script
4182
4183 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004184 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004185 def Lock(o_any: any)
4186 lockvar o_any.val5
4187 enddef
4188 endclass
4189 var o = C.new(3)
4190 o.Lock(C.new(5))
4191 END
Ernie Rael64885642023-10-04 20:16:22 +02004192 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004193
4194 # read-only lockvar from class method arg
4195 lines =<< trim END
4196 vim9script
4197
4198 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004199 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004200 static def Lock(o_any: any)
4201 lockvar o_any.val6
4202 enddef
4203 endclass
4204 var o = C.new(3)
4205 C.Lock(o)
4206 END
Ernie Rael64885642023-10-04 20:16:22 +02004207 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004208
4209 #
4210 # lockvar of public object variable
4211 #
4212
4213 # lockvar from object method
4214 lines =<< trim END
4215 vim9script
4216
4217 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004218 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004219 def Lock()
4220 lockvar this.val1
4221 enddef
4222 endclass
4223 var o = C.new(3)
4224 o.Lock()
4225 END
4226 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4227
4228 # lockvar from scriptlevel
4229 lines =<< trim END
4230 vim9script
4231
4232 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004233 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004234 endclass
4235 var o = C.new(3)
4236 lockvar o.val2
4237 END
4238 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4239
4240 # lockvar of scriptlevel variable from def
4241 lines =<< trim END
4242 vim9script
4243
4244 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004245 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004246 endclass
4247 var o = C.new(3)
4248 def Lock()
4249 lockvar o.val3
4250 enddef
4251 Lock()
4252 END
4253 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4254
4255 # lockvar of def argument variable
4256 lines =<< trim END
4257 vim9script
4258
4259 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004260 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004261 endclass
4262 def Lock(o: C)
4263 lockvar o.val4
4264 enddef
4265 Lock(C.new(3))
4266 END
4267 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4268
4269 # lockvar from object method arg
4270 lines =<< trim END
4271 vim9script
4272
4273 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004274 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004275 def Lock(o_any: any)
4276 lockvar o_any.val5
4277 enddef
4278 endclass
4279 var o = C.new(3)
4280 o.Lock(C.new(5))
4281 END
4282 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4283
4284 # lockvar from class method arg
4285 lines =<< trim END
4286 vim9script
4287
4288 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004289 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004290 static def Lock(o_any: any)
4291 lockvar o_any.val6
4292 enddef
4293 endclass
4294 var o = C.new(3)
4295 C.Lock(o)
4296 END
4297 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4298enddef
4299
4300" Test trying to lock a class variable from various places
4301def Test_lockvar_class_variable()
4302
4303 # lockvar bare static from object method
4304 var lines =<< trim END
4305 vim9script
4306
4307 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004308 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004309 def Lock()
4310 lockvar sval1
4311 enddef
4312 endclass
4313 var o = C.new()
4314 o.Lock()
4315 END
4316 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4317
4318 # lockvar C.static from object method
4319 lines =<< trim END
4320 vim9script
4321
4322 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004323 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004324 def Lock()
4325 lockvar C.sval2
4326 enddef
4327 endclass
4328 var o = C.new()
4329 o.Lock()
4330 END
4331 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4332
4333 # lockvar bare static from class method
4334 lines =<< trim END
4335 vim9script
4336
4337 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004338 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004339 static def Lock()
4340 lockvar sval3
4341 enddef
4342 endclass
4343 C.Lock()
4344 END
4345 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4346
4347 # lockvar C.static from class method
4348 lines =<< trim END
4349 vim9script
4350
4351 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004352 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004353 static def Lock()
4354 lockvar C.sval4
4355 enddef
4356 endclass
4357 C.Lock()
4358 END
4359 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4360
4361 # lockvar C.static from script level
4362 lines =<< trim END
4363 vim9script
4364
4365 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004366 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004367 endclass
4368 lockvar C.sval5
4369 END
4370 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4371
4372 # lockvar o.static from script level
4373 lines =<< trim END
4374 vim9script
4375
4376 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004377 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004378 endclass
4379 var o = C.new()
4380 lockvar o.sval6
4381 END
4382 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4383enddef
4384
4385" Test locking an argument to :def
4386def Test_lockvar_argument()
4387 # Lockvar a function arg
4388 var lines =<< trim END
4389 vim9script
4390
4391 def Lock(val: any)
4392 lockvar val
4393 enddef
4394
4395 var d = {a: 1, b: 2}
4396 Lock(d)
4397
4398 d->extend({c: 3})
4399 END
4400 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4401
4402 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4403 # class member in "C". This tests lval_root_is_arg.
4404 lines =<< trim END
4405 vim9script
4406
4407 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004408 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004409 endclass
4410
4411 def Lock2(sval: any)
4412 lockvar sval
4413 enddef
4414
4415 var o = C.new()
4416 Lock2(o)
4417 END
4418 v9.CheckSourceSuccess(lines)
4419
4420 # Lock a class.
4421 lines =<< trim END
4422 vim9script
4423
4424 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004425 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004426 endclass
4427
4428 def Lock2(sval: any)
4429 lockvar sval
4430 enddef
4431
4432 Lock2(C)
4433 END
Ernie Raelb077b582023-12-14 20:11:44 +01004434 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004435
4436 # Lock an object.
4437 lines =<< trim END
4438 vim9script
4439
4440 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004441 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004442 endclass
4443
4444 def Lock2(sval: any)
4445 lockvar sval
4446 enddef
4447
4448 Lock2(C.new())
4449 END
4450 v9.CheckSourceSuccess(lines)
4451
4452 # In this case (unlike previous) "lockvar sval" is a class member.
4453 lines =<< trim END
4454 vim9script
4455
4456 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004457 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004458 def Lock2()
4459 lockvar sval
4460 enddef
4461 endclass
4462
4463
4464 var o = C.new()
4465 o.Lock2()
4466 END
4467 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4468enddef
4469
4470" Test that this can be locked without error
4471def Test_lockvar_this()
4472 # lockvar this
4473 var lines =<< trim END
4474 vim9script
4475 class C
4476 def TLock()
4477 lockvar this
4478 enddef
4479 endclass
4480 var o = C.new()
4481 o.TLock()
4482 END
4483 v9.CheckSourceSuccess(lines)
4484
4485 # lockvar four (four letter word, but not this)
4486 lines =<< trim END
4487 vim9script
4488 class C
4489 def TLock4()
4490 var four: number
4491 lockvar four
4492 enddef
4493 endclass
4494 var o = C.new()
4495 o.TLock4()
4496 END
4497 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4498
4499 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4500 lines =<< trim END
4501 vim9script
4502 class C
4503 def TLock5()
4504 var this5: number
4505 lockvar this5
4506 enddef
4507 endclass
4508 var o = C.new()
4509 o.TLock5()
4510 END
4511 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4512enddef
4513
4514" Test some general lockvar cases
4515def Test_lockvar_general()
4516 # lockvar an object and a class. It does nothing
4517 var lines =<< trim END
4518 vim9script
4519 class C
4520 endclass
4521 var o = C.new()
4522 lockvar o
4523 lockvar C
4524 END
4525 v9.CheckSourceSuccess(lines)
4526
4527 # Lock a list element that's nested in an object variable from a :def
4528 lines =<< trim END
4529 vim9script
4530
4531 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004532 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004533 endclass
4534 def Lock2(obj: any)
4535 lockvar obj.val[1]
4536 enddef
4537
4538 var o = C.new()
4539 Lock2(o)
4540 o.val[0] = [9]
4541 assert_equal([ [9], [2], [3] ], o.val)
4542 try
4543 o.val[1] = [999]
4544 call assert_false(true, 'assign should have failed')
4545 catch
4546 assert_exception('E741:')
4547 endtry
4548 o.val[2] = [8]
4549 assert_equal([ [9], [2], [8] ], o.val)
4550 END
4551 v9.CheckSourceSuccess(lines)
4552
4553 # Lock a list element that's nested in an object variable from scriptlevel
4554 lines =<< trim END
4555 vim9script
4556
4557 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004558 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004559 endclass
4560
4561 var o = C.new()
4562 lockvar o.val[1]
4563 o.val[0] = [9]
4564 assert_equal([ [9], [2], [3] ], o.val)
4565 try
4566 o.val[1] = [999]
4567 call assert_false(true, 'assign should have failed')
4568 catch
4569 assert_exception('E741:')
4570 endtry
4571 o.val[2] = [8]
4572 assert_equal([ [9], [2], [8] ], o.val)
4573 END
4574 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004575
4576 # lock a script level variable from an object method
4577 lines =<< trim END
4578 vim9script
4579
4580 class C
4581 def Lock()
4582 lockvar l
4583 enddef
4584 endclass
4585
4586 var l = [1]
4587 C.new().Lock()
4588 l[0] = 11
4589 END
4590 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4591
Ernie Rael03042a22023-11-11 08:53:32 +01004592 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004593 # in an object fetched via a script level list
4594 lines =<< trim END
4595 vim9script
4596
4597 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004598 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004599 def Lock()
4600 lockvar lc[0]._v1[1]
4601 enddef
4602 endclass
4603
4604 var l = [[1], [2], [3]]
4605 var o = C.new(l)
4606 var lc: list<C> = [ o ]
4607
4608 o.Lock()
4609 l[0] = [22]
4610 l[1] = [33]
4611 END
4612 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4613
4614 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004615 # in a class that does not own the protected variable.
4616 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004617 # the same name.
4618 lines =<< trim END
4619 vim9script
4620
4621 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004622 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004623 def Lock(obj: any)
4624 lockvar lc[0]._v1[1]
4625 enddef
4626 endclass
4627
4628 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004629 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004630 endclass
4631
4632 var l = [[1], [2], [3]]
4633 var o = C.new(l)
4634 var lc: list<C> = [ o ]
4635
4636 var o2 = C2.new()
4637 o2.Lock(o)
4638 END
Ernie Rael03042a22023-11-11 08:53:32 +01004639 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004640enddef
4641
Ernie Rael9771b2a2023-10-07 22:05:40 +02004642" Test builtin islocked()
4643def Test_lockvar_islocked()
4644 # Can't lock class/object variable
4645 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004646 # Lock item of variable's value (a list item)
4647 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004648 var lines =<< trim END
4649 vim9script
4650
4651 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004652 var o0: list<list<number>> = [ [0], [1], [2]]
4653 var o1: list<list<number>> = [[10], [11], [12]]
4654 static var c0: list<list<number>> = [[20], [21], [22]]
4655 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004656 endclass
4657
4658 def LockIt(arg: any)
4659 lockvar arg
4660 enddef
4661
4662 def UnlockIt(arg: any)
4663 unlockvar arg
4664 enddef
4665
4666 var obj = C.new()
4667 #lockvar obj.o1 # can't lock something you can't write to
4668
4669 try
4670 lockvar obj.o1 # can't lock something you can't write to
4671 call assert_false(1, '"lockvar obj.o1" should have failed')
4672 catch
4673 call assert_exception('E1335:')
4674 endtry
4675
4676 LockIt(obj.o1) # but can lock it's value
4677 assert_equal(1, islocked("obj.o1"))
4678 assert_equal(1, islocked("obj.o1[0]"))
4679 assert_equal(1, islocked("obj.o1[1]"))
4680 UnlockIt(obj.o1)
4681 assert_equal(0, islocked("obj.o1"))
4682 assert_equal(0, islocked("obj.o1[0]"))
4683
4684 lockvar obj.o1[0]
4685 assert_equal(0, islocked("obj.o1"))
4686 assert_equal(1, islocked("obj.o1[0]"))
4687 assert_equal(0, islocked("obj.o1[1]"))
4688 unlockvar obj.o1[0]
4689 assert_equal(0, islocked("obj.o1"))
4690 assert_equal(0, islocked("obj.o1[0]"))
4691
4692 # Same thing, but with a static
4693
4694 try
4695 lockvar C.c1 # can't lock something you can't write to
4696 call assert_false(1, '"lockvar C.c1" should have failed')
4697 catch
4698 call assert_exception('E1335:')
4699 endtry
4700
4701 LockIt(C.c1) # but can lock it's value
4702 assert_equal(1, islocked("C.c1"))
4703 assert_equal(1, islocked("C.c1[0]"))
4704 assert_equal(1, islocked("C.c1[1]"))
4705 UnlockIt(C.c1)
4706 assert_equal(0, islocked("C.c1"))
4707 assert_equal(0, islocked("C.c1[0]"))
4708
4709 lockvar C.c1[0]
4710 assert_equal(0, islocked("C.c1"))
4711 assert_equal(1, islocked("C.c1[0]"))
4712 assert_equal(0, islocked("C.c1[1]"))
4713 unlockvar C.c1[0]
4714 assert_equal(0, islocked("C.c1"))
4715 assert_equal(0, islocked("C.c1[0]"))
4716 END
4717 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004718
4719 # Do islocked() from an object method
4720 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004721 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004722 vim9script
4723
4724 var l0o0 = [ [0], [1], [2]]
4725 var l0o1 = [ [10], [11], [12]]
4726 var l0c0 = [[120], [121], [122]]
4727 var l0c1 = [[130], [131], [132]]
4728
4729 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004730 var o0: list<list<number>> = l0o0
4731 var o1: list<list<number>> = l0o1
4732 static var c0: list<list<number>> = l0c0
4733 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004734 def Islocked(arg: string): number
4735 return islocked(arg)
4736 enddef
4737 static def SIslocked(arg: string): number
4738 return islocked(arg)
4739 enddef
4740 endclass
4741
4742 var l2o0 = [[20000], [20001], [20002]]
4743 var l2o1 = [[20010], [20011], [20012]]
4744 var l2c0 = [[20120], [20121], [20122]]
4745 var l2c1 = [[20130], [20131], [20132]]
4746
4747 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004748 var o0: list<list<number>> = l2o0
4749 var o1: list<list<number>> = l2o1
4750 static var c0: list<list<number>> = l2c0
4751 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004752 def Islocked(arg: string): number
4753 return islocked(arg)
4754 enddef
4755 static def SIslocked(arg: string): number
4756 return islocked(arg)
4757 enddef
4758 endclass
4759
4760 var obj0 = C0.new()
4761 var obj2 = C2.new()
4762
4763 var l = [ obj0, null_object, obj2 ]
4764
4765 # lock list, object func access through script var expr
4766 assert_equal(0, obj0.Islocked("l[0].o0"))
4767 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4768 lockvar l0o0
4769 assert_equal(1, obj0.Islocked("l[0].o0"))
4770 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4771
4772 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4773
4774 # lock list element, object func access through script var expr
4775 lockvar l0o1[1]
4776 assert_equal(0, obj0.Islocked("this.o1[0]"))
4777 assert_equal(1, obj0.Islocked("this.o1[1]"))
4778
4779 assert_equal(0, obj0.Islocked("this.o1"))
4780 lockvar l0o1
4781 assert_equal(1, obj0.Islocked("this.o1"))
4782 unlockvar l0o1
4783
4784 lockvar l0c1[1]
4785
4786 # static by class name member expr from same class
4787 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4788 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4789 # static by bare name member expr from same class
4790 assert_equal(0, obj0.Islocked("c1[0]"))
4791 assert_equal(1, obj0.Islocked("c1[1]"))
4792
4793 # static by class name member expr from other class
4794 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4795 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4796 # static by bare name member expr from other class
4797 assert_equal(0, obj2.Islocked("c1[0]"))
4798 assert_equal(0, obj2.Islocked("c1[1]"))
4799
4800
4801 # static by bare name in same class
4802 assert_equal(0, obj0.Islocked("c0"))
4803 lockvar l0c0
4804 assert_equal(1, obj0.Islocked("c0"))
4805
4806 #
4807 # similar stuff, but use static method
4808 #
4809
4810 unlockvar l0o0
4811
4812 # lock list, object func access through script var expr
4813 assert_equal(0, C0.SIslocked("l[0].o0"))
4814 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4815 lockvar l0o0
4816 assert_equal(1, C0.SIslocked("l[0].o0"))
4817 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4818
4819 unlockvar l0o1
4820
4821 # can't access "this" from class method
4822 try
4823 C0.SIslocked("this.o1[0]")
4824 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4825 catch
4826 call assert_exception('E121: Undefined variable: this')
4827 endtry
4828
4829 lockvar l0c1[1]
4830
4831 # static by class name member expr from same class
4832 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4833 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4834 # static by bare name member expr from same class
4835 assert_equal(0, C0.SIslocked("c1[0]"))
4836 assert_equal(1, C0.SIslocked("c1[1]"))
4837
4838 # static by class name member expr from other class
4839 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4840 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4841 # static by bare name member expr from other class
4842 assert_equal(0, C2.SIslocked("c1[0]"))
4843 assert_equal(0, C2.SIslocked("c1[1]"))
4844
4845
4846 # static by bare name in same class
4847 unlockvar l0c0
4848 assert_equal(0, C0.SIslocked("c0"))
4849 lockvar l0c0
4850 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004851 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004852 v9.CheckSourceSuccess(lines)
4853
4854 # Check islocked class/object from various places.
4855 lines =<< trim END
4856 vim9script
4857
4858 class C
4859 def Islocked(arg: string): number
4860 return islocked(arg)
4861 enddef
4862 static def SIslocked(arg: string): number
4863 return islocked(arg)
4864 enddef
4865 endclass
4866 var obj = C.new()
4867
4868 # object method
4869 assert_equal(0, obj.Islocked("this"))
4870 assert_equal(0, obj.Islocked("C"))
4871
4872 # class method
4873 ### assert_equal(0, C.SIslocked("this"))
4874 assert_equal(0, C.SIslocked("C"))
4875
4876 #script level
4877 var v: number
4878 v = islocked("C")
4879 assert_equal(0, v)
4880 v = islocked("obj")
4881 assert_equal(0, v)
4882 END
4883 v9.CheckSourceSuccess(lines)
4884enddef
4885
4886def Test_lockvar_islocked_notfound()
4887 # Try non-existent things
4888 var lines =<< trim END
4889 vim9script
4890
4891 class C
4892 def Islocked(arg: string): number
4893 return islocked(arg)
4894 enddef
4895 static def SIslocked(arg: string): number
4896 return islocked(arg)
4897 enddef
4898 endclass
4899 var obj = C.new()
4900 assert_equal(-1, obj.Islocked("anywhere"))
4901 assert_equal(-1, C.SIslocked("notanywhere"))
4902 END
4903 v9.CheckSourceSuccess(lines)
4904
4905 # Something not found of the form "name1.name2" is an error
4906 lines =<< trim END
4907 vim9script
4908
4909 islocked("one.two")
4910 END
4911 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4912
4913 lines =<< trim END
4914 vim9script
4915
4916 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004917 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004918 def Islocked(arg: string): number
4919 return islocked(arg)
4920 enddef
4921 endclass
4922 var obj = C.new()
4923 obj.Islocked("this.val.not_there"))
4924 END
4925 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4926
4927 lines =<< trim END
4928 vim9script
4929
4930 class C
4931 def Islocked(arg: string): number
4932 return islocked(arg)
4933 enddef
4934 endclass
4935 var obj = C.new()
4936 obj.Islocked("this.notobjmember")
4937 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004938 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004939
4940 # access a script variable through methods
4941 lines =<< trim END
4942 vim9script
4943
4944 var l = [1]
4945 class C
4946 def Islocked(arg: string): number
4947 return islocked(arg)
4948 enddef
4949 static def SIslocked(arg: string): number
4950 return islocked(arg)
4951 enddef
4952 endclass
4953 var obj = C.new()
4954 assert_equal(0, obj.Islocked("l"))
4955 assert_equal(0, C.SIslocked("l"))
4956 lockvar l
4957 assert_equal(1, obj.Islocked("l"))
4958 assert_equal(1, C.SIslocked("l"))
4959 END
4960 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004961enddef
4962
Ernie Rael03042a22023-11-11 08:53:32 +01004963" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004964def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004965 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004966 var lines =<< trim END
4967 vim9script
4968
4969 class A
4970 def _Foo(): number
4971 return 1234
4972 enddef
4973 endclass
4974 var a = A.new()
4975 a._Foo()
4976 END
Ernie Rael03042a22023-11-11 08:53:32 +01004977 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004978
Ernie Rael03042a22023-11-11 08:53:32 +01004979 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004980 lines =<< trim END
4981 vim9script
4982
4983 class A
4984 def _Foo(): number
4985 return 1234
4986 enddef
4987 endclass
4988 def T()
4989 var a = A.new()
4990 a._Foo()
4991 enddef
4992 T()
4993 END
Ernie Rael03042a22023-11-11 08:53:32 +01004994 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004995
Ernie Rael03042a22023-11-11 08:53:32 +01004996 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004997 lines =<< trim END
4998 vim9script
4999
5000 class A
5001 def _Foo(): number
5002 return 1234
5003 enddef
5004 def Bar(): number
5005 return this._Foo()
5006 enddef
5007 endclass
5008 var a = A.new()
5009 assert_equal(1234, a.Bar())
5010 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005011 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005012
Ernie Rael03042a22023-11-11 08:53:32 +01005013 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005014 lines =<< trim END
5015 vim9script
5016
5017 class A
5018 def _Foo(): number
5019 return 1234
5020 enddef
5021 def Bar(): number
5022 return this._Foo()
5023 enddef
5024 endclass
5025 def T()
5026 var a = A.new()
5027 assert_equal(1234, a.Bar())
5028 enddef
5029 T()
5030 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005031 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005032
Ernie Rael03042a22023-11-11 08:53:32 +01005033 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005034 lines =<< trim END
5035 vim9script
5036
5037 class A
5038 def _Foo(): number
5039 return 1234
5040 enddef
5041 def Bar(): number
5042 return _Foo()
5043 enddef
5044 endclass
5045 var a = A.new()
5046 a.Bar()
5047 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005048 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005049
Ernie Rael03042a22023-11-11 08:53:32 +01005050 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005051 lines =<< trim END
5052 vim9script
5053
5054 class A
5055 def _Foo(): number
5056 return 1234
5057 enddef
5058 endclass
5059 A._Foo()
5060 END
Ernie Rael03042a22023-11-11 08:53:32 +01005061 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005062
Ernie Rael03042a22023-11-11 08:53:32 +01005063 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005064 lines =<< trim END
5065 vim9script
5066
5067 class A
5068 def _Foo()
5069 enddef
5070 def _Foo()
5071 enddef
5072 endclass
5073 var a = A.new()
5074 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005075 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005076
Ernie Rael03042a22023-11-11 08:53:32 +01005077 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005078 lines =<< trim END
5079 vim9script
5080
5081 class A
5082 def _Foo()
5083 enddef
5084 def Foo()
5085 enddef
5086 endclass
5087 var a = A.new()
5088 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005089 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005090
Ernie Rael03042a22023-11-11 08:53:32 +01005091 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005092 lines =<< trim END
5093 vim9script
5094
5095 class A
5096 def Foo()
5097 enddef
5098 def _Foo()
5099 enddef
5100 endclass
5101 var a = A.new()
5102 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005103 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005104
Ernie Rael03042a22023-11-11 08:53:32 +01005105 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005106 lines =<< trim END
5107 vim9script
5108
5109 class A
5110 def Foo(): number
5111 return 100
5112 enddef
5113 def _Bar(): number
5114 return 200
5115 enddef
5116 def _Baz()
5117 assert_equal(100, this.Foo())
5118 assert_equal(200, this._Bar())
5119 enddef
5120 def T()
5121 this._Baz()
5122 enddef
5123 endclass
5124 var a = A.new()
5125 a.T()
5126 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005127 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005128
Ernie Rael03042a22023-11-11 08:53:32 +01005129 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005130 lines =<< trim END
5131 vim9script
5132
5133 class A
5134 def _Foo(): number
5135 return 100
5136 enddef
5137 endclass
5138 class B
5139 def Foo(): number
5140 var a = A.new()
5141 a._Foo()
5142 enddef
5143 endclass
5144 var b = B.new()
5145 b.Foo()
5146 END
Ernie Rael03042a22023-11-11 08:53:32 +01005147 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005148
Ernie Rael03042a22023-11-11 08:53:32 +01005149 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005150 lines =<< trim END
5151 vim9script
5152 class A
5153 def _Foo(): number
5154 return 1234
5155 enddef
5156 endclass
5157 class B extends A
5158 def Bar()
5159 enddef
5160 endclass
5161 class C extends B
5162 def Baz(): number
5163 return this._Foo()
5164 enddef
5165 endclass
5166 var c = C.new()
5167 assert_equal(1234, c.Baz())
5168 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005169 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005170
Ernie Rael03042a22023-11-11 08:53:32 +01005171 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005172 lines =<< trim END
5173 vim9script
5174 class A
5175 def _Foo(): number
5176 return 1234
5177 enddef
5178 endclass
5179 class B extends A
5180 def Bar()
5181 enddef
5182 endclass
5183 class C extends B
5184 def Baz(): number
5185 enddef
5186 endclass
5187 var c = C.new()
5188 assert_equal(1234, c._Foo())
5189 END
Ernie Rael03042a22023-11-11 08:53:32 +01005190 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005191
5192 # Using "_" prefix in a method name should fail outside of a class
5193 lines =<< trim END
5194 vim9script
5195 def _Foo(): number
5196 return 1234
5197 enddef
5198 var a = _Foo()
5199 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005200 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005201enddef
5202
Ernie Rael03042a22023-11-11 08:53:32 +01005203" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005204def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005205 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005206 var lines =<< trim END
5207 vim9script
5208
5209 class A
5210 static def _Foo(): number
5211 return 1234
5212 enddef
5213 endclass
5214 A._Foo()
5215 END
Ernie Rael03042a22023-11-11 08:53:32 +01005216 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005217
Ernie Rael03042a22023-11-11 08:53:32 +01005218 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005219 lines =<< trim END
5220 vim9script
5221
5222 class A
5223 static def _Foo(): number
5224 return 1234
5225 enddef
5226 endclass
5227 def T()
5228 A._Foo()
5229 enddef
5230 T()
5231 END
Ernie Rael03042a22023-11-11 08:53:32 +01005232 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005233
Ernie Rael03042a22023-11-11 08:53:32 +01005234 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005235 lines =<< trim END
5236 vim9script
5237
5238 class A
5239 static def _Foo(): number
5240 return 1234
5241 enddef
5242 endclass
5243 var a = A.new()
5244 a._Foo()
5245 END
Ernie Rael03042a22023-11-11 08:53:32 +01005246 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005247
Ernie Rael03042a22023-11-11 08:53:32 +01005248 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005249 lines =<< trim END
5250 vim9script
5251
5252 class A
5253 static def _Foo(): number
5254 return 1234
5255 enddef
5256 endclass
5257 def T()
5258 var a = A.new()
5259 a._Foo()
5260 enddef
5261 T()
5262 END
Ernie Rael03042a22023-11-11 08:53:32 +01005263 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005264
Ernie Rael03042a22023-11-11 08:53:32 +01005265 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005266 lines =<< trim END
5267 vim9script
5268
5269 class A
5270 static def _Foo(): number
5271 return 1234
5272 enddef
5273 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005274 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005275 enddef
5276 endclass
5277 var a = A.new()
5278 a.Bar()
5279 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005280 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005281
Ernie Rael03042a22023-11-11 08:53:32 +01005282 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005283 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005284 lines =<< trim END
5285 vim9script
5286
5287 class A
5288 static def _Foo1(): number
5289 return 1234
5290 enddef
5291 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005292 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005293 enddef
5294 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005295 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005296 enddef
5297 endclass
5298 var a = A.new()
5299 a.Bar()
5300 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005301 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005302
Ernie Rael03042a22023-11-11 08:53:32 +01005303 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005304 lines =<< trim END
5305 vim9script
5306
5307 class A
5308 static def _Foo()
5309 enddef
5310 static def Foo()
5311 enddef
5312 endclass
5313 var a = A.new()
5314 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005315 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005316
Ernie Rael03042a22023-11-11 08:53:32 +01005317 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005318 lines =<< trim END
5319 vim9script
5320
5321 class A
5322 static def _Foo(): number
5323 return 1234
5324 enddef
5325 endclass
5326 class B
5327 def Foo(): number
5328 return A._Foo()
5329 enddef
5330 endclass
5331 var b = B.new()
5332 assert_equal(1234, b.Foo())
5333 END
Ernie Rael03042a22023-11-11 08:53:32 +01005334 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005335
Ernie Rael03042a22023-11-11 08:53:32 +01005336 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005337 lines =<< trim END
5338 vim9script
5339 class A
5340 static def _Foo(): number
5341 return 1234
5342 enddef
5343 endclass
5344 class B extends A
5345 def Bar()
5346 enddef
5347 endclass
5348 class C extends B
5349 def Baz(): number
5350 return A._Foo()
5351 enddef
5352 endclass
5353 var c = C.new()
5354 assert_equal(1234, c.Baz())
5355 END
Ernie Rael03042a22023-11-11 08:53:32 +01005356 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005357
Ernie Rael03042a22023-11-11 08:53:32 +01005358 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005359 lines =<< trim END
5360 vim9script
5361 class A
5362 static def _Foo(): number
5363 return 1234
5364 enddef
5365 endclass
5366 class B extends A
5367 def Bar()
5368 enddef
5369 endclass
5370 class C extends B
5371 static def Baz(): number
5372 return A._Foo()
5373 enddef
5374 endclass
5375 assert_equal(1234, C.Baz())
5376 END
Ernie Rael03042a22023-11-11 08:53:32 +01005377 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005378
Ernie Rael03042a22023-11-11 08:53:32 +01005379 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005380 lines =<< trim END
5381 vim9script
5382 class A
5383 static def _Foo(): number
5384 return 1234
5385 enddef
5386 endclass
5387 class B extends A
5388 def Bar()
5389 enddef
5390 endclass
5391 class C extends B
5392 def Baz(): number
5393 enddef
5394 endclass
5395 var c = C.new()
5396 assert_equal(1234, C._Foo())
5397 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005398 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005399enddef
5400
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005401" Test for using the return value of a class/object method as a function
5402" argument.
5403def Test_objmethod_funcarg()
5404 var lines =<< trim END
5405 vim9script
5406
5407 class C
5408 def Foo(): string
5409 return 'foo'
5410 enddef
5411 endclass
5412
5413 def Bar(a: number, s: string): string
5414 return s
5415 enddef
5416
5417 def Baz(c: C)
5418 assert_equal('foo', Bar(10, c.Foo()))
5419 enddef
5420
5421 var t = C.new()
5422 Baz(t)
5423 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005424 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005425
5426 lines =<< trim END
5427 vim9script
5428
5429 class C
5430 static def Foo(): string
5431 return 'foo'
5432 enddef
5433 endclass
5434
5435 def Bar(a: number, s: string): string
5436 return s
5437 enddef
5438
5439 def Baz()
5440 assert_equal('foo', Bar(10, C.Foo()))
5441 enddef
5442
5443 Baz()
5444 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005445 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005446enddef
5447
Ernie Raelcf138d42023-09-06 20:45:03 +02005448def Test_static_inheritence()
5449 # subclasses get their own static copy
5450 var lines =<< trim END
5451 vim9script
5452
5453 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005454 static var _svar: number
5455 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005456 def new()
5457 _svar = 1
5458 this._mvar = 101
5459 enddef
5460 def AccessObject(): number
5461 return this._mvar
5462 enddef
5463 def AccessStaticThroughObject(): number
5464 return _svar
5465 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005466 endclass
5467
5468 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005469 def new()
5470 this._mvar = 102
5471 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005472 endclass
5473
5474 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005475 def new()
5476 this._mvar = 103
5477 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005478
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005479 def AccessPrivateStaticThroughClassName(): number
5480 assert_equal(1, A._svar)
5481 return 444
5482 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005483 endclass
5484
5485 var oa = A.new()
5486 var ob = B.new()
5487 var oc = C.new()
5488 assert_equal(101, oa.AccessObject())
5489 assert_equal(102, ob.AccessObject())
5490 assert_equal(103, oc.AccessObject())
5491
Ernie Rael03042a22023-11-11 08:53:32 +01005492 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005493
5494 # verify object properly resolves to correct static
5495 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005496 assert_equal(1, ob.AccessStaticThroughObject())
5497 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005498 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005499 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005500enddef
5501
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005502" Test for declaring duplicate object and class members
5503def Test_dup_member_variable()
5504 # Duplicate member variable
5505 var lines =<< trim END
5506 vim9script
5507 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005508 var val = 10
5509 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005510 endclass
5511 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005512 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005513
Ernie Rael03042a22023-11-11 08:53:32 +01005514 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005515 lines =<< trim END
5516 vim9script
5517 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005518 var _val = 10
5519 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005520 endclass
5521 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005522 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005523
5524 # Duplicate public member variable
5525 lines =<< trim END
5526 vim9script
5527 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005528 public var val = 10
5529 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005530 endclass
5531 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005532 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005533
Ernie Rael03042a22023-11-11 08:53:32 +01005534 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005535 lines =<< trim END
5536 vim9script
5537 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005538 var val = 10
5539 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005540 endclass
5541 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005542 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005543
Ernie Rael03042a22023-11-11 08:53:32 +01005544 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005545 lines =<< trim END
5546 vim9script
5547 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005548 var _val = 20
5549 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005550 endclass
5551 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005552 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005553
5554 # Duplicate class member variable
5555 lines =<< trim END
5556 vim9script
5557 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005558 static var s: string = "abc"
5559 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005560 endclass
5561 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005562 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005563
Ernie Rael03042a22023-11-11 08:53:32 +01005564 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005565 lines =<< trim END
5566 vim9script
5567 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005568 public static var s: string = "abc"
5569 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005570 endclass
5571 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005572 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005573
5574 # Duplicate class and object member variable
5575 lines =<< trim END
5576 vim9script
5577 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005578 static var val = 10
5579 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005580 def new()
5581 enddef
5582 endclass
5583 var c = C.new()
5584 assert_equal(10, C.val)
5585 assert_equal(20, c.val)
5586 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005587 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005588
5589 # Duplicate object member variable in a derived class
5590 lines =<< trim END
5591 vim9script
5592 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005593 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005594 endclass
5595 class B extends A
5596 endclass
5597 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005598 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005599 endclass
5600 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005601 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005602
Ernie Rael03042a22023-11-11 08:53:32 +01005603 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005604 lines =<< trim END
5605 vim9script
5606 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005607 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005608 endclass
5609 class B extends A
5610 endclass
5611 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005612 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005613 endclass
5614 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005615 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005616
Ernie Rael03042a22023-11-11 08:53:32 +01005617 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005618 lines =<< trim END
5619 vim9script
5620 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005621 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005622 endclass
5623 class B extends A
5624 endclass
5625 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005626 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005627 endclass
5628 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005629 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005630
5631 # Duplicate object member variable in a derived class
5632 lines =<< trim END
5633 vim9script
5634 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005635 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005636 endclass
5637 class B extends A
5638 endclass
5639 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005640 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005641 endclass
5642 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005643 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005644
5645 # Two member variables with a common prefix
5646 lines =<< trim END
5647 vim9script
5648 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005649 public static var svar2: number
5650 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005651 endclass
5652 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005653 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005654enddef
5655
Ernie Rael03042a22023-11-11 08:53:32 +01005656" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005657def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005658 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005659 var lines =<< trim END
5660 vim9script
5661 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005662 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005663 def GetVal(): number
5664 return this._val
5665 enddef
5666 endclass
5667 def T()
5668 var a = A.new()
5669 a._val = 20
5670 enddef
5671 T()
5672 END
Ernie Rael03042a22023-11-11 08:53:32 +01005673 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005674
Ernie Rael03042a22023-11-11 08:53:32 +01005675 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005676 lines =<< trim END
5677 vim9script
5678 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005679 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005680 endclass
5681 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005682 var a = A.new()
5683 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005684 enddef
5685 T()
5686 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005687 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005688
Ernie Rael03042a22023-11-11 08:53:32 +01005689 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005690 lines =<< trim END
5691 vim9script
5692 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005693 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005694 endclass
5695 def T()
5696 var a = A.new()
5697 var x = a._val
5698 enddef
5699 T()
5700 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005701 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005702
Ernie Rael03042a22023-11-11 08:53:32 +01005703 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005704 lines =<< trim END
5705 vim9script
5706 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005707 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005708 endclass
5709 def T()
5710 var a = A.new()
5711 a._val = 3
5712 enddef
5713 T()
5714 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005715 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005716
Ernie Rael03042a22023-11-11 08:53:32 +01005717 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005718 lines =<< trim END
5719 vim9script
5720 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005721 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005722 endclass
5723 def T()
5724 var x = A._val
5725 enddef
5726 T()
5727 END
Ernie Rael03042a22023-11-11 08:53:32 +01005728 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005729
Ernie Rael03042a22023-11-11 08:53:32 +01005730 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005731 lines =<< trim END
5732 vim9script
5733 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005734 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005735 endclass
5736 def T()
5737 A._val = 3
5738 enddef
5739 T()
5740 END
Ernie Rael03042a22023-11-11 08:53:32 +01005741 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005742enddef
5743
5744" Test for changing the member access of an interface in a implementation class
5745def Test_change_interface_member_access()
5746 var lines =<< trim END
5747 vim9script
5748 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005749 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005750 endinterface
5751 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005752 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005753 endclass
5754 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005755 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005756
5757 lines =<< trim END
5758 vim9script
5759 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005760 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005761 endinterface
5762 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005763 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005764 endclass
5765 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005766 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005767enddef
5768
5769" Test for trying to change a readonly member from a def function
5770def Test_readonly_member_change_in_def_func()
5771 var lines =<< trim END
5772 vim9script
5773 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005774 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005775 endclass
5776 def T()
5777 var a = A.new()
5778 a.val = 20
5779 enddef
5780 T()
5781 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005782 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005783enddef
5784
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005785" Test for reading and writing a class member from a def function
5786def Test_modify_class_member_from_def_function()
5787 var lines =<< trim END
5788 vim9script
5789 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005790 var var1: number = 10
5791 public static var var2: list<number> = [1, 2]
5792 public static var var3: dict<number> = {a: 1, b: 2}
5793 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005794 endclass
5795 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005796 assert_equal([1, 2], A.var2)
5797 assert_equal({a: 1, b: 2}, A.var3)
5798 A.var2 = [3, 4]
5799 A.var3 = {c: 3, d: 4}
5800 assert_equal([3, 4], A.var2)
5801 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005802 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005803 enddef
5804 T()
5805 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005806 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005807enddef
5808
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005809" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005810def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005811 var lines =<< trim END
5812 vim9script
5813 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005814 public static var svar1: list<number> = [1]
5815 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005816 endclass
5817
5818 A.svar1->add(3)
5819 A.svar2->add(4)
5820 assert_equal([1, 3], A.svar1)
5821 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005822
5823 def Foo()
5824 A.svar1->add(7)
5825 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005826 assert_equal([1, 3, 7], A.svar1)
5827 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005828 enddef
5829 Foo()
5830 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005831 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005832
5833 # Cannot read from a class variable using an object in script context
5834 lines =<< trim END
5835 vim9script
5836 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005837 public var var1: number
5838 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005839 endclass
5840
5841 var a = A.new()
5842 echo a.svar2
5843 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005844 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005845
5846 # Cannot write to a class variable using an object in script context
5847 lines =<< trim END
5848 vim9script
5849 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005850 public var var1: number
5851 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005852 endclass
5853
5854 var a = A.new()
5855 a.svar2 = [2]
5856 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005857 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005858
5859 # Cannot read from a class variable using an object in def method context
5860 lines =<< trim END
5861 vim9script
5862 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005863 public var var1: number
5864 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005865 endclass
5866
5867 def T()
5868 var a = A.new()
5869 echo a.svar2
5870 enddef
5871 T()
5872 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005873 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005874
5875 # Cannot write to a class variable using an object in def method context
5876 lines =<< trim END
5877 vim9script
5878 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005879 public var var1: number
5880 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005881 endclass
5882
5883 def T()
5884 var a = A.new()
5885 a.svar2 = [2]
5886 enddef
5887 T()
5888 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005889 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005890enddef
5891
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005892" Test for using a interface method using a child object
5893def Test_interface_method_from_child()
5894 var lines =<< trim END
5895 vim9script
5896
5897 interface A
5898 def Foo(): string
5899 endinterface
5900
5901 class B implements A
5902 def Foo(): string
5903 return 'foo'
5904 enddef
5905 endclass
5906
5907 class C extends B
5908 def Bar(): string
5909 return 'bar'
5910 enddef
5911 endclass
5912
5913 def T1(a: A)
5914 assert_equal('foo', a.Foo())
5915 enddef
5916
5917 def T2(b: B)
5918 assert_equal('foo', b.Foo())
5919 enddef
5920
5921 var c = C.new()
5922 T1(c)
5923 T2(c)
5924 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005925 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005926enddef
5927
5928" Test for using an interface method using a child object when it is overridden
5929" by the child class.
5930" FIXME: This test fails.
5931" def Test_interface_overridden_method_from_child()
5932" var lines =<< trim END
5933" vim9script
5934"
5935" interface A
5936" def Foo(): string
5937" endinterface
5938"
5939" class B implements A
5940" def Foo(): string
5941" return 'b-foo'
5942" enddef
5943" endclass
5944"
5945" class C extends B
5946" def Bar(): string
5947" return 'bar'
5948" enddef
5949" def Foo(): string
5950" return 'c-foo'
5951" enddef
5952" endclass
5953"
5954" def T1(a: A)
5955" assert_equal('c-foo', a.Foo())
5956" enddef
5957"
5958" def T2(b: B)
5959" assert_equal('c-foo', b.Foo())
5960" enddef
5961"
5962" var c = C.new()
5963" T1(c)
5964" T2(c)
5965" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005966" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005967" enddef
5968
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005969" Test for abstract methods
5970def Test_abstract_method()
5971 # Use two abstract methods
5972 var lines =<< trim END
5973 vim9script
5974 abstract class A
5975 def M1(): number
5976 return 10
5977 enddef
5978 abstract def M2(): number
5979 abstract def M3(): number
5980 endclass
5981 class B extends A
5982 def M2(): number
5983 return 20
5984 enddef
5985 def M3(): number
5986 return 30
5987 enddef
5988 endclass
5989 var b = B.new()
5990 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5991 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005992 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005993
5994 # Don't define an abstract method
5995 lines =<< trim END
5996 vim9script
5997 abstract class A
5998 abstract def Foo()
5999 endclass
6000 class B extends A
6001 endclass
6002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006003 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006004
6005 # Use abstract method in a concrete class
6006 lines =<< trim END
6007 vim9script
6008 class A
6009 abstract def Foo()
6010 endclass
6011 class B extends A
6012 endclass
6013 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006014 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006015
6016 # Use abstract method in an interface
6017 lines =<< trim END
6018 vim9script
6019 interface A
6020 abstract def Foo()
6021 endinterface
6022 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006023 def Foo()
6024 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006025 endclass
6026 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01006027 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6028
6029 # Use abstract static method in an interface
6030 lines =<< trim END
6031 vim9script
6032 interface A
6033 abstract static def Foo()
6034 enddef
6035 endinterface
6036 END
6037 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6038
6039 # Use abstract static variable in an interface
6040 lines =<< trim END
6041 vim9script
6042 interface A
6043 abstract static foo: number = 10
6044 endinterface
6045 END
6046 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006047
6048 # Abbreviate the "abstract" keyword
6049 lines =<< trim END
6050 vim9script
6051 class A
6052 abs def Foo()
6053 endclass
6054 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006055 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006056
6057 # Use "abstract" with a member variable
6058 lines =<< trim END
6059 vim9script
6060 abstract class A
6061 abstract this.val = 10
6062 endclass
6063 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006064 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006065
6066 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01006067 lines =<< trim END
6068 vim9script
6069 abstract class A
6070 abstract static def Foo(): number
6071 endclass
6072 END
6073 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006074
6075 # Type mismatch between abstract method and concrete method
6076 lines =<< trim END
6077 vim9script
6078 abstract class A
6079 abstract def Foo(a: string, b: number): list<number>
6080 endclass
6081 class B extends A
6082 def Foo(a: number, b: string): list<string>
6083 return []
6084 enddef
6085 endclass
6086 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006087 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 +02006088
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006089 # Invoke an abstract method from a def function
6090 lines =<< trim END
6091 vim9script
6092 abstract class A
6093 abstract def Foo(): list<number>
6094 endclass
6095 class B extends A
6096 def Foo(): list<number>
6097 return [3, 5]
6098 enddef
6099 endclass
6100 def Bar(c: B)
6101 assert_equal([3, 5], c.Foo())
6102 enddef
6103 var b = B.new()
6104 Bar(b)
6105 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006106 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006107
6108 # Use a static method in an abstract class
6109 lines =<< trim END
6110 vim9script
6111 abstract class A
6112 static def Foo(): string
6113 return 'foo'
6114 enddef
6115 endclass
6116 assert_equal('foo', A.Foo())
6117 END
6118 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006119enddef
6120
6121" Test for calling a class method from a subclass
6122def Test_class_method_call_from_subclass()
6123 # class method call from a subclass
6124 var lines =<< trim END
6125 vim9script
6126
6127 class A
6128 static def Foo()
6129 echo "foo"
6130 enddef
6131 endclass
6132
6133 class B extends A
6134 def Bar()
6135 Foo()
6136 enddef
6137 endclass
6138
6139 var b = B.new()
6140 b.Bar()
6141 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006142 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006143enddef
6144
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006145" Test for calling a class method using an object in a def function context and
6146" script context.
6147def Test_class_method_call_using_object()
6148 # script context
6149 var lines =<< trim END
6150 vim9script
6151 class A
6152 static def Foo(): list<string>
6153 return ['a', 'b']
6154 enddef
6155 def Bar()
6156 assert_equal(['a', 'b'], A.Foo())
6157 assert_equal(['a', 'b'], Foo())
6158 enddef
6159 endclass
6160
6161 def T()
6162 assert_equal(['a', 'b'], A.Foo())
6163 var t_a = A.new()
6164 t_a.Bar()
6165 enddef
6166
6167 assert_equal(['a', 'b'], A.Foo())
6168 var a = A.new()
6169 a.Bar()
6170 T()
6171 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006172 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006173
6174 # script context
6175 lines =<< trim END
6176 vim9script
6177 class A
6178 static def Foo(): string
6179 return 'foo'
6180 enddef
6181 endclass
6182
6183 var a = A.new()
6184 assert_equal('foo', a.Foo())
6185 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006186 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006187
6188 # def function context
6189 lines =<< trim END
6190 vim9script
6191 class A
6192 static def Foo(): string
6193 return 'foo'
6194 enddef
6195 endclass
6196
6197 def T()
6198 var a = A.new()
6199 assert_equal('foo', a.Foo())
6200 enddef
6201 T()
6202 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006203 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006204enddef
6205
6206def Test_class_variable()
6207 var lines =<< trim END
6208 vim9script
6209
6210 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006211 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006212 static def ClassFunc()
6213 assert_equal(10, val)
6214 enddef
6215 def ObjFunc()
6216 assert_equal(10, val)
6217 enddef
6218 endclass
6219
6220 class B extends A
6221 endclass
6222
6223 assert_equal(10, A.val)
6224 A.ClassFunc()
6225 var a = A.new()
6226 a.ObjFunc()
6227 var b = B.new()
6228 b.ObjFunc()
6229
6230 def T1(a1: A)
6231 a1.ObjFunc()
6232 A.ClassFunc()
6233 enddef
6234 T1(b)
6235
6236 A.val = 20
6237 assert_equal(20, A.val)
6238 END
6239 v9.CheckSourceSuccess(lines)
6240
6241 # Modifying a parent class variable from a child class method
6242 lines =<< trim END
6243 vim9script
6244
6245 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006246 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006247 endclass
6248
6249 class B extends A
6250 static def ClassFunc()
6251 val = 20
6252 enddef
6253 endclass
6254 B.ClassFunc()
6255 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006256 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006257
6258 # Reading a parent class variable from a child class method
6259 lines =<< trim END
6260 vim9script
6261
6262 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006263 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006264 endclass
6265
6266 class B extends A
6267 static def ClassFunc()
6268 var i = val
6269 enddef
6270 endclass
6271 B.ClassFunc()
6272 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006273 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006274
6275 # Modifying a parent class variable from a child object method
6276 lines =<< trim END
6277 vim9script
6278
6279 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006280 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006281 endclass
6282
6283 class B extends A
6284 def ObjFunc()
6285 val = 20
6286 enddef
6287 endclass
6288 var b = B.new()
6289 b.ObjFunc()
6290 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006291 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006292
6293 # Reading a parent class variable from a child object method
6294 lines =<< trim END
6295 vim9script
6296
6297 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006298 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006299 endclass
6300
6301 class B extends A
6302 def ObjFunc()
6303 var i = val
6304 enddef
6305 endclass
6306 var b = B.new()
6307 b.ObjFunc()
6308 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006309 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006310
6311 # Modifying a class variable using an object at script level
6312 lines =<< trim END
6313 vim9script
6314
6315 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006316 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006317 endclass
6318 var a = A.new()
6319 a.val = 20
6320 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006321 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006322
6323 # Reading a class variable using an object at script level
6324 lines =<< trim END
6325 vim9script
6326
6327 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006328 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006329 endclass
6330 var a = A.new()
6331 var i = a.val
6332 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006333 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006334
6335 # Modifying a class variable using an object at function level
6336 lines =<< trim END
6337 vim9script
6338
6339 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006340 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006341 endclass
6342
6343 def T()
6344 var a = A.new()
6345 a.val = 20
6346 enddef
6347 T()
6348 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006349 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006350
6351 # Reading a class variable using an object at function level
6352 lines =<< trim END
6353 vim9script
6354
6355 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006356 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006357 endclass
6358 def T()
6359 var a = A.new()
6360 var i = a.val
6361 enddef
6362 T()
6363 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006364 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006365
6366 # Use old implicit var declaration syntax (without initialization)
6367 lines =<< trim END
6368 vim9script
6369
6370 class A
6371 static val: number
6372 endclass
6373 END
6374 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6375
6376 # Use old implicit var declaration syntax (with initialization)
6377 lines =<< trim END
6378 vim9script
6379
6380 class A
6381 static val: number = 10
6382 endclass
6383 END
6384 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6385
6386 # Use old implicit var declaration syntax (type inferred)
6387 lines =<< trim END
6388 vim9script
6389
6390 class A
6391 static val = 10
6392 endclass
6393 END
6394 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6395
6396 # Missing ":var" in "var" class variable declaration (without initialization)
6397 lines =<< trim END
6398 vim9script
6399
6400 class A
6401 static var: number
6402 endclass
6403 END
6404 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6405
6406 # Missing ":var" in "var" class variable declaration (with initialization)
6407 lines =<< trim END
6408 vim9script
6409
6410 class A
6411 static var: number = 10
6412 endclass
6413 END
6414 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6415
6416 # Missing ":var" in "var" class variable declaration (type inferred)
6417 lines =<< trim END
6418 vim9script
6419
6420 class A
6421 static var = 10
6422 endclass
6423 END
6424 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6425
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006426enddef
6427
6428" Test for using a duplicate class method and class variable in a child class
6429def Test_dup_class_member()
6430 # duplicate class variable, class method and overridden object method
6431 var lines =<< trim END
6432 vim9script
6433 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006434 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006435 static def Check()
6436 assert_equal(100, sval)
6437 enddef
6438 def GetVal(): number
6439 return sval
6440 enddef
6441 endclass
6442
6443 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006444 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006445 static def Check()
6446 assert_equal(200, sval)
6447 enddef
6448 def GetVal(): number
6449 return sval
6450 enddef
6451 endclass
6452
6453 def T1(aa: A): number
6454 return aa.GetVal()
6455 enddef
6456
6457 def T2(bb: B): number
6458 return bb.GetVal()
6459 enddef
6460
6461 assert_equal(100, A.sval)
6462 assert_equal(200, B.sval)
6463 var a = A.new()
6464 assert_equal(100, a.GetVal())
6465 var b = B.new()
6466 assert_equal(200, b.GetVal())
6467 assert_equal(200, T1(b))
6468 assert_equal(200, T2(b))
6469 END
6470 v9.CheckSourceSuccess(lines)
6471
6472 # duplicate class variable and class method
6473 lines =<< trim END
6474 vim9script
6475 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006476 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006477 static def Check()
6478 assert_equal(100, sval)
6479 enddef
6480 def GetVal(): number
6481 return sval
6482 enddef
6483 endclass
6484
6485 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006486 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006487 static def Check()
6488 assert_equal(200, sval)
6489 enddef
6490 endclass
6491
6492 def T1(aa: A): number
6493 return aa.GetVal()
6494 enddef
6495
6496 def T2(bb: B): number
6497 return bb.GetVal()
6498 enddef
6499
6500 assert_equal(100, A.sval)
6501 assert_equal(200, B.sval)
6502 var a = A.new()
6503 assert_equal(100, a.GetVal())
6504 var b = B.new()
6505 assert_equal(100, b.GetVal())
6506 assert_equal(100, T1(b))
6507 assert_equal(100, T2(b))
6508 END
6509 v9.CheckSourceSuccess(lines)
6510enddef
6511
6512" Test for calling an instance method using the class
6513def Test_instance_method_call_using_class()
6514 # Invoke an object method using a class in script context
6515 var lines =<< trim END
6516 vim9script
6517 class A
6518 def Foo()
6519 echo "foo"
6520 enddef
6521 endclass
6522 A.Foo()
6523 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006524 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006525
6526 # Invoke an object method using a class in def function context
6527 lines =<< trim END
6528 vim9script
6529 class A
6530 def Foo()
6531 echo "foo"
6532 enddef
6533 endclass
6534 def T()
6535 A.Foo()
6536 enddef
6537 T()
6538 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006539 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006540enddef
6541
6542" Test for duplicate class method and instance method
6543def Test_dup_classmethod_objmethod()
6544 # Duplicate instance method
6545 var lines =<< trim END
6546 vim9script
6547 class A
6548 static def Foo()
6549 enddef
6550 def Foo()
6551 enddef
6552 endclass
6553 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006554 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006555
Ernie Rael03042a22023-11-11 08:53:32 +01006556 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006557 lines =<< trim END
6558 vim9script
6559 class A
6560 static def Foo()
6561 enddef
6562 def _Foo()
6563 enddef
6564 endclass
6565 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006566 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006567
6568 # Duplicate class method
6569 lines =<< trim END
6570 vim9script
6571 class A
6572 def Foo()
6573 enddef
6574 static def Foo()
6575 enddef
6576 endclass
6577 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006578 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006579
Ernie Rael03042a22023-11-11 08:53:32 +01006580 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006581 lines =<< trim END
6582 vim9script
6583 class A
6584 def Foo()
6585 enddef
6586 static def _Foo()
6587 enddef
6588 endclass
6589 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006590 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006591
Ernie Rael03042a22023-11-11 08:53:32 +01006592 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006593 lines =<< trim END
6594 vim9script
6595 class A
6596 def _Foo()
6597 enddef
6598 static def _Foo()
6599 enddef
6600 endclass
6601 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006602 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006603enddef
6604
6605" Test for an instance method access level comparison with parent instance
6606" methods.
6607def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006608 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006609 var lines =<< trim END
6610 vim9script
6611 class A
6612 def Foo()
6613 enddef
6614 endclass
6615 class B extends A
6616 endclass
6617 class C extends B
6618 def _Foo()
6619 enddef
6620 endclass
6621 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006622 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006623
6624 # Public method in subclass
6625 lines =<< trim END
6626 vim9script
6627 class A
6628 def _Foo()
6629 enddef
6630 endclass
6631 class B extends A
6632 endclass
6633 class C extends B
6634 def Foo()
6635 enddef
6636 endclass
6637 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006638 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006639enddef
6640
6641def Test_extend_empty_class()
6642 var lines =<< trim END
6643 vim9script
6644 class A
6645 endclass
6646 class B extends A
6647 endclass
6648 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006649 public static var rw_class_var = 1
6650 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006651 static def ClassMethod(): number
6652 return 3
6653 enddef
6654 def ObjMethod(): number
6655 return 4
6656 enddef
6657 endclass
6658 assert_equal(1, C.rw_class_var)
6659 assert_equal(3, C.ClassMethod())
6660 var c = C.new()
6661 assert_equal(2, c.rw_obj_var)
6662 assert_equal(4, c.ObjMethod())
6663 END
6664 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006665enddef
6666
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006667" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006668" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006669def Test_interface_with_unsupported_members()
6670 var lines =<< trim END
6671 vim9script
6672 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006673 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006674 endinterface
6675 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006676 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006677
6678 lines =<< trim END
6679 vim9script
6680 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006681 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006682 endinterface
6683 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006684 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006685
6686 lines =<< trim END
6687 vim9script
6688 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006689 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006690 endinterface
6691 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006692 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006693
6694 lines =<< trim END
6695 vim9script
6696 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006697 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006698 endinterface
6699 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006700 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006701
6702 lines =<< trim END
6703 vim9script
6704 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006705 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006706 endinterface
6707 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006708 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006709
6710 lines =<< trim END
6711 vim9script
6712 interface A
6713 static def Foo(d: dict<any>): list<string>
6714 endinterface
6715 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006716 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006717
6718 lines =<< trim END
6719 vim9script
6720 interface A
6721 static def _Foo(d: dict<any>): list<string>
6722 endinterface
6723 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006724 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006725
6726 lines =<< trim END
6727 vim9script
6728 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006729 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006730 endinterface
6731 END
Ernie Rael03042a22023-11-11 08:53:32 +01006732 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006733
6734 lines =<< trim END
6735 vim9script
6736 interface A
6737 def _Foo(d: dict<any>): list<string>
6738 endinterface
6739 END
Ernie Rael03042a22023-11-11 08:53:32 +01006740 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006741enddef
6742
6743" Test for extending an interface
6744def Test_extend_interface()
6745 var lines =<< trim END
6746 vim9script
6747 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006748 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006749 def Foo()
6750 endinterface
6751 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006752 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006753 def Bar()
6754 endinterface
6755 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006756 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006757 def Foo()
6758 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006759 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006760 def Bar()
6761 enddef
6762 endclass
6763 END
6764 v9.CheckSourceSuccess(lines)
6765
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006766 # extending empty interface
6767 lines =<< trim END
6768 vim9script
6769 interface A
6770 endinterface
6771 interface B extends A
6772 endinterface
6773 class C implements B
6774 endclass
6775 END
6776 v9.CheckSourceSuccess(lines)
6777
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006778 lines =<< trim END
6779 vim9script
6780 interface A
6781 def Foo()
6782 endinterface
6783 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006784 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006785 endinterface
6786 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006787 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006788 endclass
6789 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006790 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006791
6792 lines =<< trim END
6793 vim9script
6794 interface A
6795 def Foo()
6796 endinterface
6797 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006798 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006799 endinterface
6800 class C implements A, B
6801 def Foo()
6802 enddef
6803 endclass
6804 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006805 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006806
6807 # interface cannot extend a class
6808 lines =<< trim END
6809 vim9script
6810 class A
6811 endclass
6812 interface B extends A
6813 endinterface
6814 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006815 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006816
6817 # class cannot extend an interface
6818 lines =<< trim END
6819 vim9script
6820 interface A
6821 endinterface
6822 class B extends A
6823 endclass
6824 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006825 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006826
6827 # interface cannot implement another interface
6828 lines =<< trim END
6829 vim9script
6830 interface A
6831 endinterface
6832 interface B implements A
6833 endinterface
6834 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006835 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006836
6837 # interface cannot extend multiple interfaces
6838 lines =<< trim END
6839 vim9script
6840 interface A
6841 endinterface
6842 interface B
6843 endinterface
6844 interface C extends A, B
6845 endinterface
6846 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006847 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006848
6849 # Variable type in an extended interface is of different type
6850 lines =<< trim END
6851 vim9script
6852 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006853 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006854 endinterface
6855 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006856 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006857 endinterface
6858 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006859 var val1: string
6860 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006861 endinterface
6862 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006863 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006864enddef
6865
6866" Test for a child class implementing an interface when some of the methods are
6867" defined in the parent class.
6868def Test_child_class_implements_interface()
6869 var lines =<< trim END
6870 vim9script
6871
6872 interface Intf
6873 def F1(): list<list<number>>
6874 def F2(): list<list<number>>
6875 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006876 var var1: list<dict<number>>
6877 var var2: list<dict<number>>
6878 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006879 endinterface
6880
6881 class A
6882 def A1()
6883 enddef
6884 def F3(): list<list<number>>
6885 return [[3]]
6886 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006887 var v1: list<list<number>> = [[0]]
6888 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006889 endclass
6890
6891 class B extends A
6892 def B1()
6893 enddef
6894 def F2(): list<list<number>>
6895 return [[2]]
6896 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006897 var v2: list<list<number>> = [[0]]
6898 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006899 endclass
6900
6901 class C extends B implements Intf
6902 def C1()
6903 enddef
6904 def F1(): list<list<number>>
6905 return [[1]]
6906 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006907 var v3: list<list<number>> = [[0]]
6908 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006909 endclass
6910
6911 def T(if: Intf)
6912 assert_equal([[1]], if.F1())
6913 assert_equal([[2]], if.F2())
6914 assert_equal([[3]], if.F3())
6915 assert_equal([{a: 10}], if.var1)
6916 assert_equal([{b: 20}], if.var2)
6917 assert_equal([{c: 30}], if.var3)
6918 enddef
6919
6920 var c = C.new()
6921 T(c)
6922 assert_equal([[1]], c.F1())
6923 assert_equal([[2]], c.F2())
6924 assert_equal([[3]], c.F3())
6925 assert_equal([{a: 10}], c.var1)
6926 assert_equal([{b: 20}], c.var2)
6927 assert_equal([{c: 30}], c.var3)
6928 END
6929 v9.CheckSourceSuccess(lines)
6930
6931 # One of the interface methods is not found
6932 lines =<< trim END
6933 vim9script
6934
6935 interface Intf
6936 def F1()
6937 def F2()
6938 def F3()
6939 endinterface
6940
6941 class A
6942 def A1()
6943 enddef
6944 endclass
6945
6946 class B extends A
6947 def B1()
6948 enddef
6949 def F2()
6950 enddef
6951 endclass
6952
6953 class C extends B implements Intf
6954 def C1()
6955 enddef
6956 def F1()
6957 enddef
6958 endclass
6959 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006960 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006961
6962 # One of the interface methods is of different type
6963 lines =<< trim END
6964 vim9script
6965
6966 interface Intf
6967 def F1()
6968 def F2()
6969 def F3()
6970 endinterface
6971
6972 class A
6973 def F3(): number
6974 return 0
6975 enddef
6976 def A1()
6977 enddef
6978 endclass
6979
6980 class B extends A
6981 def B1()
6982 enddef
6983 def F2()
6984 enddef
6985 endclass
6986
6987 class C extends B implements Intf
6988 def C1()
6989 enddef
6990 def F1()
6991 enddef
6992 endclass
6993 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006994 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006995
6996 # One of the interface variables is not present
6997 lines =<< trim END
6998 vim9script
6999
7000 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007001 var var1: list<dict<number>>
7002 var var2: list<dict<number>>
7003 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007004 endinterface
7005
7006 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007007 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007008 endclass
7009
7010 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007011 var v2: list<list<number>> = [[0]]
7012 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007013 endclass
7014
7015 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007016 var v3: list<list<number>> = [[0]]
7017 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007018 endclass
7019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007020 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007021
7022 # One of the interface variables is of different type
7023 lines =<< trim END
7024 vim9script
7025
7026 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007027 var var1: list<dict<number>>
7028 var var2: list<dict<number>>
7029 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007030 endinterface
7031
7032 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007033 var v1: list<list<number>> = [[0]]
7034 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007035 endclass
7036
7037 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007038 var v2: list<list<number>> = [[0]]
7039 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007040 endclass
7041
7042 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007043 var v3: list<list<number>> = [[0]]
7044 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007045 endclass
7046 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007047 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 +02007048enddef
7049
7050" Test for extending an interface with duplicate variables and methods
7051def Test_interface_extends_with_dup_members()
7052 var lines =<< trim END
7053 vim9script
7054 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007055 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007056 def Foo1(): number
7057 endinterface
7058 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007059 var n2: number
7060 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007061 def Foo2(): number
7062 def Foo1(): number
7063 endinterface
7064 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007065 var n1 = 10
7066 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007067 def Foo1(): number
7068 return 30
7069 enddef
7070 def Foo2(): number
7071 return 40
7072 enddef
7073 endclass
7074 def T1(a: A)
7075 assert_equal(10, a.n1)
7076 assert_equal(30, a.Foo1())
7077 enddef
7078 def T2(b: B)
7079 assert_equal(10, b.n1)
7080 assert_equal(20, b.n2)
7081 assert_equal(30, b.Foo1())
7082 assert_equal(40, b.Foo2())
7083 enddef
7084 var c = C.new()
7085 T1(c)
7086 T2(c)
7087 END
7088 v9.CheckSourceSuccess(lines)
7089enddef
7090
7091" Test for using "any" type for a variable in a sub-class while it has a
7092" concrete type in the interface
7093def Test_implements_using_var_type_any()
7094 var lines =<< trim END
7095 vim9script
7096 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007097 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007098 endinterface
7099 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007100 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007101 endclass
7102 var b = B.new()
7103 assert_equal([{a: '1'}, {b: '2'}], b.val)
7104 END
7105 v9.CheckSourceSuccess(lines)
7106
7107 # initialize instance variable using a different type
7108 lines =<< trim END
7109 vim9script
7110 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007111 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007112 endinterface
7113 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007114 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007115 endclass
7116 var b = B.new()
7117 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007118 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007119enddef
7120
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007121" Test for assigning to a member variable in a nested class
7122def Test_nested_object_assignment()
7123 var lines =<< trim END
7124 vim9script
7125
7126 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007127 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007128 endclass
7129
7130 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007131 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007132 endclass
7133
7134 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007135 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007136 endclass
7137
7138 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007139 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007140 endclass
7141
7142 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007143 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007144 enddef
7145
7146 var d = D.new()
7147 T(d)
7148 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007149 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007150enddef
7151
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007152" Test for calling methods using a null object
7153def Test_null_object_method_call()
7154 # Calling a object method using a null object in script context
7155 var lines =<< trim END
7156 vim9script
7157
7158 class C
7159 def Foo()
7160 assert_report('This method should not be executed')
7161 enddef
7162 endclass
7163
7164 var o: C
7165 o.Foo()
7166 END
7167 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7168
7169 # Calling a object method using a null object in def function context
7170 lines =<< trim END
7171 vim9script
7172
7173 class C
7174 def Foo()
7175 assert_report('This method should not be executed')
7176 enddef
7177 endclass
7178
7179 def T()
7180 var o: C
7181 o.Foo()
7182 enddef
7183 T()
7184 END
7185 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7186
7187 # Calling a object method through another class method using a null object in
7188 # script context
7189 lines =<< trim END
7190 vim9script
7191
7192 class C
7193 def Foo()
7194 assert_report('This method should not be executed')
7195 enddef
7196
7197 static def Bar(o_any: any)
7198 var o_typed: C = o_any
7199 o_typed.Foo()
7200 enddef
7201 endclass
7202
7203 var o: C
7204 C.Bar(o)
7205 END
7206 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7207
7208 # Calling a object method through another class method using a null object in
7209 # def function context
7210 lines =<< trim END
7211 vim9script
7212
7213 class C
7214 def Foo()
7215 assert_report('This method should not be executed')
7216 enddef
7217
7218 static def Bar(o_any: any)
7219 var o_typed: C = o_any
7220 o_typed.Foo()
7221 enddef
7222 endclass
7223
7224 def T()
7225 var o: C
7226 C.Bar(o)
7227 enddef
7228 T()
7229 END
7230 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Ernie Raelbe828252024-07-26 18:37:02 +02007231
7232 # Calling an object method defined in a class that is extended. This differs
7233 # from the previous by invoking ISN_METHODCALL instead of ISN_DCALL.
7234 lines =<< trim END
7235 vim9script
7236
7237 class C0
7238 def F()
7239 enddef
7240 endclass
7241
7242 class C extends C0
7243 endclass
7244
7245 def X()
7246 var o: C0 = null_object
7247 o.F()
7248 enddef
7249 X()
7250 END
7251 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7252
7253 # Getting a function ref an object method.
7254 lines =<< trim END
7255 vim9script
7256
7257 class C0
7258 def F()
7259 enddef
7260 endclass
7261
7262 class C extends C0
7263 endclass
7264
7265 def X()
7266 var o: C0 = null_object
7267 var XXX = o.F
7268 enddef
7269 X()
7270 END
7271 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007272enddef
7273
7274" Test for using a dict as an object member
7275def Test_dict_object_member()
7276 var lines =<< trim END
7277 vim9script
7278
7279 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007280 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007281 def GetState(): dict<number>
7282 return this.state
7283 enddef
7284 endclass
7285
7286 var ctx = Context.new()
7287 ctx.state->extend({a: 1})
7288 ctx.state['b'] = 2
7289 assert_equal({a: 1, b: 2}, ctx.GetState())
7290
7291 def F()
7292 ctx.state['c'] = 3
7293 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7294 enddef
7295 F()
7296 assert_equal(3, ctx.state.c)
7297 ctx.state.c = 4
7298 assert_equal(4, ctx.state.c)
7299 END
7300 v9.CheckSourceSuccess(lines)
7301enddef
7302
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007303" The following test was failing after 9.0.1914. This was caused by using a
7304" freed object from a previous method call.
7305def Test_freed_object_from_previous_method_call()
7306 var lines =<< trim END
7307 vim9script
7308
7309 class Context
7310 endclass
7311
7312 class Result
7313 endclass
7314
7315 def Failure(): Result
7316 return Result.new()
7317 enddef
7318
7319 def GetResult(ctx: Context): Result
7320 return Failure()
7321 enddef
7322
7323 def Test_GetResult()
7324 var ctx = Context.new()
7325 var result = GetResult(ctx)
7326 enddef
7327
7328 Test_GetResult()
7329 END
7330 v9.CheckSourceSuccess(lines)
7331enddef
7332
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007333" Test for duplicate object and class variable
7334def Test_duplicate_variable()
7335 # Object variable name is same as the class variable name
7336 var lines =<< trim END
7337 vim9script
7338 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007339 public static var sval: number
7340 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007341 endclass
7342 var a = A.new()
7343 END
7344 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7345
7346 # Duplicate variable name and calling a class method
7347 lines =<< trim END
7348 vim9script
7349 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007350 public static var sval: number
7351 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007352 def F1()
7353 echo this.sval
7354 enddef
7355 static def F2()
7356 echo sval
7357 enddef
7358 endclass
7359 A.F2()
7360 END
7361 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7362
7363 # Duplicate variable with an empty constructor
7364 lines =<< trim END
7365 vim9script
7366 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007367 public static var sval: number
7368 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007369 def new()
7370 enddef
7371 endclass
7372 var a = A.new()
7373 END
7374 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7375enddef
7376
7377" Test for using a reserved keyword as a variable name
7378def Test_reserved_varname()
7379 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7380 'null_function', 'null_list', 'null_partial', 'null_string',
7381 'null_channel', 'null_job', 'super', 'this']
7382
7383 var lines =<< trim eval END
7384 vim9script
7385 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007386 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007387 endclass
7388 var o = C.new()
7389 END
7390 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7391
7392 lines =<< trim eval END
7393 vim9script
7394 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007395 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007396 def new()
7397 enddef
7398 endclass
7399 var o = C.new()
7400 END
7401 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7402
7403 lines =<< trim eval END
7404 vim9script
7405 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007406 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007407 def new()
7408 enddef
7409 def F()
7410 echo this.{kword}
7411 enddef
7412 endclass
7413 var o = C.new()
7414 o.F()
7415 END
7416 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007417
7418 # class variable name
7419 if kword != 'this'
7420 lines =<< trim eval END
7421 vim9script
7422 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007423 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007424 endclass
7425 END
7426 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7427 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007428 endfor
7429enddef
7430
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007431" Test for checking the type of the arguments and the return value of a object
7432" method in an extended class.
7433def Test_extended_obj_method_type_check()
7434 var lines =<< trim END
7435 vim9script
7436
7437 class A
7438 endclass
7439 class B extends A
7440 endclass
7441 class C extends B
7442 endclass
7443
7444 class Foo
7445 def Doit(p: B): B
7446 return B.new()
7447 enddef
7448 endclass
7449
7450 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007451 def Doit(p: C): B
7452 return B.new()
7453 enddef
7454 endclass
7455 END
7456 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7457
7458 lines =<< trim END
7459 vim9script
7460
7461 class A
7462 endclass
7463 class B extends A
7464 endclass
7465 class C extends B
7466 endclass
7467
7468 class Foo
7469 def Doit(p: B): B
7470 return B.new()
7471 enddef
7472 endclass
7473
7474 class Bar extends Foo
7475 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007476 return C.new()
7477 enddef
7478 endclass
7479 END
7480 v9.CheckSourceSuccess(lines)
7481
7482 lines =<< trim END
7483 vim9script
7484
7485 class A
7486 endclass
7487 class B extends A
7488 endclass
7489 class C extends B
7490 endclass
7491
7492 class Foo
7493 def Doit(p: B): B
7494 return B.new()
7495 enddef
7496 endclass
7497
7498 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007499 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007500 return B.new()
7501 enddef
7502 endclass
7503 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007504 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 +02007505
7506 lines =<< trim END
7507 vim9script
7508
7509 class A
7510 endclass
7511 class B extends A
7512 endclass
7513 class C extends B
7514 endclass
7515
7516 class Foo
7517 def Doit(p: B): B
7518 return B.new()
7519 enddef
7520 endclass
7521
7522 class Bar extends Foo
7523 def Doit(p: B): A
7524 return A.new()
7525 enddef
7526 endclass
7527 END
7528 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 +02007529
7530 # check varargs type mismatch
7531 lines =<< trim END
7532 vim9script
7533
7534 class B
7535 def F(...xxx: list<any>)
7536 enddef
7537 endclass
7538 class C extends B
7539 def F(xxx: list<any>)
7540 enddef
7541 endclass
7542 END
7543 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 +02007544enddef
7545
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007546" Test type checking for class variable in assignments
7547func Test_class_variable_complex_type_check()
7548 " class variable with a specific type. Try assigning a different type at
7549 " script level.
7550 let lines =<< trim END
7551 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007552 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007553 return {}
7554 enddef
7555 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007556 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007557 endclass
7558 test_garbagecollect_now()
7559 A.Fn = "abc"
7560 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007561 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 +02007562
7563 " class variable with a specific type. Try assigning a different type at
7564 " class def method level.
7565 let lines =<< trim END
7566 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007567 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007568 return {}
7569 enddef
7570 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007571 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007572 def Bar()
7573 Fn = "abc"
7574 enddef
7575 endclass
7576 var a = A.new()
7577 test_garbagecollect_now()
7578 a.Bar()
7579 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007580 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 +02007581
7582 " class variable with a specific type. Try assigning a different type at
7583 " script def method level.
7584 let lines =<< trim END
7585 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007586 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007587 return {}
7588 enddef
7589 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007590 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007591 endclass
7592 def Bar()
7593 A.Fn = "abc"
7594 enddef
7595 test_garbagecollect_now()
7596 Bar()
7597 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007598 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 +02007599
7600 " class variable without any type. Should be set to the initialization
7601 " expression type. Try assigning a different type from script level.
7602 let lines =<< trim END
7603 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007604 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007605 return {}
7606 enddef
7607 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007608 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007609 endclass
7610 test_garbagecollect_now()
7611 A.Fn = "abc"
7612 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007613 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 +02007614
7615 " class variable without any type. Should be set to the initialization
7616 " expression type. Try assigning a different type at class def level.
7617 let lines =<< trim END
7618 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007619 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007620 return {}
7621 enddef
7622 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007623 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007624 def Bar()
7625 Fn = "abc"
7626 enddef
7627 endclass
7628 var a = A.new()
7629 test_garbagecollect_now()
7630 a.Bar()
7631 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007632 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 +02007633
7634 " class variable without any type. Should be set to the initialization
7635 " expression type. Try assigning a different type at script def level.
7636 let lines =<< trim END
7637 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007638 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007639 return {}
7640 enddef
7641 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007642 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007643 endclass
7644 def Bar()
7645 A.Fn = "abc"
7646 enddef
7647 test_garbagecollect_now()
7648 Bar()
7649 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007650 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 +02007651
7652 " class variable with 'any" type. Can be assigned different types.
7653 let lines =<< trim END
7654 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007655 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007656 return {}
7657 enddef
7658 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007659 public static var Fn: any = Foo
7660 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007661 endclass
7662 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007663 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007664 A.Fn = "abc"
7665 test_garbagecollect_now()
7666 assert_equal('string', typename(A.Fn))
7667 A.Fn2 = Foo
7668 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007669 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007670 A.Fn2 = "xyz"
7671 test_garbagecollect_now()
7672 assert_equal('string', typename(A.Fn2))
7673 END
7674 call v9.CheckSourceSuccess(lines)
7675
7676 " class variable with 'any" type. Can be assigned different types.
7677 let lines =<< trim END
7678 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007679 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007680 return {}
7681 enddef
7682 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007683 public static var Fn: any = Foo
7684 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007685
7686 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007687 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007688 Fn = "abc"
7689 assert_equal('string', typename(Fn))
7690 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007691 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007692 Fn2 = "xyz"
7693 assert_equal('string', typename(Fn2))
7694 enddef
7695 endclass
7696 var a = A.new()
7697 test_garbagecollect_now()
7698 a.Bar()
7699 test_garbagecollect_now()
7700 A.Fn = Foo
7701 a.Bar()
7702 END
7703 call v9.CheckSourceSuccess(lines)
7704
7705 " class variable with 'any" type. Can be assigned different types.
7706 let lines =<< trim END
7707 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007708 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007709 return {}
7710 enddef
7711 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007712 public static var Fn: any = Foo
7713 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007714 endclass
7715
7716 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007717 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007718 A.Fn = "abc"
7719 assert_equal('string', typename(A.Fn))
7720 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007721 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007722 A.Fn2 = "xyz"
7723 assert_equal('string', typename(A.Fn2))
7724 enddef
7725 Bar()
7726 test_garbagecollect_now()
7727 A.Fn = Foo
7728 Bar()
7729 END
7730 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007731
7732 let lines =<< trim END
7733 vim9script
7734 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007735 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007736 endclass
7737 assert_equal([0z10, 0z20], A.foo)
7738 A.foo = [0z30]
7739 assert_equal([0z30], A.foo)
7740 var a = A.foo
7741 assert_equal([0z30], a)
7742 END
7743 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007744endfunc
7745
7746" Test type checking for object variable in assignments
7747func Test_object_variable_complex_type_check()
7748 " object variable with a specific type. Try assigning a different type at
7749 " script level.
7750 let lines =<< trim END
7751 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007752 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007753 return {}
7754 enddef
7755 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007756 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007757 endclass
7758 var a = A.new()
7759 test_garbagecollect_now()
7760 a.Fn = "abc"
7761 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007762 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 +02007763
7764 " object variable with a specific type. Try assigning a different type at
7765 " object def method level.
7766 let lines =<< trim END
7767 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007768 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007769 return {}
7770 enddef
7771 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007772 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007773 def Bar()
7774 this.Fn = "abc"
7775 this.Fn = Foo
7776 enddef
7777 endclass
7778 var a = A.new()
7779 test_garbagecollect_now()
7780 a.Bar()
7781 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007782 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007783
7784 " object variable with a specific type. Try assigning a different type at
7785 " script def method level.
7786 let lines =<< trim END
7787 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007788 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007789 return {}
7790 enddef
7791 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007792 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007793 endclass
7794 def Bar()
7795 var a = A.new()
7796 a.Fn = "abc"
7797 a.Fn = Foo
7798 enddef
7799 test_garbagecollect_now()
7800 Bar()
7801 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007802 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 +02007803
7804 " object variable without any type. Should be set to the initialization
7805 " expression type. Try assigning a different type from script level.
7806 let lines =<< trim END
7807 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007808 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007809 return {}
7810 enddef
7811 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007812 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007813 endclass
7814 var a = A.new()
7815 test_garbagecollect_now()
7816 a.Fn = "abc"
7817 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007818 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 +02007819
7820 " object variable without any type. Should be set to the initialization
7821 " expression type. Try assigning a different type at object def level.
7822 let lines =<< trim END
7823 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007824 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007825 return {}
7826 enddef
7827 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007828 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007829 def Bar()
7830 this.Fn = "abc"
7831 this.Fn = Foo
7832 enddef
7833 endclass
7834 var a = A.new()
7835 test_garbagecollect_now()
7836 a.Bar()
7837 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007838 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 +02007839
7840 " object variable without any type. Should be set to the initialization
7841 " expression type. Try assigning a different type at script def level.
7842 let lines =<< trim END
7843 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007844 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007845 return {}
7846 enddef
7847 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007848 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007849 endclass
7850 def Bar()
7851 var a = A.new()
7852 a.Fn = "abc"
7853 a.Fn = Foo
7854 enddef
7855 test_garbagecollect_now()
7856 Bar()
7857 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007858 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 +02007859
7860 " object variable with 'any" type. Can be assigned different types.
7861 let lines =<< trim END
7862 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007863 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007864 return {}
7865 enddef
7866 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007867 public var Fn: any = Foo
7868 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007869 endclass
7870
7871 var a = A.new()
7872 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007873 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007874 a.Fn = "abc"
7875 test_garbagecollect_now()
7876 assert_equal('string', typename(a.Fn))
7877 a.Fn2 = Foo
7878 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007879 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007880 a.Fn2 = "xyz"
7881 test_garbagecollect_now()
7882 assert_equal('string', typename(a.Fn2))
7883 END
7884 call v9.CheckSourceSuccess(lines)
7885
7886 " object variable with 'any" type. Can be assigned different types.
7887 let lines =<< trim END
7888 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007889 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007890 return {}
7891 enddef
7892 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007893 public var Fn: any = Foo
7894 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007895
7896 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007897 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007898 this.Fn = "abc"
7899 assert_equal('string', typename(this.Fn))
7900 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007901 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007902 this.Fn2 = "xyz"
7903 assert_equal('string', typename(this.Fn2))
7904 enddef
7905 endclass
7906
7907 var a = A.new()
7908 test_garbagecollect_now()
7909 a.Bar()
7910 test_garbagecollect_now()
7911 a.Fn = Foo
7912 a.Bar()
7913 END
7914 call v9.CheckSourceSuccess(lines)
7915
7916 " object variable with 'any" type. Can be assigned different types.
7917 let lines =<< trim END
7918 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007919 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007920 return {}
7921 enddef
7922 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007923 public var Fn: any = Foo
7924 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007925 endclass
7926
7927 def Bar()
7928 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007929 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007930 a.Fn = "abc"
7931 assert_equal('string', typename(a.Fn))
7932 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007933 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007934 a.Fn2 = "xyz"
7935 assert_equal('string', typename(a.Fn2))
7936 enddef
7937 test_garbagecollect_now()
7938 Bar()
7939 test_garbagecollect_now()
7940 Bar()
7941 END
7942 call v9.CheckSourceSuccess(lines)
7943endfunc
7944
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007945" Test for recursively calling an object method. This used to cause an
7946" use-after-free error.
7947def Test_recursive_object_method_call()
7948 var lines =<< trim END
7949 vim9script
7950 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007951 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007952 def Foo(): number
7953 if this.val >= 90
7954 return this.val
7955 endif
7956 this.val += 1
7957 return this.Foo()
7958 enddef
7959 endclass
7960 var a = A.new()
7961 assert_equal(90, a.Foo())
7962 END
7963 v9.CheckSourceSuccess(lines)
7964enddef
7965
7966" Test for recursively calling a class method.
7967def Test_recursive_class_method_call()
7968 var lines =<< trim END
7969 vim9script
7970 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007971 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007972 static def Foo(): number
7973 if val >= 90
7974 return val
7975 endif
7976 val += 1
7977 return Foo()
7978 enddef
7979 endclass
7980 assert_equal(90, A.Foo())
7981 END
7982 v9.CheckSourceSuccess(lines)
7983enddef
7984
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007985" Test for checking the argument types and the return type when assigning a
7986" funcref to make sure the invariant class type is used.
7987def Test_funcref_argtype_returntype_check()
7988 var lines =<< trim END
7989 vim9script
7990 class A
7991 endclass
7992 class B extends A
7993 endclass
7994
7995 def Foo(p: B): B
7996 return B.new()
7997 enddef
7998
7999 var Bar: func(A): A = Foo
8000 END
8001 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
8002
8003 lines =<< trim END
8004 vim9script
8005 class A
8006 endclass
8007 class B extends A
8008 endclass
8009
8010 def Foo(p: B): B
8011 return B.new()
8012 enddef
8013
8014 def Baz()
8015 var Bar: func(A): A = Foo
8016 enddef
8017 Baz()
8018 END
8019 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
8020enddef
8021
Ernie Rael96952b22023-10-17 18:15:01 +02008022def Test_funcref_argtype_invariance_check()
8023 var lines =<< trim END
8024 vim9script
8025
8026 class A
8027 endclass
8028 class B extends A
8029 endclass
8030 class C extends B
8031 endclass
8032
8033 var Func: func(B): number
8034 Func = (o: B): number => 3
8035 assert_equal(3, Func(B.new()))
8036 END
8037 v9.CheckSourceSuccess(lines)
8038
8039 lines =<< trim END
8040 vim9script
8041
8042 class A
8043 endclass
8044 class B extends A
8045 endclass
8046 class C extends B
8047 endclass
8048
8049 var Func: func(B): number
8050 Func = (o: A): number => 3
8051 END
8052 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
8053
8054 lines =<< trim END
8055 vim9script
8056
8057 class A
8058 endclass
8059 class B extends A
8060 endclass
8061 class C extends B
8062 endclass
8063
8064 var Func: func(B): number
8065 Func = (o: C): number => 3
8066 END
8067 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
8068enddef
8069
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008070" Test for using an operator (e.g. +) with an assignment
8071def Test_op_and_assignment()
8072 # Using += with a class variable
8073 var lines =<< trim END
8074 vim9script
8075 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008076 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008077 static def Foo(): list<number>
8078 val += [1]
8079 return val
8080 enddef
8081 endclass
8082 def Bar(): list<number>
8083 A.val += [2]
8084 return A.val
8085 enddef
8086 assert_equal([1], A.Foo())
8087 assert_equal([1, 2], Bar())
8088 A.val += [3]
8089 assert_equal([1, 2, 3], A.val)
8090 END
8091 v9.CheckSourceSuccess(lines)
8092
8093 # Using += with an object variable
8094 lines =<< trim END
8095 vim9script
8096 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008097 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008098 def Foo(): list<number>
8099 this.val += [1]
8100 return this.val
8101 enddef
8102 endclass
8103 def Bar(bar_a: A): list<number>
8104 bar_a.val += [2]
8105 return bar_a.val
8106 enddef
8107 var a = A.new()
8108 assert_equal([1], a.Foo())
8109 assert_equal([1, 2], Bar(a))
8110 a.val += [3]
8111 assert_equal([1, 2, 3], a.val)
8112 END
8113 v9.CheckSourceSuccess(lines)
8114enddef
8115
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008116" Test for using an object method as a funcref
8117def Test_object_funcref()
8118 # Using object method funcref from a def function
8119 var lines =<< trim END
8120 vim9script
8121 class A
8122 def Foo(): list<number>
8123 return [3, 2, 1]
8124 enddef
8125 endclass
8126 def Bar()
8127 var a = A.new()
8128 var Fn = a.Foo
8129 assert_equal([3, 2, 1], Fn())
8130 enddef
8131 Bar()
8132 END
8133 v9.CheckSourceSuccess(lines)
8134
8135 # Using object method funcref at the script level
8136 lines =<< trim END
8137 vim9script
8138 class A
8139 def Foo(): dict<number>
8140 return {a: 1, b: 2}
8141 enddef
8142 endclass
8143 var a = A.new()
8144 var Fn = a.Foo
8145 assert_equal({a: 1, b: 2}, Fn())
8146 END
8147 v9.CheckSourceSuccess(lines)
8148
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008149 # Using object method funcref at the script level
8150 lines =<< trim END
8151 vim9script
8152 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008153 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008154 def Foo(): number
8155 return this.val
8156 enddef
8157 endclass
8158 var a = A.new(345)
8159 var Fn = a.Foo
8160 assert_equal(345, Fn())
8161 END
8162 v9.CheckSourceSuccess(lines)
8163
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008164 # Using object method funcref from another object method
8165 lines =<< trim END
8166 vim9script
8167 class A
8168 def Foo(): list<number>
8169 return [3, 2, 1]
8170 enddef
8171 def Bar()
8172 var Fn = this.Foo
8173 assert_equal([3, 2, 1], Fn())
8174 enddef
8175 endclass
8176 var a = A.new()
8177 a.Bar()
8178 END
8179 v9.CheckSourceSuccess(lines)
8180
8181 # Using function() to get a object method funcref
8182 lines =<< trim END
8183 vim9script
8184 class A
8185 def Foo(l: list<any>): list<any>
8186 return l
8187 enddef
8188 endclass
8189 var a = A.new()
8190 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8191 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8192 END
8193 v9.CheckSourceSuccess(lines)
8194
8195 # Use an object method with a function returning a funcref and then call the
8196 # funcref.
8197 lines =<< trim END
8198 vim9script
8199
8200 def Map(F: func(number): number): func(number): number
8201 return (n: number) => F(n)
8202 enddef
8203
8204 class Math
8205 def Double(n: number): number
8206 return 2 * n
8207 enddef
8208 endclass
8209
8210 const math = Math.new()
8211 assert_equal(48, Map(math.Double)(24))
8212 END
8213 v9.CheckSourceSuccess(lines)
8214
Ernie Rael03042a22023-11-11 08:53:32 +01008215 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008216 lines =<< trim END
8217 vim9script
8218 class A
8219 def _Foo()
8220 enddef
8221 endclass
8222 def Bar()
8223 var a = A.new()
8224 var Fn = a._Foo
8225 enddef
8226 Bar()
8227 END
Ernie Rael03042a22023-11-11 08:53:32 +01008228 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008229
Ernie Rael03042a22023-11-11 08:53:32 +01008230 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008231 lines =<< trim END
8232 vim9script
8233 class A
8234 def _Foo()
8235 enddef
8236 endclass
8237 var a = A.new()
8238 var Fn = a._Foo
8239 END
Ernie Rael03042a22023-11-11 08:53:32 +01008240 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008241
Ernie Rael03042a22023-11-11 08:53:32 +01008242 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008243 lines =<< trim END
8244 vim9script
8245 class A
8246 def _Foo(): list<number>
8247 return [3, 2, 1]
8248 enddef
8249 def Bar()
8250 var Fn = this._Foo
8251 assert_equal([3, 2, 1], Fn())
8252 enddef
8253 endclass
8254 var a = A.new()
8255 a.Bar()
8256 END
8257 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008258
8259 # Using object method funcref using call()
8260 lines =<< trim END
8261 vim9script
8262 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008263 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008264 def Foo(): number
8265 return this.val
8266 enddef
8267 endclass
8268
8269 def Bar(obj: A)
8270 assert_equal(123, call(obj.Foo, []))
8271 enddef
8272
8273 var a = A.new(123)
8274 Bar(a)
8275 assert_equal(123, call(a.Foo, []))
8276 END
8277 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008278enddef
8279
8280" Test for using a class method as a funcref
8281def Test_class_funcref()
8282 # Using class method funcref in a def function
8283 var lines =<< trim END
8284 vim9script
8285 class A
8286 static def Foo(): list<number>
8287 return [3, 2, 1]
8288 enddef
8289 endclass
8290 def Bar()
8291 var Fn = A.Foo
8292 assert_equal([3, 2, 1], Fn())
8293 enddef
8294 Bar()
8295 END
8296 v9.CheckSourceSuccess(lines)
8297
8298 # Using class method funcref at script level
8299 lines =<< trim END
8300 vim9script
8301 class A
8302 static def Foo(): dict<number>
8303 return {a: 1, b: 2}
8304 enddef
8305 endclass
8306 var Fn = A.Foo
8307 assert_equal({a: 1, b: 2}, Fn())
8308 END
8309 v9.CheckSourceSuccess(lines)
8310
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008311 # Using class method funcref at the script level
8312 lines =<< trim END
8313 vim9script
8314 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008315 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008316 static def Foo(): number
8317 return val
8318 enddef
8319 endclass
8320 A.val = 567
8321 var Fn = A.Foo
8322 assert_equal(567, Fn())
8323 END
8324 v9.CheckSourceSuccess(lines)
8325
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008326 # Using function() to get a class method funcref
8327 lines =<< trim END
8328 vim9script
8329 class A
8330 static def Foo(l: list<any>): list<any>
8331 return l
8332 enddef
8333 endclass
8334 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8335 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8336 END
8337 v9.CheckSourceSuccess(lines)
8338
8339 # Using a class method funcref from another class method
8340 lines =<< trim END
8341 vim9script
8342 class A
8343 static def Foo(): list<number>
8344 return [3, 2, 1]
8345 enddef
8346 static def Bar()
8347 var Fn = Foo
8348 assert_equal([3, 2, 1], Fn())
8349 enddef
8350 endclass
8351 A.Bar()
8352 END
8353 v9.CheckSourceSuccess(lines)
8354
8355 # Use a class method with a function returning a funcref and then call the
8356 # funcref.
8357 lines =<< trim END
8358 vim9script
8359
8360 def Map(F: func(number): number): func(number): number
8361 return (n: number) => F(n)
8362 enddef
8363
8364 class Math
8365 static def StaticDouble(n: number): number
8366 return 2 * n
8367 enddef
8368 endclass
8369
8370 assert_equal(48, Map(Math.StaticDouble)(24))
8371 END
8372 v9.CheckSourceSuccess(lines)
8373
Ernie Rael03042a22023-11-11 08:53:32 +01008374 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008375 lines =<< trim END
8376 vim9script
8377 class A
8378 static def _Foo()
8379 enddef
8380 endclass
8381 def Bar()
8382 var Fn = A._Foo
8383 enddef
8384 Bar()
8385 END
Ernie Rael03042a22023-11-11 08:53:32 +01008386 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008387
Ernie Rael03042a22023-11-11 08:53:32 +01008388 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008389 lines =<< trim END
8390 vim9script
8391 class A
8392 static def _Foo()
8393 enddef
8394 endclass
8395 var Fn = A._Foo
8396 END
Ernie Rael03042a22023-11-11 08:53:32 +01008397 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008398
Ernie Rael03042a22023-11-11 08:53:32 +01008399 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008400 lines =<< trim END
8401 vim9script
8402 class A
8403 static def _Foo(): list<number>
8404 return [3, 2, 1]
8405 enddef
8406 static def Bar()
8407 var Fn = _Foo
8408 assert_equal([3, 2, 1], Fn())
8409 enddef
8410 endclass
8411 A.Bar()
8412 END
8413 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008414
8415 # Using class method funcref using call()
8416 lines =<< trim END
8417 vim9script
8418 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008419 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008420 static def Foo(): number
8421 return val
8422 enddef
8423 endclass
8424
8425 def Bar()
8426 A.val = 468
8427 assert_equal(468, call(A.Foo, []))
8428 enddef
8429 Bar()
8430 assert_equal(468, call(A.Foo, []))
8431 END
8432 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008433enddef
8434
8435" Test for using an object member as a funcref
8436def Test_object_member_funcref()
8437 # Using a funcref object variable in an object method
8438 var lines =<< trim END
8439 vim9script
8440 def Foo(n: number): number
8441 return n * 10
8442 enddef
8443
8444 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008445 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008446 def Bar()
8447 assert_equal(200, this.Cb(20))
8448 enddef
8449 endclass
8450
8451 var a = A.new()
8452 a.Bar()
8453 END
8454 v9.CheckSourceSuccess(lines)
8455
8456 # Using a funcref object variable in a def method
8457 lines =<< trim END
8458 vim9script
8459 def Foo(n: number): number
8460 return n * 10
8461 enddef
8462
8463 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008464 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008465 endclass
8466
8467 def Bar()
8468 var a = A.new()
8469 assert_equal(200, a.Cb(20))
8470 enddef
8471 Bar()
8472 END
8473 v9.CheckSourceSuccess(lines)
8474
8475 # Using a funcref object variable at script level
8476 lines =<< trim END
8477 vim9script
8478 def Foo(n: number): number
8479 return n * 10
8480 enddef
8481
8482 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008483 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008484 endclass
8485
8486 var a = A.new()
8487 assert_equal(200, a.Cb(20))
8488 END
8489 v9.CheckSourceSuccess(lines)
8490
8491 # Using a funcref object variable pointing to an object method in an object
8492 # method.
8493 lines =<< trim END
8494 vim9script
8495 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008496 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008497 def Foo(n: number): number
8498 return n * 10
8499 enddef
8500 def Bar()
8501 assert_equal(200, this.Cb(20))
8502 enddef
8503 endclass
8504
8505 var a = A.new()
8506 a.Bar()
8507 END
8508 v9.CheckSourceSuccess(lines)
8509
8510 # Using a funcref object variable pointing to an object method in a def
8511 # method.
8512 lines =<< trim END
8513 vim9script
8514 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008515 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008516 def Foo(n: number): number
8517 return n * 10
8518 enddef
8519 endclass
8520
8521 def Bar()
8522 var a = A.new()
8523 assert_equal(200, a.Cb(20))
8524 enddef
8525 Bar()
8526 END
8527 v9.CheckSourceSuccess(lines)
8528
8529 # Using a funcref object variable pointing to an object method at script
8530 # level.
8531 lines =<< trim END
8532 vim9script
8533 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008534 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008535 def Foo(n: number): number
8536 return n * 10
8537 enddef
8538 endclass
8539
8540 var a = A.new()
8541 assert_equal(200, a.Cb(20))
8542 END
8543 v9.CheckSourceSuccess(lines)
8544enddef
8545
8546" Test for using a class member as a funcref
8547def Test_class_member_funcref()
8548 # Using a funcref class variable in a class method
8549 var lines =<< trim END
8550 vim9script
8551 def Foo(n: number): number
8552 return n * 10
8553 enddef
8554
8555 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008556 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008557 static def Bar()
8558 assert_equal(200, Cb(20))
8559 enddef
8560 endclass
8561
8562 A.Bar()
8563 END
8564 v9.CheckSourceSuccess(lines)
8565
8566 # Using a funcref class variable in a def method
8567 lines =<< trim END
8568 vim9script
8569 def Foo(n: number): number
8570 return n * 10
8571 enddef
8572
8573 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008574 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008575 endclass
8576
8577 def Bar()
8578 assert_equal(200, A.Cb(20))
8579 enddef
8580 Bar()
8581 END
8582 v9.CheckSourceSuccess(lines)
8583
8584 # Using a funcref class variable at script level
8585 lines =<< trim END
8586 vim9script
8587 def Foo(n: number): number
8588 return n * 10
8589 enddef
8590
8591 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008592 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008593 endclass
8594
8595 assert_equal(200, A.Cb(20))
8596 END
8597 v9.CheckSourceSuccess(lines)
8598
8599 # Using a funcref class variable pointing to a class method in a class
8600 # method.
8601 lines =<< trim END
8602 vim9script
8603 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008604 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008605 static def Foo(n: number): number
8606 return n * 10
8607 enddef
8608 static def Init()
8609 Cb = Foo
8610 enddef
8611 static def Bar()
8612 assert_equal(200, Cb(20))
8613 enddef
8614 endclass
8615
8616 A.Init()
8617 A.Bar()
8618 END
8619 v9.CheckSourceSuccess(lines)
8620
8621 # Using a funcref class variable pointing to a class method in a def method.
8622 lines =<< trim END
8623 vim9script
8624 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008625 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008626 static def Foo(n: number): number
8627 return n * 10
8628 enddef
8629 static def Init()
8630 Cb = Foo
8631 enddef
8632 endclass
8633
8634 def Bar()
8635 A.Init()
8636 assert_equal(200, A.Cb(20))
8637 enddef
8638 Bar()
8639 END
8640 v9.CheckSourceSuccess(lines)
8641
8642 # Using a funcref class variable pointing to a class method at script level.
8643 lines =<< trim END
8644 vim9script
8645 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008646 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008647 static def Foo(n: number): number
8648 return n * 10
8649 enddef
8650 static def Init()
8651 Cb = Foo
8652 enddef
8653 endclass
8654
8655 A.Init()
8656 assert_equal(200, A.Cb(20))
8657 END
8658 v9.CheckSourceSuccess(lines)
8659enddef
8660
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008661" Test for using object methods as popup callback functions
8662def Test_objmethod_popup_callback()
8663 # Use the popup from the script level
8664 var lines =<< trim END
8665 vim9script
8666
8667 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008668 var selection: number = -1
8669 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008670
8671 def PopupFilter(id: number, key: string): bool
8672 add(this.filterkeys, key)
8673 return popup_filter_yesno(id, key)
8674 enddef
8675
8676 def PopupCb(id: number, result: number)
8677 this.selection = result ? 100 : 200
8678 enddef
8679 endclass
8680
8681 var a = A.new()
8682 feedkeys('', 'xt')
8683 var winid = popup_create('Y/N?',
8684 {filter: a.PopupFilter, callback: a.PopupCb})
8685 feedkeys('y', 'xt')
8686 popup_close(winid)
8687 assert_equal(100, a.selection)
8688 assert_equal(['y'], a.filterkeys)
8689 feedkeys('', 'xt')
8690 winid = popup_create('Y/N?',
8691 {filter: a.PopupFilter, callback: a.PopupCb})
8692 feedkeys('n', 'xt')
8693 popup_close(winid)
8694 assert_equal(200, a.selection)
8695 assert_equal(['y', 'n'], a.filterkeys)
8696 END
8697 v9.CheckSourceSuccess(lines)
8698
8699 # Use the popup from a def function
8700 lines =<< trim END
8701 vim9script
8702
8703 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008704 var selection: number = -1
8705 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008706
8707 def PopupFilter(id: number, key: string): bool
8708 add(this.filterkeys, key)
8709 return popup_filter_yesno(id, key)
8710 enddef
8711
8712 def PopupCb(id: number, result: number)
8713 this.selection = result ? 100 : 200
8714 enddef
8715 endclass
8716
8717 def Foo()
8718 var a = A.new()
8719 feedkeys('', 'xt')
8720 var winid = popup_create('Y/N?',
8721 {filter: a.PopupFilter, callback: a.PopupCb})
8722 feedkeys('y', 'xt')
8723 popup_close(winid)
8724 assert_equal(100, a.selection)
8725 assert_equal(['y'], a.filterkeys)
8726 feedkeys('', 'xt')
8727 winid = popup_create('Y/N?',
8728 {filter: a.PopupFilter, callback: a.PopupCb})
8729 feedkeys('n', 'xt')
8730 popup_close(winid)
8731 assert_equal(200, a.selection)
8732 assert_equal(['y', 'n'], a.filterkeys)
8733 enddef
8734 Foo()
8735 END
8736 v9.CheckSourceSuccess(lines)
8737enddef
8738
8739" Test for using class methods as popup callback functions
8740def Test_classmethod_popup_callback()
8741 # Use the popup from the script level
8742 var lines =<< trim END
8743 vim9script
8744
8745 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008746 static var selection: number = -1
8747 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008748
8749 static def PopupFilter(id: number, key: string): bool
8750 add(filterkeys, key)
8751 return popup_filter_yesno(id, key)
8752 enddef
8753
8754 static def PopupCb(id: number, result: number)
8755 selection = result ? 100 : 200
8756 enddef
8757 endclass
8758
8759 feedkeys('', 'xt')
8760 var winid = popup_create('Y/N?',
8761 {filter: A.PopupFilter, callback: A.PopupCb})
8762 feedkeys('y', 'xt')
8763 popup_close(winid)
8764 assert_equal(100, A.selection)
8765 assert_equal(['y'], A.filterkeys)
8766 feedkeys('', 'xt')
8767 winid = popup_create('Y/N?',
8768 {filter: A.PopupFilter, callback: A.PopupCb})
8769 feedkeys('n', 'xt')
8770 popup_close(winid)
8771 assert_equal(200, A.selection)
8772 assert_equal(['y', 'n'], A.filterkeys)
8773 END
8774 v9.CheckSourceSuccess(lines)
8775
8776 # Use the popup from a def function
8777 lines =<< trim END
8778 vim9script
8779
8780 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008781 static var selection: number = -1
8782 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008783
8784 static def PopupFilter(id: number, key: string): bool
8785 add(filterkeys, key)
8786 return popup_filter_yesno(id, key)
8787 enddef
8788
8789 static def PopupCb(id: number, result: number)
8790 selection = result ? 100 : 200
8791 enddef
8792 endclass
8793
8794 def Foo()
8795 feedkeys('', 'xt')
8796 var winid = popup_create('Y/N?',
8797 {filter: A.PopupFilter, callback: A.PopupCb})
8798 feedkeys('y', 'xt')
8799 popup_close(winid)
8800 assert_equal(100, A.selection)
8801 assert_equal(['y'], A.filterkeys)
8802 feedkeys('', 'xt')
8803 winid = popup_create('Y/N?',
8804 {filter: A.PopupFilter, callback: A.PopupCb})
8805 feedkeys('n', 'xt')
8806 popup_close(winid)
8807 assert_equal(200, A.selection)
8808 assert_equal(['y', 'n'], A.filterkeys)
8809 enddef
8810 Foo()
8811 END
8812 v9.CheckSourceSuccess(lines)
8813enddef
8814
8815" Test for using an object method as a timer callback function
8816def Test_objmethod_timer_callback()
8817 # Use the timer callback from script level
8818 var lines =<< trim END
8819 vim9script
8820
8821 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008822 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008823 def TimerCb(timerID: number)
8824 this.timerTick = 6
8825 enddef
8826 endclass
8827
8828 var a = A.new()
8829 timer_start(0, a.TimerCb)
8830 var maxWait = 5
8831 while maxWait > 0 && a.timerTick == -1
8832 :sleep 10m
8833 maxWait -= 1
8834 endwhile
8835 assert_equal(6, a.timerTick)
8836 END
8837 v9.CheckSourceSuccess(lines)
8838
8839 # Use the timer callback from a def function
8840 lines =<< trim END
8841 vim9script
8842
8843 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008844 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008845 def TimerCb(timerID: number)
8846 this.timerTick = 6
8847 enddef
8848 endclass
8849
8850 def Foo()
8851 var a = A.new()
8852 timer_start(0, a.TimerCb)
8853 var maxWait = 5
8854 while maxWait > 0 && a.timerTick == -1
8855 :sleep 10m
8856 maxWait -= 1
8857 endwhile
8858 assert_equal(6, a.timerTick)
8859 enddef
8860 Foo()
8861 END
8862 v9.CheckSourceSuccess(lines)
8863enddef
8864
8865" Test for using a class method as a timer callback function
8866def Test_classmethod_timer_callback()
8867 # Use the timer callback from script level
8868 var lines =<< trim END
8869 vim9script
8870
8871 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008872 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008873 static def TimerCb(timerID: number)
8874 timerTick = 6
8875 enddef
8876 endclass
8877
8878 timer_start(0, A.TimerCb)
8879 var maxWait = 5
8880 while maxWait > 0 && A.timerTick == -1
8881 :sleep 10m
8882 maxWait -= 1
8883 endwhile
8884 assert_equal(6, A.timerTick)
8885 END
8886 v9.CheckSourceSuccess(lines)
8887
8888 # Use the timer callback from a def function
8889 lines =<< trim END
8890 vim9script
8891
8892 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008893 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008894 static def TimerCb(timerID: number)
8895 timerTick = 6
8896 enddef
8897 endclass
8898
8899 def Foo()
8900 timer_start(0, A.TimerCb)
8901 var maxWait = 5
8902 while maxWait > 0 && A.timerTick == -1
8903 :sleep 10m
8904 maxWait -= 1
8905 endwhile
8906 assert_equal(6, A.timerTick)
8907 enddef
8908 Foo()
8909 END
8910 v9.CheckSourceSuccess(lines)
8911enddef
8912
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008913" Test for using a class variable as the first and/or second operand of a binary
8914" operator.
8915def Test_class_variable_as_operands()
8916 var lines =<< trim END
8917 vim9script
8918 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008919 static var truthy: bool = true
8920 public static var TruthyFn: func
8921 static var list: list<any> = []
8922 static var four: number = 4
8923 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008924
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008925 static def Str(): string
8926 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008927 enddef
8928
8929 static def Four(): number
8930 return four
8931 enddef
8932
8933 static def List(): list<any>
8934 return list
8935 enddef
8936
8937 static def Truthy(): bool
8938 return truthy
8939 enddef
8940
8941 def TestOps()
8942 assert_true(Tests.truthy == truthy)
8943 assert_true(truthy == Tests.truthy)
8944 assert_true(Tests.list isnot [])
8945 assert_true([] isnot Tests.list)
8946 assert_equal(2, Tests.four >> 1)
8947 assert_equal(16, 1 << Tests.four)
8948 assert_equal(8, Tests.four + four)
8949 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008950 assert_equal('hellohello', Tests.str .. str)
8951 assert_equal('hellohello', str .. Tests.str)
8952
8953 # Using class variable for list indexing
8954 var l = range(10)
8955 assert_equal(4, l[Tests.four])
8956 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8957
8958 # Using class variable for Dict key
8959 var d = {hello: 'abc'}
8960 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008961 enddef
8962 endclass
8963
8964 def TestOps2()
8965 assert_true(Tests.truthy == Tests.Truthy())
8966 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008967 assert_true(Tests.truthy == Tests.TruthyFn())
8968 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008969 assert_true(Tests.list is Tests.List())
8970 assert_true(Tests.List() is Tests.list)
8971 assert_equal(2, Tests.four >> 1)
8972 assert_equal(16, 1 << Tests.four)
8973 assert_equal(8, Tests.four + Tests.Four())
8974 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008975 assert_equal('hellohello', Tests.str .. Tests.Str())
8976 assert_equal('hellohello', Tests.Str() .. Tests.str)
8977
8978 # Using class variable for list indexing
8979 var l = range(10)
8980 assert_equal(4, l[Tests.four])
8981 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8982
8983 # Using class variable for Dict key
8984 var d = {hello: 'abc'}
8985 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008986 enddef
8987
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008988 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008989 var t = Tests.new()
8990 t.TestOps()
8991 TestOps2()
8992
8993 assert_true(Tests.truthy == Tests.Truthy())
8994 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008995 assert_true(Tests.truthy == Tests.TruthyFn())
8996 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008997 assert_true(Tests.list is Tests.List())
8998 assert_true(Tests.List() is Tests.list)
8999 assert_equal(2, Tests.four >> 1)
9000 assert_equal(16, 1 << Tests.four)
9001 assert_equal(8, Tests.four + Tests.Four())
9002 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009003 assert_equal('hellohello', Tests.str .. Tests.Str())
9004 assert_equal('hellohello', Tests.Str() .. Tests.str)
9005
9006 # Using class variable for list indexing
9007 var l = range(10)
9008 assert_equal(4, l[Tests.four])
9009 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9010
9011 # Using class variable for Dict key
9012 var d = {hello: 'abc'}
9013 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009014 END
9015 v9.CheckSourceSuccess(lines)
9016enddef
9017
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009018" Test for checking the type of the key used to access an object dict member.
9019def Test_dict_member_key_type_check()
9020 var lines =<< trim END
9021 vim9script
9022
9023 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01009024 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009025 endclass
9026
9027 class Test extends State
9028 def ObjMethodTests()
9029 var cursor: number = 0
9030 var z: number = 0
9031 [this.numbers[cursor]] = ['zero.1']
9032 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9033 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9034 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9035 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9036 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9037 [this.numbers[cursor], z] = ['zero.4', 1]
9038 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9039 [z, this.numbers[cursor]] = [1, 'zero.5']
9040 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9041 enddef
9042
9043 static def ClassMethodTests(that: State)
9044 var cursor: number = 0
9045 var z: number = 0
9046 [that.numbers[cursor]] = ['zero.1']
9047 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9048 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9049 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9050 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9051 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9052 [that.numbers[cursor], z] = ['zero.4', 1]
9053 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9054 [z, that.numbers[cursor]] = [1, 'zero.5']
9055 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9056 enddef
9057
9058 def new()
9059 enddef
9060
9061 def newMethodTests()
9062 var cursor: number = 0
9063 var z: number
9064 [this.numbers[cursor]] = ['zero.1']
9065 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9066 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9067 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9068 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9069 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9070 [this.numbers[cursor], z] = ['zero.4', 1]
9071 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9072 [z, this.numbers[cursor]] = [1, 'zero.5']
9073 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9074 enddef
9075 endclass
9076
9077 def DefFuncTests(that: Test)
9078 var cursor: number = 0
9079 var z: number
9080 [that.numbers[cursor]] = ['zero.1']
9081 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9082 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9083 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9084 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9085 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9086 [that.numbers[cursor], z] = ['zero.4', 1]
9087 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9088 [z, that.numbers[cursor]] = [1, 'zero.5']
9089 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9090 enddef
9091
9092 Test.newMethodTests()
9093 Test.new().ObjMethodTests()
9094 Test.ClassMethodTests(Test.new())
9095 DefFuncTests(Test.new())
9096
9097 const test: Test = Test.new()
9098 var cursor: number = 0
9099 [test.numbers[cursor], cursor] = ['zero', 1]
9100 [cursor, test.numbers[cursor]] = [1, 'one']
9101 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
9102 END
9103 v9.CheckSourceSuccess(lines)
9104
9105 lines =<< trim END
9106 vim9script
9107
9108 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009109 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009110
9111 def new()
9112 enddef
9113
9114 def Foo()
9115 var z: number
9116 [this.numbers.a, z] = [{}, 10]
9117 enddef
9118 endclass
9119
9120 var a = A.new()
9121 a.Foo()
9122 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009123 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009124
9125 lines =<< trim END
9126 vim9script
9127
9128 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009129 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009130
9131 def new()
9132 enddef
9133
9134 def Foo()
9135 var x: string = 'a'
9136 var y: number
9137 [this.numbers[x], y] = [{}, 10]
9138 enddef
9139 endclass
9140
9141 var a = A.new()
9142 a.Foo()
9143 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009144 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009145enddef
9146
mityua5550692023-11-25 15:41:20 +01009147def Test_compile_many_def_functions_in_funcref_instr()
9148 # This used to crash Vim. This is reproducible only when run on new instance
9149 # of Vim.
9150 var lines =<< trim END
9151 vim9script
9152
9153 class A
9154 def new()
9155 this.TakeFunc(this.F00)
9156 enddef
9157
9158 def TakeFunc(F: func)
9159 enddef
9160
9161 def F00()
9162 this.F01()
9163 this.F02()
9164 this.F03()
9165 this.F04()
9166 this.F05()
9167 this.F06()
9168 this.F07()
9169 this.F08()
9170 this.F09()
9171 this.F10()
9172 this.F11()
9173 this.F12()
9174 this.F13()
9175 this.F14()
9176 this.F15()
9177 this.F16()
9178 this.F17()
9179 this.F18()
9180 this.F19()
9181 this.F20()
9182 this.F21()
9183 this.F22()
9184 this.F23()
9185 this.F24()
9186 this.F25()
9187 this.F26()
9188 this.F27()
9189 this.F28()
9190 this.F29()
9191 this.F30()
9192 this.F31()
9193 this.F32()
9194 this.F33()
9195 this.F34()
9196 this.F35()
9197 this.F36()
9198 this.F37()
9199 this.F38()
9200 this.F39()
9201 this.F40()
9202 this.F41()
9203 this.F42()
9204 this.F43()
9205 this.F44()
9206 this.F45()
9207 this.F46()
9208 this.F47()
9209 enddef
9210
9211 def F01()
9212 enddef
9213 def F02()
9214 enddef
9215 def F03()
9216 enddef
9217 def F04()
9218 enddef
9219 def F05()
9220 enddef
9221 def F06()
9222 enddef
9223 def F07()
9224 enddef
9225 def F08()
9226 enddef
9227 def F09()
9228 enddef
9229 def F10()
9230 enddef
9231 def F11()
9232 enddef
9233 def F12()
9234 enddef
9235 def F13()
9236 enddef
9237 def F14()
9238 enddef
9239 def F15()
9240 enddef
9241 def F16()
9242 enddef
9243 def F17()
9244 enddef
9245 def F18()
9246 enddef
9247 def F19()
9248 enddef
9249 def F20()
9250 enddef
9251 def F21()
9252 enddef
9253 def F22()
9254 enddef
9255 def F23()
9256 enddef
9257 def F24()
9258 enddef
9259 def F25()
9260 enddef
9261 def F26()
9262 enddef
9263 def F27()
9264 enddef
9265 def F28()
9266 enddef
9267 def F29()
9268 enddef
9269 def F30()
9270 enddef
9271 def F31()
9272 enddef
9273 def F32()
9274 enddef
9275 def F33()
9276 enddef
9277 def F34()
9278 enddef
9279 def F35()
9280 enddef
9281 def F36()
9282 enddef
9283 def F37()
9284 enddef
9285 def F38()
9286 enddef
9287 def F39()
9288 enddef
9289 def F40()
9290 enddef
9291 def F41()
9292 enddef
9293 def F42()
9294 enddef
9295 def F43()
9296 enddef
9297 def F44()
9298 enddef
9299 def F45()
9300 enddef
9301 def F46()
9302 enddef
9303 def F47()
9304 enddef
9305 endclass
9306
9307 A.new()
9308 END
9309 writefile(lines, 'Xscript', 'D')
9310 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9311 assert_equal(0, v:shell_error)
9312enddef
9313
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009314" Test for 'final' class and object variables
9315def Test_final_class_object_variable()
9316 # Test for changing a final object variable from an object function
9317 var lines =<< trim END
9318 vim9script
9319 class A
9320 final foo: string = "abc"
9321 def Foo()
9322 this.foo = "def"
9323 enddef
9324 endclass
9325 defcompile A.Foo
9326 END
9327 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9328
9329 # Test for changing a final object variable from the 'new' function
9330 lines =<< trim END
9331 vim9script
9332 class A
9333 final s1: string
9334 final s2: string
9335 def new(this.s1)
9336 this.s2 = 'def'
9337 enddef
9338 endclass
9339 var a = A.new('abc')
9340 assert_equal('abc', a.s1)
9341 assert_equal('def', a.s2)
9342 END
9343 v9.CheckSourceSuccess(lines)
9344
9345 # Test for a final class variable
9346 lines =<< trim END
9347 vim9script
9348 class A
9349 static final s1: string = "abc"
9350 endclass
9351 assert_equal('abc', A.s1)
9352 END
9353 v9.CheckSourceSuccess(lines)
9354
9355 # Test for changing a final class variable from a class function
9356 lines =<< trim END
9357 vim9script
9358 class A
9359 static final s1: string = "abc"
9360 static def Foo()
9361 s1 = "def"
9362 enddef
9363 endclass
9364 A.Foo()
9365 END
9366 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9367
9368 # Test for changing a public final class variable at script level
9369 lines =<< trim END
9370 vim9script
9371 class A
9372 public static final s1: string = "abc"
9373 endclass
9374 assert_equal('abc', A.s1)
9375 A.s1 = 'def'
9376 END
9377 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9378
9379 # Test for changing a public final class variable from a class function
9380 lines =<< trim END
9381 vim9script
9382 class A
9383 public static final s1: string = "abc"
9384 static def Foo()
9385 s1 = "def"
9386 enddef
9387 endclass
9388 A.Foo()
9389 END
9390 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9391
9392 # Test for changing a public final class variable from a function
9393 lines =<< trim END
9394 vim9script
9395 class A
9396 public static final s1: string = "abc"
9397 endclass
9398 def Foo()
9399 A.s1 = 'def'
9400 enddef
9401 defcompile
9402 END
9403 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9404
9405 # Test for using a final variable of composite type
9406 lines =<< trim END
9407 vim9script
9408 class A
9409 public final l: list<number>
9410 def new()
9411 this.l = [1, 2]
9412 enddef
9413 def Foo()
9414 this.l[0] = 3
9415 this.l->add(4)
9416 enddef
9417 endclass
9418 var a = A.new()
9419 assert_equal([1, 2], a.l)
9420 a.Foo()
9421 assert_equal([3, 2, 4], a.l)
9422 END
9423 v9.CheckSourceSuccess(lines)
9424
9425 # Test for changing a final variable of composite type from another object
9426 # function
9427 lines =<< trim END
9428 vim9script
9429 class A
9430 public final l: list<number> = [1, 2]
9431 def Foo()
9432 this.l = [3, 4]
9433 enddef
9434 endclass
9435 var a = A.new()
9436 a.Foo()
9437 END
9438 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9439
9440 # Test for modifying a final variable of composite type at script level
9441 lines =<< trim END
9442 vim9script
9443 class A
9444 public final l: list<number> = [1, 2]
9445 endclass
9446 var a = A.new()
9447 a.l[0] = 3
9448 a.l->add(4)
9449 assert_equal([3, 2, 4], a.l)
9450 END
9451 v9.CheckSourceSuccess(lines)
9452
9453 # Test for modifying a final variable of composite type from a function
9454 lines =<< trim END
9455 vim9script
9456 class A
9457 public final l: list<number> = [1, 2]
9458 endclass
9459 def Foo()
9460 var a = A.new()
9461 a.l[0] = 3
9462 a.l->add(4)
9463 assert_equal([3, 2, 4], a.l)
9464 enddef
9465 Foo()
9466 END
9467 v9.CheckSourceSuccess(lines)
9468
9469 # Test for modifying a final variable of composite type from another object
9470 # function
9471 lines =<< trim END
9472 vim9script
9473 class A
9474 public final l: list<number> = [1, 2]
9475 def Foo()
9476 this.l[0] = 3
9477 this.l->add(4)
9478 enddef
9479 endclass
9480 var a = A.new()
9481 a.Foo()
9482 assert_equal([3, 2, 4], a.l)
9483 END
9484 v9.CheckSourceSuccess(lines)
9485
9486 # Test for assigning a new value to a final variable of composite type at
9487 # script level
9488 lines =<< trim END
9489 vim9script
9490 class A
9491 public final l: list<number> = [1, 2]
9492 endclass
9493 var a = A.new()
9494 a.l = [3, 4]
9495 END
9496 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9497
9498 # Test for assigning a new value to a final variable of composite type from
9499 # another object function
9500 lines =<< trim END
9501 vim9script
9502 class A
9503 public final l: list<number> = [1, 2]
9504 def Foo()
9505 this.l = [3, 4]
9506 enddef
9507 endclass
9508 var a = A.new()
9509 a.Foo()
9510 END
9511 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9512
9513 # Test for assigning a new value to a final variable of composite type from
9514 # another function
9515 lines =<< trim END
9516 vim9script
9517 class A
9518 public final l: list<number> = [1, 2]
9519 endclass
9520 def Foo()
9521 var a = A.new()
9522 a.l = [3, 4]
9523 enddef
9524 Foo()
9525 END
9526 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9527
9528 # Error case: Use 'final' with just a variable name
9529 lines =<< trim END
9530 vim9script
9531 class A
9532 final foo
9533 endclass
9534 var a = A.new()
9535 END
9536 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9537
9538 # Error case: Use 'final' followed by 'public'
9539 lines =<< trim END
9540 vim9script
9541 class A
9542 final public foo: number
9543 endclass
9544 var a = A.new()
9545 END
9546 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9547
9548 # Error case: Use 'final' followed by 'static'
9549 lines =<< trim END
9550 vim9script
9551 class A
9552 final static foo: number
9553 endclass
9554 var a = A.new()
9555 END
9556 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9557
9558 # Error case: 'final' cannot be used in an interface
9559 lines =<< trim END
9560 vim9script
9561 interface A
9562 final foo: number = 10
9563 endinterface
9564 END
9565 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9566
9567 # Error case: 'final' not supported for an object method
9568 lines =<< trim END
9569 vim9script
9570 class A
9571 final def Foo()
9572 enddef
9573 endclass
9574 END
9575 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9576
9577 # Error case: 'final' not supported for a class method
9578 lines =<< trim END
9579 vim9script
9580 class A
9581 static final def Foo()
9582 enddef
9583 endclass
9584 END
9585 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9586enddef
9587
9588" Test for 'const' class and object variables
9589def Test_const_class_object_variable()
9590 # Test for changing a const object variable from an object function
9591 var lines =<< trim END
9592 vim9script
9593 class A
9594 const foo: string = "abc"
9595 def Foo()
9596 this.foo = "def"
9597 enddef
9598 endclass
9599 defcompile A.Foo
9600 END
9601 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9602
9603 # Test for changing a const object variable from the 'new' function
9604 lines =<< trim END
9605 vim9script
9606 class A
9607 const s1: string
9608 const s2: string
9609 def new(this.s1)
9610 this.s2 = 'def'
9611 enddef
9612 endclass
9613 var a = A.new('abc')
9614 assert_equal('abc', a.s1)
9615 assert_equal('def', a.s2)
9616 END
9617 v9.CheckSourceSuccess(lines)
9618
9619 # Test for changing a const object variable from an object method called from
9620 # the 'new' function
9621 lines =<< trim END
9622 vim9script
9623 class A
9624 const s1: string = 'abc'
9625 def new()
9626 this.ChangeStr()
9627 enddef
9628 def ChangeStr()
9629 this.s1 = 'def'
9630 enddef
9631 endclass
9632 var a = A.new()
9633 END
9634 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9635
9636 # Test for a const class variable
9637 lines =<< trim END
9638 vim9script
9639 class A
9640 static const s1: string = "abc"
9641 endclass
9642 assert_equal('abc', A.s1)
9643 END
9644 v9.CheckSourceSuccess(lines)
9645
9646 # Test for changing a const class variable from a class function
9647 lines =<< trim END
9648 vim9script
9649 class A
9650 static const s1: string = "abc"
9651 static def Foo()
9652 s1 = "def"
9653 enddef
9654 endclass
9655 A.Foo()
9656 END
9657 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9658
9659 # Test for changing a public const class variable at script level
9660 lines =<< trim END
9661 vim9script
9662 class A
9663 public static const s1: string = "abc"
9664 endclass
9665 assert_equal('abc', A.s1)
9666 A.s1 = 'def'
9667 END
9668 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9669
9670 # Test for changing a public const class variable from a class function
9671 lines =<< trim END
9672 vim9script
9673 class A
9674 public static const s1: string = "abc"
9675 static def Foo()
9676 s1 = "def"
9677 enddef
9678 endclass
9679 A.Foo()
9680 END
9681 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9682
9683 # Test for changing a public const class variable from a function
9684 lines =<< trim END
9685 vim9script
9686 class A
9687 public static const s1: string = "abc"
9688 endclass
9689 def Foo()
9690 A.s1 = 'def'
9691 enddef
9692 defcompile
9693 END
9694 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9695
9696 # Test for changing a const List item from an object function
9697 lines =<< trim END
9698 vim9script
9699 class A
9700 public const l: list<number>
9701 def new()
9702 this.l = [1, 2]
9703 enddef
9704 def Foo()
9705 this.l[0] = 3
9706 enddef
9707 endclass
9708 var a = A.new()
9709 assert_equal([1, 2], a.l)
9710 a.Foo()
9711 END
9712 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9713
9714 # Test for adding a value to a const List from an object function
9715 lines =<< trim END
9716 vim9script
9717 class A
9718 public const l: list<number>
9719 def new()
9720 this.l = [1, 2]
9721 enddef
9722 def Foo()
9723 this.l->add(3)
9724 enddef
9725 endclass
9726 var a = A.new()
9727 a.Foo()
9728 END
9729 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9730
9731 # Test for reassigning a const List from an object function
9732 lines =<< trim END
9733 vim9script
9734 class A
9735 public const l: list<number> = [1, 2]
9736 def Foo()
9737 this.l = [3, 4]
9738 enddef
9739 endclass
9740 var a = A.new()
9741 a.Foo()
9742 END
9743 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9744
9745 # Test for changing a const List item at script level
9746 lines =<< trim END
9747 vim9script
9748 class A
9749 public const l: list<number> = [1, 2]
9750 endclass
9751 var a = A.new()
9752 a.l[0] = 3
9753 END
9754 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9755
9756 # Test for adding a value to a const List item at script level
9757 lines =<< trim END
9758 vim9script
9759 class A
9760 public const l: list<number> = [1, 2]
9761 endclass
9762 var a = A.new()
9763 a.l->add(4)
9764 END
9765 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9766
9767 # Test for changing a const List item from a function
9768 lines =<< trim END
9769 vim9script
9770 class A
9771 public const l: list<number> = [1, 2]
9772 endclass
9773 def Foo()
9774 var a = A.new()
9775 a.l[0] = 3
9776 enddef
9777 Foo()
9778 END
9779 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9780
9781 # Test for adding a value to a const List item from a function
9782 lines =<< trim END
9783 vim9script
9784 class A
9785 public const l: list<number> = [1, 2]
9786 endclass
9787 def Foo()
9788 var a = A.new()
9789 a.l->add(4)
9790 enddef
9791 Foo()
9792 END
9793 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9794
9795 # Test for changing a const List item from an object method
9796 lines =<< trim END
9797 vim9script
9798 class A
9799 public const l: list<number> = [1, 2]
9800 def Foo()
9801 this.l[0] = 3
9802 enddef
9803 endclass
9804 var a = A.new()
9805 a.Foo()
9806 END
9807 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9808
9809 # Test for adding a value to a const List item from an object method
9810 lines =<< trim END
9811 vim9script
9812 class A
9813 public const l: list<number> = [1, 2]
9814 def Foo()
9815 this.l->add(4)
9816 enddef
9817 endclass
9818 var a = A.new()
9819 a.Foo()
9820 END
9821 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9822
9823 # Test for reassigning a const List object variable at script level
9824 lines =<< trim END
9825 vim9script
9826 class A
9827 public const l: list<number> = [1, 2]
9828 endclass
9829 var a = A.new()
9830 a.l = [3, 4]
9831 END
9832 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9833
9834 # Test for reassigning a const List object variable from an object method
9835 lines =<< trim END
9836 vim9script
9837 class A
9838 public const l: list<number> = [1, 2]
9839 def Foo()
9840 this.l = [3, 4]
9841 enddef
9842 endclass
9843 var a = A.new()
9844 a.Foo()
9845 END
9846 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9847
9848 # Test for reassigning a const List object variable from another function
9849 lines =<< trim END
9850 vim9script
9851 class A
9852 public const l: list<number> = [1, 2]
9853 endclass
9854 def Foo()
9855 var a = A.new()
9856 a.l = [3, 4]
9857 enddef
9858 Foo()
9859 END
9860 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9861
9862 # Error case: Use 'const' with just a variable name
9863 lines =<< trim END
9864 vim9script
9865 class A
9866 const foo
9867 endclass
9868 var a = A.new()
9869 END
9870 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9871
9872 # Error case: Use 'const' followed by 'public'
9873 lines =<< trim END
9874 vim9script
9875 class A
9876 const public foo: number
9877 endclass
9878 var a = A.new()
9879 END
9880 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9881
9882 # Error case: Use 'const' followed by 'static'
9883 lines =<< trim END
9884 vim9script
9885 class A
9886 const static foo: number
9887 endclass
9888 var a = A.new()
9889 END
9890 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9891
9892 # Error case: 'const' cannot be used in an interface
9893 lines =<< trim END
9894 vim9script
9895 interface A
9896 const foo: number = 10
9897 endinterface
9898 END
9899 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9900
9901 # Error case: 'const' not supported for an object method
9902 lines =<< trim END
9903 vim9script
9904 class A
9905 const def Foo()
9906 enddef
9907 endclass
9908 END
9909 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9910
9911 # Error case: 'const' not supported for a class method
9912 lines =<< trim END
9913 vim9script
9914 class A
9915 static const def Foo()
9916 enddef
9917 endclass
9918 END
9919 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9920enddef
9921
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009922" Test for compiling class/object methods using :defcompile
9923def Test_defcompile_class()
9924 # defcompile all the classes in the current script
9925 var lines =<< trim END
9926 vim9script
9927 class A
9928 def Foo()
9929 var i = 10
9930 enddef
9931 endclass
9932 class B
9933 def Bar()
9934 var i = 20
9935 xxx
9936 enddef
9937 endclass
9938 defcompile
9939 END
9940 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9941
9942 # defcompile a specific class
9943 lines =<< trim END
9944 vim9script
9945 class A
9946 def Foo()
9947 xxx
9948 enddef
9949 endclass
9950 class B
9951 def Bar()
9952 yyy
9953 enddef
9954 endclass
9955 defcompile B
9956 END
9957 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9958
9959 # defcompile a non-class
9960 lines =<< trim END
9961 vim9script
9962 class A
9963 def Foo()
9964 enddef
9965 endclass
9966 var X: list<number> = []
9967 defcompile X
9968 END
9969 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9970
9971 # defcompile a class twice
9972 lines =<< trim END
9973 vim9script
9974 class A
9975 def new()
9976 enddef
9977 endclass
9978 defcompile A
9979 defcompile A
9980 assert_equal('Function A.new does not need compiling', v:statusmsg)
9981 END
9982 v9.CheckSourceSuccess(lines)
9983
9984 # defcompile should not compile an imported class
9985 lines =<< trim END
9986 vim9script
9987 export class A
9988 def Foo()
9989 xxx
9990 enddef
9991 endclass
9992 END
9993 writefile(lines, 'Xdefcompileimport.vim', 'D')
9994 lines =<< trim END
9995 vim9script
9996
9997 import './Xdefcompileimport.vim'
9998 class B
9999 endclass
10000 defcompile
10001 END
10002 v9.CheckScriptSuccess(lines)
10003enddef
10004
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +010010005" Test for cases common to all the object builtin methods
10006def Test_object_builtin_method()
10007 var lines =<< trim END
10008 vim9script
10009 class A
10010 def abc()
10011 enddef
10012 endclass
10013 END
10014 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
10015
10016 for funcname in ["len", "string", "empty"]
10017 lines =<< trim eval END
10018 vim9script
10019 class A
10020 static def {funcname}(): number
10021 enddef
10022 endclass
10023 END
10024 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
10025 endfor
10026enddef
10027
10028" Test for using the empty() builtin method with an object
10029" This is a legacy function to use the test_garbagecollect_now() function.
10030func Test_object_empty()
10031 let lines =<< trim END
10032 vim9script
10033 class A
10034 def empty(): bool
10035 return true
10036 enddef
10037 endclass
10038
10039 def Foo()
10040 var afoo = A.new()
10041 assert_equal(true, empty(afoo))
10042 assert_equal(true, afoo->empty())
10043 enddef
10044
10045 var a = A.new()
10046 assert_equal(1, empty(a))
10047 assert_equal(1, a->empty())
10048 test_garbagecollect_now()
10049 assert_equal(1, empty(a))
10050 Foo()
10051 test_garbagecollect_now()
10052 Foo()
10053 END
10054 call v9.CheckSourceSuccess(lines)
10055
10056 " empty() should return 1 without a builtin method
10057 let lines =<< trim END
10058 vim9script
10059 class A
10060 endclass
10061
10062 def Foo()
10063 var afoo = A.new()
10064 assert_equal(1, empty(afoo))
10065 enddef
10066
10067 var a = A.new()
10068 assert_equal(1, empty(a))
10069 Foo()
10070 END
10071 call v9.CheckSourceSuccess(lines)
10072
10073 " Unsupported signature for the empty() method
10074 let lines =<< trim END
10075 vim9script
10076 class A
10077 def empty()
10078 enddef
10079 endclass
10080 END
10081 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
10082
10083 " Error when calling the empty() method
10084 let lines =<< trim END
10085 vim9script
10086 class A
10087 def empty(): bool
10088 throw "Failed to check emptiness"
10089 enddef
10090 endclass
10091
10092 def Foo()
10093 var afoo = A.new()
10094 var i = empty(afoo)
10095 enddef
10096
10097 var a = A.new()
10098 assert_fails('empty(a)', 'Failed to check emptiness')
10099 assert_fails('Foo()', 'Failed to check emptiness')
10100 END
10101 call v9.CheckSourceSuccess(lines)
10102
10103 " call empty() using an object from a script
10104 let lines =<< trim END
10105 vim9script
10106 class A
10107 def empty(): bool
10108 return true
10109 enddef
10110 endclass
10111 var afoo = A.new()
10112 assert_equal(true, afoo.empty())
10113 END
10114 call v9.CheckSourceSuccess(lines)
10115
10116 " call empty() using an object from a method
10117 let lines =<< trim END
10118 vim9script
10119 class A
10120 def empty(): bool
10121 return true
10122 enddef
10123 endclass
10124 def Foo()
10125 var afoo = A.new()
10126 assert_equal(true, afoo.empty())
10127 enddef
10128 Foo()
10129 END
10130 call v9.CheckSourceSuccess(lines)
10131
10132 " call empty() using "this" from an object method
10133 let lines =<< trim END
10134 vim9script
10135 class A
10136 def empty(): bool
10137 return true
10138 enddef
10139 def Foo(): bool
10140 return this.empty()
10141 enddef
10142 endclass
10143 def Bar()
10144 var abar = A.new()
10145 assert_equal(true, abar.Foo())
10146 enddef
10147 Bar()
10148 END
10149 call v9.CheckSourceSuccess(lines)
10150
10151 " Call empty() from a derived object
10152 let lines =<< trim END
10153 vim9script
10154 class A
10155 def empty(): bool
10156 return false
10157 enddef
10158 endclass
10159 class B extends A
10160 def empty(): bool
10161 return true
10162 enddef
10163 endclass
10164 def Foo(afoo: A)
10165 assert_equal(true, empty(afoo))
10166 var bfoo = B.new()
10167 assert_equal(true, empty(bfoo))
10168 enddef
10169 var b = B.new()
10170 assert_equal(1, empty(b))
10171 Foo(b)
10172 END
10173 call v9.CheckSourceSuccess(lines)
10174
10175 " Invoking empty method using an interface
10176 let lines =<< trim END
10177 vim9script
10178 interface A
10179 def empty(): bool
10180 endinterface
10181 class B implements A
10182 def empty(): bool
10183 return false
10184 enddef
10185 endclass
10186 def Foo(a: A)
10187 assert_equal(false, empty(a))
10188 enddef
10189 var b = B.new()
10190 Foo(b)
10191 END
10192 call v9.CheckSourceSuccess(lines)
10193endfunc
10194
10195" Test for using the len() builtin method with an object
10196" This is a legacy function to use the test_garbagecollect_now() function.
10197func Test_object_length()
10198 let lines =<< trim END
10199 vim9script
10200 class A
10201 var mylen: number = 0
10202 def new(n: number)
10203 this.mylen = n
10204 enddef
10205 def len(): number
10206 return this.mylen
10207 enddef
10208 endclass
10209
10210 def Foo()
10211 var afoo = A.new(12)
10212 assert_equal(12, len(afoo))
10213 assert_equal(12, afoo->len())
10214 enddef
10215
10216 var a = A.new(22)
10217 assert_equal(22, len(a))
10218 assert_equal(22, a->len())
10219 test_garbagecollect_now()
10220 assert_equal(22, len(a))
10221 Foo()
10222 test_garbagecollect_now()
10223 Foo()
10224 END
10225 call v9.CheckSourceSuccess(lines)
10226
10227 " len() should return 0 without a builtin method
10228 let lines =<< trim END
10229 vim9script
10230 class A
10231 endclass
10232
10233 def Foo()
10234 var afoo = A.new()
10235 assert_equal(0, len(afoo))
10236 enddef
10237
10238 var a = A.new()
10239 assert_equal(0, len(a))
10240 Foo()
10241 END
10242 call v9.CheckSourceSuccess(lines)
10243
10244 " Unsupported signature for the len() method
10245 let lines =<< trim END
10246 vim9script
10247 class A
10248 def len()
10249 enddef
10250 endclass
10251 END
10252 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10253
10254 " Error when calling the len() method
10255 let lines =<< trim END
10256 vim9script
10257 class A
10258 def len(): number
10259 throw "Failed to compute length"
10260 enddef
10261 endclass
10262
10263 def Foo()
10264 var afoo = A.new()
10265 var i = len(afoo)
10266 enddef
10267
10268 var a = A.new()
10269 assert_fails('len(a)', 'Failed to compute length')
10270 assert_fails('Foo()', 'Failed to compute length')
10271 END
10272 call v9.CheckSourceSuccess(lines)
10273
10274 " call len() using an object from a script
10275 let lines =<< trim END
10276 vim9script
10277 class A
10278 def len(): number
10279 return 5
10280 enddef
10281 endclass
10282 var afoo = A.new()
10283 assert_equal(5, afoo.len())
10284 END
10285 call v9.CheckSourceSuccess(lines)
10286
10287 " call len() using an object from a method
10288 let lines =<< trim END
10289 vim9script
10290 class A
10291 def len(): number
10292 return 5
10293 enddef
10294 endclass
10295 def Foo()
10296 var afoo = A.new()
10297 assert_equal(5, afoo.len())
10298 enddef
10299 Foo()
10300 END
10301 call v9.CheckSourceSuccess(lines)
10302
10303 " call len() using "this" from an object method
10304 let lines =<< trim END
10305 vim9script
10306 class A
10307 def len(): number
10308 return 8
10309 enddef
10310 def Foo(): number
10311 return this.len()
10312 enddef
10313 endclass
10314 def Bar()
10315 var abar = A.new()
10316 assert_equal(8, abar.Foo())
10317 enddef
10318 Bar()
10319 END
10320 call v9.CheckSourceSuccess(lines)
10321
10322 " Call len() from a derived object
10323 let lines =<< trim END
10324 vim9script
10325 class A
10326 def len(): number
10327 return 10
10328 enddef
10329 endclass
10330 class B extends A
10331 def len(): number
10332 return 20
10333 enddef
10334 endclass
10335 def Foo(afoo: A)
10336 assert_equal(20, len(afoo))
10337 var bfoo = B.new()
10338 assert_equal(20, len(bfoo))
10339 enddef
10340 var b = B.new()
10341 assert_equal(20, len(b))
10342 Foo(b)
10343 END
10344 call v9.CheckSourceSuccess(lines)
10345
10346 " Invoking len method using an interface
10347 let lines =<< trim END
10348 vim9script
10349 interface A
10350 def len(): number
10351 endinterface
10352 class B implements A
10353 def len(): number
10354 return 123
10355 enddef
10356 endclass
10357 def Foo(a: A)
10358 assert_equal(123, len(a))
10359 enddef
10360 var b = B.new()
10361 Foo(b)
10362 END
10363 call v9.CheckSourceSuccess(lines)
10364endfunc
10365
10366" Test for using the string() builtin method with an object
10367" This is a legacy function to use the test_garbagecollect_now() function.
10368func Test_object_string()
10369 let lines =<< trim END
10370 vim9script
10371 class A
10372 var name: string
10373 def string(): string
10374 return this.name
10375 enddef
10376 endclass
10377
10378 def Foo()
10379 var afoo = A.new("foo-A")
10380 assert_equal('foo-A', string(afoo))
10381 assert_equal('foo-A', afoo->string())
10382 enddef
10383
10384 var a = A.new("script-A")
10385 assert_equal('script-A', string(a))
10386 assert_equal('script-A', a->string())
10387 assert_equal(['script-A'], execute('echo a')->split("\n"))
10388 test_garbagecollect_now()
10389 assert_equal('script-A', string(a))
10390 Foo()
10391 test_garbagecollect_now()
10392 Foo()
10393 END
10394 call v9.CheckSourceSuccess(lines)
10395
10396 " string() should return "object of A {}" without a builtin method
10397 let lines =<< trim END
10398 vim9script
10399 class A
10400 endclass
10401
10402 def Foo()
10403 var afoo = A.new()
10404 assert_equal('object of A {}', string(afoo))
10405 enddef
10406
10407 var a = A.new()
10408 assert_equal('object of A {}', string(a))
10409 Foo()
10410 END
10411 call v9.CheckSourceSuccess(lines)
10412
10413 " Unsupported signature for the string() method
10414 let lines =<< trim END
10415 vim9script
10416 class A
10417 def string()
10418 enddef
10419 endclass
10420 END
10421 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10422
10423 " Error when calling the string() method
10424 let lines =<< trim END
10425 vim9script
10426 class A
10427 def string(): string
10428 throw "Failed to get text"
10429 enddef
10430 endclass
10431
10432 def Foo()
10433 var afoo = A.new()
10434 var i = string(afoo)
10435 enddef
10436
10437 var a = A.new()
10438 assert_fails('string(a)', 'Failed to get text')
10439 assert_fails('Foo()', 'Failed to get text')
10440 END
10441 call v9.CheckSourceSuccess(lines)
10442
10443 " call string() using an object from a script
10444 let lines =<< trim END
10445 vim9script
10446 class A
10447 def string(): string
10448 return 'A'
10449 enddef
10450 endclass
10451 var afoo = A.new()
10452 assert_equal('A', afoo.string())
10453 END
10454 call v9.CheckSourceSuccess(lines)
10455
10456 " call string() using an object from a method
10457 let lines =<< trim END
10458 vim9script
10459 class A
10460 def string(): string
10461 return 'A'
10462 enddef
10463 endclass
10464 def Foo()
10465 var afoo = A.new()
10466 assert_equal('A', afoo.string())
10467 enddef
10468 Foo()
10469 END
10470 call v9.CheckSourceSuccess(lines)
10471
10472 " call string() using "this" from an object method
10473 let lines =<< trim END
10474 vim9script
10475 class A
10476 def string(): string
10477 return 'A'
10478 enddef
10479 def Foo(): string
10480 return this.string()
10481 enddef
10482 endclass
10483 def Bar()
10484 var abar = A.new()
10485 assert_equal('A', abar.string())
10486 enddef
10487 Bar()
10488 END
10489 call v9.CheckSourceSuccess(lines)
10490
10491 " Call string() from a derived object
10492 let lines =<< trim END
10493 vim9script
10494 class A
10495 def string(): string
10496 return 'A'
10497 enddef
10498 endclass
10499 class B extends A
10500 def string(): string
10501 return 'B'
10502 enddef
10503 endclass
10504 def Foo(afoo: A)
10505 assert_equal('B', string(afoo))
10506 var bfoo = B.new()
10507 assert_equal('B', string(bfoo))
10508 enddef
10509 var b = B.new()
10510 assert_equal('B', string(b))
10511 Foo(b)
10512 END
10513 call v9.CheckSourceSuccess(lines)
10514
10515 " Invoking string method using an interface
10516 let lines =<< trim END
10517 vim9script
10518 interface A
10519 def string(): string
10520 endinterface
10521 class B implements A
10522 def string(): string
10523 return 'B'
10524 enddef
10525 endclass
10526 def Foo(a: A)
10527 assert_equal('B', string(a))
10528 enddef
10529 var b = B.new()
10530 Foo(b)
10531 END
10532 call v9.CheckSourceSuccess(lines)
10533endfunc
10534
Ernie Rael9d779c52024-07-07 20:41:44 +020010535" Test for using the string() builtin method with an object's method
10536def Test_method_string()
10537 var lines =<< trim END
10538 vim9script
10539 class A
10540 def F()
10541 enddef
10542 endclass
10543 assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F))
10544 END
10545 v9.CheckScriptSuccess(lines)
10546enddef
10547
10548
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010549" Test for using a class in the class definition
10550def Test_Ref_Class_Within_Same_Class()
10551 var lines =<< trim END
10552 vim9script
10553 class A
10554 var n: number = 0
10555 def Equals(other: A): bool
10556 return this.n == other.n
10557 enddef
10558 endclass
10559
10560 var a1 = A.new(10)
10561 var a2 = A.new(10)
10562 var a3 = A.new(20)
10563 assert_equal(true, a1.Equals(a2))
10564 assert_equal(false, a2.Equals(a3))
10565 END
10566 v9.CheckScriptSuccess(lines)
10567
10568 lines =<< trim END
10569 vim9script
10570
10571 class Foo
10572 var num: number
10573 def Clone(): Foo
10574 return Foo.new(this.num)
10575 enddef
10576 endclass
10577
10578 var f1 = Foo.new(1)
10579
10580 def F()
10581 var f2: Foo = f1.Clone()
10582 assert_equal(false, f2 is f1)
10583 assert_equal(true, f2.num == f1.num)
10584 enddef
10585 F()
10586
10587 var f3: Foo = f1.Clone()
10588 assert_equal(false, f3 is f1)
10589 assert_equal(true, f3.num == f1.num)
10590 END
10591 v9.CheckScriptSuccess(lines)
10592
10593 # Test for trying to use a class to extend when defining the same class
10594 lines =<< trim END
10595 vim9script
10596 class A extends A
10597 endclass
10598 END
10599 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10600
10601 # Test for trying to use a class to implement when defining the same class
10602 lines =<< trim END
10603 vim9script
10604 class A implements A
10605 endclass
10606 END
10607 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10608enddef
10609
Ernie Raelf0e69142024-06-22 11:12:00 +020010610" Test for comparing a class referencing itself
10611def Test_Object_Compare_With_Recursive_Class_Ref()
10612 var lines =<< trim END
10613 vim9script
10614
10615 class C
10616 public var nest: C
10617 endclass
10618
10619 var o1 = C.new()
10620 o1.nest = o1
10621
10622 var result = o1 == o1
10623 assert_equal(true, result)
10624 END
10625 v9.CheckScriptSuccess(lines)
Ernie Rael86257142024-06-23 09:54:45 +020010626
10627 lines =<< trim END
10628 vim9script
10629
10630 class C
10631 public var nest: C
10632 endclass
10633 var o1 = C.new()
10634 var o2 = C.new(C.new())
10635
10636 var result = o1 == o2
10637 assert_equal(false, result)
10638 END
10639 v9.CheckScriptSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +020010640
10641 lines =<< trim END
10642 vim9script
10643 class C
10644 var nest1: C
10645 var nest2: C
10646 def Init(n1: C, n2: C)
10647 this.nest1 = n1
10648 this.nest2 = n2
10649 enddef
10650 endclass
10651
10652 var o1 = C.new()
10653 var o2 = C.new()
10654 o1.Init(o1, o2)
10655 o2.Init(o2, o1)
10656
10657 var result = o1 == o2
10658 assert_equal(true, result)
10659 END
10660 v9.CheckScriptSuccess(lines)
Ernie Raelf0e69142024-06-22 11:12:00 +020010661enddef
10662
Ernie Raelf3975492024-07-06 11:44:37 +020010663" Test for comparing a class with nesting objects
10664def Test_Object_Compare_With_Nesting_Objects()
10665 # On a compare, after vim equal recurses 1000 times, not finding an unequal,
10666 # return the compare is equal.
10667 # Test that limit
10668
10669 var lines =<< trim END
10670 vim9script
10671 class C
10672 public var n: number
10673 public var nest: C
10674
10675 # Create a "C" that chains/nests to indicated depth.
10676 # return {head: firstC, tail: lastC}
10677 static def CreateNested(depth: number): dict<C>
10678 var first = C.new(1, null_object)
10679 var last = first
10680 for i in range(2, depth)
10681 last.nest = C.new(i, null_object)
10682 last = last.nest
10683 endfor
10684 return {head: first, tail: last}
10685 enddef
10686
10687 # Return pointer to nth item in chain.
10688 def GetLink(depth: number): C
10689 var count = 1
10690 var p: C = this
10691 while count < depth
10692 p = p.nest
10693 if p == null
10694 throw "too deep"
10695 endif
10696 count += 1
10697 endwhile
10698 return p
10699 enddef
10700
10701 # Return the length of the chain
10702 def len(): number
10703 var count = 1
10704 var p: C = this
10705 while p.nest != null
10706 p = p.nest
10707 count += 1
10708 endwhile
10709 return count
10710 enddef
10711 endclass
10712
10713 var chain = C.CreateNested(3)
10714 var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}"
10715 assert_equal(s, string(chain.head))
10716 assert_equal(3, chain.head->len())
10717
10718 var chain1 = C.CreateNested(100)
10719 var chain2 = C.CreateNested(100)
10720 assert_true(chain1.head == chain2.head)
10721
10722 # modify the tail of chain2, compare not equal
10723 chain2.tail.n = 123456
10724 assert_true(chain1.head != chain2.head)
10725
10726 # a tail of a different length compares not equal
10727 chain2 = C.CreateNested(101)
10728 assert_true(chain1.head != chain2.head)
10729
10730 chain1 = C.CreateNested(1000)
10731 chain2 = C.CreateNested(1000)
10732 assert_true(chain1.head == chain2.head)
10733
10734 # modify the tail of chain2, compare not equal
10735 chain2.tail.n = 123456
10736 assert_true(chain1.head != chain2.head)
10737
10738 # try a chain longer that the limit
10739 chain1 = C.CreateNested(1001)
10740 chain2 = C.CreateNested(1001)
10741 assert_true(chain1.head == chain2.head)
10742
10743 # modify the tail, but still equal
10744 chain2.tail.n = 123456
10745 assert_true(chain1.head == chain2.head)
10746
10747 # remove 2 items from front, shorten the chain by two.
10748 chain1.head = chain1.head.GetLink(3)
10749 chain2.head = chain2.head.GetLink(3)
10750 assert_equal(3, chain1.head.n)
10751 assert_equal(3, chain2.head.n)
10752 assert_equal(999, chain1.head->len())
10753 assert_equal(999, chain2.head->len())
10754 # Now less than the limit, compare not equal
10755 assert_true(chain1.head != chain2.head)
10756 END
10757 v9.CheckScriptSuccess(lines)
10758enddef
10759
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010760" Test for using a compound operator from a lambda function in an object method
10761def Test_compound_op_in_objmethod_lambda()
10762 # Test using the "+=" operator
10763 var lines =<< trim END
10764 vim9script
10765 class A
10766 var n: number = 10
10767 def Foo()
10768 var Fn = () => {
10769 this.n += 1
10770 }
10771 Fn()
10772 enddef
10773 endclass
10774
10775 var a = A.new()
10776 a.Foo()
10777 assert_equal(11, a.n)
10778 END
10779 v9.CheckScriptSuccess(lines)
10780
10781 # Test using the "..=" operator
10782 lines =<< trim END
10783 vim9script
10784 class A
10785 var s: string = "a"
10786 def Foo()
10787 var Fn = () => {
10788 this.s ..= "a"
10789 }
10790 Fn()
10791 enddef
10792 endclass
10793
10794 var a = A.new()
10795 a.Foo()
10796 a.Foo()
10797 assert_equal("aaa", a.s)
10798 END
10799 v9.CheckScriptSuccess(lines)
10800enddef
10801
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010802" Test for using test_refcount() with a class and an object
10803def Test_class_object_refcount()
10804 var lines =<< trim END
10805 vim9script
10806 class A
10807 endclass
10808 var a: A = A.new()
10809 assert_equal(2, test_refcount(A))
10810 assert_equal(1, test_refcount(a))
10811 var b = a
10812 assert_equal(2, test_refcount(A))
10813 assert_equal(2, test_refcount(a))
10814 assert_equal(2, test_refcount(b))
10815 END
10816 v9.CheckScriptSuccess(lines)
10817enddef
10818
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010819" call a lambda function in one object from another object
10820def Test_lambda_invocation_across_classes()
10821 var lines =<< trim END
10822 vim9script
10823 class A
10824 var s: string = "foo"
10825 def GetFn(): func
10826 var Fn = (): string => {
10827 return this.s
10828 }
10829 return Fn
10830 enddef
10831 endclass
10832
10833 class B
10834 var s: string = "bar"
10835 def GetFn(): func
10836 var a = A.new()
10837 return a.GetFn()
10838 enddef
10839 endclass
10840
10841 var b = B.new()
10842 var Fn = b.GetFn()
10843 assert_equal("foo", Fn())
10844 END
10845 v9.CheckScriptSuccess(lines)
10846enddef
10847
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010848" Test for using a class member which is an object of the current class
10849def Test_current_class_object_class_member()
10850 var lines =<< trim END
10851 vim9script
10852 class A
10853 public static var obj1: A = A.new(10)
10854 var n: number
10855 endclass
10856 defcompile
10857 assert_equal(10, A.obj1.n)
10858 END
10859 v9.CheckScriptSuccess(lines)
10860enddef
10861
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020010862" Test for updating a base class variable from a base class method without the
10863" class name. This used to crash Vim (Github issue #14352).
10864def Test_use_base_class_variable_from_base_class_method()
10865 var lines =<< trim END
10866 vim9script
10867
10868 class DictKeyClass
10869 static var _obj_id_count = 1
10870 def _GenerateKey()
10871 _obj_id_count += 1
10872 enddef
10873 static def GetIdCount(): number
10874 return _obj_id_count
10875 enddef
10876 endclass
10877
10878 class C extends DictKeyClass
10879 def F()
10880 this._GenerateKey()
10881 enddef
10882 endclass
10883
10884 C.new().F()
10885 assert_equal(2, DictKeyClass.GetIdCount())
10886 END
10887 v9.CheckScriptSuccess(lines)
10888enddef
10889
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020010890" Test for accessing protected funcref object and class variables
10891def Test_protected_funcref()
10892 # protected funcref object variable
10893 var lines =<< trim END
10894 vim9script
10895 class Test1
10896 const _Id: func(any): any = (v) => v
10897 endclass
10898 var n = Test1.new()._Id(1)
10899 END
10900 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
10901
10902 # protected funcref class variable
10903 lines =<< trim END
10904 vim9script
10905 class Test2
10906 static const _Id: func(any): any = (v) => v
10907 endclass
10908 var n = Test2._Id(2)
10909 END
10910 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
10911enddef
10912
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020010913" Test for using lambda block in classes
10914def Test_lambda_block_in_class()
10915 # This used to crash Vim
10916 var lines =<< trim END
10917 vim9script
10918 class IdClass1
10919 const Id: func(number): number = (num: number): number => {
10920 # Return a ID
10921 return num * 10
10922 }
10923 endclass
10924 var id = IdClass1.new()
10925 assert_equal(20, id.Id(2))
10926 END
10927 v9.CheckScriptSuccess(lines)
10928
10929 # This used to crash Vim
10930 lines =<< trim END
10931 vim9script
10932 class IdClass2
10933 static const Id: func(number): number = (num: number): number => {
10934 # Return a ID
10935 return num * 2
10936 }
10937 endclass
10938 assert_equal(16, IdClass2.Id(8))
10939 END
10940 v9.CheckScriptSuccess(lines)
10941enddef
10942
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020010943" Test for defcompiling an abstract method
10944def Test_abstract_method_defcompile()
10945 # Compile an abstract class with abstract object methods
10946 var lines =<< trim END
10947 vim9script
10948 abstract class A
10949 abstract def Foo(): string
10950 abstract def Bar(): list<string>
10951 endclass
10952 defcompile
10953 END
10954 v9.CheckScriptSuccess(lines)
10955
10956 # Compile a concrete object method in an abstract class
10957 lines =<< trim END
10958 vim9script
10959 abstract class A
10960 abstract def Foo(): string
10961 abstract def Bar(): list<string>
10962 def Baz(): string
10963 pass
10964 enddef
10965 endclass
10966 defcompile
10967 END
10968 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10969
10970 # Compile a concrete class method in an abstract class
10971 lines =<< trim END
10972 vim9script
10973 abstract class A
10974 abstract def Foo(): string
10975 abstract def Bar(): list<string>
10976 static def Baz(): string
10977 pass
10978 enddef
10979 endclass
10980 defcompile
10981 END
10982 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10983enddef
10984
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020010985" Test for defining a class in a function
10986def Test_class_definition_in_a_function()
10987 var lines =<< trim END
10988 vim9script
10989 def Foo()
10990 class A
10991 endclass
10992 enddef
10993 defcompile
10994 END
10995 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
10996enddef
10997
Yegappan Lakshmanandbac0da2024-05-25 20:23:54 +020010998" Test for using [] with a class and an object
10999def Test_class_object_index()
11000 var lines =<< trim END
11001 vim9script
11002 class A
11003 endclass
11004 A[10] = 1
11005 END
11006 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a class: A[10] = 1', 4)
11007
11008 lines =<< trim END
11009 vim9script
11010 class A
11011 endclass
11012 var a = A.new()
11013 a[10] = 1
11014 END
11015 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5)
11016enddef
11017
LemonBoyf4af3312024-07-04 13:43:12 +020011018def Test_class_member_init_typecheck()
11019 # Ensure the class member is assigned its declared type.
11020 var lines =<< trim END
11021 vim9script
11022 class S
11023 static var l: list<string> = []
11024 endclass
11025 S.l->add(123)
11026 END
11027 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5)
11028
11029 # Ensure the initializer value and the declared type match.
11030 lines =<< trim END
11031 vim9script
11032 class S
11033 var l: list<string> = [1, 2, 3]
11034 endclass
11035 var o = S.new()
11036 END
11037 v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>')
11038
11039 # Ensure the class member is assigned its declared type.
11040 lines =<< trim END
11041 vim9script
11042 class S
11043 var l: list<string> = []
11044 endclass
11045 var o = S.new()
11046 o.l->add(123)
11047 END
11048 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6)
11049enddef
11050
LemonBoy50d48542024-07-04 17:03:17 +020011051def Test_class_cast()
11052 var lines =<< trim END
11053 vim9script
11054 class A
11055 endclass
11056 class B extends A
11057 var mylen: number
11058 endclass
11059 def F(o: A): number
11060 return (<B>o).mylen
11061 enddef
11062
11063 defcompile F
11064 END
11065 v9.CheckScriptSuccess(lines)
11066enddef
11067
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011068" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker