blob: 56c7b99d943e045d905ff9fbdc77178f20fd5454 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +010038 # Only the complete word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmananac773182024-04-27 11:36:12 +020070 # Additional command after "class name"
71 lines =<< trim END
72 vim9script
73 class Something | var x = 10
74 endclass
75 END
76 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
77
78 # Additional command after "object variable"
79 lines =<< trim END
80 vim9script
81 class Something
82 var l: list<number> = [] | var y = 10
83 endclass
84 END
85 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
86
87 # Additional command after "class variable"
88 lines =<< trim END
89 vim9script
90 class Something
91 static var d = {a: 10} | var y = 10
92 endclass
93 END
94 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
95
96 # Additional command after "object method"
97 lines =<< trim END
98 vim9script
99 class Something
100 def Foo() | var y = 10
101 enddef
102 endclass
103 END
104 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
105
Yegappan Lakshmananfe55c312024-04-28 09:54:09 +0200106 # Comments are allowed after an inline block
107 lines =<< trim END
108 vim9script
109 class Foo
110 static const bar = { # {{{
111 baz: 'qux'
112 } # }}}
113 endclass
114 assert_equal({baz: 'qux'}, Foo.bar)
115 END
116 v9.CheckSourceSuccess(lines)
117
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +0100118 # Try to define a class with the same name as an existing variable
119 lines =<< trim END
120 vim9script
121 var Something: list<number> = [1]
122 class Thing
123 endclass
124 interface Api
125 endinterface
126 class Something extends Thing implements Api
127 var v1: string = ''
128 def Foo()
129 enddef
130 endclass
131 END
132 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 7)
133
zeertzjqe7102202024-02-13 20:32:04 +0100134 # Use old "this." prefixed member variable declaration syntax (without initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100135 lines =<< trim END
136 vim9script
137 class Something
138 this.count: number
139 endclass
140 END
141 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
142
zeertzjqe7102202024-02-13 20:32:04 +0100143 # Use old "this." prefixed member variable declaration syntax (with initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100144 lines =<< trim END
145 vim9script
146 class Something
147 this.count: number = 42
148 endclass
149 END
150 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
151
152 # Use old "this." prefixed member variable declaration syntax (type inferred)
153 lines =<< trim END
154 vim9script
155 class Something
156 this.count = 42
157 endclass
158 END
159 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
160
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200161 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000162 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 vim9script
164 class Something
165 this
166 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000167 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100168 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000169
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200170 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000171 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200172 vim9script
173 class Something
174 this.
175 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000176 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100177 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000178
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200179 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000180 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200181 vim9script
182 class Something
183 this .count
184 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000185 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100186 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000187
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200188 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000189 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200190 vim9script
191 class Something
192 this. count
193 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000194 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100195 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000196
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200197 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000198 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200199 vim9script
200 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100201 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200202 that.count
203 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200205 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000206
Doug Kearns74da0ee2023-12-14 20:26:26 +0100207 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000208 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200209 vim9script
210 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100211 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000213 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100214 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
215
216 # Use "variable" instead of "var" for member variable declaration (with initialization)
217 lines =<< trim END
218 vim9script
219 class Something
220 variable count: number = 42
221 endclass
222 END
223 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
224
225 # Use "variable" instead of "var" for member variable declaration (type inferred)
226 lines =<< trim END
227 vim9script
228 class Something
229 variable count = 42
230 endclass
231 END
232 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000233
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200234 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000235 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200236 vim9script
237 class Something
238 def new()
239 this.state = 0
240 enddef
241 endclass
242 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000243 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200244 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000245
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200246 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000247 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200248 vim9script
249 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100250 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200251 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000252 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200253 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000254
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200255 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000256 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200257 vim9script
258 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100259 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200260 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000261 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200262 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000263
Doug Kearns74da0ee2023-12-14 20:26:26 +0100264 # Missing ":var" in a "var" member variable declaration (without initialization)
265 lines =<< trim END
266 vim9script
267 class Something
268 var: number
269 endclass
270 END
271 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
272
273 # Missing ":var" in a "var" member variable declaration (with initialization)
274 lines =<< trim END
275 vim9script
276 class Something
277 var: number = 42
278 endclass
279 END
280 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
281
282 # Missing ":var" in a "var" member variable declaration (type inferred)
283 lines =<< trim END
284 vim9script
285 class Something
286 var = 42
287 endclass
288 END
289 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
290
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200291 # Test for unsupported comment specifier
292 lines =<< trim END
293 vim9script
294 class Something
295 # comment
296 #{
297 endclass
298 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200299 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200300
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200301 # Test for using class as a bool
302 lines =<< trim END
303 vim9script
304 class A
305 endclass
306 if A
307 endif
308 END
Ernie Raele75fde62023-12-21 17:18:54 +0100309 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200310
311 # Test for using object as a bool
312 lines =<< trim END
313 vim9script
314 class A
315 endclass
316 var a = A.new()
317 if a
318 endif
319 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200320 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200321
322 # Test for using class as a float
323 lines =<< trim END
324 vim9script
325 class A
326 endclass
327 sort([1.1, A], 'f')
328 END
Ernie Raelfa831102023-12-14 20:06:39 +0100329 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200330
331 # Test for using object as a float
332 lines =<< trim END
333 vim9script
334 class A
335 endclass
336 var a = A.new()
337 sort([1.1, a], 'f')
338 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200339 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200340
341 # Test for using class as a string
342 lines =<< trim END
343 vim9script
344 class A
345 endclass
346 :exe 'call ' .. A
347 END
Ernie Raele75fde62023-12-21 17:18:54 +0100348 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200349
350 # Test for using object as a string
351 lines =<< trim END
352 vim9script
353 class A
354 endclass
355 var a = A.new()
356 :exe 'call ' .. a
357 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200358 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200359
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200360 # Test creating a class with member variables and methods, calling a object
361 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000362 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200363 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000364
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200365 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100366 var lnum: number
367 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000368
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200369 # make a nicely formatted string
370 def ToString(): string
371 return $'({this.lnum}, {this.col})'
372 enddef
373 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000374
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200375 # use the automatically generated new() method
376 var pos = TextPosition.new(2, 12)
377 assert_equal(2, pos.lnum)
378 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000379
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200380 # call an object method
381 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000382
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200383 assert_equal(v:t_class, type(TextPosition))
384 assert_equal(v:t_object, type(pos))
385 assert_equal('class<TextPosition>', typename(TextPosition))
386 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000387 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200388 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200389
390 # When referencing object methods, space cannot be used after a "."
391 lines =<< trim END
392 vim9script
393 class A
394 def Foo(): number
395 return 10
396 enddef
397 endclass
398 var a = A.new()
399 var v = a. Foo()
400 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200401 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200402
403 # Using an object without specifying a method or a member variable
404 lines =<< trim END
405 vim9script
406 class A
407 def Foo(): number
408 return 10
409 enddef
410 endclass
411 var a = A.new()
412 var v = a.
413 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200414 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200415
416 # Error when parsing the arguments of an object method.
417 lines =<< trim END
418 vim9script
419 class A
420 def Foo()
421 enddef
422 endclass
423 var a = A.new()
424 var v = a.Foo(,)
425 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200426 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200427
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200428 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200429 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200430 vim9script
431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100432 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200433 X: 1
434 }
435 endclass
436 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200437 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200438 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000439enddef
440
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200441" Tests for object/class methods in a class
442def Test_class_def_method()
443 # Using the "public" keyword when defining an object method
444 var lines =<< trim END
445 vim9script
446 class A
447 public def Foo()
448 enddef
449 endclass
450 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200451 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200452
453 # Using the "public" keyword when defining a class method
454 lines =<< trim END
455 vim9script
456 class A
457 public static def Foo()
458 enddef
459 endclass
460 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200461 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200462
Ernie Rael03042a22023-11-11 08:53:32 +0100463 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200464 lines =<< trim END
465 vim9script
466 class A
467 public def _Foo()
468 enddef
469 endclass
470 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200471 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200472
Ernie Rael03042a22023-11-11 08:53:32 +0100473 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200474 lines =<< trim END
475 vim9script
476 class A
477 public static def _Foo()
478 enddef
479 endclass
480 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200481 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200482
483 # Using a "def" keyword without an object method name
484 lines =<< trim END
485 vim9script
486 class A
487 def
488 enddef
489 endclass
490 END
491 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
492
493 # Using a "def" keyword without a class method name
494 lines =<< trim END
495 vim9script
496 class A
497 static def
498 enddef
499 endclass
500 END
501 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
502enddef
503
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000504def Test_class_defined_twice()
505 # class defined twice should fail
506 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200507 vim9script
508 class There
509 endclass
510 class There
511 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000512 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200513 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000514
515 # one class, reload same script twice is OK
516 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 vim9script
518 class There
519 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000520 END
521 writefile(lines, 'XclassTwice.vim', 'D')
522 source XclassTwice.vim
523 source XclassTwice.vim
524enddef
525
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000526def Test_returning_null_object()
527 # this was causing an internal error
528 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200529 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000530
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200531 class BufferList
532 def Current(): any
533 return null_object
534 enddef
535 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000536
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200537 var buffers = BufferList.new()
538 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000539 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200540 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000541enddef
542
Bram Moolenaard13dd302023-03-11 20:56:35 +0000543def Test_using_null_class()
544 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200545 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200547 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200548
549 # Test for using a null class as a value
550 lines =<< trim END
551 vim9script
552 echo empty(null_class)
553 END
554 v9.CheckSourceFailure(lines, 'E1405: Class "" cannot be used as a value', 2)
555
556 # Test for using a null class with string()
557 lines =<< trim END
558 vim9script
559 assert_equal('class [unknown]', string(null_class))
560 END
561 v9.CheckSourceSuccess(lines)
562
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +0200563 # Test for using a null class with type() and typename()
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200564 lines =<< trim END
565 vim9script
566 assert_equal(12, type(null_class))
567 assert_equal('class<Unknown>', typename(null_class))
568 END
569 v9.CheckSourceSuccess(lines)
570enddef
571
Bram Moolenaar657aea72023-01-27 13:16:19 +0000572def Test_class_interface_wrong_end()
573 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200574 vim9script
575 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100576 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200577 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200579 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000580
581 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200582 vim9script
583 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100584 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200585 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000586 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200587 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000588enddef
589
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000590def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200591 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000592 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200593 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000594
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200595 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100596 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200597 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200599 var state: State
600 var db = {'xyz': 789}
601 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200603 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000604
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200605 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000606 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200607 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000608
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200609 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100610 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200611 def Method1()
612 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000613 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200614 endclass
615
616 var obj: Class
617 def Func()
618 obj.Method1()
619 enddef
620 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000621 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200622 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000623
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200624 # Pass an uninitialized object variable to a "new" function and try to call an
625 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000626 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200627 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000628
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200629 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100630 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200631 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000632
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200633 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100634 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200636 def GetBackground(): string
637 return this._bg.background
638 enddef
639 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000640
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200641 var bg: Background # UNINITIALIZED
642 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200644 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000645
646 # TODO: this should not give an error but be handled at runtime
647 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200648 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000649
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200650 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100651 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200652 def Method1()
653 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000654 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200655 endclass
656
657 var obj = null_object
658 def Func()
659 obj.Method1()
660 enddef
661 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000662 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200663 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Ernie Raelbe828252024-07-26 18:37:02 +0200664
665 # Reference a object variable through a null class object which is stored in a
666 # variable of type "any".
667 lines =<< trim END
668 vim9script
669
670 def Z()
671 var o: any = null_object
672 o.v = 4
673 enddef
674 Z()
675 END
676 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
677
678 # Do "echom" of a null object variable.
679 lines =<< trim END
680 vim9script
681
682 def X()
683 var x = null_object
684 echom x
685 enddef
686 X()
687 END
688 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 2)
Ernie Rael94082b62024-07-26 19:40:29 +0200689
690 # Use a null object variable that vim wants to force to number.
691 lines =<< trim END
692 vim9script
693
694 def X()
695 var o = null_object
696 var l = [ 1, o]
697 sort(l, 'N')
698 enddef
699 X()
700 END
701 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 3)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000702enddef
703
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200704" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200705def Test_null_object_assign_compare()
706 var lines =<< trim END
707 vim9script
708
709 var nullo = null_object
710 def F(): any
711 return nullo
712 enddef
713 assert_equal('object<Unknown>', typename(F()))
714
715 var o0 = F()
716 assert_true(o0 == null_object)
717 assert_true(o0 == null)
718
719 var o1: any = nullo
720 assert_true(o1 == null_object)
721 assert_true(o1 == null)
722
723 def G()
724 var x = null_object
725 enddef
726
727 class C
728 endclass
729 var o2: C
730 assert_true(o2 == null_object)
731 assert_true(o2 == null)
732
733 o2 = null_object
734 assert_true(o2 == null)
735
736 o2 = C.new()
737 assert_true(o2 != null)
738
739 o2 = null_object
740 assert_true(o2 == null)
741 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200742 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200743enddef
744
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200745" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000746def Test_class_member_initializer()
747 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200748 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000749
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200750 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100751 var lnum: number = 1
752 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000753
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200754 # constructor with only the line number
755 def new(lnum: number)
756 this.lnum = lnum
757 enddef
758 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200760 var pos = TextPosition.new(3)
761 assert_equal(3, pos.lnum)
762 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000763
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200764 var instr = execute('disassemble TextPosition.new')
765 assert_match('new\_s*' ..
766 '0 NEW TextPosition size \d\+\_s*' ..
767 '\d PUSHNR 1\_s*' ..
768 '\d STORE_THIS 0\_s*' ..
769 '\d PUSHNR 1\_s*' ..
770 '\d STORE_THIS 1\_s*' ..
771 'this.lnum = lnum\_s*' ..
772 '\d LOAD arg\[-1]\_s*' ..
773 '\d PUSHNR 0\_s*' ..
774 '\d LOAD $0\_s*' ..
775 '\d\+ STOREINDEX object\_s*' ..
776 '\d\+ RETURN object.*',
777 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000778 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200779 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000780enddef
781
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000782def Test_member_any_used_as_object()
783 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200784 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000785
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200786 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100787 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200788 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000789
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200790 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100791 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200792 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200794 def F(outer: Outer)
795 outer.inner.value = 1
796 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000797
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200798 var inner_obj = Inner.new(0)
799 var outer_obj = Outer.new(inner_obj)
800 F(outer_obj)
801 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000802 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200803 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000804
Ernie Rael03042a22023-11-11 08:53:32 +0100805 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200806 lines =<< trim END
807 vim9script
808
809 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100810 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200811 endclass
812
813 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100814 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200815 endclass
816
817 def F(outer: Outer)
818 outer.inner._value = 'b'
819 enddef
820
821 var inner_obj = Inner.new('a')
822 var outer_obj = Outer.new(inner_obj)
823 F(outer_obj)
824 END
Ernie Rael03042a22023-11-11 08:53:32 +0100825 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200826
827 # Try modifying a non-existing variable using an "any" object
828 lines =<< trim END
829 vim9script
830
831 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100832 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200833 endclass
834
835 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100836 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200837 endclass
838
839 def F(outer: Outer)
840 outer.inner.someval = 'b'
841 enddef
842
843 var inner_obj = Inner.new('a')
844 var outer_obj = Outer.new(inner_obj)
845 F(outer_obj)
846 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200847 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000848enddef
849
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200850" Nested assignment to a object variable which is of another class type
851def Test_assignment_nested_type()
852 var lines =<< trim END
853 vim9script
854
855 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100856 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200857 endclass
858
859 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100860 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200861 endclass
862
863 def F(outer: Outer)
864 outer.inner.value = 1
865 enddef
866
867 def Test_assign_to_nested_typed_member()
868 var inner = Inner.new(0)
869 var outer = Outer.new(inner)
870 F(outer)
871 assert_equal(1, inner.value)
872 enddef
873
874 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200875
876 var script_inner = Inner.new(0)
877 var script_outer = Outer.new(script_inner)
878 script_outer.inner.value = 1
879 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200880 END
881 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200882
883 # Assignment where target item is read only in :def
884 lines =<< trim END
885 vim9script
886
887 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100888 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200889 endclass
890
891 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100892 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200893 endclass
894
895 def F(outer: Outer)
896 outer.inner.value = 1
897 enddef
898
899 def Test_assign_to_nested_typed_member()
900 var inner = Inner.new(0)
901 var outer = Outer.new(inner)
902 F(outer)
903 assert_equal(1, inner.value)
904 enddef
905
906 Test_assign_to_nested_typed_member()
907 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200908 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200909
910 # Assignment where target item is read only script level
911 lines =<< trim END
912 vim9script
913
914 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100915 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200916 endclass
917
918 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100919 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200920 endclass
921
922 def F(outer: Outer)
923 outer.inner.value = 1
924 enddef
925
926 var script_inner = Inner.new(0)
927 var script_outer = Outer.new(script_inner)
928 script_outer.inner.value = 1
929 assert_equal(1, script_inner.value)
930 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200931 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200932enddef
933
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000934def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200935 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000936 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200937 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000938
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200939 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100940 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000941
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200942 def Add(n: number)
943 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100944 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200945 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100946
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200947 var f = Foo.new(3)
948 f.Add(17)
949 assert_equal(20, f.x)
950
951 def AddToFoo(obj: Foo)
952 obj.x += 3
953 enddef
954
955 AddToFoo(f)
956 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000957 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200958 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000959enddef
960
Bram Moolenaarf4508042023-01-15 16:54:57 +0000961def Test_list_of_objects()
962 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200963 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000964
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200965 class Foo
966 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000967 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200968 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000969
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200970 def ProcessList(fooList: list<Foo>)
971 for foo in fooList
972 foo.Add()
973 endfor
974 enddef
975
976 var l: list<Foo> = [Foo.new()]
977 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000978 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200979 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000980enddef
981
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000982def Test_expr_after_using_object()
983 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200984 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000985
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200986 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100987 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200988 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000989
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200990 def Foo(): Something
991 var v = Something.new()
992 echo 'in Foo(): ' .. typename(v)
993 return v
994 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000995
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200996 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000997 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200998 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000999enddef
1000
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001001def Test_class_default_new()
1002 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001003 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001004
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001005 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001006 var lnum: number = 1
1007 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001008 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001009
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001010 var pos = TextPosition.new()
1011 assert_equal(1, pos.lnum)
1012 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001013
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001014 pos = TextPosition.new(v:none, v:none)
1015 assert_equal(1, pos.lnum)
1016 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001017
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001018 pos = TextPosition.new(3, 22)
1019 assert_equal(3, pos.lnum)
1020 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001022 pos = TextPosition.new(v:none, 33)
1023 assert_equal(1, pos.lnum)
1024 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001025 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001026 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001027
1028 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001029 vim9script
1030 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001031 var name: string
1032 var age: number = 42
1033 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001034
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001035 def new(this.name, this.age = v:none, this.education = v:none)
1036 enddef
1037 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001038
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001039 var piet = Person.new("Piet")
1040 assert_equal("Piet", piet.name)
1041 assert_equal(42, piet.age)
1042 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001043
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001044 var chris = Person.new("Chris", 4, "none")
1045 assert_equal("Chris", chris.name)
1046 assert_equal(4, chris.age)
1047 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001048 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001049 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001050
1051 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001052 vim9script
1053 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001054 var name: string
1055 var age: number = 42
1056 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +00001057
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001058 def new(this.name, this.age = v:none, this.education = v:none)
1059 enddef
1060 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001061
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001062 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +00001063 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001064 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001065
1066 # Using a specific value to initialize an instance variable in the new()
1067 # method.
1068 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001069 vim9script
1070 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001071 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001072 def new(this.val = 'a')
1073 enddef
1074 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001075 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001076 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001077enddef
1078
h-east2261c892023-08-16 21:49:54 +09001079def Test_class_new_with_object_member()
1080 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001081 vim9script
h-east2261c892023-08-16 21:49:54 +09001082
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001083 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001084 var str: string
1085 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001086 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +09001087 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001088 def newVals(this.str, this.num)
1089 enddef
1090 endclass
h-east2261c892023-08-16 21:49:54 +09001091
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001092 def Check()
1093 try
1094 var c = C.new('cats', 2)
1095 assert_equal('cats', c.str)
1096 assert_equal(2, c.num)
1097
1098 c = C.newVals('dogs', 4)
1099 assert_equal('dogs', c.str)
1100 assert_equal(4, c.num)
1101 catch
1102 assert_report($'Unexpected exception was caught: {v:exception}')
1103 endtry
1104 enddef
1105
1106 Check()
h-east2261c892023-08-16 21:49:54 +09001107 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001108 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001109
1110 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001111 vim9script
1112
1113 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001114 var str: string
1115 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001116 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001117 enddef
1118 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001119
1120 def Check()
1121 try
1122 var c = C.new(1, 2)
1123 catch
1124 assert_report($'Unexpected exception was caught: {v:exception}')
1125 endtry
1126 enddef
1127
1128 Check()
h-eastdb385522023-09-28 22:18:19 +02001129 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001130 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001131
1132 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001133 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001134
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001135 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001136 var str: string
1137 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001138 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001139 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001140 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001141
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001142 def Check()
1143 try
1144 var c = C.newVals('dogs', 'apes')
1145 catch
1146 assert_report($'Unexpected exception was caught: {v:exception}')
1147 endtry
1148 enddef
1149
1150 Check()
1151 END
1152 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1153
1154 lines =<< trim END
1155 vim9script
1156
1157 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001158 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001159 def new(str: any)
1160 enddef
1161 endclass
1162
1163 def Check()
1164 try
1165 var c = C.new(1)
1166 catch
1167 assert_report($'Unexpected exception was caught: {v:exception}')
1168 endtry
1169 enddef
1170
1171 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001172 END
1173 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001174
1175 # Try using "this." argument in a class method
1176 lines =<< trim END
1177 vim9script
1178 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001179 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001180 static def Foo(this.val: number)
1181 enddef
1182 endclass
1183 END
1184 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1185
1186 # Try using "this." argument in an object method
1187 lines =<< trim END
1188 vim9script
1189 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001190 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001191 def Foo(this.val: number)
1192 enddef
1193 endclass
1194 END
1195 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001196enddef
1197
Bram Moolenaar74e12742022-12-13 21:14:28 +00001198def Test_class_object_member_inits()
1199 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001200 vim9script
1201 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001202 var lnum: number
1203 var col = 1
1204 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001205 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001206
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001207 var pos = TextPosition.new()
1208 assert_equal(0, pos.lnum)
1209 assert_equal(1, pos.col)
1210 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001211 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001212 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001213
1214 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001215 vim9script
1216 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001217 var lnum
1218 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001219 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001220 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001221 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001222
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001223 # If the type is not specified for a member, then it should be set during
1224 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001225 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001226 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001227
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001228 var init_count = 0
1229 def Init(): string
1230 init_count += 1
1231 return 'foo'
1232 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001233
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001234 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001235 var str1 = Init()
1236 var str2: string = Init()
1237 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001238 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001239
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001240 assert_equal(init_count, 0)
1241 var a = A.new()
1242 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001243 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001244 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001245
1246 # Test for initializing an object member with an unknown variable/type
1247 lines =<< trim END
1248 vim9script
1249 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001250 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001251 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001252 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001253 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001254 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001255
1256 # Test for initializing an object member with an special type
1257 lines =<< trim END
1258 vim9script
1259 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001260 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001261 endclass
1262 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001263 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001264enddef
1265
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001266" Test for instance variable access
1267def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001268 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001269 vim9script
1270 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001271 var _one = 1
1272 var two = 2
1273 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001274
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001275 def GetOne(): number
1276 return this._one
1277 enddef
1278 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001279
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001280 var trip = Triple.new()
1281 assert_equal(1, trip.GetOne())
1282 assert_equal(2, trip.two)
1283 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001284 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001285
Ernie Rael03042a22023-11-11 08:53:32 +01001286 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001287 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1288 trip.three = 33
1289 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001290
Ernie Raeld4802ec2023-10-20 11:59:00 +02001291 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001292 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001293 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001294
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001295 # Test for a public member variable name beginning with an underscore
1296 lines =<< trim END
1297 vim9script
1298 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001299 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001300 endclass
1301 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001302 v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001303
Bram Moolenaar590162c2022-12-24 21:24:06 +00001304 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001305 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001306
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001307 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001308 var make: string
1309 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001310
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001311 def new(make_arg: string)
1312 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001313 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001314
1315 def GetMake(): string
1316 return $"make = {this.make}"
1317 enddef
1318 def GetAge(): number
1319 return this.age
1320 enddef
1321 endclass
1322
1323 var c = MyCar.new("abc")
1324 assert_equal('make = abc', c.GetMake())
1325
1326 c = MyCar.new("def")
1327 assert_equal('make = def', c.GetMake())
1328
1329 var c2 = MyCar.new("123")
1330 assert_equal('make = 123', c2.GetMake())
1331
1332 def CheckCar()
1333 assert_equal("make = def", c.GetMake())
1334 assert_equal(5, c.GetAge())
1335 enddef
1336 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001337 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001338 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001339
1340 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001341 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001342
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001343 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001344 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001345
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001346 def new(make_arg: string)
1347 this.make = make_arg
1348 enddef
1349 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001350
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001351 var c = MyCar.new("abc")
1352 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001353 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001354 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001355
1356 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001357 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001359 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001360 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001361
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001362 def Add(n: number): any
1363 this.x->add(n)
1364 return this
1365 enddef
1366 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001367
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001368 echo Foo.new().Add(1).Add(2).x
1369 echo Foo.new().Add(1).Add(2)
1370 .x
1371 echo Foo.new().Add(1)
1372 .Add(2).x
1373 echo Foo.new()
1374 .Add(1).Add(2).x
1375 echo Foo.new()
1376 .Add(1)
1377 .Add(2)
1378 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001379 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001380 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001381
1382 # Test for "public" cannot be abbreviated
1383 lines =<< trim END
1384 vim9script
1385 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001386 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001387 endclass
1388 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001389 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001390
Doug Kearns74da0ee2023-12-14 20:26:26 +01001391 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001392 lines =<< trim END
1393 vim9script
1394 class Something
1395 public val = 1
1396 endclass
1397 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001398 v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001399
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001400 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001401 lines =<< trim END
1402 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001403 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001404 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001405 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001406 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001407 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001408 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001409
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001410 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001411 lines =<< trim END
1412 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001413 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001414 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001415 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001416 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001417 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001418 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001419
1420 # Modify a instance variable using the class name in a def function
1421 lines =<< trim END
1422 vim9script
1423 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001424 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001425 endclass
1426 def T()
1427 A.val = 1
1428 enddef
1429 T()
1430 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001431 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001432
1433 # Read a instance variable using the class name in a def function
1434 lines =<< trim END
1435 vim9script
1436 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001437 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001438 endclass
1439 def T()
1440 var i = A.val
1441 enddef
1442 T()
1443 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001444 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001445
1446 # Access from child class extending a class:
1447 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001448 vim9script
1449 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001450 var ro_obj_var = 10
1451 public var rw_obj_var = 20
1452 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001453 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001454
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001455 class B extends A
1456 def Foo()
1457 var x: number
1458 x = this.ro_obj_var
1459 this.ro_obj_var = 0
1460 x = this.rw_obj_var
1461 this.rw_obj_var = 0
1462 x = this._priv_obj_var
1463 this._priv_obj_var = 0
1464 enddef
1465 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001466
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001467 var b = B.new()
1468 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001469 END
1470 v9.CheckSourceSuccess(lines)
1471enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001472
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001473" Test for class variable access
1474def Test_class_variable_access()
1475 # Test for "static" cannot be abbreviated
1476 var lines =<< trim END
1477 vim9script
1478 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001479 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001480 endclass
1481 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001482 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001483
1484 # Test for "static" cannot be followed by "public".
1485 lines =<< trim END
1486 vim9script
1487 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001488 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001489 endclass
1490 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001491 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001492
1493 # A readonly class variable cannot be modified from a child class
1494 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001495 vim9script
1496 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001497 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001499
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001500 class B extends A
1501 def Foo()
1502 A.ro_class_var = 50
1503 enddef
1504 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001505
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001506 var b = B.new()
1507 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001508 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001509 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001510
Ernie Rael03042a22023-11-11 08:53:32 +01001511 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001512 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001513 vim9script
1514 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001515 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001516 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001517
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001518 class B extends A
1519 def Foo()
1520 var i = A._priv_class_var
1521 enddef
1522 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001523
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001524 var b = B.new()
1525 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001526 END
Ernie Rael03042a22023-11-11 08:53:32 +01001527 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001528
Ernie Rael03042a22023-11-11 08:53:32 +01001529 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001530 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001531 vim9script
1532 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001533 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001534 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001535
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001536 class B extends A
1537 def Foo()
1538 A._priv_class_var = 0
1539 enddef
1540 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001541
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001542 var b = B.new()
1543 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001544 END
Ernie Rael03042a22023-11-11 08:53:32 +01001545 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001546
1547 # Access from child class extending a class and from script context
1548 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001549 vim9script
1550 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001551 static var ro_class_var = 10
1552 public static var rw_class_var = 20
1553 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001554 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001555
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001556 class B extends A
1557 def Foo()
1558 var x: number
1559 x = A.ro_class_var
1560 assert_equal(10, x)
1561 x = A.rw_class_var
1562 assert_equal(25, x)
1563 A.rw_class_var = 20
1564 assert_equal(20, A.rw_class_var)
1565 enddef
1566 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001567
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001568 assert_equal(10, A.ro_class_var)
1569 assert_equal(20, A.rw_class_var)
1570 A.rw_class_var = 25
1571 assert_equal(25, A.rw_class_var)
1572 var b = B.new()
1573 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001574 END
1575 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001576enddef
1577
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001578def Test_class_object_compare()
1579 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001580 vim9script
1581 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001582 var nr = 0
1583 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001584 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001585 END
1586
1587 # used at the script level and in a compiled function
1588 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001589 var i1 = Item.new()
1590 assert_equal(i1, i1)
1591 assert_true(i1 is i1)
1592 var i2 = Item.new()
1593 assert_equal(i1, i2)
1594 assert_false(i1 is i2)
1595 var i3 = Item.new(0, 'xx')
1596 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001598 var io1 = Item.new(1, 'xx')
1599 assert_notequal(i1, io1)
1600 var io2 = Item.new(0, 'yy')
1601 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001602 END
1603
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001604 v9.CheckSourceSuccess(class_lines + test_lines)
1605 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001606 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001607
1608 for op in ['>', '>=', '<', '<=', '=~', '!~']
1609 var op_lines = [
1610 'var i1 = Item.new()',
1611 'var i2 = Item.new()',
1612 'echo i1 ' .. op .. ' i2',
1613 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001614 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001615 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001616 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001617 endfor
1618enddef
1619
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001620def Test_object_type()
1621 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001622 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001623
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001624 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001625 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001626 endclass
1627 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001628 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001629 endclass
1630 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001631 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001632 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001633
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001634 var o: One = One.new()
1635 var t: Two = Two.new()
1636 var m: TwoMore = TwoMore.new()
1637 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001638
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001639 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001640 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001641 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001642
1643 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001644 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001645
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001646 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001647 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001648 endclass
1649 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001650 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001651 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001652
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001653 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001654 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001655 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001656
1657 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001658 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001659
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001660 interface One
1661 def GetMember(): number
1662 endinterface
1663 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001664 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001665 def GetMember(): number
1666 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001667 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001668 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001669
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001670 var o: One = Two.new(5)
1671 assert_equal(5, o.GetMember())
1672 END
1673 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001674
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001675 lines =<< trim END
1676 vim9script
1677
1678 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001679 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001680 endclass
1681
1682 def Ref(name: string): func(Num): Num
1683 return (arg: Num): Num => {
1684 return eval(name)(arg)
1685 }
1686 enddef
1687
1688 const Fn = Ref('Double')
1689 var Double = (m: Num): Num => Num.new(m.n * 2)
1690
1691 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001692 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001693 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001694enddef
1695
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001696def Test_class_member()
1697 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001698 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001699 vim9script
1700 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001701 var lnum = 1
1702 var col = 1
1703 static var counter = 0
1704 static var _secret = 7
1705 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001706
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001707 static def AddToCounter(nr: number)
1708 counter += nr
1709 enddef
1710 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001711
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001712 assert_equal(0, TextPos.counter)
1713 TextPos.AddToCounter(3)
1714 assert_equal(3, TextPos.counter)
1715 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001716
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001717 def GetCounter(): number
1718 return TextPos.counter
1719 enddef
1720 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001722 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1723 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1724 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001725
Ernie Rael03042a22023-11-11 08:53:32 +01001726 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1727 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001728
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001729 assert_equal(42, TextPos.anybody)
1730 TextPos.anybody = 12
1731 assert_equal(12, TextPos.anybody)
1732 TextPos.anybody += 5
1733 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001734 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001735 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001736
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001737 # example in the help
1738 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001739 vim9script
1740 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001741 var size: number
1742 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001743
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001744 def new(this.size)
1745 totalSize += this.size
1746 enddef
1747 endclass
1748 assert_equal(0, OtherThing.totalSize)
1749 var to3 = OtherThing.new(3)
1750 assert_equal(3, OtherThing.totalSize)
1751 var to7 = OtherThing.new(7)
1752 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001753 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001754 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001755
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001756 # using static class member twice
1757 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001758 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001760 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001761 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001762
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001763 static def MacroSubstitute(s: string): string
1764 return substitute(s, '{{author}}', author, 'gi')
1765 enddef
1766 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001767
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001768 assert_equal('some text', HTML.MacroSubstitute('some text'))
1769 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001770 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001771 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001772
Ernie Rael03042a22023-11-11 08:53:32 +01001773 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001774 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001775 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001776
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001777 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001778 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001779
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001780 def Add(n: number): number
1781 const F = (): number => this._x + n
1782 return F()
1783 enddef
1784 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001785
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001786 var foo = Foo.new()
1787 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001789 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001790
Ernie Rael03042a22023-11-11 08:53:32 +01001791 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001792 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001793 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001794
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001795 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001796 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001797
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001798 def Add(n: number): number
1799 var Lam = () => {
1800 this._x = this._x + n
1801 }
1802 Lam()
1803 return this._x
1804 enddef
1805 endclass
h-east2bd6a092023-05-19 19:01:17 +01001806
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001807 var foo = Foo.new()
1808 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001809 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001810 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001811
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001812 # check shadowing
1813 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001814 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001815
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001816 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001817 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001818 def Method(count: number)
1819 echo count
1820 enddef
1821 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001822
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001823 var s = Some.new()
1824 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001825 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001826 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001827
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001828 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001829 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001830 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001831
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001832 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001833 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001834 def Method(arg: number)
1835 var count = 3
1836 echo arg count
1837 enddef
1838 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001839
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001840 var s = Some.new()
1841 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001842 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001843 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001844
1845 # Test for using an invalid type for a member variable
1846 lines =<< trim END
1847 vim9script
1848 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001849 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001850 endclass
1851 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001852 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001853
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001854 # Test for setting a member on a null object
1855 lines =<< trim END
1856 vim9script
1857 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001858 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001859 endclass
1860
1861 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001862 var obj: A
1863 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001864 enddef
1865 F()
1866 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001867 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001868
1869 # Test for accessing a member on a null object
1870 lines =<< trim END
1871 vim9script
1872 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001873 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001874 endclass
1875
1876 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001877 var obj: A
1878 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001879 enddef
1880 F()
1881 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001882 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001883
1884 # Test for setting a member on a null object, at script level
1885 lines =<< trim END
1886 vim9script
1887 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001888 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001889 endclass
1890
1891 var obj: A
1892 obj.val = ""
1893 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001894 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001895
1896 # Test for accessing a member on a null object, at script level
1897 lines =<< trim END
1898 vim9script
1899 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001900 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001901 endclass
1902
1903 var obj: A
1904 echo obj.val
1905 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001906 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001907
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001908 # Test for no space before or after the '=' when initializing a member
1909 # variable
1910 lines =<< trim END
1911 vim9script
1912 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001913 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001914 endclass
1915 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001916 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001917 lines =<< trim END
1918 vim9script
1919 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001920 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001921 endclass
1922 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001923 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001924
1925 # Access a non-existing member
1926 lines =<< trim END
1927 vim9script
1928 class A
1929 endclass
1930 var a = A.new()
1931 var v = a.bar
1932 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001933 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001934enddef
1935
Ernie Raele6c9aa52023-10-06 19:55:52 +02001936" These messages should show the defining class of the variable (base class),
1937" not the class that did the reference (super class)
1938def Test_defining_class_message()
1939 var lines =<< trim END
1940 vim9script
1941
1942 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001943 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001944 endclass
1945
1946 class Child extends Base
1947 endclass
1948
1949 var o = Child.new()
1950 var x = o._v1
1951 END
Ernie Rael03042a22023-11-11 08:53:32 +01001952 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001953 lines =<< trim END
1954 vim9script
1955
1956 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001957 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001958 endclass
1959
1960 class Child extends Base
1961 endclass
1962
1963 def F()
1964 var o = Child.new()
1965 var x = o._v1
1966 enddef
1967 F()
1968 END
Ernie Rael03042a22023-11-11 08:53:32 +01001969 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001970 lines =<< trim END
1971 vim9script
1972
1973 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001974 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001975 endclass
1976
1977 class Child extends Base
1978 endclass
1979
1980 var o = Child.new()
1981 o.v1 = []
1982 END
1983 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1984 lines =<< trim END
1985 vim9script
1986
1987 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001988 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001989 endclass
1990
1991 class Child extends Base
1992 endclass
1993
1994 def F()
1995 var o = Child.new()
1996 o.v1 = []
1997 enddef
1998 F()
1999 END
2000
Ernie Rael03042a22023-11-11 08:53:32 +01002001 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02002002 # of the class hierarchy.
2003 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
2004 lines =<< trim END
2005 vim9script
2006
2007 class Base0
2008 endclass
2009
2010 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01002011 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002012 endclass
2013
2014 class Child extends Base
2015 endclass
2016
2017 def F()
2018 var o = Child.new()
2019 var x = o._v1
2020 enddef
2021 F()
2022 END
Ernie Rael03042a22023-11-11 08:53:32 +01002023 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002024
Ernie Rael03042a22023-11-11 08:53:32 +01002025 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02002026 # of the class hierarchy.
2027 lines =<< trim END
2028 vim9script
2029
2030 class Base0
2031 endclass
2032
2033 class Base extends Base0
2034 endclass
2035
2036 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002037 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002038 endclass
2039
2040 def F()
2041 var o = Child.new()
2042 var x = o._v1
2043 enddef
2044 F()
2045 END
Ernie Rael03042a22023-11-11 08:53:32 +01002046 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002047enddef
2048
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002049func Test_class_garbagecollect()
2050 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002051 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002052
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002053 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002054 var p = [2, 3]
2055 static var pl = ['a', 'b']
2056 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002057 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002058
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002059 echo Point.pl Point.pd
2060 call test_garbagecollect_now()
2061 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002062 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002063 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002064
2065 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002066 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002067
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002068 interface View
2069 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002070
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002071 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01002072 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002073 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002074
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002075 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01002076 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002077
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002078 def new()
2079 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01002080 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002081 enddef
2082 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002083
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002084 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002085
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002086 # overwrite "view", will be garbage-collected next
2087 view = MyView.new()
2088 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002089 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002090 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002091endfunc
2092
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002093" Test interface garbage collection
2094func Test_interface_garbagecollect()
2095 let lines =<< trim END
2096 vim9script
2097
2098 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002099 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002100
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002101 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002102 endinterface
2103
2104 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002105 static var ro_class_var: number = 10
2106 public static var rw_class_var: number = 20
2107 static var _priv_class_var: number = 30
2108 var ro_obj_var: number = 40
2109 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002110
2111 static def _ClassBar(): number
2112 return _priv_class_var
2113 enddef
2114
2115 static def ClassFoo(): number
2116 return ro_class_var + rw_class_var + A._ClassBar()
2117 enddef
2118
2119 def _ObjBar(): number
2120 return this._priv_obj_var
2121 enddef
2122
2123 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002124 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002125 enddef
2126 endclass
2127
2128 assert_equal(60, A.ClassFoo())
2129 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002130 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002131 test_garbagecollect_now()
2132 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002133 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002134 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002135 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002136endfunc
2137
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002138def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002139 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002140 vim9script
2141 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002142 var value = 0
2143 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002144
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002145 def new(v: number)
2146 this.value = v
2147 ++objects
2148 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002149
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002150 static def GetCount(): number
2151 return objects
2152 enddef
2153 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002154
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002155 assert_equal(0, Value.GetCount())
2156 var v1 = Value.new(2)
2157 assert_equal(1, Value.GetCount())
2158 var v2 = Value.new(7)
2159 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002160 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002161 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002162
2163 # Test for cleaning up after a class definition failure when using class
2164 # functions.
2165 lines =<< trim END
2166 vim9script
2167 class A
2168 static def Foo()
2169 enddef
2170 aaa
2171 endclass
2172 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002173 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002174
2175 # Test for calling a class method from another class method without the class
2176 # name prefix.
2177 lines =<< trim END
2178 vim9script
2179 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002180 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002181 static def Foo(n: number)
2182 myList->add(n)
2183 enddef
2184 static def Bar()
2185 Foo(2)
2186 enddef
2187 def Baz()
2188 Foo(3)
2189 enddef
2190 endclass
2191 A.Bar()
2192 var a = A.new()
2193 a.Baz()
2194 assert_equal([1, 2, 3], A.myList)
2195 END
2196 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002197enddef
2198
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002199def Test_class_defcompile()
2200 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002201 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 class C
2204 def Fo(i: number): string
2205 return i
2206 enddef
2207 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002208
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002209 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002210 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002211 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002212
2213 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002214 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002215
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002216 class C
2217 static def Fc(): number
2218 return 'x'
2219 enddef
2220 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002221
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002222 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002223 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002224 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002225
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002226 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002227 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002228
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002229 class C
2230 static def new()
2231 enddef
2232 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002233
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002234 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002235 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002236 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002237
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002238 # Trying to compile a function using a non-existing class variable
2239 lines =<< trim END
2240 vim9script
2241 defcompile x.Foo()
2242 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002243 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002244
2245 # Trying to compile a function using a variable which is not a class
2246 lines =<< trim END
2247 vim9script
2248 var x: number
2249 defcompile x.Foo()
2250 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002251 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002252
2253 # Trying to compile a function without specifying the name
2254 lines =<< trim END
2255 vim9script
2256 class A
2257 endclass
2258 defcompile A.
2259 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002260 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002261
2262 # Trying to compile a non-existing class object member function
2263 lines =<< trim END
2264 vim9script
2265 class A
2266 endclass
2267 var a = A.new()
2268 defcompile a.Foo()
2269 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002270 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002271enddef
2272
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002273def Test_class_object_to_string()
2274 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002275 vim9script
2276 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002277 var lnum = 1
2278 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002279 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002280
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002281 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002282
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002283 var pos = TextPosition.new()
2284 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002285 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002286 v9.CheckSourceSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +02002287
2288 # check string() with object nesting
2289 lines =<< trim END
2290 vim9script
2291 class C
2292 var nest1: C
2293 var nest2: C
2294 def Init(n1: C, n2: C)
2295 this.nest1 = n1
2296 this.nest2 = n2
2297 enddef
2298 endclass
2299
2300 var o1 = C.new()
2301 var o2 = C.new()
2302 o1.Init(o1, o2)
2303 o2.Init(o2, o1)
2304
2305 # The following previously put's vim into an infinite loop.
2306
2307 var expect = "object of C {nest1: object of C {...}, nest2: object of C {nest1: object of C {...}, nest2: object of C {...}}}"
2308 assert_equal(expect, string(o1))
2309 END
2310 v9.CheckSourceSuccess(lines)
2311
2312 lines =<< trim END
2313 vim9script
2314
2315 class B
2316 endclass
2317
2318 class C
2319 var b: B
2320 var c: C
2321 endclass
2322
2323 var o1 = C.new(B.new(), C.new(B.new()))
2324 var expect = "object of C {b: object of B {}, c: object of C {b: object of B {}, c: object of [unknown]}}"
2325 assert_equal(expect, string(o1))
2326 END
2327 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002328enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002329
Bram Moolenaar554d0312023-01-05 19:59:18 +00002330def Test_interface_basics()
2331 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002332 vim9script
2333 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002334 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002335 def GetCount(): number
2336 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002337 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002338 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002339
2340 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002341 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002342 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002343 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002344 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002345 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002346
2347 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002348 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002349
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002350 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002351 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002352 def Method(value: number)
2353 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002354 END
h-east61378a12023-04-18 19:07:29 +01002355 # The argument name and the object member name are the same, but this is not a
2356 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002357 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002358
2359 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002360 vim9script
2361 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002362 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002363 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002364 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002365 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002366
2367 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002368 vim9script
2369 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002370 var value: string
2371 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002372 def GetCount(): number
2373 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002374 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002375 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002376
2377 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002378 vim9script
2379 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002380 var value: string
2381 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 def GetCount(): number
2383 return 5
2384 enddef
2385 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002386 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002387 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002388
Yegappan Lakshmananac773182024-04-27 11:36:12 +02002389 # Additional commands after "interface name"
2390 lines =<< trim END
2391 vim9script
2392 interface Something | var x = 10 | var y = 20
2393 endinterface
2394 END
2395 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
2396
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002397 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002398 vim9script
2399 export interface EnterExit
2400 def Enter(): void
2401 def Exit(): void
2402 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002403 END
2404 writefile(lines, 'XdefIntf.vim', 'D')
2405
2406 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002407 vim9script
2408 import './XdefIntf.vim' as defIntf
2409 export def With(ee: defIntf.EnterExit, F: func)
2410 ee.Enter()
2411 try
2412 F()
2413 finally
2414 ee.Exit()
2415 endtry
2416 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002417 END
2418 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002419
2420 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002421 vim9script
2422 export abstract class EnterExit
2423 def Enter(): void
2424 enddef
2425 def Exit(): void
2426 enddef
2427 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002428 END
2429 writefile(imported, 'XdefIntf2.vim', 'D')
2430
2431 lines[1] = " import './XdefIntf2.vim' as defIntf"
2432 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002433enddef
2434
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002435" Test for using string() with an interface
2436def Test_interface_to_string()
2437 var lines =<< trim END
2438 vim9script
2439 interface Intf
2440 def Method(nr: number)
2441 endinterface
2442 assert_equal("interface Intf", string(Intf))
2443 END
2444 v9.CheckSourceSuccess(lines)
2445enddef
2446
Bram Moolenaar94674f22023-01-06 18:42:20 +00002447def Test_class_implements_interface()
2448 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002449 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002450
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002451 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002452 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002453 def Method(nr: number)
2454 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002455
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002456 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002457 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002458 def Method(nr: number)
2459 echo nr
2460 enddef
2461 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002462
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002463 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002464 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002465 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002466
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002467 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002468 var member = 'abc'
2469 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002470 def Method(nr: number)
2471 echo nr
2472 enddef
2473 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002474 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002475 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002476
2477 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002478 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +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 implements 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, 'E1350: Duplicate "implements"', 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 count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002495 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002496
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002497 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002498 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002499 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002500 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002501 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002502
2503 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002504 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002505
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002506 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002507 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002508 def Method(nr: number)
2509 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002510
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002511 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002512 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002513 def Method(nr: number)
2514 echo nr
2515 enddef
2516 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002517 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002518 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002519
2520 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002521 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002522
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002523 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002524 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002525 def Methods(nr: number)
2526 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002527
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002528 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002529 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002530 def Method(nr: number)
2531 echo nr
2532 enddef
2533 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002534 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002535 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002536
2537 # Check different order of members in class and interface works.
2538 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002539 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002540
2541 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002542 var label: string
2543 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002544 endinterface
2545
2546 # order of members is opposite of interface
2547 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002548 public var lnum: number = 5
2549 var errpos: number = 42
2550 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002551 endclass
2552
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002553 def Test()
2554 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002555
2556 assert_equal('label', result.label)
2557 assert_equal(42, result.errpos)
2558 enddef
2559
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002560 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002561 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002562 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002563
2564 # Interface name after "extends" doesn't end in a space or NUL character
2565 lines =<< trim END
2566 vim9script
2567 interface A
2568 endinterface
2569 class B extends A"
2570 endclass
2571 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002572 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002573
2574 # Trailing characters after a class name
2575 lines =<< trim END
2576 vim9script
2577 class A bbb
2578 endclass
2579 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002580 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002581
2582 # using "implements" with a non-existing class
2583 lines =<< trim END
2584 vim9script
2585 class A implements B
2586 endclass
2587 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002588 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002589
2590 # using "implements" with a regular class
2591 lines =<< trim END
2592 vim9script
2593 class A
2594 endclass
2595 class B implements A
2596 endclass
2597 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002598 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002599
2600 # using "implements" with a variable
2601 lines =<< trim END
2602 vim9script
2603 var T: number = 10
2604 class A implements T
2605 endclass
2606 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002607 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002608
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002609 # implements should be followed by a white space
2610 lines =<< trim END
2611 vim9script
2612 interface A
2613 endinterface
2614 class B implements A;
2615 endclass
2616 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002617 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002618
LemonBoyc5d27442023-08-19 13:02:35 +02002619 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: number): string
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(number): string', 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: bool): 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(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002644
2645 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002646 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002647
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002648 interface One
2649 def IsEven(nr: number): bool
2650 endinterface
2651 class Two implements One
2652 def IsEven(nr: number, ...extra: list<number>): bool
2653 enddef
2654 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002655 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002656 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 +02002657
2658 # access superclass interface members from subclass, mix variable order
2659 lines =<< trim END
2660 vim9script
2661
2662 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002663 var mvar1: number
2664 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002665 endinterface
2666
2667 # NOTE: the order is swapped
2668 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002669 var mvar2: number
2670 var mvar1: number
2671 public static var svar2: number
2672 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002673 def new()
2674 svar1 = 11
2675 svar2 = 12
2676 this.mvar1 = 111
2677 this.mvar2 = 112
2678 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002679 endclass
2680
2681 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002682 def new()
2683 this.mvar1 = 121
2684 this.mvar2 = 122
2685 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002686 endclass
2687
2688 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002689 def new()
2690 this.mvar1 = 131
2691 this.mvar2 = 132
2692 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002693 endclass
2694
Ernie Raelcf138d42023-09-06 20:45:03 +02002695 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002696 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002697 enddef
2698
2699 var oa = A.new()
2700 var ob = B.new()
2701 var oc = C.new()
2702
Ernie Raelcf138d42023-09-06 20:45:03 +02002703 assert_equal([111, 112], F2(oa))
2704 assert_equal([121, 122], F2(ob))
2705 assert_equal([131, 132], F2(oc))
2706 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002707 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002708
2709 # Access superclass interface members from subclass, mix variable order.
2710 # Two interfaces, one on A, one on B; each has both kinds of variables
2711 lines =<< trim END
2712 vim9script
2713
2714 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002715 var mvar1: number
2716 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002717 endinterface
2718
2719 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002720 var mvar3: number
2721 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002722 endinterface
2723
2724 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002725 public static var svar1: number
2726 public static var svar2: number
2727 var mvar1: number
2728 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002729 def new()
2730 svar1 = 11
2731 svar2 = 12
2732 this.mvar1 = 111
2733 this.mvar2 = 112
2734 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002735 endclass
2736
2737 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002738 static var svar3: number
2739 static var svar4: number
2740 var mvar3: number
2741 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002742 def new()
2743 svar3 = 23
2744 svar4 = 24
2745 this.mvar1 = 121
2746 this.mvar2 = 122
2747 this.mvar3 = 123
2748 this.mvar4 = 124
2749 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002750 endclass
2751
2752 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002753 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002754 def new()
2755 svar5 = 1001
2756 this.mvar1 = 131
2757 this.mvar2 = 132
2758 this.mvar3 = 133
2759 this.mvar4 = 134
2760 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002761 endclass
2762
Ernie Raelcf138d42023-09-06 20:45:03 +02002763 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002764 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002765 enddef
2766
Ernie Raelcf138d42023-09-06 20:45:03 +02002767 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002768 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002769 enddef
2770
Ernie Raelcf138d42023-09-06 20:45:03 +02002771 var oa = A.new()
2772 var ob = B.new()
2773 var oc = C.new()
2774
Ernie Raelcf138d42023-09-06 20:45:03 +02002775 assert_equal([[111, 112]], [F2(oa)])
2776 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2777 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002778 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002779 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002780
2781 # Using two interface names without a space after the ","
2782 lines =<< trim END
2783 vim9script
2784 interface A
2785 endinterface
2786 interface B
2787 endinterface
2788 class C implements A,B
2789 endclass
2790 END
2791 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2792
2793 # No interface name after a comma
2794 lines =<< trim END
2795 vim9script
2796 interface A
2797 endinterface
2798 class B implements A,
2799 endclass
2800 END
2801 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2802
2803 # No interface name after implements
2804 lines =<< trim END
2805 vim9script
2806 class A implements
2807 endclass
2808 END
2809 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002810enddef
2811
Bram Moolenaard0200c82023-01-28 15:19:40 +00002812def Test_call_interface_method()
2813 var lines =<< trim END
2814 vim9script
2815 interface Base
2816 def Enter(): void
2817 endinterface
2818
2819 class Child implements Base
2820 def Enter(): void
2821 g:result ..= 'child'
2822 enddef
2823 endclass
2824
2825 def F(obj: Base)
2826 obj.Enter()
2827 enddef
2828
2829 g:result = ''
2830 F(Child.new())
2831 assert_equal('child', g:result)
2832 unlet g:result
2833 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002834 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002835
2836 lines =<< trim END
2837 vim9script
2838 class Base
2839 def Enter(): void
2840 g:result ..= 'base'
2841 enddef
2842 endclass
2843
2844 class Child extends Base
2845 def Enter(): void
2846 g:result ..= 'child'
2847 enddef
2848 endclass
2849
2850 def F(obj: Base)
2851 obj.Enter()
2852 enddef
2853
2854 g:result = ''
2855 F(Child.new())
2856 assert_equal('child', g:result)
2857 unlet g:result
2858 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002859 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002860
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002861 # method of interface returns a value
2862 lines =<< trim END
2863 vim9script
2864 interface Base
2865 def Enter(): string
2866 endinterface
2867
2868 class Child implements Base
2869 def Enter(): string
2870 g:result ..= 'child'
2871 return "/resource"
2872 enddef
2873 endclass
2874
2875 def F(obj: Base)
2876 var r = obj.Enter()
2877 g:result ..= r
2878 enddef
2879
2880 g:result = ''
2881 F(Child.new())
2882 assert_equal('child/resource', g:result)
2883 unlet g:result
2884 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002885 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002886
2887 lines =<< trim END
2888 vim9script
2889 class Base
2890 def Enter(): string
2891 return null_string
2892 enddef
2893 endclass
2894
2895 class Child extends Base
2896 def Enter(): string
2897 g:result ..= 'child'
2898 return "/resource"
2899 enddef
2900 endclass
2901
2902 def F(obj: Base)
2903 var r = obj.Enter()
2904 g:result ..= r
2905 enddef
2906
2907 g:result = ''
2908 F(Child.new())
2909 assert_equal('child/resource', g:result)
2910 unlet g:result
2911 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002912 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002913
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002914 # No class that implements the interface.
2915 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002916 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002917
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002918 interface IWithEE
2919 def Enter(): any
2920 def Exit(): void
2921 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002922
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002923 def With1(ee: IWithEE, F: func)
2924 var r = ee.Enter()
2925 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002926
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002927 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002928 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002929 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002930enddef
2931
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002932def Test_class_used_as_type()
2933 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002934 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002935
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002936 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002937 var x = 0
2938 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002939 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002940
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002941 var p: Point
2942 p = Point.new(2, 33)
2943 assert_equal(2, p.x)
2944 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002945 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002946 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002947
2948 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002949 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002950
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002951 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002952 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002953 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002954
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002955 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002956 var x = 0
2957 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002958 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002959
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002960 var p: Point
2961 p = Point.new(2, 33)
2962 var hx = p
2963 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002964 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002965 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002966
2967 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002968 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002969
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002970 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002971 var x = 0
2972 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002973 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002974
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002975 var p: Point
2976 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002977 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002978 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002979enddef
2980
Bram Moolenaar83677162023-01-08 19:54:10 +00002981def Test_class_extends()
2982 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002983 vim9script
2984 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002985 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002986 def GetOne(): number
2987 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002988 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002989 endclass
2990 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002991 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002992 def GetTotal(): number
2993 return this.one + this.two
2994 enddef
2995 endclass
2996 var o = Child.new()
2997 assert_equal(1, o.one)
2998 assert_equal(2, o.two)
2999 assert_equal(1, o.GetOne())
3000 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00003001 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003002 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00003003
3004 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003005 vim9script
3006 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003007 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003008 endclass
3009 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003010 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003011 endclass
3012 var o = Child.new(3, 44)
3013 assert_equal(3, o.one)
3014 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00003015 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003016 v9.CheckSourceSuccess(lines)
3017
3018 lines =<< trim END
3019 vim9script
3020 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003021 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003022 endclass
3023 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003024 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003025 endclass
3026 END
3027 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
3028
3029 lines =<< trim END
3030 vim9script
3031 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01003032 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003033 endclass
3034 END
3035 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
3036
3037 lines =<< trim END
3038 vim9script
3039 var SomeVar = 99
3040 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01003041 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003042 endclass
3043 END
3044 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
3045
3046 lines =<< trim END
3047 vim9script
3048 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003049 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003050 def ToString(): string
3051 return this.name
3052 enddef
3053 endclass
3054
3055 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003056 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003057 def ToString(): string
3058 return super.ToString() .. ': ' .. this.age
3059 enddef
3060 endclass
3061
3062 var o = Child.new('John', 42)
3063 assert_equal('John: 42', o.ToString())
3064 END
3065 v9.CheckSourceSuccess(lines)
3066
3067 lines =<< trim END
3068 vim9script
3069 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003070 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003071 def ToString(): number
3072 return this.age
3073 enddef
3074 def ToString(): string
3075 return this.age
3076 enddef
3077 endclass
3078 END
3079 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
3080
3081 lines =<< trim END
3082 vim9script
3083 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003084 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003085 def ToString(): string
3086 return super .ToString() .. ': ' .. this.age
3087 enddef
3088 endclass
3089 var o = Child.new(42)
3090 echo o.ToString()
3091 END
3092 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
3093
3094 lines =<< trim END
3095 vim9script
3096 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003097 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003098 def ToString(): string
3099 return this.name
3100 enddef
3101 endclass
3102
3103 var age = 42
3104 def ToString(): string
3105 return super.ToString() .. ': ' .. age
3106 enddef
3107 echo ToString()
3108 END
3109 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
3110
3111 lines =<< trim END
3112 vim9script
3113 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003114 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003115 def ToString(): string
3116 return super.ToString() .. ': ' .. this.age
3117 enddef
3118 endclass
3119 var o = Child.new(42)
3120 echo o.ToString()
3121 END
3122 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
3123
3124 lines =<< trim END
3125 vim9script
3126 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003127 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003128 static def ToString(): string
3129 return 'Base class'
3130 enddef
3131 endclass
3132
3133 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003134 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003135 def ToString(): string
3136 return Base.ToString() .. ': ' .. this.age
3137 enddef
3138 endclass
3139
3140 var o = Child.new('John', 42)
3141 assert_equal('Base class: 42', o.ToString())
3142 END
3143 v9.CheckSourceSuccess(lines)
3144
3145 lines =<< trim END
3146 vim9script
3147 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003148 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003149 def new(init: number)
3150 this.value = number + 1
3151 enddef
3152 endclass
3153 class Child extends Base
3154 def new()
3155 this.new(3)
3156 enddef
3157 endclass
3158 var c = Child.new()
3159 END
3160 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003161
3162 # base class with more than one object member
3163 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003164 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003165
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003166 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003167 var success: bool
3168 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003169 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003170
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003171 class Success extends Result
3172 def new(this.value = v:none)
3173 this.success = true
3174 enddef
3175 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003176
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003177 var v = Success.new('asdf')
3178 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003179 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003180 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003181
3182 # class name after "extends" doesn't end in a space or NUL character
3183 lines =<< trim END
3184 vim9script
3185 class A
3186 endclass
3187 class B extends A"
3188 endclass
3189 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003190 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003191enddef
3192
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003193def Test_using_base_class()
3194 var lines =<< trim END
3195 vim9script
3196
3197 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003198 def Enter(): any
3199 return null
3200 enddef
3201 def Exit(resource: any): void
3202 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003203 endclass
3204
3205 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003206 def Enter(): any
3207 return 42
3208 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003209
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003210 def Exit(resource: number): void
3211 g:result ..= '/exit'
3212 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003213 endclass
3214
3215 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003216 var r = ee.Enter()
3217 try
3218 g:result ..= r
3219 finally
3220 g:result ..= '/finally'
3221 ee.Exit(r)
3222 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003223 enddef
3224
3225 g:result = ''
3226 With(ChildEE.new())
3227 assert_equal('42/finally/exit', g:result)
3228 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003229 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003230 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003231
3232 # Using super, Child invokes Base method which has optional arg. #12471
3233 lines =<< trim END
3234 vim9script
3235
3236 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003237 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003238 def Method(arg = 0)
3239 this.success = true
3240 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003241 endclass
3242
3243 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003244 def new()
3245 super.Method()
3246 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003247 endclass
3248
3249 var obj = Child.new()
3250 assert_equal(true, obj.success)
3251 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003252 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003253enddef
3254
Bram Moolenaara86655a2023-01-12 17:06:27 +00003255def Test_class_import()
3256 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003257 vim9script
3258 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003259 var kind: string
3260 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003261 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003262 END
3263 writefile(lines, 'Xanimal.vim', 'D')
3264
3265 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003266 vim9script
3267 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003268
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003269 var a: animal.Animal
3270 a = animal.Animal.new('fish', 'Eric')
3271 assert_equal('fish', a.kind)
3272 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003273
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003274 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3275 assert_equal('cat', b.kind)
3276 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003277 END
3278 v9.CheckScriptSuccess(lines)
3279enddef
3280
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003281" Test for importing a class into a legacy script and calling the class method
3282def Test_class_method_from_legacy_script()
3283 var lines =<< trim END
3284 vim9script
3285 export class A
3286 static var name: string = 'a'
3287 static def SetName(n: string)
3288 name = n
3289 enddef
3290 endclass
3291 END
3292 writefile(lines, 'Xvim9export.vim', 'D')
3293
3294 lines =<< trim END
3295 import './Xvim9export.vim' as vim9
3296
3297 call s:vim9.A.SetName('b')
3298 call assert_equal('b', s:vim9.A.name)
3299 END
3300 v9.CheckScriptSuccess(lines)
3301enddef
3302
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003303" Test for implementing an imported interface
3304def Test_implement_imported_interface()
3305 var lines =<< trim END
3306 vim9script
3307 export interface Imp_Intf1
3308 def Fn1(): number
3309 endinterface
3310 export interface Imp_Intf2
3311 def Fn2(): number
3312 endinterface
3313 END
3314 writefile(lines, 'Ximportinterface.vim', 'D')
3315
3316 lines =<< trim END
3317 vim9script
3318 import './Ximportinterface.vim' as Xintf
3319
3320 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3321 def Fn1(): number
3322 return 10
3323 enddef
3324 def Fn2(): number
3325 return 20
3326 enddef
3327 endclass
3328 var a = A.new()
3329 assert_equal(10, a.Fn1())
3330 assert_equal(20, a.Fn2())
3331 END
3332 v9.CheckScriptSuccess(lines)
3333enddef
3334
3335" Test for extending an imported class
3336def Test_extend_imported_class()
3337 var lines =<< trim END
3338 vim9script
3339 export class Imp_C1
3340 def Fn1(): number
3341 return 5
3342 enddef
3343 endclass
3344 END
3345 writefile(lines, 'Xextendimportclass.vim', 'D')
3346
3347 lines =<< trim END
3348 vim9script
3349 import './Xextendimportclass.vim' as XClass
3350
3351 class A extends XClass.Imp_C1
3352 endclass
3353 var a = A.new()
3354 assert_equal(5, a.Fn1())
3355 END
3356 v9.CheckScriptSuccess(lines)
3357enddef
3358
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003359def Test_abstract_class()
3360 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003361 vim9script
3362 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003363 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003364 endclass
3365 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003366 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003367 endclass
3368 var p: Base = Person.new('Peter', 42)
3369 assert_equal('Peter', p.name)
3370 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003371 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003372 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003373
3374 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003375 vim9script
3376 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003377 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003378 endclass
3379 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003380 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003381 endclass
3382 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003383 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003384 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003385
3386 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003387 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003388 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003389 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003390 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003391 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003392
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003393 # Additional commands after "abstract class"
3394 lines =<< trim END
3395 vim9script
3396 abstract class Something | var x = []
3397 endclass
3398 END
3399 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3400
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003401 # Abstract class cannot have a "new" function
3402 lines =<< trim END
3403 vim9script
3404 abstract class Base
3405 def new()
3406 enddef
3407 endclass
3408 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003409 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003410
3411 # extending an abstract class with class methods and variables
3412 lines =<< trim END
3413 vim9script
3414 abstract class A
3415 static var s: string = 'vim'
3416 static def Fn(): list<number>
3417 return [10]
3418 enddef
3419 endclass
3420 class B extends A
3421 endclass
3422 var b = B.new()
3423 assert_equal('vim', A.s)
3424 assert_equal([10], A.Fn())
3425 END
3426 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003427enddef
3428
Bram Moolenaar486fc252023-01-18 14:51:07 +00003429def Test_closure_in_class()
3430 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003431 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003432
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003433 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003434 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003435
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003436 def new()
3437 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3438 enddef
3439 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003440
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003441 Foo.new()
3442 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003443 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003444 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003445enddef
3446
Ernie Rael9ed53752023-12-11 17:40:46 +01003447def Test_construct_object_from_legacy()
3448 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003449 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003450 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003451
Ernie Rael9ed53752023-12-11 17:40:46 +01003452 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003453
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003454 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003455 def new(arg: string)
3456 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003457 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003458 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003459
Ernie Rael9ed53752023-12-11 17:40:46 +01003460 export def CreateA(...args: list<any>): A
3461 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003462 enddef
3463
Ernie Rael9ed53752023-12-11 17:40:46 +01003464 g:P = CreateA
3465 legacy call g:P('some_arg')
3466 assert_equal(true, newCalled)
3467 unlet g:P
3468 END
3469 v9.CheckSourceSuccess(lines)
3470
3471 lines =<< trim END
3472 vim9script
3473
3474 var newCalled = false
3475
3476 class A
3477 static def CreateA(options = {}): any
3478 return A.new()
3479 enddef
3480 def new()
3481 newCalled = true
3482 enddef
3483 endclass
3484
3485 g:P = A.CreateA
3486 legacy call g:P()
3487 assert_equal(true, newCalled)
3488 unlet g:P
3489 END
3490 v9.CheckSourceSuccess(lines)
3491
3492 # This also tests invoking "new()" with "call"
3493 lines =<< trim END
3494 vim9script
3495
3496 var createdObject: any
3497
3498 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003499 var val1: number
3500 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003501 static def CreateA(...args: list<any>): any
3502 createdObject = call(A.new, args)
3503 return createdObject
3504 enddef
3505 endclass
3506
3507 g:P = A.CreateA
3508 legacy call g:P(3, 5)
3509 assert_equal(3, createdObject.val1)
3510 assert_equal(5, createdObject.val2)
3511 legacy call g:P()
3512 assert_equal(0, createdObject.val1)
3513 assert_equal(0, createdObject.val2)
3514 legacy call g:P(7)
3515 assert_equal(7, createdObject.val1)
3516 assert_equal(0, createdObject.val2)
3517 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003518 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003519 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003520enddef
3521
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003522def Test_defer_with_object()
3523 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003524 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003525
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003526 class CWithEE
3527 def Enter()
3528 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003529 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003530 def Exit()
3531 g:result ..= "exited"
3532 enddef
3533 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003534
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003535 def With(ee: CWithEE, F: func)
3536 ee.Enter()
3537 defer ee.Exit()
3538 F()
3539 enddef
3540
3541 g:result = ''
3542 var obj = CWithEE.new()
3543 obj->With(() => {
3544 g:result ..= "called/"
3545 })
3546 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003547 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003548 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003549 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003550
3551 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003552 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003554 class BaseWithEE
3555 def Enter()
3556 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003557 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003558 def Exit()
3559 g:result ..= "exited-base"
3560 enddef
3561 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003562
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003563 class CWithEE extends BaseWithEE
3564 def Enter()
3565 g:result ..= "entered-child/"
3566 enddef
3567 def Exit()
3568 g:result ..= "exited-child"
3569 enddef
3570 endclass
3571
3572 def With(ee: BaseWithEE, F: func)
3573 ee.Enter()
3574 defer ee.Exit()
3575 F()
3576 enddef
3577
3578 g:result = ''
3579 var obj = CWithEE.new()
3580 obj->With(() => {
3581 g:result ..= "called/"
3582 })
3583 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003584 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003585 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003586 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003587enddef
3588
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003589" The following test used to crash Vim (Github issue #12676)
3590def Test_extends_method_crashes_vim()
3591 var lines =<< trim END
3592 vim9script
3593
3594 class Observer
3595 endclass
3596
3597 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003598 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003599
3600 def Set(v: any)
3601 if v != this.value
3602 this.value = v
3603 endif
3604 enddef
3605
3606 def Register(observer: Observer)
3607 enddef
3608 endclass
3609
3610 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003611 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003612 endclass
3613
3614 def Observe(obj: Property, who: Observer)
3615 obj.Register(who)
3616 enddef
3617
3618 var p = Bool.new(false)
3619 var myObserver = Observer.new()
3620
3621 Observe(p, myObserver)
3622
3623 p.Set(true)
3624 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003625 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003626enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003627
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003628" Test for calling a method in a class that is extended
3629def Test_call_method_in_extended_class()
3630 var lines =<< trim END
3631 vim9script
3632
3633 var prop_init_called = false
3634 var prop_register_called = false
3635
3636 class Property
3637 def Init()
3638 prop_init_called = true
3639 enddef
3640
3641 def Register()
3642 prop_register_called = true
3643 enddef
3644 endclass
3645
3646 class Bool extends Property
3647 endclass
3648
3649 def Observe(obj: Property)
3650 obj.Register()
3651 enddef
3652
3653 var p = Property.new()
3654 Observe(p)
3655
3656 p.Init()
3657 assert_true(prop_init_called)
3658 assert_true(prop_register_called)
3659 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003660 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003661enddef
3662
LemonBoyafe04662023-08-23 21:08:11 +02003663def Test_instanceof()
3664 var lines =<< trim END
3665 vim9script
3666
3667 class Base1
3668 endclass
3669
3670 class Base2 extends Base1
3671 endclass
3672
3673 interface Intf1
3674 endinterface
3675
3676 class Mix1 implements Intf1
3677 endclass
3678
3679 class Base3 extends Mix1
3680 endclass
3681
Ernie Rael2025af12023-12-12 16:58:00 +01003682 type AliasBase1 = Base1
3683 type AliasBase2 = Base2
3684 type AliasIntf1 = Intf1
3685 type AliasMix1 = Mix1
3686
LemonBoyafe04662023-08-23 21:08:11 +02003687 var b1 = Base1.new()
3688 var b2 = Base2.new()
3689 var b3 = Base3.new()
3690
3691 assert_true(instanceof(b1, Base1))
3692 assert_true(instanceof(b2, Base1))
3693 assert_false(instanceof(b1, Base2))
3694 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003695 assert_true(instanceof(b3, Base1, Base2, Intf1))
3696
3697 assert_true(instanceof(b1, AliasBase1))
3698 assert_true(instanceof(b2, AliasBase1))
3699 assert_false(instanceof(b1, AliasBase2))
3700 assert_true(instanceof(b3, AliasMix1))
3701 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003702
3703 def Foo()
3704 var a1 = Base1.new()
3705 var a2 = Base2.new()
3706 var a3 = Base3.new()
3707
3708 assert_true(instanceof(a1, Base1))
3709 assert_true(instanceof(a2, Base1))
3710 assert_false(instanceof(a1, Base2))
3711 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003712 assert_true(instanceof(a3, Base1, Base2, Intf1))
3713
3714 assert_true(instanceof(a1, AliasBase1))
3715 assert_true(instanceof(a2, AliasBase1))
3716 assert_false(instanceof(a1, AliasBase2))
3717 assert_true(instanceof(a3, AliasMix1))
3718 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003719 enddef
3720 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003721
3722 var o_null: Base1
3723 assert_false(instanceof(o_null, Base1))
3724
LemonBoyafe04662023-08-23 21:08:11 +02003725 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003726 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003727
3728 lines =<< trim END
3729 vim9script
3730
3731 class Base1
3732 endclass
3733 instanceof(Base1.new())
3734 END
3735 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3736
3737 lines =<< trim END
3738 vim9script
3739
3740 class Base1
3741 endclass
3742 def F()
3743 instanceof(Base1.new())
3744 enddef
3745 F()
3746 END
3747 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3748
3749 lines =<< trim END
3750 vim9script
3751
3752 class Base1
3753 endclass
3754
3755 class Base2
3756 endclass
3757
3758 var o = Base2.new()
3759 instanceof(o, Base1, Base2, 3)
3760 END
3761 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3762
3763 lines =<< trim END
3764 vim9script
3765
3766 class Base1
3767 endclass
3768
3769 class Base2
3770 endclass
3771
3772 def F()
3773 var o = Base2.new()
3774 instanceof(o, Base1, Base2, 3)
3775 enddef
3776 F()
3777 END
3778 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003779enddef
3780
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003781" Test for calling a method in the parent class that is extended partially.
3782" This used to fail with the 'E118: Too many arguments for function: Text' error
3783" message (Github issue #12524).
3784def Test_call_method_in_parent_class()
3785 var lines =<< trim END
3786 vim9script
3787
3788 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003789 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003790
3791 def SetY(lnum: number)
3792 this._lnum = lnum
3793 enddef
3794
3795 def Text(): string
3796 return ''
3797 enddef
3798 endclass
3799
3800 class Foo extends Widget
3801 def Text(): string
3802 return '<Foo>'
3803 enddef
3804 endclass
3805
3806 def Stack(w1: Widget, w2: Widget): list<Widget>
3807 w1.SetY(1)
3808 w2.SetY(2)
3809 return [w1, w2]
3810 enddef
3811
3812 var foo1 = Foo.new()
3813 var foo2 = Foo.new()
3814 var l = Stack(foo1, foo2)
3815 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003816 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003817enddef
3818
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003819" Test for calling methods from three levels of classes
3820def Test_multi_level_method_call()
3821 var lines =<< trim END
3822 vim9script
3823
3824 var A_func1: number = 0
3825 var A_func2: number = 0
3826 var A_func3: number = 0
3827 var B_func2: number = 0
3828 var B_func3: number = 0
3829 var C_func3: number = 0
3830
3831 class A
3832 def Func1()
3833 A_func1 += 1
3834 enddef
3835
3836 def Func2()
3837 A_func2 += 1
3838 enddef
3839
3840 def Func3()
3841 A_func3 += 1
3842 enddef
3843 endclass
3844
3845 class B extends A
3846 def Func2()
3847 B_func2 += 1
3848 enddef
3849
3850 def Func3()
3851 B_func3 += 1
3852 enddef
3853 endclass
3854
3855 class C extends B
3856 def Func3()
3857 C_func3 += 1
3858 enddef
3859 endclass
3860
3861 def A_CallFuncs(a: A)
3862 a.Func1()
3863 a.Func2()
3864 a.Func3()
3865 enddef
3866
3867 def B_CallFuncs(b: B)
3868 b.Func1()
3869 b.Func2()
3870 b.Func3()
3871 enddef
3872
3873 def C_CallFuncs(c: C)
3874 c.Func1()
3875 c.Func2()
3876 c.Func3()
3877 enddef
3878
3879 var cobj = C.new()
3880 A_CallFuncs(cobj)
3881 B_CallFuncs(cobj)
3882 C_CallFuncs(cobj)
3883 assert_equal(3, A_func1)
3884 assert_equal(0, A_func2)
3885 assert_equal(0, A_func3)
3886 assert_equal(3, B_func2)
3887 assert_equal(0, B_func3)
3888 assert_equal(3, C_func3)
3889 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003890 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003891enddef
3892
3893" Test for using members from three levels of classes
3894def Test_multi_level_member_access()
3895 var lines =<< trim END
3896 vim9script
3897
3898 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003899 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003900 endclass
3901
3902 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003903 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003904 endclass
3905
3906 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003907 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003908 endclass
3909
3910 def A_members(a: A)
3911 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003912 enddef
3913
3914 def B_members(b: B)
3915 b.val1 += 1
3916 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003917 enddef
3918
3919 def C_members(c: C)
3920 c.val1 += 1
3921 c.val2 += 1
3922 c.val3 += 1
3923 enddef
3924
3925 var cobj = C.new()
3926 A_members(cobj)
3927 B_members(cobj)
3928 C_members(cobj)
3929 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003930 assert_equal(2, cobj.val2)
3931 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003932 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003933 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003934enddef
3935
LemonBoy0ffc17a2023-08-20 18:09:11 +02003936" Test expansion of <stack> with class methods.
3937def Test_stack_expansion_with_methods()
3938 var lines =<< trim END
3939 vim9script
3940
3941 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003942 def M1()
3943 F0()
3944 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003945 endclass
3946
3947 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02003948 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02003949 enddef
3950
3951 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003952 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003953 enddef
3954
3955 F()
3956 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003957 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003958enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003959
3960" Test the return type of the new() constructor
3961def Test_new_return_type()
3962 # new() uses the default return type and there is no return statement
3963 var lines =<< trim END
3964 vim9script
3965
3966 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003967 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003968
3969 def new(this._bufnr)
3970 if !bufexists(this._bufnr)
3971 this._bufnr = -1
3972 endif
3973 enddef
3974 endclass
3975
3976 var c = C.new(12345)
3977 assert_equal('object<C>', typename(c))
3978
3979 var v1: C
3980 v1 = C.new(12345)
3981 assert_equal('object<C>', typename(v1))
3982
3983 def F()
3984 var v2: C
3985 v2 = C.new(12345)
3986 assert_equal('object<C>', typename(v2))
3987 enddef
3988 F()
3989 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003990 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003991
3992 # new() uses the default return type and an empty 'return' statement
3993 lines =<< trim END
3994 vim9script
3995
3996 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003997 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003998
3999 def new(this._bufnr)
4000 if !bufexists(this._bufnr)
4001 this._bufnr = -1
4002 return
4003 endif
4004 enddef
4005 endclass
4006
4007 var c = C.new(12345)
4008 assert_equal('object<C>', typename(c))
4009
4010 var v1: C
4011 v1 = C.new(12345)
4012 assert_equal('object<C>', typename(v1))
4013
4014 def F()
4015 var v2: C
4016 v2 = C.new(12345)
4017 assert_equal('object<C>', typename(v2))
4018 enddef
4019 F()
4020 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004021 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004022
4023 # new() uses "any" return type and returns "this"
4024 lines =<< trim END
4025 vim9script
4026
4027 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004028 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004029
4030 def new(this._bufnr): any
4031 if !bufexists(this._bufnr)
4032 this._bufnr = -1
4033 return this
4034 endif
4035 enddef
4036 endclass
4037 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004038 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004039
4040 # new() uses 'Dict' return type and returns a Dict
4041 lines =<< trim END
4042 vim9script
4043
4044 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004045 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004046
4047 def new(): dict<any>
4048 this._state = {}
4049 return this._state
4050 enddef
4051 endclass
4052
4053 var c = C.new()
4054 assert_equal('object<C>', typename(c))
4055 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004056 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004057enddef
4058
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004059" Test for checking a member initialization type at run time.
4060def Test_runtime_type_check_for_member_init()
4061 var lines =<< trim END
4062 vim9script
4063
4064 var retnum: bool = false
4065
4066 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004067 retnum = !retnum
4068 if retnum
4069 return 1
4070 else
4071 return "hello"
4072 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004073 enddef
4074
4075 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004076 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004077 endclass
4078
4079 var c1 = C.new()
4080 var c2 = C.new()
4081 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004082 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004083enddef
4084
4085" Test for locking a variable referring to an object and reassigning to another
4086" object.
Ernie Raelee865f32023-09-29 19:53:55 +02004087def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004088 var lines =<< trim END
4089 vim9script
4090
4091 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004092 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004093 def new(this.val)
4094 enddef
4095 endclass
4096
4097 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
4098 lockvar 2 some_dict
4099
4100 var current: C
4101 current = some_dict['c']
4102 assert_equal(3, current.val)
4103 current = some_dict['b']
4104 assert_equal(2, current.val)
4105
4106 def F()
4107 current = some_dict['c']
4108 enddef
4109
4110 def G()
4111 current = some_dict['b']
4112 enddef
4113
4114 F()
4115 assert_equal(3, current.val)
4116 G()
4117 assert_equal(2, current.val)
4118 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004119 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004120enddef
4121
Ernie Raelee865f32023-09-29 19:53:55 +02004122" Test trying to lock an object variable from various places
4123def Test_lockvar_object_variable()
4124 # An object variable lockvar has several cases:
4125 # object method, scriptlevel, scriplevel from :def, :def arg
4126 # method arg, static method arg.
4127 # Also different depths
4128
Ernie Raelee865f32023-09-29 19:53:55 +02004129 #
4130 # lockvar of read-only object variable
4131 #
4132
4133 # read-only lockvar from object method
4134 var lines =<< trim END
4135 vim9script
4136
4137 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004138 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004139 def Lock()
4140 lockvar this.val1
4141 enddef
4142 endclass
4143 var o = C.new(3)
4144 o.Lock()
4145 END
Ernie Rael64885642023-10-04 20:16:22 +02004146 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004147
4148 # read-only lockvar from scriptlevel
4149 lines =<< trim END
4150 vim9script
4151
4152 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004153 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004154 endclass
4155 var o = C.new(3)
4156 lockvar o.val2
4157 END
4158 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4159
4160 # read-only lockvar of scriptlevel variable from def
4161 lines =<< trim END
4162 vim9script
4163
4164 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004165 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004166 endclass
4167 var o = C.new(3)
4168 def Lock()
4169 lockvar o.val3
4170 enddef
4171 Lock()
4172 END
4173 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4174
4175 # read-only lockvar of def argument variable
4176 lines =<< trim END
4177 vim9script
4178
4179 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004180 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004181 endclass
4182 def Lock(o: C)
4183 lockvar o.val4
4184 enddef
4185 Lock(C.new(3))
4186 END
4187 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4188
4189 # TODO: the following tests use type "any" for argument. Need a run time
4190 # check for access. Probably OK as is for now.
4191
4192 # read-only lockvar from object method arg
4193 lines =<< trim END
4194 vim9script
4195
4196 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004197 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004198 def Lock(o_any: any)
4199 lockvar o_any.val5
4200 enddef
4201 endclass
4202 var o = C.new(3)
4203 o.Lock(C.new(5))
4204 END
Ernie Rael64885642023-10-04 20:16:22 +02004205 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004206
4207 # read-only lockvar from class method arg
4208 lines =<< trim END
4209 vim9script
4210
4211 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004212 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004213 static def Lock(o_any: any)
4214 lockvar o_any.val6
4215 enddef
4216 endclass
4217 var o = C.new(3)
4218 C.Lock(o)
4219 END
Ernie Rael64885642023-10-04 20:16:22 +02004220 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004221
4222 #
4223 # lockvar of public object variable
4224 #
4225
4226 # lockvar from object method
4227 lines =<< trim END
4228 vim9script
4229
4230 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004231 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004232 def Lock()
4233 lockvar this.val1
4234 enddef
4235 endclass
4236 var o = C.new(3)
4237 o.Lock()
4238 END
4239 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4240
4241 # lockvar from scriptlevel
4242 lines =<< trim END
4243 vim9script
4244
4245 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004246 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004247 endclass
4248 var o = C.new(3)
4249 lockvar o.val2
4250 END
4251 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4252
4253 # lockvar of scriptlevel variable from def
4254 lines =<< trim END
4255 vim9script
4256
4257 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004258 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004259 endclass
4260 var o = C.new(3)
4261 def Lock()
4262 lockvar o.val3
4263 enddef
4264 Lock()
4265 END
4266 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4267
4268 # lockvar of def argument variable
4269 lines =<< trim END
4270 vim9script
4271
4272 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004273 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004274 endclass
4275 def Lock(o: C)
4276 lockvar o.val4
4277 enddef
4278 Lock(C.new(3))
4279 END
4280 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4281
4282 # lockvar from object method arg
4283 lines =<< trim END
4284 vim9script
4285
4286 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004287 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004288 def Lock(o_any: any)
4289 lockvar o_any.val5
4290 enddef
4291 endclass
4292 var o = C.new(3)
4293 o.Lock(C.new(5))
4294 END
4295 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4296
4297 # lockvar from class method arg
4298 lines =<< trim END
4299 vim9script
4300
4301 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004302 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004303 static def Lock(o_any: any)
4304 lockvar o_any.val6
4305 enddef
4306 endclass
4307 var o = C.new(3)
4308 C.Lock(o)
4309 END
4310 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4311enddef
4312
4313" Test trying to lock a class variable from various places
4314def Test_lockvar_class_variable()
4315
4316 # lockvar bare static from object method
4317 var lines =<< trim END
4318 vim9script
4319
4320 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004321 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004322 def Lock()
4323 lockvar sval1
4324 enddef
4325 endclass
4326 var o = C.new()
4327 o.Lock()
4328 END
4329 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4330
4331 # lockvar C.static from object method
4332 lines =<< trim END
4333 vim9script
4334
4335 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004336 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004337 def Lock()
4338 lockvar C.sval2
4339 enddef
4340 endclass
4341 var o = C.new()
4342 o.Lock()
4343 END
4344 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4345
4346 # lockvar bare static from class method
4347 lines =<< trim END
4348 vim9script
4349
4350 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004351 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004352 static def Lock()
4353 lockvar sval3
4354 enddef
4355 endclass
4356 C.Lock()
4357 END
4358 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4359
4360 # lockvar C.static from class method
4361 lines =<< trim END
4362 vim9script
4363
4364 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004365 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004366 static def Lock()
4367 lockvar C.sval4
4368 enddef
4369 endclass
4370 C.Lock()
4371 END
4372 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4373
4374 # lockvar C.static from script level
4375 lines =<< trim END
4376 vim9script
4377
4378 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004379 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004380 endclass
4381 lockvar C.sval5
4382 END
4383 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4384
4385 # lockvar o.static from script level
4386 lines =<< trim END
4387 vim9script
4388
4389 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004390 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004391 endclass
4392 var o = C.new()
4393 lockvar o.sval6
4394 END
4395 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4396enddef
4397
4398" Test locking an argument to :def
4399def Test_lockvar_argument()
4400 # Lockvar a function arg
4401 var lines =<< trim END
4402 vim9script
4403
4404 def Lock(val: any)
4405 lockvar val
4406 enddef
4407
4408 var d = {a: 1, b: 2}
4409 Lock(d)
4410
4411 d->extend({c: 3})
4412 END
4413 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4414
4415 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4416 # class member in "C". This tests lval_root_is_arg.
4417 lines =<< trim END
4418 vim9script
4419
4420 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004421 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004422 endclass
4423
4424 def Lock2(sval: any)
4425 lockvar sval
4426 enddef
4427
4428 var o = C.new()
4429 Lock2(o)
4430 END
4431 v9.CheckSourceSuccess(lines)
4432
4433 # Lock a class.
4434 lines =<< trim END
4435 vim9script
4436
4437 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004438 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004439 endclass
4440
4441 def Lock2(sval: any)
4442 lockvar sval
4443 enddef
4444
4445 Lock2(C)
4446 END
Ernie Raelb077b582023-12-14 20:11:44 +01004447 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004448
4449 # Lock an object.
4450 lines =<< trim END
4451 vim9script
4452
4453 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004454 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004455 endclass
4456
4457 def Lock2(sval: any)
4458 lockvar sval
4459 enddef
4460
4461 Lock2(C.new())
4462 END
4463 v9.CheckSourceSuccess(lines)
4464
4465 # In this case (unlike previous) "lockvar sval" is a class member.
4466 lines =<< trim END
4467 vim9script
4468
4469 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004470 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004471 def Lock2()
4472 lockvar sval
4473 enddef
4474 endclass
4475
4476
4477 var o = C.new()
4478 o.Lock2()
4479 END
4480 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4481enddef
4482
4483" Test that this can be locked without error
4484def Test_lockvar_this()
4485 # lockvar this
4486 var lines =<< trim END
4487 vim9script
4488 class C
4489 def TLock()
4490 lockvar this
4491 enddef
4492 endclass
4493 var o = C.new()
4494 o.TLock()
4495 END
4496 v9.CheckSourceSuccess(lines)
4497
4498 # lockvar four (four letter word, but not this)
4499 lines =<< trim END
4500 vim9script
4501 class C
4502 def TLock4()
4503 var four: number
4504 lockvar four
4505 enddef
4506 endclass
4507 var o = C.new()
4508 o.TLock4()
4509 END
4510 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4511
4512 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4513 lines =<< trim END
4514 vim9script
4515 class C
4516 def TLock5()
4517 var this5: number
4518 lockvar this5
4519 enddef
4520 endclass
4521 var o = C.new()
4522 o.TLock5()
4523 END
4524 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4525enddef
4526
4527" Test some general lockvar cases
4528def Test_lockvar_general()
4529 # lockvar an object and a class. It does nothing
4530 var lines =<< trim END
4531 vim9script
4532 class C
4533 endclass
4534 var o = C.new()
4535 lockvar o
4536 lockvar C
4537 END
4538 v9.CheckSourceSuccess(lines)
4539
4540 # Lock a list element that's nested in an object variable from a :def
4541 lines =<< trim END
4542 vim9script
4543
4544 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004545 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004546 endclass
4547 def Lock2(obj: any)
4548 lockvar obj.val[1]
4549 enddef
4550
4551 var o = C.new()
4552 Lock2(o)
4553 o.val[0] = [9]
4554 assert_equal([ [9], [2], [3] ], o.val)
4555 try
4556 o.val[1] = [999]
4557 call assert_false(true, 'assign should have failed')
4558 catch
4559 assert_exception('E741:')
4560 endtry
4561 o.val[2] = [8]
4562 assert_equal([ [9], [2], [8] ], o.val)
4563 END
4564 v9.CheckSourceSuccess(lines)
4565
4566 # Lock a list element that's nested in an object variable from scriptlevel
4567 lines =<< trim END
4568 vim9script
4569
4570 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004571 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004572 endclass
4573
4574 var o = C.new()
4575 lockvar o.val[1]
4576 o.val[0] = [9]
4577 assert_equal([ [9], [2], [3] ], o.val)
4578 try
4579 o.val[1] = [999]
4580 call assert_false(true, 'assign should have failed')
4581 catch
4582 assert_exception('E741:')
4583 endtry
4584 o.val[2] = [8]
4585 assert_equal([ [9], [2], [8] ], o.val)
4586 END
4587 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004588
4589 # lock a script level variable from an object method
4590 lines =<< trim END
4591 vim9script
4592
4593 class C
4594 def Lock()
4595 lockvar l
4596 enddef
4597 endclass
4598
4599 var l = [1]
4600 C.new().Lock()
4601 l[0] = 11
4602 END
4603 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4604
Ernie Rael03042a22023-11-11 08:53:32 +01004605 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004606 # in an object fetched via a script level list
4607 lines =<< trim END
4608 vim9script
4609
4610 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004611 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004612 def Lock()
4613 lockvar lc[0]._v1[1]
4614 enddef
4615 endclass
4616
4617 var l = [[1], [2], [3]]
4618 var o = C.new(l)
4619 var lc: list<C> = [ o ]
4620
4621 o.Lock()
4622 l[0] = [22]
4623 l[1] = [33]
4624 END
4625 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4626
4627 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004628 # in a class that does not own the protected variable.
4629 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004630 # the same name.
4631 lines =<< trim END
4632 vim9script
4633
4634 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004635 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004636 def Lock(obj: any)
4637 lockvar lc[0]._v1[1]
4638 enddef
4639 endclass
4640
4641 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004642 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004643 endclass
4644
4645 var l = [[1], [2], [3]]
4646 var o = C.new(l)
4647 var lc: list<C> = [ o ]
4648
4649 var o2 = C2.new()
4650 o2.Lock(o)
4651 END
Ernie Rael03042a22023-11-11 08:53:32 +01004652 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004653enddef
4654
Ernie Rael9771b2a2023-10-07 22:05:40 +02004655" Test builtin islocked()
4656def Test_lockvar_islocked()
4657 # Can't lock class/object variable
4658 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004659 # Lock item of variable's value (a list item)
4660 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004661 var lines =<< trim END
4662 vim9script
4663
4664 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004665 var o0: list<list<number>> = [ [0], [1], [2]]
4666 var o1: list<list<number>> = [[10], [11], [12]]
4667 static var c0: list<list<number>> = [[20], [21], [22]]
4668 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004669 endclass
4670
4671 def LockIt(arg: any)
4672 lockvar arg
4673 enddef
4674
4675 def UnlockIt(arg: any)
4676 unlockvar arg
4677 enddef
4678
4679 var obj = C.new()
4680 #lockvar obj.o1 # can't lock something you can't write to
4681
4682 try
4683 lockvar obj.o1 # can't lock something you can't write to
4684 call assert_false(1, '"lockvar obj.o1" should have failed')
4685 catch
4686 call assert_exception('E1335:')
4687 endtry
4688
4689 LockIt(obj.o1) # but can lock it's value
4690 assert_equal(1, islocked("obj.o1"))
4691 assert_equal(1, islocked("obj.o1[0]"))
4692 assert_equal(1, islocked("obj.o1[1]"))
4693 UnlockIt(obj.o1)
4694 assert_equal(0, islocked("obj.o1"))
4695 assert_equal(0, islocked("obj.o1[0]"))
4696
4697 lockvar obj.o1[0]
4698 assert_equal(0, islocked("obj.o1"))
4699 assert_equal(1, islocked("obj.o1[0]"))
4700 assert_equal(0, islocked("obj.o1[1]"))
4701 unlockvar obj.o1[0]
4702 assert_equal(0, islocked("obj.o1"))
4703 assert_equal(0, islocked("obj.o1[0]"))
4704
4705 # Same thing, but with a static
4706
4707 try
4708 lockvar C.c1 # can't lock something you can't write to
4709 call assert_false(1, '"lockvar C.c1" should have failed')
4710 catch
4711 call assert_exception('E1335:')
4712 endtry
4713
4714 LockIt(C.c1) # but can lock it's value
4715 assert_equal(1, islocked("C.c1"))
4716 assert_equal(1, islocked("C.c1[0]"))
4717 assert_equal(1, islocked("C.c1[1]"))
4718 UnlockIt(C.c1)
4719 assert_equal(0, islocked("C.c1"))
4720 assert_equal(0, islocked("C.c1[0]"))
4721
4722 lockvar C.c1[0]
4723 assert_equal(0, islocked("C.c1"))
4724 assert_equal(1, islocked("C.c1[0]"))
4725 assert_equal(0, islocked("C.c1[1]"))
4726 unlockvar C.c1[0]
4727 assert_equal(0, islocked("C.c1"))
4728 assert_equal(0, islocked("C.c1[0]"))
4729 END
4730 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004731
4732 # Do islocked() from an object method
4733 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004734 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004735 vim9script
4736
4737 var l0o0 = [ [0], [1], [2]]
4738 var l0o1 = [ [10], [11], [12]]
4739 var l0c0 = [[120], [121], [122]]
4740 var l0c1 = [[130], [131], [132]]
4741
4742 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004743 var o0: list<list<number>> = l0o0
4744 var o1: list<list<number>> = l0o1
4745 static var c0: list<list<number>> = l0c0
4746 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004747 def Islocked(arg: string): number
4748 return islocked(arg)
4749 enddef
4750 static def SIslocked(arg: string): number
4751 return islocked(arg)
4752 enddef
4753 endclass
4754
4755 var l2o0 = [[20000], [20001], [20002]]
4756 var l2o1 = [[20010], [20011], [20012]]
4757 var l2c0 = [[20120], [20121], [20122]]
4758 var l2c1 = [[20130], [20131], [20132]]
4759
4760 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004761 var o0: list<list<number>> = l2o0
4762 var o1: list<list<number>> = l2o1
4763 static var c0: list<list<number>> = l2c0
4764 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004765 def Islocked(arg: string): number
4766 return islocked(arg)
4767 enddef
4768 static def SIslocked(arg: string): number
4769 return islocked(arg)
4770 enddef
4771 endclass
4772
4773 var obj0 = C0.new()
4774 var obj2 = C2.new()
4775
4776 var l = [ obj0, null_object, obj2 ]
4777
4778 # lock list, object func access through script var expr
4779 assert_equal(0, obj0.Islocked("l[0].o0"))
4780 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4781 lockvar l0o0
4782 assert_equal(1, obj0.Islocked("l[0].o0"))
4783 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4784
4785 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4786
4787 # lock list element, object func access through script var expr
4788 lockvar l0o1[1]
4789 assert_equal(0, obj0.Islocked("this.o1[0]"))
4790 assert_equal(1, obj0.Islocked("this.o1[1]"))
4791
4792 assert_equal(0, obj0.Islocked("this.o1"))
4793 lockvar l0o1
4794 assert_equal(1, obj0.Islocked("this.o1"))
4795 unlockvar l0o1
4796
4797 lockvar l0c1[1]
4798
4799 # static by class name member expr from same class
4800 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4801 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4802 # static by bare name member expr from same class
4803 assert_equal(0, obj0.Islocked("c1[0]"))
4804 assert_equal(1, obj0.Islocked("c1[1]"))
4805
4806 # static by class name member expr from other class
4807 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4808 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4809 # static by bare name member expr from other class
4810 assert_equal(0, obj2.Islocked("c1[0]"))
4811 assert_equal(0, obj2.Islocked("c1[1]"))
4812
4813
4814 # static by bare name in same class
4815 assert_equal(0, obj0.Islocked("c0"))
4816 lockvar l0c0
4817 assert_equal(1, obj0.Islocked("c0"))
4818
4819 #
4820 # similar stuff, but use static method
4821 #
4822
4823 unlockvar l0o0
4824
4825 # lock list, object func access through script var expr
4826 assert_equal(0, C0.SIslocked("l[0].o0"))
4827 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4828 lockvar l0o0
4829 assert_equal(1, C0.SIslocked("l[0].o0"))
4830 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4831
4832 unlockvar l0o1
4833
4834 # can't access "this" from class method
4835 try
4836 C0.SIslocked("this.o1[0]")
4837 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4838 catch
4839 call assert_exception('E121: Undefined variable: this')
4840 endtry
4841
4842 lockvar l0c1[1]
4843
4844 # static by class name member expr from same class
4845 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4846 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4847 # static by bare name member expr from same class
4848 assert_equal(0, C0.SIslocked("c1[0]"))
4849 assert_equal(1, C0.SIslocked("c1[1]"))
4850
4851 # static by class name member expr from other class
4852 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4853 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4854 # static by bare name member expr from other class
4855 assert_equal(0, C2.SIslocked("c1[0]"))
4856 assert_equal(0, C2.SIslocked("c1[1]"))
4857
4858
4859 # static by bare name in same class
4860 unlockvar l0c0
4861 assert_equal(0, C0.SIslocked("c0"))
4862 lockvar l0c0
4863 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004864 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004865 v9.CheckSourceSuccess(lines)
4866
4867 # Check islocked class/object from various places.
4868 lines =<< trim END
4869 vim9script
4870
4871 class C
4872 def Islocked(arg: string): number
4873 return islocked(arg)
4874 enddef
4875 static def SIslocked(arg: string): number
4876 return islocked(arg)
4877 enddef
4878 endclass
4879 var obj = C.new()
4880
4881 # object method
4882 assert_equal(0, obj.Islocked("this"))
4883 assert_equal(0, obj.Islocked("C"))
4884
4885 # class method
4886 ### assert_equal(0, C.SIslocked("this"))
4887 assert_equal(0, C.SIslocked("C"))
4888
4889 #script level
4890 var v: number
4891 v = islocked("C")
4892 assert_equal(0, v)
4893 v = islocked("obj")
4894 assert_equal(0, v)
4895 END
4896 v9.CheckSourceSuccess(lines)
4897enddef
4898
4899def Test_lockvar_islocked_notfound()
4900 # Try non-existent things
4901 var lines =<< trim END
4902 vim9script
4903
4904 class C
4905 def Islocked(arg: string): number
4906 return islocked(arg)
4907 enddef
4908 static def SIslocked(arg: string): number
4909 return islocked(arg)
4910 enddef
4911 endclass
4912 var obj = C.new()
4913 assert_equal(-1, obj.Islocked("anywhere"))
4914 assert_equal(-1, C.SIslocked("notanywhere"))
4915 END
4916 v9.CheckSourceSuccess(lines)
4917
4918 # Something not found of the form "name1.name2" is an error
4919 lines =<< trim END
4920 vim9script
4921
4922 islocked("one.two")
4923 END
4924 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4925
4926 lines =<< trim END
4927 vim9script
4928
4929 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004930 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004931 def Islocked(arg: string): number
4932 return islocked(arg)
4933 enddef
4934 endclass
4935 var obj = C.new()
4936 obj.Islocked("this.val.not_there"))
4937 END
4938 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4939
4940 lines =<< trim END
4941 vim9script
4942
4943 class C
4944 def Islocked(arg: string): number
4945 return islocked(arg)
4946 enddef
4947 endclass
4948 var obj = C.new()
4949 obj.Islocked("this.notobjmember")
4950 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004951 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004952
4953 # access a script variable through methods
4954 lines =<< trim END
4955 vim9script
4956
4957 var l = [1]
4958 class C
4959 def Islocked(arg: string): number
4960 return islocked(arg)
4961 enddef
4962 static def SIslocked(arg: string): number
4963 return islocked(arg)
4964 enddef
4965 endclass
4966 var obj = C.new()
4967 assert_equal(0, obj.Islocked("l"))
4968 assert_equal(0, C.SIslocked("l"))
4969 lockvar l
4970 assert_equal(1, obj.Islocked("l"))
4971 assert_equal(1, C.SIslocked("l"))
4972 END
4973 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004974enddef
4975
Ernie Rael03042a22023-11-11 08:53:32 +01004976" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004977def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004978 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004979 var lines =<< trim END
4980 vim9script
4981
4982 class A
4983 def _Foo(): number
4984 return 1234
4985 enddef
4986 endclass
4987 var a = A.new()
4988 a._Foo()
4989 END
Ernie Rael03042a22023-11-11 08:53:32 +01004990 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004991
Ernie Rael03042a22023-11-11 08:53:32 +01004992 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004993 lines =<< trim END
4994 vim9script
4995
4996 class A
4997 def _Foo(): number
4998 return 1234
4999 enddef
5000 endclass
5001 def T()
5002 var a = A.new()
5003 a._Foo()
5004 enddef
5005 T()
5006 END
Ernie Rael03042a22023-11-11 08:53:32 +01005007 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005008
Ernie Rael03042a22023-11-11 08:53:32 +01005009 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005010 lines =<< trim END
5011 vim9script
5012
5013 class A
5014 def _Foo(): number
5015 return 1234
5016 enddef
5017 def Bar(): number
5018 return this._Foo()
5019 enddef
5020 endclass
5021 var a = A.new()
5022 assert_equal(1234, a.Bar())
5023 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005024 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005025
Ernie Rael03042a22023-11-11 08:53:32 +01005026 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005027 lines =<< trim END
5028 vim9script
5029
5030 class A
5031 def _Foo(): number
5032 return 1234
5033 enddef
5034 def Bar(): number
5035 return this._Foo()
5036 enddef
5037 endclass
5038 def T()
5039 var a = A.new()
5040 assert_equal(1234, a.Bar())
5041 enddef
5042 T()
5043 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005044 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005045
Ernie Rael03042a22023-11-11 08:53:32 +01005046 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005047 lines =<< trim END
5048 vim9script
5049
5050 class A
5051 def _Foo(): number
5052 return 1234
5053 enddef
5054 def Bar(): number
5055 return _Foo()
5056 enddef
5057 endclass
5058 var a = A.new()
5059 a.Bar()
5060 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005061 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005062
Ernie Rael03042a22023-11-11 08:53:32 +01005063 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005064 lines =<< trim END
5065 vim9script
5066
5067 class A
5068 def _Foo(): number
5069 return 1234
5070 enddef
5071 endclass
5072 A._Foo()
5073 END
Ernie Rael03042a22023-11-11 08:53:32 +01005074 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005075
Ernie Rael03042a22023-11-11 08:53:32 +01005076 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005077 lines =<< trim END
5078 vim9script
5079
5080 class A
5081 def _Foo()
5082 enddef
5083 def _Foo()
5084 enddef
5085 endclass
5086 var a = A.new()
5087 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005088 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005089
Ernie Rael03042a22023-11-11 08:53:32 +01005090 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005091 lines =<< trim END
5092 vim9script
5093
5094 class A
5095 def _Foo()
5096 enddef
5097 def Foo()
5098 enddef
5099 endclass
5100 var a = A.new()
5101 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005102 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005103
Ernie Rael03042a22023-11-11 08:53:32 +01005104 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005105 lines =<< trim END
5106 vim9script
5107
5108 class A
5109 def Foo()
5110 enddef
5111 def _Foo()
5112 enddef
5113 endclass
5114 var a = A.new()
5115 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005116 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005117
Ernie Rael03042a22023-11-11 08:53:32 +01005118 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005119 lines =<< trim END
5120 vim9script
5121
5122 class A
5123 def Foo(): number
5124 return 100
5125 enddef
5126 def _Bar(): number
5127 return 200
5128 enddef
5129 def _Baz()
5130 assert_equal(100, this.Foo())
5131 assert_equal(200, this._Bar())
5132 enddef
5133 def T()
5134 this._Baz()
5135 enddef
5136 endclass
5137 var a = A.new()
5138 a.T()
5139 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005140 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005141
Ernie Rael03042a22023-11-11 08:53:32 +01005142 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005143 lines =<< trim END
5144 vim9script
5145
5146 class A
5147 def _Foo(): number
5148 return 100
5149 enddef
5150 endclass
5151 class B
5152 def Foo(): number
5153 var a = A.new()
5154 a._Foo()
5155 enddef
5156 endclass
5157 var b = B.new()
5158 b.Foo()
5159 END
Ernie Rael03042a22023-11-11 08:53:32 +01005160 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005161
Ernie Rael03042a22023-11-11 08:53:32 +01005162 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005163 lines =<< trim END
5164 vim9script
5165 class A
5166 def _Foo(): number
5167 return 1234
5168 enddef
5169 endclass
5170 class B extends A
5171 def Bar()
5172 enddef
5173 endclass
5174 class C extends B
5175 def Baz(): number
5176 return this._Foo()
5177 enddef
5178 endclass
5179 var c = C.new()
5180 assert_equal(1234, c.Baz())
5181 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005182 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005183
Ernie Rael03042a22023-11-11 08:53:32 +01005184 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005185 lines =<< trim END
5186 vim9script
5187 class A
5188 def _Foo(): number
5189 return 1234
5190 enddef
5191 endclass
5192 class B extends A
5193 def Bar()
5194 enddef
5195 endclass
5196 class C extends B
5197 def Baz(): number
5198 enddef
5199 endclass
5200 var c = C.new()
5201 assert_equal(1234, c._Foo())
5202 END
Ernie Rael03042a22023-11-11 08:53:32 +01005203 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005204
5205 # Using "_" prefix in a method name should fail outside of a class
5206 lines =<< trim END
5207 vim9script
5208 def _Foo(): number
5209 return 1234
5210 enddef
5211 var a = _Foo()
5212 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005213 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005214enddef
5215
Ernie Rael03042a22023-11-11 08:53:32 +01005216" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005217def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005218 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005219 var lines =<< trim END
5220 vim9script
5221
5222 class A
5223 static def _Foo(): number
5224 return 1234
5225 enddef
5226 endclass
5227 A._Foo()
5228 END
Ernie Rael03042a22023-11-11 08:53:32 +01005229 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005230
Ernie Rael03042a22023-11-11 08:53:32 +01005231 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005232 lines =<< trim END
5233 vim9script
5234
5235 class A
5236 static def _Foo(): number
5237 return 1234
5238 enddef
5239 endclass
5240 def T()
5241 A._Foo()
5242 enddef
5243 T()
5244 END
Ernie Rael03042a22023-11-11 08:53:32 +01005245 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005246
Ernie Rael03042a22023-11-11 08:53:32 +01005247 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005248 lines =<< trim END
5249 vim9script
5250
5251 class A
5252 static def _Foo(): number
5253 return 1234
5254 enddef
5255 endclass
5256 var a = A.new()
5257 a._Foo()
5258 END
Ernie Rael03042a22023-11-11 08:53:32 +01005259 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005260
Ernie Rael03042a22023-11-11 08:53:32 +01005261 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005262 lines =<< trim END
5263 vim9script
5264
5265 class A
5266 static def _Foo(): number
5267 return 1234
5268 enddef
5269 endclass
5270 def T()
5271 var a = A.new()
5272 a._Foo()
5273 enddef
5274 T()
5275 END
Ernie Rael03042a22023-11-11 08:53:32 +01005276 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005277
Ernie Rael03042a22023-11-11 08:53:32 +01005278 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005279 lines =<< trim END
5280 vim9script
5281
5282 class A
5283 static def _Foo(): number
5284 return 1234
5285 enddef
5286 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005287 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005288 enddef
5289 endclass
5290 var a = A.new()
5291 a.Bar()
5292 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005293 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005294
Ernie Rael03042a22023-11-11 08:53:32 +01005295 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005296 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005297 lines =<< trim END
5298 vim9script
5299
5300 class A
5301 static def _Foo1(): number
5302 return 1234
5303 enddef
5304 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005305 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005306 enddef
5307 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005308 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005309 enddef
5310 endclass
5311 var a = A.new()
5312 a.Bar()
5313 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005314 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005315
Ernie Rael03042a22023-11-11 08:53:32 +01005316 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005317 lines =<< trim END
5318 vim9script
5319
5320 class A
5321 static def _Foo()
5322 enddef
5323 static def Foo()
5324 enddef
5325 endclass
5326 var a = A.new()
5327 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005328 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005329
Ernie Rael03042a22023-11-11 08:53:32 +01005330 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005331 lines =<< trim END
5332 vim9script
5333
5334 class A
5335 static def _Foo(): number
5336 return 1234
5337 enddef
5338 endclass
5339 class B
5340 def Foo(): number
5341 return A._Foo()
5342 enddef
5343 endclass
5344 var b = B.new()
5345 assert_equal(1234, b.Foo())
5346 END
Ernie Rael03042a22023-11-11 08:53:32 +01005347 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005348
Ernie Rael03042a22023-11-11 08:53:32 +01005349 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005350 lines =<< trim END
5351 vim9script
5352 class A
5353 static def _Foo(): number
5354 return 1234
5355 enddef
5356 endclass
5357 class B extends A
5358 def Bar()
5359 enddef
5360 endclass
5361 class C extends B
5362 def Baz(): number
5363 return A._Foo()
5364 enddef
5365 endclass
5366 var c = C.new()
5367 assert_equal(1234, c.Baz())
5368 END
Ernie Rael03042a22023-11-11 08:53:32 +01005369 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005370
Ernie Rael03042a22023-11-11 08:53:32 +01005371 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005372 lines =<< trim END
5373 vim9script
5374 class A
5375 static def _Foo(): number
5376 return 1234
5377 enddef
5378 endclass
5379 class B extends A
5380 def Bar()
5381 enddef
5382 endclass
5383 class C extends B
5384 static def Baz(): number
5385 return A._Foo()
5386 enddef
5387 endclass
5388 assert_equal(1234, C.Baz())
5389 END
Ernie Rael03042a22023-11-11 08:53:32 +01005390 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005391
Ernie Rael03042a22023-11-11 08:53:32 +01005392 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005393 lines =<< trim END
5394 vim9script
5395 class A
5396 static def _Foo(): number
5397 return 1234
5398 enddef
5399 endclass
5400 class B extends A
5401 def Bar()
5402 enddef
5403 endclass
5404 class C extends B
5405 def Baz(): number
5406 enddef
5407 endclass
5408 var c = C.new()
5409 assert_equal(1234, C._Foo())
5410 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005411 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005412enddef
5413
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005414" Test for using the return value of a class/object method as a function
5415" argument.
5416def Test_objmethod_funcarg()
5417 var lines =<< trim END
5418 vim9script
5419
5420 class C
5421 def Foo(): string
5422 return 'foo'
5423 enddef
5424 endclass
5425
5426 def Bar(a: number, s: string): string
5427 return s
5428 enddef
5429
5430 def Baz(c: C)
5431 assert_equal('foo', Bar(10, c.Foo()))
5432 enddef
5433
5434 var t = C.new()
5435 Baz(t)
5436 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005437 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005438
5439 lines =<< trim END
5440 vim9script
5441
5442 class C
5443 static def Foo(): string
5444 return 'foo'
5445 enddef
5446 endclass
5447
5448 def Bar(a: number, s: string): string
5449 return s
5450 enddef
5451
5452 def Baz()
5453 assert_equal('foo', Bar(10, C.Foo()))
5454 enddef
5455
5456 Baz()
5457 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005458 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005459enddef
5460
Ernie Raelcf138d42023-09-06 20:45:03 +02005461def Test_static_inheritence()
5462 # subclasses get their own static copy
5463 var lines =<< trim END
5464 vim9script
5465
5466 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005467 static var _svar: number
5468 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005469 def new()
5470 _svar = 1
5471 this._mvar = 101
5472 enddef
5473 def AccessObject(): number
5474 return this._mvar
5475 enddef
5476 def AccessStaticThroughObject(): number
5477 return _svar
5478 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005479 endclass
5480
5481 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005482 def new()
5483 this._mvar = 102
5484 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005485 endclass
5486
5487 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005488 def new()
5489 this._mvar = 103
5490 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005491
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005492 def AccessPrivateStaticThroughClassName(): number
5493 assert_equal(1, A._svar)
5494 return 444
5495 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005496 endclass
5497
5498 var oa = A.new()
5499 var ob = B.new()
5500 var oc = C.new()
5501 assert_equal(101, oa.AccessObject())
5502 assert_equal(102, ob.AccessObject())
5503 assert_equal(103, oc.AccessObject())
5504
Ernie Rael03042a22023-11-11 08:53:32 +01005505 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005506
5507 # verify object properly resolves to correct static
5508 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005509 assert_equal(1, ob.AccessStaticThroughObject())
5510 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005511 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005512 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005513enddef
5514
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005515" Test for declaring duplicate object and class members
5516def Test_dup_member_variable()
5517 # Duplicate member variable
5518 var lines =<< trim END
5519 vim9script
5520 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005521 var val = 10
5522 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005523 endclass
5524 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005525 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005526
Ernie Rael03042a22023-11-11 08:53:32 +01005527 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005528 lines =<< trim END
5529 vim9script
5530 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005531 var _val = 10
5532 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005533 endclass
5534 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005535 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005536
5537 # Duplicate public member variable
5538 lines =<< trim END
5539 vim9script
5540 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005541 public var val = 10
5542 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005543 endclass
5544 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005545 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005546
Ernie Rael03042a22023-11-11 08:53:32 +01005547 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005548 lines =<< trim END
5549 vim9script
5550 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005551 var val = 10
5552 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005553 endclass
5554 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005555 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005556
Ernie Rael03042a22023-11-11 08:53:32 +01005557 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005558 lines =<< trim END
5559 vim9script
5560 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005561 var _val = 20
5562 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005563 endclass
5564 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005565 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005566
5567 # Duplicate class member variable
5568 lines =<< trim END
5569 vim9script
5570 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005571 static var s: string = "abc"
5572 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005573 endclass
5574 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005575 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005576
Ernie Rael03042a22023-11-11 08:53:32 +01005577 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005578 lines =<< trim END
5579 vim9script
5580 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005581 public static var s: string = "abc"
5582 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005583 endclass
5584 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005585 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005586
5587 # Duplicate class and object member variable
5588 lines =<< trim END
5589 vim9script
5590 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005591 static var val = 10
5592 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005593 def new()
5594 enddef
5595 endclass
5596 var c = C.new()
5597 assert_equal(10, C.val)
5598 assert_equal(20, c.val)
5599 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005600 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005601
5602 # Duplicate object member variable in a derived class
5603 lines =<< trim END
5604 vim9script
5605 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005606 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005607 endclass
5608 class B extends A
5609 endclass
5610 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005611 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005612 endclass
5613 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005614 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005615
Ernie Rael03042a22023-11-11 08:53:32 +01005616 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005617 lines =<< trim END
5618 vim9script
5619 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005620 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005621 endclass
5622 class B extends A
5623 endclass
5624 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005625 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005626 endclass
5627 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005628 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005629
Ernie Rael03042a22023-11-11 08:53:32 +01005630 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005631 lines =<< trim END
5632 vim9script
5633 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005634 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005635 endclass
5636 class B extends A
5637 endclass
5638 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005639 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005640 endclass
5641 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005642 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005643
5644 # Duplicate object member variable in a derived class
5645 lines =<< trim END
5646 vim9script
5647 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005648 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005649 endclass
5650 class B extends A
5651 endclass
5652 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005653 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005654 endclass
5655 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005656 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005657
5658 # Two member variables with a common prefix
5659 lines =<< trim END
5660 vim9script
5661 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005662 public static var svar2: number
5663 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005664 endclass
5665 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005666 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005667enddef
5668
Ernie Rael03042a22023-11-11 08:53:32 +01005669" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005670def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005671 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005672 var lines =<< trim END
5673 vim9script
5674 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005675 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005676 def GetVal(): number
5677 return this._val
5678 enddef
5679 endclass
5680 def T()
5681 var a = A.new()
5682 a._val = 20
5683 enddef
5684 T()
5685 END
Ernie Rael03042a22023-11-11 08:53:32 +01005686 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005687
Ernie Rael03042a22023-11-11 08:53:32 +01005688 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005689 lines =<< trim END
5690 vim9script
5691 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005692 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005693 endclass
5694 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005695 var a = A.new()
5696 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005697 enddef
5698 T()
5699 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005700 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005701
Ernie Rael03042a22023-11-11 08:53:32 +01005702 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005703 lines =<< trim END
5704 vim9script
5705 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005706 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005707 endclass
5708 def T()
5709 var a = A.new()
5710 var x = a._val
5711 enddef
5712 T()
5713 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005714 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005715
Ernie Rael03042a22023-11-11 08:53:32 +01005716 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005717 lines =<< trim END
5718 vim9script
5719 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005720 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005721 endclass
5722 def T()
5723 var a = A.new()
5724 a._val = 3
5725 enddef
5726 T()
5727 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005728 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
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 var x = A._val
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)
Ernie Rael18143d32023-09-04 22:30:41 +02005742
Ernie Rael03042a22023-11-11 08:53:32 +01005743 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005744 lines =<< trim END
5745 vim9script
5746 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005747 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005748 endclass
5749 def T()
5750 A._val = 3
5751 enddef
5752 T()
5753 END
Ernie Rael03042a22023-11-11 08:53:32 +01005754 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005755enddef
5756
5757" Test for changing the member access of an interface in a implementation class
5758def Test_change_interface_member_access()
5759 var lines =<< trim END
5760 vim9script
5761 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005762 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005763 endinterface
5764 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005765 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005766 endclass
5767 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005768 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005769
5770 lines =<< trim END
5771 vim9script
5772 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005773 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005774 endinterface
5775 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005776 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005777 endclass
5778 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005779 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005780enddef
5781
5782" Test for trying to change a readonly member from a def function
5783def Test_readonly_member_change_in_def_func()
5784 var lines =<< trim END
5785 vim9script
5786 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005787 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005788 endclass
5789 def T()
5790 var a = A.new()
5791 a.val = 20
5792 enddef
5793 T()
5794 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005795 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005796enddef
5797
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005798" Test for reading and writing a class member from a def function
5799def Test_modify_class_member_from_def_function()
5800 var lines =<< trim END
5801 vim9script
5802 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005803 var var1: number = 10
5804 public static var var2: list<number> = [1, 2]
5805 public static var var3: dict<number> = {a: 1, b: 2}
5806 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005807 endclass
5808 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005809 assert_equal([1, 2], A.var2)
5810 assert_equal({a: 1, b: 2}, A.var3)
5811 A.var2 = [3, 4]
5812 A.var3 = {c: 3, d: 4}
5813 assert_equal([3, 4], A.var2)
5814 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005815 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005816 enddef
5817 T()
5818 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005819 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005820enddef
5821
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005822" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005823def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005824 var lines =<< trim END
5825 vim9script
5826 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005827 public static var svar1: list<number> = [1]
5828 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005829 endclass
5830
5831 A.svar1->add(3)
5832 A.svar2->add(4)
5833 assert_equal([1, 3], A.svar1)
5834 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005835
5836 def Foo()
5837 A.svar1->add(7)
5838 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005839 assert_equal([1, 3, 7], A.svar1)
5840 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005841 enddef
5842 Foo()
5843 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005844 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005845
5846 # Cannot read from 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 echo a.svar2
5856 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005857 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005858
5859 # Cannot write to a class variable using an object in script 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 var a = A.new()
5868 a.svar2 = [2]
5869 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005870 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005871
5872 # Cannot read from a class variable using an object in def method context
5873 lines =<< trim END
5874 vim9script
5875 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005876 public var var1: number
5877 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005878 endclass
5879
5880 def T()
5881 var a = A.new()
5882 echo a.svar2
5883 enddef
5884 T()
5885 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005886 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005887
5888 # Cannot write to a class variable using an object in def method context
5889 lines =<< trim END
5890 vim9script
5891 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005892 public var var1: number
5893 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005894 endclass
5895
5896 def T()
5897 var a = A.new()
5898 a.svar2 = [2]
5899 enddef
5900 T()
5901 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005902 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005903enddef
5904
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005905" Test for using a interface method using a child object
5906def Test_interface_method_from_child()
5907 var lines =<< trim END
5908 vim9script
5909
5910 interface A
5911 def Foo(): string
5912 endinterface
5913
5914 class B implements A
5915 def Foo(): string
5916 return 'foo'
5917 enddef
5918 endclass
5919
5920 class C extends B
5921 def Bar(): string
5922 return 'bar'
5923 enddef
5924 endclass
5925
5926 def T1(a: A)
5927 assert_equal('foo', a.Foo())
5928 enddef
5929
5930 def T2(b: B)
5931 assert_equal('foo', b.Foo())
5932 enddef
5933
5934 var c = C.new()
5935 T1(c)
5936 T2(c)
5937 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005938 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005939enddef
5940
5941" Test for using an interface method using a child object when it is overridden
5942" by the child class.
5943" FIXME: This test fails.
5944" def Test_interface_overridden_method_from_child()
5945" var lines =<< trim END
5946" vim9script
5947"
5948" interface A
5949" def Foo(): string
5950" endinterface
5951"
5952" class B implements A
5953" def Foo(): string
5954" return 'b-foo'
5955" enddef
5956" endclass
5957"
5958" class C extends B
5959" def Bar(): string
5960" return 'bar'
5961" enddef
5962" def Foo(): string
5963" return 'c-foo'
5964" enddef
5965" endclass
5966"
5967" def T1(a: A)
5968" assert_equal('c-foo', a.Foo())
5969" enddef
5970"
5971" def T2(b: B)
5972" assert_equal('c-foo', b.Foo())
5973" enddef
5974"
5975" var c = C.new()
5976" T1(c)
5977" T2(c)
5978" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005979" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005980" enddef
5981
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005982" Test for abstract methods
5983def Test_abstract_method()
5984 # Use two abstract methods
5985 var lines =<< trim END
5986 vim9script
5987 abstract class A
5988 def M1(): number
5989 return 10
5990 enddef
5991 abstract def M2(): number
5992 abstract def M3(): number
5993 endclass
5994 class B extends A
5995 def M2(): number
5996 return 20
5997 enddef
5998 def M3(): number
5999 return 30
6000 enddef
6001 endclass
6002 var b = B.new()
6003 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
6004 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006005 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006006
6007 # Don't define an abstract method
6008 lines =<< trim END
6009 vim9script
6010 abstract class A
6011 abstract def Foo()
6012 endclass
6013 class B extends A
6014 endclass
6015 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006016 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006017
6018 # Use abstract method in a concrete class
6019 lines =<< trim END
6020 vim9script
6021 class A
6022 abstract def Foo()
6023 endclass
6024 class B extends A
6025 endclass
6026 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006027 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006028
6029 # Use abstract method in an interface
6030 lines =<< trim END
6031 vim9script
6032 interface A
6033 abstract def Foo()
6034 endinterface
6035 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006036 def Foo()
6037 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006038 endclass
6039 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01006040 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6041
6042 # Use abstract static method in an interface
6043 lines =<< trim END
6044 vim9script
6045 interface A
6046 abstract static def Foo()
6047 enddef
6048 endinterface
6049 END
6050 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6051
6052 # Use abstract static variable in an interface
6053 lines =<< trim END
6054 vim9script
6055 interface A
6056 abstract static foo: number = 10
6057 endinterface
6058 END
6059 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006060
6061 # Abbreviate the "abstract" keyword
6062 lines =<< trim END
6063 vim9script
6064 class A
6065 abs def Foo()
6066 endclass
6067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006068 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006069
6070 # Use "abstract" with a member variable
6071 lines =<< trim END
6072 vim9script
6073 abstract class A
6074 abstract this.val = 10
6075 endclass
6076 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006077 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006078
6079 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01006080 lines =<< trim END
6081 vim9script
6082 abstract class A
6083 abstract static def Foo(): number
6084 endclass
6085 END
6086 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006087
6088 # Type mismatch between abstract method and concrete method
6089 lines =<< trim END
6090 vim9script
6091 abstract class A
6092 abstract def Foo(a: string, b: number): list<number>
6093 endclass
6094 class B extends A
6095 def Foo(a: number, b: string): list<string>
6096 return []
6097 enddef
6098 endclass
6099 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006100 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 +02006101
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006102 # Invoke an abstract method from a def function
6103 lines =<< trim END
6104 vim9script
6105 abstract class A
6106 abstract def Foo(): list<number>
6107 endclass
6108 class B extends A
6109 def Foo(): list<number>
6110 return [3, 5]
6111 enddef
6112 endclass
6113 def Bar(c: B)
6114 assert_equal([3, 5], c.Foo())
6115 enddef
6116 var b = B.new()
6117 Bar(b)
6118 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006119 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006120
6121 # Use a static method in an abstract class
6122 lines =<< trim END
6123 vim9script
6124 abstract class A
6125 static def Foo(): string
6126 return 'foo'
6127 enddef
6128 endclass
6129 assert_equal('foo', A.Foo())
6130 END
6131 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006132enddef
6133
6134" Test for calling a class method from a subclass
6135def Test_class_method_call_from_subclass()
6136 # class method call from a subclass
6137 var lines =<< trim END
6138 vim9script
6139
6140 class A
6141 static def Foo()
6142 echo "foo"
6143 enddef
6144 endclass
6145
6146 class B extends A
6147 def Bar()
6148 Foo()
6149 enddef
6150 endclass
6151
6152 var b = B.new()
6153 b.Bar()
6154 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006155 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006156enddef
6157
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006158" Test for calling a class method using an object in a def function context and
6159" script context.
6160def Test_class_method_call_using_object()
6161 # script context
6162 var lines =<< trim END
6163 vim9script
6164 class A
6165 static def Foo(): list<string>
6166 return ['a', 'b']
6167 enddef
6168 def Bar()
6169 assert_equal(['a', 'b'], A.Foo())
6170 assert_equal(['a', 'b'], Foo())
6171 enddef
6172 endclass
6173
6174 def T()
6175 assert_equal(['a', 'b'], A.Foo())
6176 var t_a = A.new()
6177 t_a.Bar()
6178 enddef
6179
6180 assert_equal(['a', 'b'], A.Foo())
6181 var a = A.new()
6182 a.Bar()
6183 T()
6184 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006185 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006186
6187 # script context
6188 lines =<< trim END
6189 vim9script
6190 class A
6191 static def Foo(): string
6192 return 'foo'
6193 enddef
6194 endclass
6195
6196 var a = A.new()
6197 assert_equal('foo', a.Foo())
6198 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006199 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006200
6201 # def function context
6202 lines =<< trim END
6203 vim9script
6204 class A
6205 static def Foo(): string
6206 return 'foo'
6207 enddef
6208 endclass
6209
6210 def T()
6211 var a = A.new()
6212 assert_equal('foo', a.Foo())
6213 enddef
6214 T()
6215 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006216 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006217enddef
6218
6219def Test_class_variable()
6220 var lines =<< trim END
6221 vim9script
6222
6223 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006224 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006225 static def ClassFunc()
6226 assert_equal(10, val)
6227 enddef
6228 def ObjFunc()
6229 assert_equal(10, val)
6230 enddef
6231 endclass
6232
6233 class B extends A
6234 endclass
6235
6236 assert_equal(10, A.val)
6237 A.ClassFunc()
6238 var a = A.new()
6239 a.ObjFunc()
6240 var b = B.new()
6241 b.ObjFunc()
6242
6243 def T1(a1: A)
6244 a1.ObjFunc()
6245 A.ClassFunc()
6246 enddef
6247 T1(b)
6248
6249 A.val = 20
6250 assert_equal(20, A.val)
6251 END
6252 v9.CheckSourceSuccess(lines)
6253
6254 # Modifying a parent class variable from a child class method
6255 lines =<< trim END
6256 vim9script
6257
6258 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006259 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006260 endclass
6261
6262 class B extends A
6263 static def ClassFunc()
6264 val = 20
6265 enddef
6266 endclass
6267 B.ClassFunc()
6268 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006269 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006270
6271 # Reading a parent class variable from a child class method
6272 lines =<< trim END
6273 vim9script
6274
6275 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006276 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006277 endclass
6278
6279 class B extends A
6280 static def ClassFunc()
6281 var i = val
6282 enddef
6283 endclass
6284 B.ClassFunc()
6285 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006286 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006287
6288 # Modifying a parent class variable from a child object method
6289 lines =<< trim END
6290 vim9script
6291
6292 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006293 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006294 endclass
6295
6296 class B extends A
6297 def ObjFunc()
6298 val = 20
6299 enddef
6300 endclass
6301 var b = B.new()
6302 b.ObjFunc()
6303 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006304 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006305
6306 # Reading a parent class variable from a child object method
6307 lines =<< trim END
6308 vim9script
6309
6310 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006311 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006312 endclass
6313
6314 class B extends A
6315 def ObjFunc()
6316 var i = val
6317 enddef
6318 endclass
6319 var b = B.new()
6320 b.ObjFunc()
6321 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006322 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006323
6324 # Modifying a class variable using an object at script level
6325 lines =<< trim END
6326 vim9script
6327
6328 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006329 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006330 endclass
6331 var a = A.new()
6332 a.val = 20
6333 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006334 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006335
6336 # Reading a class variable using an object at script level
6337 lines =<< trim END
6338 vim9script
6339
6340 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006341 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006342 endclass
6343 var a = A.new()
6344 var i = a.val
6345 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006346 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006347
6348 # Modifying a class variable using an object at function level
6349 lines =<< trim END
6350 vim9script
6351
6352 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006353 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006354 endclass
6355
6356 def T()
6357 var a = A.new()
6358 a.val = 20
6359 enddef
6360 T()
6361 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006362 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006363
6364 # Reading a class variable using an object at function level
6365 lines =<< trim END
6366 vim9script
6367
6368 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006369 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006370 endclass
6371 def T()
6372 var a = A.new()
6373 var i = a.val
6374 enddef
6375 T()
6376 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006377 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006378
6379 # Use old implicit var declaration syntax (without initialization)
6380 lines =<< trim END
6381 vim9script
6382
6383 class A
6384 static val: number
6385 endclass
6386 END
6387 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6388
6389 # Use old implicit var declaration syntax (with initialization)
6390 lines =<< trim END
6391 vim9script
6392
6393 class A
6394 static val: number = 10
6395 endclass
6396 END
6397 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6398
6399 # Use old implicit var declaration syntax (type inferred)
6400 lines =<< trim END
6401 vim9script
6402
6403 class A
6404 static val = 10
6405 endclass
6406 END
6407 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6408
6409 # Missing ":var" in "var" class variable declaration (without initialization)
6410 lines =<< trim END
6411 vim9script
6412
6413 class A
6414 static var: number
6415 endclass
6416 END
6417 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6418
6419 # Missing ":var" in "var" class variable declaration (with initialization)
6420 lines =<< trim END
6421 vim9script
6422
6423 class A
6424 static var: number = 10
6425 endclass
6426 END
6427 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6428
6429 # Missing ":var" in "var" class variable declaration (type inferred)
6430 lines =<< trim END
6431 vim9script
6432
6433 class A
6434 static var = 10
6435 endclass
6436 END
6437 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6438
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006439enddef
6440
6441" Test for using a duplicate class method and class variable in a child class
6442def Test_dup_class_member()
6443 # duplicate class variable, class method and overridden object method
6444 var lines =<< trim END
6445 vim9script
6446 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006447 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006448 static def Check()
6449 assert_equal(100, sval)
6450 enddef
6451 def GetVal(): number
6452 return sval
6453 enddef
6454 endclass
6455
6456 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006457 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006458 static def Check()
6459 assert_equal(200, sval)
6460 enddef
6461 def GetVal(): number
6462 return sval
6463 enddef
6464 endclass
6465
6466 def T1(aa: A): number
6467 return aa.GetVal()
6468 enddef
6469
6470 def T2(bb: B): number
6471 return bb.GetVal()
6472 enddef
6473
6474 assert_equal(100, A.sval)
6475 assert_equal(200, B.sval)
6476 var a = A.new()
6477 assert_equal(100, a.GetVal())
6478 var b = B.new()
6479 assert_equal(200, b.GetVal())
6480 assert_equal(200, T1(b))
6481 assert_equal(200, T2(b))
6482 END
6483 v9.CheckSourceSuccess(lines)
6484
6485 # duplicate class variable and class method
6486 lines =<< trim END
6487 vim9script
6488 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006489 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006490 static def Check()
6491 assert_equal(100, sval)
6492 enddef
6493 def GetVal(): number
6494 return sval
6495 enddef
6496 endclass
6497
6498 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006499 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006500 static def Check()
6501 assert_equal(200, sval)
6502 enddef
6503 endclass
6504
6505 def T1(aa: A): number
6506 return aa.GetVal()
6507 enddef
6508
6509 def T2(bb: B): number
6510 return bb.GetVal()
6511 enddef
6512
6513 assert_equal(100, A.sval)
6514 assert_equal(200, B.sval)
6515 var a = A.new()
6516 assert_equal(100, a.GetVal())
6517 var b = B.new()
6518 assert_equal(100, b.GetVal())
6519 assert_equal(100, T1(b))
6520 assert_equal(100, T2(b))
6521 END
6522 v9.CheckSourceSuccess(lines)
6523enddef
6524
6525" Test for calling an instance method using the class
6526def Test_instance_method_call_using_class()
6527 # Invoke an object method using a class in script context
6528 var lines =<< trim END
6529 vim9script
6530 class A
6531 def Foo()
6532 echo "foo"
6533 enddef
6534 endclass
6535 A.Foo()
6536 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006537 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006538
6539 # Invoke an object method using a class in def function context
6540 lines =<< trim END
6541 vim9script
6542 class A
6543 def Foo()
6544 echo "foo"
6545 enddef
6546 endclass
6547 def T()
6548 A.Foo()
6549 enddef
6550 T()
6551 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006552 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006553enddef
6554
6555" Test for duplicate class method and instance method
6556def Test_dup_classmethod_objmethod()
6557 # Duplicate instance method
6558 var lines =<< trim END
6559 vim9script
6560 class A
6561 static def Foo()
6562 enddef
6563 def Foo()
6564 enddef
6565 endclass
6566 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006567 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006568
Ernie Rael03042a22023-11-11 08:53:32 +01006569 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006570 lines =<< trim END
6571 vim9script
6572 class A
6573 static def Foo()
6574 enddef
6575 def _Foo()
6576 enddef
6577 endclass
6578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006579 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006580
6581 # Duplicate class method
6582 lines =<< trim END
6583 vim9script
6584 class A
6585 def Foo()
6586 enddef
6587 static def Foo()
6588 enddef
6589 endclass
6590 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006591 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006592
Ernie Rael03042a22023-11-11 08:53:32 +01006593 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006594 lines =<< trim END
6595 vim9script
6596 class A
6597 def Foo()
6598 enddef
6599 static def _Foo()
6600 enddef
6601 endclass
6602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006603 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006604
Ernie Rael03042a22023-11-11 08:53:32 +01006605 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006606 lines =<< trim END
6607 vim9script
6608 class A
6609 def _Foo()
6610 enddef
6611 static def _Foo()
6612 enddef
6613 endclass
6614 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006615 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006616enddef
6617
6618" Test for an instance method access level comparison with parent instance
6619" methods.
6620def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006621 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006622 var lines =<< trim END
6623 vim9script
6624 class A
6625 def Foo()
6626 enddef
6627 endclass
6628 class B extends A
6629 endclass
6630 class C extends B
6631 def _Foo()
6632 enddef
6633 endclass
6634 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006635 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006636
6637 # Public method in subclass
6638 lines =<< trim END
6639 vim9script
6640 class A
6641 def _Foo()
6642 enddef
6643 endclass
6644 class B extends A
6645 endclass
6646 class C extends B
6647 def Foo()
6648 enddef
6649 endclass
6650 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006651 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006652enddef
6653
6654def Test_extend_empty_class()
6655 var lines =<< trim END
6656 vim9script
6657 class A
6658 endclass
6659 class B extends A
6660 endclass
6661 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006662 public static var rw_class_var = 1
6663 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006664 static def ClassMethod(): number
6665 return 3
6666 enddef
6667 def ObjMethod(): number
6668 return 4
6669 enddef
6670 endclass
6671 assert_equal(1, C.rw_class_var)
6672 assert_equal(3, C.ClassMethod())
6673 var c = C.new()
6674 assert_equal(2, c.rw_obj_var)
6675 assert_equal(4, c.ObjMethod())
6676 END
6677 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006678enddef
6679
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006680" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006681" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006682def Test_interface_with_unsupported_members()
6683 var lines =<< trim END
6684 vim9script
6685 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006686 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006687 endinterface
6688 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006689 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006690
6691 lines =<< trim END
6692 vim9script
6693 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006694 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006695 endinterface
6696 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006697 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006698
6699 lines =<< trim END
6700 vim9script
6701 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006702 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006703 endinterface
6704 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006705 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006706
6707 lines =<< trim END
6708 vim9script
6709 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006710 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006711 endinterface
6712 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006713 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006714
6715 lines =<< trim END
6716 vim9script
6717 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006718 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006719 endinterface
6720 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006721 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006722
6723 lines =<< trim END
6724 vim9script
6725 interface A
6726 static def Foo(d: dict<any>): list<string>
6727 endinterface
6728 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006729 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006730
6731 lines =<< trim END
6732 vim9script
6733 interface A
6734 static def _Foo(d: dict<any>): list<string>
6735 endinterface
6736 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006737 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006738
6739 lines =<< trim END
6740 vim9script
6741 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006742 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006743 endinterface
6744 END
Ernie Rael03042a22023-11-11 08:53:32 +01006745 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006746
6747 lines =<< trim END
6748 vim9script
6749 interface A
6750 def _Foo(d: dict<any>): list<string>
6751 endinterface
6752 END
Ernie Rael03042a22023-11-11 08:53:32 +01006753 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006754enddef
6755
6756" Test for extending an interface
6757def Test_extend_interface()
6758 var lines =<< trim END
6759 vim9script
6760 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006761 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006762 def Foo()
6763 endinterface
6764 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006765 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006766 def Bar()
6767 endinterface
6768 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006769 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006770 def Foo()
6771 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006772 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006773 def Bar()
6774 enddef
6775 endclass
6776 END
6777 v9.CheckSourceSuccess(lines)
6778
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006779 # extending empty interface
6780 lines =<< trim END
6781 vim9script
6782 interface A
6783 endinterface
6784 interface B extends A
6785 endinterface
6786 class C implements B
6787 endclass
6788 END
6789 v9.CheckSourceSuccess(lines)
6790
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006791 lines =<< trim END
6792 vim9script
6793 interface A
6794 def Foo()
6795 endinterface
6796 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006797 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006798 endinterface
6799 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006800 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006801 endclass
6802 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006803 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006804
6805 lines =<< trim END
6806 vim9script
6807 interface A
6808 def Foo()
6809 endinterface
6810 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006811 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006812 endinterface
6813 class C implements A, B
6814 def Foo()
6815 enddef
6816 endclass
6817 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006818 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006819
6820 # interface cannot extend a class
6821 lines =<< trim END
6822 vim9script
6823 class A
6824 endclass
6825 interface B extends A
6826 endinterface
6827 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006828 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006829
6830 # class cannot extend an interface
6831 lines =<< trim END
6832 vim9script
6833 interface A
6834 endinterface
6835 class B extends A
6836 endclass
6837 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006838 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006839
6840 # interface cannot implement another interface
6841 lines =<< trim END
6842 vim9script
6843 interface A
6844 endinterface
6845 interface B implements A
6846 endinterface
6847 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006848 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006849
6850 # interface cannot extend multiple interfaces
6851 lines =<< trim END
6852 vim9script
6853 interface A
6854 endinterface
6855 interface B
6856 endinterface
6857 interface C extends A, B
6858 endinterface
6859 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006860 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006861
6862 # Variable type in an extended interface is of different type
6863 lines =<< trim END
6864 vim9script
6865 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006866 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006867 endinterface
6868 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006869 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006870 endinterface
6871 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006872 var val1: string
6873 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006874 endinterface
6875 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006876 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006877enddef
6878
6879" Test for a child class implementing an interface when some of the methods are
6880" defined in the parent class.
6881def Test_child_class_implements_interface()
6882 var lines =<< trim END
6883 vim9script
6884
6885 interface Intf
6886 def F1(): list<list<number>>
6887 def F2(): list<list<number>>
6888 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006889 var var1: list<dict<number>>
6890 var var2: list<dict<number>>
6891 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006892 endinterface
6893
6894 class A
6895 def A1()
6896 enddef
6897 def F3(): list<list<number>>
6898 return [[3]]
6899 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006900 var v1: list<list<number>> = [[0]]
6901 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006902 endclass
6903
6904 class B extends A
6905 def B1()
6906 enddef
6907 def F2(): list<list<number>>
6908 return [[2]]
6909 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006910 var v2: list<list<number>> = [[0]]
6911 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006912 endclass
6913
6914 class C extends B implements Intf
6915 def C1()
6916 enddef
6917 def F1(): list<list<number>>
6918 return [[1]]
6919 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006920 var v3: list<list<number>> = [[0]]
6921 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006922 endclass
6923
6924 def T(if: Intf)
6925 assert_equal([[1]], if.F1())
6926 assert_equal([[2]], if.F2())
6927 assert_equal([[3]], if.F3())
6928 assert_equal([{a: 10}], if.var1)
6929 assert_equal([{b: 20}], if.var2)
6930 assert_equal([{c: 30}], if.var3)
6931 enddef
6932
6933 var c = C.new()
6934 T(c)
6935 assert_equal([[1]], c.F1())
6936 assert_equal([[2]], c.F2())
6937 assert_equal([[3]], c.F3())
6938 assert_equal([{a: 10}], c.var1)
6939 assert_equal([{b: 20}], c.var2)
6940 assert_equal([{c: 30}], c.var3)
6941 END
6942 v9.CheckSourceSuccess(lines)
6943
6944 # One of the interface methods is not found
6945 lines =<< trim END
6946 vim9script
6947
6948 interface Intf
6949 def F1()
6950 def F2()
6951 def F3()
6952 endinterface
6953
6954 class A
6955 def A1()
6956 enddef
6957 endclass
6958
6959 class B extends A
6960 def B1()
6961 enddef
6962 def F2()
6963 enddef
6964 endclass
6965
6966 class C extends B implements Intf
6967 def C1()
6968 enddef
6969 def F1()
6970 enddef
6971 endclass
6972 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006973 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006974
6975 # One of the interface methods is of different type
6976 lines =<< trim END
6977 vim9script
6978
6979 interface Intf
6980 def F1()
6981 def F2()
6982 def F3()
6983 endinterface
6984
6985 class A
6986 def F3(): number
6987 return 0
6988 enddef
6989 def A1()
6990 enddef
6991 endclass
6992
6993 class B extends A
6994 def B1()
6995 enddef
6996 def F2()
6997 enddef
6998 endclass
6999
7000 class C extends B implements Intf
7001 def C1()
7002 enddef
7003 def F1()
7004 enddef
7005 endclass
7006 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007007 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007008
7009 # One of the interface variables is not present
7010 lines =<< trim END
7011 vim9script
7012
7013 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007014 var var1: list<dict<number>>
7015 var var2: list<dict<number>>
7016 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007017 endinterface
7018
7019 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007020 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007021 endclass
7022
7023 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007024 var v2: list<list<number>> = [[0]]
7025 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007026 endclass
7027
7028 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007029 var v3: list<list<number>> = [[0]]
7030 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007031 endclass
7032 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007033 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007034
7035 # One of the interface variables is of different type
7036 lines =<< trim END
7037 vim9script
7038
7039 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007040 var var1: list<dict<number>>
7041 var var2: list<dict<number>>
7042 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007043 endinterface
7044
7045 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007046 var v1: list<list<number>> = [[0]]
7047 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007048 endclass
7049
7050 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007051 var v2: list<list<number>> = [[0]]
7052 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007053 endclass
7054
7055 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007056 var v3: list<list<number>> = [[0]]
7057 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007058 endclass
7059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007060 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 +02007061enddef
7062
7063" Test for extending an interface with duplicate variables and methods
7064def Test_interface_extends_with_dup_members()
7065 var lines =<< trim END
7066 vim9script
7067 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007068 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007069 def Foo1(): number
7070 endinterface
7071 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007072 var n2: number
7073 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007074 def Foo2(): number
7075 def Foo1(): number
7076 endinterface
7077 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007078 var n1 = 10
7079 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007080 def Foo1(): number
7081 return 30
7082 enddef
7083 def Foo2(): number
7084 return 40
7085 enddef
7086 endclass
7087 def T1(a: A)
7088 assert_equal(10, a.n1)
7089 assert_equal(30, a.Foo1())
7090 enddef
7091 def T2(b: B)
7092 assert_equal(10, b.n1)
7093 assert_equal(20, b.n2)
7094 assert_equal(30, b.Foo1())
7095 assert_equal(40, b.Foo2())
7096 enddef
7097 var c = C.new()
7098 T1(c)
7099 T2(c)
7100 END
7101 v9.CheckSourceSuccess(lines)
7102enddef
7103
7104" Test for using "any" type for a variable in a sub-class while it has a
7105" concrete type in the interface
7106def Test_implements_using_var_type_any()
7107 var lines =<< trim END
7108 vim9script
7109 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007110 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007111 endinterface
7112 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007113 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007114 endclass
7115 var b = B.new()
7116 assert_equal([{a: '1'}, {b: '2'}], b.val)
7117 END
7118 v9.CheckSourceSuccess(lines)
7119
7120 # initialize instance variable using a different type
7121 lines =<< trim END
7122 vim9script
7123 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007124 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007125 endinterface
7126 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007127 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007128 endclass
7129 var b = B.new()
7130 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007131 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007132enddef
7133
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007134" Test for assigning to a member variable in a nested class
7135def Test_nested_object_assignment()
7136 var lines =<< trim END
7137 vim9script
7138
7139 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007140 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007141 endclass
7142
7143 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007144 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007145 endclass
7146
7147 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007148 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007149 endclass
7150
7151 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007152 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007153 endclass
7154
7155 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007156 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007157 enddef
7158
7159 var d = D.new()
7160 T(d)
7161 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007162 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007163enddef
7164
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007165" Test for calling methods using a null object
7166def Test_null_object_method_call()
7167 # Calling a object method using a null object in script context
7168 var lines =<< trim END
7169 vim9script
7170
7171 class C
7172 def Foo()
7173 assert_report('This method should not be executed')
7174 enddef
7175 endclass
7176
7177 var o: C
7178 o.Foo()
7179 END
7180 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7181
7182 # Calling a object method using a null object in def function context
7183 lines =<< trim END
7184 vim9script
7185
7186 class C
7187 def Foo()
7188 assert_report('This method should not be executed')
7189 enddef
7190 endclass
7191
7192 def T()
7193 var o: C
7194 o.Foo()
7195 enddef
7196 T()
7197 END
7198 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7199
7200 # Calling a object method through another class method using a null object in
7201 # script context
7202 lines =<< trim END
7203 vim9script
7204
7205 class C
7206 def Foo()
7207 assert_report('This method should not be executed')
7208 enddef
7209
7210 static def Bar(o_any: any)
7211 var o_typed: C = o_any
7212 o_typed.Foo()
7213 enddef
7214 endclass
7215
7216 var o: C
7217 C.Bar(o)
7218 END
7219 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7220
7221 # Calling a object method through another class method using a null object in
7222 # def function context
7223 lines =<< trim END
7224 vim9script
7225
7226 class C
7227 def Foo()
7228 assert_report('This method should not be executed')
7229 enddef
7230
7231 static def Bar(o_any: any)
7232 var o_typed: C = o_any
7233 o_typed.Foo()
7234 enddef
7235 endclass
7236
7237 def T()
7238 var o: C
7239 C.Bar(o)
7240 enddef
7241 T()
7242 END
7243 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Ernie Raelbe828252024-07-26 18:37:02 +02007244
7245 # Calling an object method defined in a class that is extended. This differs
7246 # from the previous by invoking ISN_METHODCALL instead of ISN_DCALL.
7247 lines =<< trim END
7248 vim9script
7249
7250 class C0
7251 def F()
7252 enddef
7253 endclass
7254
7255 class C extends C0
7256 endclass
7257
7258 def X()
7259 var o: C0 = null_object
7260 o.F()
7261 enddef
7262 X()
7263 END
7264 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7265
7266 # Getting a function ref an object method.
7267 lines =<< trim END
7268 vim9script
7269
7270 class C0
7271 def F()
7272 enddef
7273 endclass
7274
7275 class C extends C0
7276 endclass
7277
7278 def X()
7279 var o: C0 = null_object
7280 var XXX = o.F
7281 enddef
7282 X()
7283 END
7284 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007285enddef
7286
7287" Test for using a dict as an object member
7288def Test_dict_object_member()
7289 var lines =<< trim END
7290 vim9script
7291
7292 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007293 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007294 def GetState(): dict<number>
7295 return this.state
7296 enddef
7297 endclass
7298
7299 var ctx = Context.new()
7300 ctx.state->extend({a: 1})
7301 ctx.state['b'] = 2
7302 assert_equal({a: 1, b: 2}, ctx.GetState())
7303
7304 def F()
7305 ctx.state['c'] = 3
7306 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7307 enddef
7308 F()
7309 assert_equal(3, ctx.state.c)
7310 ctx.state.c = 4
7311 assert_equal(4, ctx.state.c)
7312 END
7313 v9.CheckSourceSuccess(lines)
7314enddef
7315
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007316" The following test was failing after 9.0.1914. This was caused by using a
7317" freed object from a previous method call.
7318def Test_freed_object_from_previous_method_call()
7319 var lines =<< trim END
7320 vim9script
7321
7322 class Context
7323 endclass
7324
7325 class Result
7326 endclass
7327
7328 def Failure(): Result
7329 return Result.new()
7330 enddef
7331
7332 def GetResult(ctx: Context): Result
7333 return Failure()
7334 enddef
7335
7336 def Test_GetResult()
7337 var ctx = Context.new()
7338 var result = GetResult(ctx)
7339 enddef
7340
7341 Test_GetResult()
7342 END
7343 v9.CheckSourceSuccess(lines)
7344enddef
7345
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007346" Test for duplicate object and class variable
7347def Test_duplicate_variable()
7348 # Object variable name is same as the class variable name
7349 var lines =<< trim END
7350 vim9script
7351 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007352 public static var sval: number
7353 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007354 endclass
7355 var a = A.new()
7356 END
7357 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7358
7359 # Duplicate variable name and calling a class method
7360 lines =<< trim END
7361 vim9script
7362 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007363 public static var sval: number
7364 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007365 def F1()
7366 echo this.sval
7367 enddef
7368 static def F2()
7369 echo sval
7370 enddef
7371 endclass
7372 A.F2()
7373 END
7374 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7375
7376 # Duplicate variable with an empty constructor
7377 lines =<< trim END
7378 vim9script
7379 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007380 public static var sval: number
7381 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007382 def new()
7383 enddef
7384 endclass
7385 var a = A.new()
7386 END
7387 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7388enddef
7389
7390" Test for using a reserved keyword as a variable name
7391def Test_reserved_varname()
7392 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7393 'null_function', 'null_list', 'null_partial', 'null_string',
7394 'null_channel', 'null_job', 'super', 'this']
7395
7396 var lines =<< trim eval END
7397 vim9script
7398 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007399 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007400 endclass
7401 var o = C.new()
7402 END
7403 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7404
7405 lines =<< trim eval END
7406 vim9script
7407 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007408 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007409 def new()
7410 enddef
7411 endclass
7412 var o = C.new()
7413 END
7414 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7415
7416 lines =<< trim eval END
7417 vim9script
7418 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007419 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007420 def new()
7421 enddef
7422 def F()
7423 echo this.{kword}
7424 enddef
7425 endclass
7426 var o = C.new()
7427 o.F()
7428 END
7429 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007430
7431 # class variable name
7432 if kword != 'this'
7433 lines =<< trim eval END
7434 vim9script
7435 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007436 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007437 endclass
7438 END
7439 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7440 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007441 endfor
7442enddef
7443
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007444" Test for checking the type of the arguments and the return value of a object
7445" method in an extended class.
7446def Test_extended_obj_method_type_check()
7447 var lines =<< trim END
7448 vim9script
7449
7450 class A
7451 endclass
7452 class B extends A
7453 endclass
7454 class C extends B
7455 endclass
7456
7457 class Foo
7458 def Doit(p: B): B
7459 return B.new()
7460 enddef
7461 endclass
7462
7463 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007464 def Doit(p: C): B
7465 return B.new()
7466 enddef
7467 endclass
7468 END
7469 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7470
7471 lines =<< trim END
7472 vim9script
7473
7474 class A
7475 endclass
7476 class B extends A
7477 endclass
7478 class C extends B
7479 endclass
7480
7481 class Foo
7482 def Doit(p: B): B
7483 return B.new()
7484 enddef
7485 endclass
7486
7487 class Bar extends Foo
7488 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007489 return C.new()
7490 enddef
7491 endclass
7492 END
7493 v9.CheckSourceSuccess(lines)
7494
7495 lines =<< trim END
7496 vim9script
7497
7498 class A
7499 endclass
7500 class B extends A
7501 endclass
7502 class C extends B
7503 endclass
7504
7505 class Foo
7506 def Doit(p: B): B
7507 return B.new()
7508 enddef
7509 endclass
7510
7511 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007512 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007513 return B.new()
7514 enddef
7515 endclass
7516 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007517 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 +02007518
7519 lines =<< trim END
7520 vim9script
7521
7522 class A
7523 endclass
7524 class B extends A
7525 endclass
7526 class C extends B
7527 endclass
7528
7529 class Foo
7530 def Doit(p: B): B
7531 return B.new()
7532 enddef
7533 endclass
7534
7535 class Bar extends Foo
7536 def Doit(p: B): A
7537 return A.new()
7538 enddef
7539 endclass
7540 END
7541 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 +02007542
7543 # check varargs type mismatch
7544 lines =<< trim END
7545 vim9script
7546
7547 class B
7548 def F(...xxx: list<any>)
7549 enddef
7550 endclass
7551 class C extends B
7552 def F(xxx: list<any>)
7553 enddef
7554 endclass
7555 END
7556 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 +02007557enddef
7558
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007559" Test type checking for class variable in assignments
7560func Test_class_variable_complex_type_check()
7561 " class variable with a specific type. Try assigning a different type at
7562 " script level.
7563 let lines =<< trim END
7564 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007565 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007566 return {}
7567 enddef
7568 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007569 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007570 endclass
7571 test_garbagecollect_now()
7572 A.Fn = "abc"
7573 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007574 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 +02007575
7576 " class variable with a specific type. Try assigning a different type at
7577 " class def method level.
7578 let lines =<< trim END
7579 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007580 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007581 return {}
7582 enddef
7583 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007584 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007585 def Bar()
7586 Fn = "abc"
7587 enddef
7588 endclass
7589 var a = A.new()
7590 test_garbagecollect_now()
7591 a.Bar()
7592 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007593 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 +02007594
7595 " class variable with a specific type. Try assigning a different type at
7596 " script def method level.
7597 let lines =<< trim END
7598 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007599 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007600 return {}
7601 enddef
7602 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007603 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007604 endclass
7605 def Bar()
7606 A.Fn = "abc"
7607 enddef
7608 test_garbagecollect_now()
7609 Bar()
7610 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007611 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 +02007612
7613 " class variable without any type. Should be set to the initialization
7614 " expression type. Try assigning a different type from script level.
7615 let lines =<< trim END
7616 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007617 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007618 return {}
7619 enddef
7620 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007621 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007622 endclass
7623 test_garbagecollect_now()
7624 A.Fn = "abc"
7625 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007626 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 +02007627
7628 " class variable without any type. Should be set to the initialization
7629 " expression type. Try assigning a different type at class def level.
7630 let lines =<< trim END
7631 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007632 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007633 return {}
7634 enddef
7635 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007636 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007637 def Bar()
7638 Fn = "abc"
7639 enddef
7640 endclass
7641 var a = A.new()
7642 test_garbagecollect_now()
7643 a.Bar()
7644 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007645 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 +02007646
7647 " class variable without any type. Should be set to the initialization
7648 " expression type. Try assigning a different type at script def level.
7649 let lines =<< trim END
7650 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007651 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007652 return {}
7653 enddef
7654 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007655 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007656 endclass
7657 def Bar()
7658 A.Fn = "abc"
7659 enddef
7660 test_garbagecollect_now()
7661 Bar()
7662 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007663 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 +02007664
7665 " class variable with 'any" type. Can be assigned different types.
7666 let lines =<< trim END
7667 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007668 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007669 return {}
7670 enddef
7671 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007672 public static var Fn: any = Foo
7673 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007674 endclass
7675 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007676 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007677 A.Fn = "abc"
7678 test_garbagecollect_now()
7679 assert_equal('string', typename(A.Fn))
7680 A.Fn2 = Foo
7681 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007682 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007683 A.Fn2 = "xyz"
7684 test_garbagecollect_now()
7685 assert_equal('string', typename(A.Fn2))
7686 END
7687 call v9.CheckSourceSuccess(lines)
7688
7689 " class variable with 'any" type. Can be assigned different types.
7690 let lines =<< trim END
7691 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007692 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007693 return {}
7694 enddef
7695 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007696 public static var Fn: any = Foo
7697 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007698
7699 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007700 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007701 Fn = "abc"
7702 assert_equal('string', typename(Fn))
7703 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007704 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007705 Fn2 = "xyz"
7706 assert_equal('string', typename(Fn2))
7707 enddef
7708 endclass
7709 var a = A.new()
7710 test_garbagecollect_now()
7711 a.Bar()
7712 test_garbagecollect_now()
7713 A.Fn = Foo
7714 a.Bar()
7715 END
7716 call v9.CheckSourceSuccess(lines)
7717
7718 " class variable with 'any" type. Can be assigned different types.
7719 let lines =<< trim END
7720 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007721 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007722 return {}
7723 enddef
7724 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007725 public static var Fn: any = Foo
7726 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007727 endclass
7728
7729 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007730 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007731 A.Fn = "abc"
7732 assert_equal('string', typename(A.Fn))
7733 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007734 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007735 A.Fn2 = "xyz"
7736 assert_equal('string', typename(A.Fn2))
7737 enddef
7738 Bar()
7739 test_garbagecollect_now()
7740 A.Fn = Foo
7741 Bar()
7742 END
7743 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007744
7745 let lines =<< trim END
7746 vim9script
7747 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007748 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007749 endclass
7750 assert_equal([0z10, 0z20], A.foo)
7751 A.foo = [0z30]
7752 assert_equal([0z30], A.foo)
7753 var a = A.foo
7754 assert_equal([0z30], a)
7755 END
7756 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007757endfunc
7758
7759" Test type checking for object variable in assignments
7760func Test_object_variable_complex_type_check()
7761 " object variable with a specific type. Try assigning a different type at
7762 " script level.
7763 let lines =<< trim END
7764 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007765 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007766 return {}
7767 enddef
7768 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007769 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007770 endclass
7771 var a = A.new()
7772 test_garbagecollect_now()
7773 a.Fn = "abc"
7774 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007775 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 +02007776
7777 " object variable with a specific type. Try assigning a different type at
7778 " object def method level.
7779 let lines =<< trim END
7780 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007781 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007782 return {}
7783 enddef
7784 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007785 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007786 def Bar()
7787 this.Fn = "abc"
7788 this.Fn = Foo
7789 enddef
7790 endclass
7791 var a = A.new()
7792 test_garbagecollect_now()
7793 a.Bar()
7794 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007795 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 +02007796
7797 " object variable with a specific type. Try assigning a different type at
7798 " script def method level.
7799 let lines =<< trim END
7800 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007801 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007802 return {}
7803 enddef
7804 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007805 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007806 endclass
7807 def Bar()
7808 var a = A.new()
7809 a.Fn = "abc"
7810 a.Fn = Foo
7811 enddef
7812 test_garbagecollect_now()
7813 Bar()
7814 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007815 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 +02007816
7817 " object variable without any type. Should be set to the initialization
7818 " expression type. Try assigning a different type from script level.
7819 let lines =<< trim END
7820 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007821 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007822 return {}
7823 enddef
7824 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007825 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007826 endclass
7827 var a = A.new()
7828 test_garbagecollect_now()
7829 a.Fn = "abc"
7830 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007831 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 +02007832
7833 " object variable without any type. Should be set to the initialization
7834 " expression type. Try assigning a different type at object def level.
7835 let lines =<< trim END
7836 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007837 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007838 return {}
7839 enddef
7840 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007841 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007842 def Bar()
7843 this.Fn = "abc"
7844 this.Fn = Foo
7845 enddef
7846 endclass
7847 var a = A.new()
7848 test_garbagecollect_now()
7849 a.Bar()
7850 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007851 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 +02007852
7853 " object variable without any type. Should be set to the initialization
7854 " expression type. Try assigning a different type at script def level.
7855 let lines =<< trim END
7856 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007857 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007858 return {}
7859 enddef
7860 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007861 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007862 endclass
7863 def Bar()
7864 var a = A.new()
7865 a.Fn = "abc"
7866 a.Fn = Foo
7867 enddef
7868 test_garbagecollect_now()
7869 Bar()
7870 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007871 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 +02007872
7873 " object variable with 'any" type. Can be assigned different types.
7874 let lines =<< trim END
7875 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007876 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007877 return {}
7878 enddef
7879 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007880 public var Fn: any = Foo
7881 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007882 endclass
7883
7884 var a = A.new()
7885 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007886 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007887 a.Fn = "abc"
7888 test_garbagecollect_now()
7889 assert_equal('string', typename(a.Fn))
7890 a.Fn2 = Foo
7891 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007892 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007893 a.Fn2 = "xyz"
7894 test_garbagecollect_now()
7895 assert_equal('string', typename(a.Fn2))
7896 END
7897 call v9.CheckSourceSuccess(lines)
7898
7899 " object variable with 'any" type. Can be assigned different types.
7900 let lines =<< trim END
7901 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007902 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007903 return {}
7904 enddef
7905 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007906 public var Fn: any = Foo
7907 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007908
7909 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007910 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007911 this.Fn = "abc"
7912 assert_equal('string', typename(this.Fn))
7913 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007914 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007915 this.Fn2 = "xyz"
7916 assert_equal('string', typename(this.Fn2))
7917 enddef
7918 endclass
7919
7920 var a = A.new()
7921 test_garbagecollect_now()
7922 a.Bar()
7923 test_garbagecollect_now()
7924 a.Fn = Foo
7925 a.Bar()
7926 END
7927 call v9.CheckSourceSuccess(lines)
7928
7929 " object variable with 'any" type. Can be assigned different types.
7930 let lines =<< trim END
7931 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007932 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007933 return {}
7934 enddef
7935 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007936 public var Fn: any = Foo
7937 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007938 endclass
7939
7940 def Bar()
7941 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007942 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007943 a.Fn = "abc"
7944 assert_equal('string', typename(a.Fn))
7945 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007946 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007947 a.Fn2 = "xyz"
7948 assert_equal('string', typename(a.Fn2))
7949 enddef
7950 test_garbagecollect_now()
7951 Bar()
7952 test_garbagecollect_now()
7953 Bar()
7954 END
7955 call v9.CheckSourceSuccess(lines)
7956endfunc
7957
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007958" Test for recursively calling an object method. This used to cause an
7959" use-after-free error.
7960def Test_recursive_object_method_call()
7961 var lines =<< trim END
7962 vim9script
7963 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007964 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007965 def Foo(): number
7966 if this.val >= 90
7967 return this.val
7968 endif
7969 this.val += 1
7970 return this.Foo()
7971 enddef
7972 endclass
7973 var a = A.new()
7974 assert_equal(90, a.Foo())
7975 END
7976 v9.CheckSourceSuccess(lines)
7977enddef
7978
7979" Test for recursively calling a class method.
7980def Test_recursive_class_method_call()
7981 var lines =<< trim END
7982 vim9script
7983 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007984 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007985 static def Foo(): number
7986 if val >= 90
7987 return val
7988 endif
7989 val += 1
7990 return Foo()
7991 enddef
7992 endclass
7993 assert_equal(90, A.Foo())
7994 END
7995 v9.CheckSourceSuccess(lines)
7996enddef
7997
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007998" Test for checking the argument types and the return type when assigning a
7999" funcref to make sure the invariant class type is used.
8000def Test_funcref_argtype_returntype_check()
8001 var lines =<< trim END
8002 vim9script
8003 class A
8004 endclass
8005 class B extends A
8006 endclass
8007
8008 def Foo(p: B): B
8009 return B.new()
8010 enddef
8011
8012 var Bar: func(A): A = Foo
8013 END
8014 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
8015
8016 lines =<< trim END
8017 vim9script
8018 class A
8019 endclass
8020 class B extends A
8021 endclass
8022
8023 def Foo(p: B): B
8024 return B.new()
8025 enddef
8026
8027 def Baz()
8028 var Bar: func(A): A = Foo
8029 enddef
8030 Baz()
8031 END
8032 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
8033enddef
8034
Ernie Rael96952b22023-10-17 18:15:01 +02008035def Test_funcref_argtype_invariance_check()
8036 var lines =<< trim END
8037 vim9script
8038
8039 class A
8040 endclass
8041 class B extends A
8042 endclass
8043 class C extends B
8044 endclass
8045
8046 var Func: func(B): number
8047 Func = (o: B): number => 3
8048 assert_equal(3, Func(B.new()))
8049 END
8050 v9.CheckSourceSuccess(lines)
8051
8052 lines =<< trim END
8053 vim9script
8054
8055 class A
8056 endclass
8057 class B extends A
8058 endclass
8059 class C extends B
8060 endclass
8061
8062 var Func: func(B): number
8063 Func = (o: A): number => 3
8064 END
8065 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
8066
8067 lines =<< trim END
8068 vim9script
8069
8070 class A
8071 endclass
8072 class B extends A
8073 endclass
8074 class C extends B
8075 endclass
8076
8077 var Func: func(B): number
8078 Func = (o: C): number => 3
8079 END
8080 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
8081enddef
8082
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008083" Test for using an operator (e.g. +) with an assignment
8084def Test_op_and_assignment()
8085 # Using += with a class variable
8086 var lines =<< trim END
8087 vim9script
8088 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008089 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008090 static def Foo(): list<number>
8091 val += [1]
8092 return val
8093 enddef
8094 endclass
8095 def Bar(): list<number>
8096 A.val += [2]
8097 return A.val
8098 enddef
8099 assert_equal([1], A.Foo())
8100 assert_equal([1, 2], Bar())
8101 A.val += [3]
8102 assert_equal([1, 2, 3], A.val)
8103 END
8104 v9.CheckSourceSuccess(lines)
8105
8106 # Using += with an object variable
8107 lines =<< trim END
8108 vim9script
8109 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008110 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008111 def Foo(): list<number>
8112 this.val += [1]
8113 return this.val
8114 enddef
8115 endclass
8116 def Bar(bar_a: A): list<number>
8117 bar_a.val += [2]
8118 return bar_a.val
8119 enddef
8120 var a = A.new()
8121 assert_equal([1], a.Foo())
8122 assert_equal([1, 2], Bar(a))
8123 a.val += [3]
8124 assert_equal([1, 2, 3], a.val)
8125 END
8126 v9.CheckSourceSuccess(lines)
8127enddef
8128
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008129" Test for using an object method as a funcref
8130def Test_object_funcref()
8131 # Using object method funcref from a def function
8132 var lines =<< trim END
8133 vim9script
8134 class A
8135 def Foo(): list<number>
8136 return [3, 2, 1]
8137 enddef
8138 endclass
8139 def Bar()
8140 var a = A.new()
8141 var Fn = a.Foo
8142 assert_equal([3, 2, 1], Fn())
8143 enddef
8144 Bar()
8145 END
8146 v9.CheckSourceSuccess(lines)
8147
8148 # Using object method funcref at the script level
8149 lines =<< trim END
8150 vim9script
8151 class A
8152 def Foo(): dict<number>
8153 return {a: 1, b: 2}
8154 enddef
8155 endclass
8156 var a = A.new()
8157 var Fn = a.Foo
8158 assert_equal({a: 1, b: 2}, Fn())
8159 END
8160 v9.CheckSourceSuccess(lines)
8161
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008162 # Using object method funcref at the script level
8163 lines =<< trim END
8164 vim9script
8165 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008166 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008167 def Foo(): number
8168 return this.val
8169 enddef
8170 endclass
8171 var a = A.new(345)
8172 var Fn = a.Foo
8173 assert_equal(345, Fn())
8174 END
8175 v9.CheckSourceSuccess(lines)
8176
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008177 # Using object method funcref from another object method
8178 lines =<< trim END
8179 vim9script
8180 class A
8181 def Foo(): list<number>
8182 return [3, 2, 1]
8183 enddef
8184 def Bar()
8185 var Fn = this.Foo
8186 assert_equal([3, 2, 1], Fn())
8187 enddef
8188 endclass
8189 var a = A.new()
8190 a.Bar()
8191 END
8192 v9.CheckSourceSuccess(lines)
8193
8194 # Using function() to get a object method funcref
8195 lines =<< trim END
8196 vim9script
8197 class A
8198 def Foo(l: list<any>): list<any>
8199 return l
8200 enddef
8201 endclass
8202 var a = A.new()
8203 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8204 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8205 END
8206 v9.CheckSourceSuccess(lines)
8207
8208 # Use an object method with a function returning a funcref and then call the
8209 # funcref.
8210 lines =<< trim END
8211 vim9script
8212
8213 def Map(F: func(number): number): func(number): number
8214 return (n: number) => F(n)
8215 enddef
8216
8217 class Math
8218 def Double(n: number): number
8219 return 2 * n
8220 enddef
8221 endclass
8222
8223 const math = Math.new()
8224 assert_equal(48, Map(math.Double)(24))
8225 END
8226 v9.CheckSourceSuccess(lines)
8227
Ernie Rael03042a22023-11-11 08:53:32 +01008228 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008229 lines =<< trim END
8230 vim9script
8231 class A
8232 def _Foo()
8233 enddef
8234 endclass
8235 def Bar()
8236 var a = A.new()
8237 var Fn = a._Foo
8238 enddef
8239 Bar()
8240 END
Ernie Rael03042a22023-11-11 08:53:32 +01008241 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008242
Ernie Rael03042a22023-11-11 08:53:32 +01008243 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008244 lines =<< trim END
8245 vim9script
8246 class A
8247 def _Foo()
8248 enddef
8249 endclass
8250 var a = A.new()
8251 var Fn = a._Foo
8252 END
Ernie Rael03042a22023-11-11 08:53:32 +01008253 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008254
Ernie Rael03042a22023-11-11 08:53:32 +01008255 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008256 lines =<< trim END
8257 vim9script
8258 class A
8259 def _Foo(): list<number>
8260 return [3, 2, 1]
8261 enddef
8262 def Bar()
8263 var Fn = this._Foo
8264 assert_equal([3, 2, 1], Fn())
8265 enddef
8266 endclass
8267 var a = A.new()
8268 a.Bar()
8269 END
8270 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008271
8272 # Using object method funcref using call()
8273 lines =<< trim END
8274 vim9script
8275 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008276 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008277 def Foo(): number
8278 return this.val
8279 enddef
8280 endclass
8281
8282 def Bar(obj: A)
8283 assert_equal(123, call(obj.Foo, []))
8284 enddef
8285
8286 var a = A.new(123)
8287 Bar(a)
8288 assert_equal(123, call(a.Foo, []))
8289 END
8290 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008291enddef
8292
8293" Test for using a class method as a funcref
8294def Test_class_funcref()
8295 # Using class method funcref in a def function
8296 var lines =<< trim END
8297 vim9script
8298 class A
8299 static def Foo(): list<number>
8300 return [3, 2, 1]
8301 enddef
8302 endclass
8303 def Bar()
8304 var Fn = A.Foo
8305 assert_equal([3, 2, 1], Fn())
8306 enddef
8307 Bar()
8308 END
8309 v9.CheckSourceSuccess(lines)
8310
8311 # Using class method funcref at script level
8312 lines =<< trim END
8313 vim9script
8314 class A
8315 static def Foo(): dict<number>
8316 return {a: 1, b: 2}
8317 enddef
8318 endclass
8319 var Fn = A.Foo
8320 assert_equal({a: 1, b: 2}, Fn())
8321 END
8322 v9.CheckSourceSuccess(lines)
8323
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008324 # Using class method funcref at the script level
8325 lines =<< trim END
8326 vim9script
8327 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008328 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008329 static def Foo(): number
8330 return val
8331 enddef
8332 endclass
8333 A.val = 567
8334 var Fn = A.Foo
8335 assert_equal(567, Fn())
8336 END
8337 v9.CheckSourceSuccess(lines)
8338
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008339 # Using function() to get a class method funcref
8340 lines =<< trim END
8341 vim9script
8342 class A
8343 static def Foo(l: list<any>): list<any>
8344 return l
8345 enddef
8346 endclass
8347 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8348 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8349 END
8350 v9.CheckSourceSuccess(lines)
8351
8352 # Using a class method funcref from another class method
8353 lines =<< trim END
8354 vim9script
8355 class A
8356 static def Foo(): list<number>
8357 return [3, 2, 1]
8358 enddef
8359 static def Bar()
8360 var Fn = Foo
8361 assert_equal([3, 2, 1], Fn())
8362 enddef
8363 endclass
8364 A.Bar()
8365 END
8366 v9.CheckSourceSuccess(lines)
8367
8368 # Use a class method with a function returning a funcref and then call the
8369 # funcref.
8370 lines =<< trim END
8371 vim9script
8372
8373 def Map(F: func(number): number): func(number): number
8374 return (n: number) => F(n)
8375 enddef
8376
8377 class Math
8378 static def StaticDouble(n: number): number
8379 return 2 * n
8380 enddef
8381 endclass
8382
8383 assert_equal(48, Map(Math.StaticDouble)(24))
8384 END
8385 v9.CheckSourceSuccess(lines)
8386
Ernie Rael03042a22023-11-11 08:53:32 +01008387 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008388 lines =<< trim END
8389 vim9script
8390 class A
8391 static def _Foo()
8392 enddef
8393 endclass
8394 def Bar()
8395 var Fn = A._Foo
8396 enddef
8397 Bar()
8398 END
Ernie Rael03042a22023-11-11 08:53:32 +01008399 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008400
Ernie Rael03042a22023-11-11 08:53:32 +01008401 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008402 lines =<< trim END
8403 vim9script
8404 class A
8405 static def _Foo()
8406 enddef
8407 endclass
8408 var Fn = A._Foo
8409 END
Ernie Rael03042a22023-11-11 08:53:32 +01008410 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008411
Ernie Rael03042a22023-11-11 08:53:32 +01008412 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008413 lines =<< trim END
8414 vim9script
8415 class A
8416 static def _Foo(): list<number>
8417 return [3, 2, 1]
8418 enddef
8419 static def Bar()
8420 var Fn = _Foo
8421 assert_equal([3, 2, 1], Fn())
8422 enddef
8423 endclass
8424 A.Bar()
8425 END
8426 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008427
8428 # Using class method funcref using call()
8429 lines =<< trim END
8430 vim9script
8431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008432 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008433 static def Foo(): number
8434 return val
8435 enddef
8436 endclass
8437
8438 def Bar()
8439 A.val = 468
8440 assert_equal(468, call(A.Foo, []))
8441 enddef
8442 Bar()
8443 assert_equal(468, call(A.Foo, []))
8444 END
8445 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008446enddef
8447
8448" Test for using an object member as a funcref
8449def Test_object_member_funcref()
8450 # Using a funcref object variable in an object method
8451 var lines =<< trim END
8452 vim9script
8453 def Foo(n: number): number
8454 return n * 10
8455 enddef
8456
8457 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008458 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008459 def Bar()
8460 assert_equal(200, this.Cb(20))
8461 enddef
8462 endclass
8463
8464 var a = A.new()
8465 a.Bar()
8466 END
8467 v9.CheckSourceSuccess(lines)
8468
8469 # Using a funcref object variable in a def method
8470 lines =<< trim END
8471 vim9script
8472 def Foo(n: number): number
8473 return n * 10
8474 enddef
8475
8476 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008477 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008478 endclass
8479
8480 def Bar()
8481 var a = A.new()
8482 assert_equal(200, a.Cb(20))
8483 enddef
8484 Bar()
8485 END
8486 v9.CheckSourceSuccess(lines)
8487
8488 # Using a funcref object variable at script level
8489 lines =<< trim END
8490 vim9script
8491 def Foo(n: number): number
8492 return n * 10
8493 enddef
8494
8495 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008496 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008497 endclass
8498
8499 var a = A.new()
8500 assert_equal(200, a.Cb(20))
8501 END
8502 v9.CheckSourceSuccess(lines)
8503
8504 # Using a funcref object variable pointing to an object method in an object
8505 # method.
8506 lines =<< trim END
8507 vim9script
8508 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008509 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008510 def Foo(n: number): number
8511 return n * 10
8512 enddef
8513 def Bar()
8514 assert_equal(200, this.Cb(20))
8515 enddef
8516 endclass
8517
8518 var a = A.new()
8519 a.Bar()
8520 END
8521 v9.CheckSourceSuccess(lines)
8522
8523 # Using a funcref object variable pointing to an object method in a def
8524 # method.
8525 lines =<< trim END
8526 vim9script
8527 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008528 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008529 def Foo(n: number): number
8530 return n * 10
8531 enddef
8532 endclass
8533
8534 def Bar()
8535 var a = A.new()
8536 assert_equal(200, a.Cb(20))
8537 enddef
8538 Bar()
8539 END
8540 v9.CheckSourceSuccess(lines)
8541
8542 # Using a funcref object variable pointing to an object method at script
8543 # level.
8544 lines =<< trim END
8545 vim9script
8546 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008547 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008548 def Foo(n: number): number
8549 return n * 10
8550 enddef
8551 endclass
8552
8553 var a = A.new()
8554 assert_equal(200, a.Cb(20))
8555 END
8556 v9.CheckSourceSuccess(lines)
8557enddef
8558
8559" Test for using a class member as a funcref
8560def Test_class_member_funcref()
8561 # Using a funcref class variable in a class method
8562 var lines =<< trim END
8563 vim9script
8564 def Foo(n: number): number
8565 return n * 10
8566 enddef
8567
8568 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008569 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008570 static def Bar()
8571 assert_equal(200, Cb(20))
8572 enddef
8573 endclass
8574
8575 A.Bar()
8576 END
8577 v9.CheckSourceSuccess(lines)
8578
8579 # Using a funcref class variable in a def method
8580 lines =<< trim END
8581 vim9script
8582 def Foo(n: number): number
8583 return n * 10
8584 enddef
8585
8586 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008587 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008588 endclass
8589
8590 def Bar()
8591 assert_equal(200, A.Cb(20))
8592 enddef
8593 Bar()
8594 END
8595 v9.CheckSourceSuccess(lines)
8596
8597 # Using a funcref class variable at script level
8598 lines =<< trim END
8599 vim9script
8600 def Foo(n: number): number
8601 return n * 10
8602 enddef
8603
8604 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008605 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008606 endclass
8607
8608 assert_equal(200, A.Cb(20))
8609 END
8610 v9.CheckSourceSuccess(lines)
8611
8612 # Using a funcref class variable pointing to a class method in a class
8613 # method.
8614 lines =<< trim END
8615 vim9script
8616 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008617 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008618 static def Foo(n: number): number
8619 return n * 10
8620 enddef
8621 static def Init()
8622 Cb = Foo
8623 enddef
8624 static def Bar()
8625 assert_equal(200, Cb(20))
8626 enddef
8627 endclass
8628
8629 A.Init()
8630 A.Bar()
8631 END
8632 v9.CheckSourceSuccess(lines)
8633
8634 # Using a funcref class variable pointing to a class method in a def method.
8635 lines =<< trim END
8636 vim9script
8637 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008638 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008639 static def Foo(n: number): number
8640 return n * 10
8641 enddef
8642 static def Init()
8643 Cb = Foo
8644 enddef
8645 endclass
8646
8647 def Bar()
8648 A.Init()
8649 assert_equal(200, A.Cb(20))
8650 enddef
8651 Bar()
8652 END
8653 v9.CheckSourceSuccess(lines)
8654
8655 # Using a funcref class variable pointing to a class method at script level.
8656 lines =<< trim END
8657 vim9script
8658 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008659 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008660 static def Foo(n: number): number
8661 return n * 10
8662 enddef
8663 static def Init()
8664 Cb = Foo
8665 enddef
8666 endclass
8667
8668 A.Init()
8669 assert_equal(200, A.Cb(20))
8670 END
8671 v9.CheckSourceSuccess(lines)
8672enddef
8673
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008674" Test for using object methods as popup callback functions
8675def Test_objmethod_popup_callback()
8676 # Use the popup from the script level
8677 var lines =<< trim END
8678 vim9script
8679
8680 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008681 var selection: number = -1
8682 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008683
8684 def PopupFilter(id: number, key: string): bool
8685 add(this.filterkeys, key)
8686 return popup_filter_yesno(id, key)
8687 enddef
8688
8689 def PopupCb(id: number, result: number)
8690 this.selection = result ? 100 : 200
8691 enddef
8692 endclass
8693
8694 var a = A.new()
8695 feedkeys('', 'xt')
8696 var winid = popup_create('Y/N?',
8697 {filter: a.PopupFilter, callback: a.PopupCb})
8698 feedkeys('y', 'xt')
8699 popup_close(winid)
8700 assert_equal(100, a.selection)
8701 assert_equal(['y'], a.filterkeys)
8702 feedkeys('', 'xt')
8703 winid = popup_create('Y/N?',
8704 {filter: a.PopupFilter, callback: a.PopupCb})
8705 feedkeys('n', 'xt')
8706 popup_close(winid)
8707 assert_equal(200, a.selection)
8708 assert_equal(['y', 'n'], a.filterkeys)
8709 END
8710 v9.CheckSourceSuccess(lines)
8711
8712 # Use the popup from a def function
8713 lines =<< trim END
8714 vim9script
8715
8716 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008717 var selection: number = -1
8718 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008719
8720 def PopupFilter(id: number, key: string): bool
8721 add(this.filterkeys, key)
8722 return popup_filter_yesno(id, key)
8723 enddef
8724
8725 def PopupCb(id: number, result: number)
8726 this.selection = result ? 100 : 200
8727 enddef
8728 endclass
8729
8730 def Foo()
8731 var a = A.new()
8732 feedkeys('', 'xt')
8733 var winid = popup_create('Y/N?',
8734 {filter: a.PopupFilter, callback: a.PopupCb})
8735 feedkeys('y', 'xt')
8736 popup_close(winid)
8737 assert_equal(100, a.selection)
8738 assert_equal(['y'], a.filterkeys)
8739 feedkeys('', 'xt')
8740 winid = popup_create('Y/N?',
8741 {filter: a.PopupFilter, callback: a.PopupCb})
8742 feedkeys('n', 'xt')
8743 popup_close(winid)
8744 assert_equal(200, a.selection)
8745 assert_equal(['y', 'n'], a.filterkeys)
8746 enddef
8747 Foo()
8748 END
8749 v9.CheckSourceSuccess(lines)
8750enddef
8751
8752" Test for using class methods as popup callback functions
8753def Test_classmethod_popup_callback()
8754 # Use the popup from the script level
8755 var lines =<< trim END
8756 vim9script
8757
8758 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008759 static var selection: number = -1
8760 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008761
8762 static def PopupFilter(id: number, key: string): bool
8763 add(filterkeys, key)
8764 return popup_filter_yesno(id, key)
8765 enddef
8766
8767 static def PopupCb(id: number, result: number)
8768 selection = result ? 100 : 200
8769 enddef
8770 endclass
8771
8772 feedkeys('', 'xt')
8773 var winid = popup_create('Y/N?',
8774 {filter: A.PopupFilter, callback: A.PopupCb})
8775 feedkeys('y', 'xt')
8776 popup_close(winid)
8777 assert_equal(100, A.selection)
8778 assert_equal(['y'], A.filterkeys)
8779 feedkeys('', 'xt')
8780 winid = popup_create('Y/N?',
8781 {filter: A.PopupFilter, callback: A.PopupCb})
8782 feedkeys('n', 'xt')
8783 popup_close(winid)
8784 assert_equal(200, A.selection)
8785 assert_equal(['y', 'n'], A.filterkeys)
8786 END
8787 v9.CheckSourceSuccess(lines)
8788
8789 # Use the popup from a def function
8790 lines =<< trim END
8791 vim9script
8792
8793 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008794 static var selection: number = -1
8795 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008796
8797 static def PopupFilter(id: number, key: string): bool
8798 add(filterkeys, key)
8799 return popup_filter_yesno(id, key)
8800 enddef
8801
8802 static def PopupCb(id: number, result: number)
8803 selection = result ? 100 : 200
8804 enddef
8805 endclass
8806
8807 def Foo()
8808 feedkeys('', 'xt')
8809 var winid = popup_create('Y/N?',
8810 {filter: A.PopupFilter, callback: A.PopupCb})
8811 feedkeys('y', 'xt')
8812 popup_close(winid)
8813 assert_equal(100, A.selection)
8814 assert_equal(['y'], A.filterkeys)
8815 feedkeys('', 'xt')
8816 winid = popup_create('Y/N?',
8817 {filter: A.PopupFilter, callback: A.PopupCb})
8818 feedkeys('n', 'xt')
8819 popup_close(winid)
8820 assert_equal(200, A.selection)
8821 assert_equal(['y', 'n'], A.filterkeys)
8822 enddef
8823 Foo()
8824 END
8825 v9.CheckSourceSuccess(lines)
8826enddef
8827
8828" Test for using an object method as a timer callback function
8829def Test_objmethod_timer_callback()
8830 # Use the timer callback from script level
8831 var lines =<< trim END
8832 vim9script
8833
8834 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008835 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008836 def TimerCb(timerID: number)
8837 this.timerTick = 6
8838 enddef
8839 endclass
8840
8841 var a = A.new()
8842 timer_start(0, a.TimerCb)
8843 var maxWait = 5
8844 while maxWait > 0 && a.timerTick == -1
8845 :sleep 10m
8846 maxWait -= 1
8847 endwhile
8848 assert_equal(6, a.timerTick)
8849 END
8850 v9.CheckSourceSuccess(lines)
8851
8852 # Use the timer callback from a def function
8853 lines =<< trim END
8854 vim9script
8855
8856 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008857 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008858 def TimerCb(timerID: number)
8859 this.timerTick = 6
8860 enddef
8861 endclass
8862
8863 def Foo()
8864 var a = A.new()
8865 timer_start(0, a.TimerCb)
8866 var maxWait = 5
8867 while maxWait > 0 && a.timerTick == -1
8868 :sleep 10m
8869 maxWait -= 1
8870 endwhile
8871 assert_equal(6, a.timerTick)
8872 enddef
8873 Foo()
8874 END
8875 v9.CheckSourceSuccess(lines)
8876enddef
8877
8878" Test for using a class method as a timer callback function
8879def Test_classmethod_timer_callback()
8880 # Use the timer callback from script level
8881 var lines =<< trim END
8882 vim9script
8883
8884 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008885 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008886 static def TimerCb(timerID: number)
8887 timerTick = 6
8888 enddef
8889 endclass
8890
8891 timer_start(0, A.TimerCb)
8892 var maxWait = 5
8893 while maxWait > 0 && A.timerTick == -1
8894 :sleep 10m
8895 maxWait -= 1
8896 endwhile
8897 assert_equal(6, A.timerTick)
8898 END
8899 v9.CheckSourceSuccess(lines)
8900
8901 # Use the timer callback from a def function
8902 lines =<< trim END
8903 vim9script
8904
8905 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008906 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008907 static def TimerCb(timerID: number)
8908 timerTick = 6
8909 enddef
8910 endclass
8911
8912 def Foo()
8913 timer_start(0, A.TimerCb)
8914 var maxWait = 5
8915 while maxWait > 0 && A.timerTick == -1
8916 :sleep 10m
8917 maxWait -= 1
8918 endwhile
8919 assert_equal(6, A.timerTick)
8920 enddef
8921 Foo()
8922 END
8923 v9.CheckSourceSuccess(lines)
8924enddef
8925
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008926" Test for using a class variable as the first and/or second operand of a binary
8927" operator.
8928def Test_class_variable_as_operands()
8929 var lines =<< trim END
8930 vim9script
8931 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008932 static var truthy: bool = true
8933 public static var TruthyFn: func
8934 static var list: list<any> = []
8935 static var four: number = 4
8936 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008937
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008938 static def Str(): string
8939 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008940 enddef
8941
8942 static def Four(): number
8943 return four
8944 enddef
8945
8946 static def List(): list<any>
8947 return list
8948 enddef
8949
8950 static def Truthy(): bool
8951 return truthy
8952 enddef
8953
8954 def TestOps()
8955 assert_true(Tests.truthy == truthy)
8956 assert_true(truthy == Tests.truthy)
8957 assert_true(Tests.list isnot [])
8958 assert_true([] isnot Tests.list)
8959 assert_equal(2, Tests.four >> 1)
8960 assert_equal(16, 1 << Tests.four)
8961 assert_equal(8, Tests.four + four)
8962 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008963 assert_equal('hellohello', Tests.str .. str)
8964 assert_equal('hellohello', str .. Tests.str)
8965
8966 # Using class variable for list indexing
8967 var l = range(10)
8968 assert_equal(4, l[Tests.four])
8969 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8970
8971 # Using class variable for Dict key
8972 var d = {hello: 'abc'}
8973 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008974 enddef
8975 endclass
8976
8977 def TestOps2()
8978 assert_true(Tests.truthy == Tests.Truthy())
8979 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008980 assert_true(Tests.truthy == Tests.TruthyFn())
8981 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008982 assert_true(Tests.list is Tests.List())
8983 assert_true(Tests.List() is Tests.list)
8984 assert_equal(2, Tests.four >> 1)
8985 assert_equal(16, 1 << Tests.four)
8986 assert_equal(8, Tests.four + Tests.Four())
8987 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008988 assert_equal('hellohello', Tests.str .. Tests.Str())
8989 assert_equal('hellohello', Tests.Str() .. Tests.str)
8990
8991 # Using class variable for list indexing
8992 var l = range(10)
8993 assert_equal(4, l[Tests.four])
8994 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8995
8996 # Using class variable for Dict key
8997 var d = {hello: 'abc'}
8998 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008999 enddef
9000
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009001 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009002 var t = Tests.new()
9003 t.TestOps()
9004 TestOps2()
9005
9006 assert_true(Tests.truthy == Tests.Truthy())
9007 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009008 assert_true(Tests.truthy == Tests.TruthyFn())
9009 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009010 assert_true(Tests.list is Tests.List())
9011 assert_true(Tests.List() is Tests.list)
9012 assert_equal(2, Tests.four >> 1)
9013 assert_equal(16, 1 << Tests.four)
9014 assert_equal(8, Tests.four + Tests.Four())
9015 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009016 assert_equal('hellohello', Tests.str .. Tests.Str())
9017 assert_equal('hellohello', Tests.Str() .. Tests.str)
9018
9019 # Using class variable for list indexing
9020 var l = range(10)
9021 assert_equal(4, l[Tests.four])
9022 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9023
9024 # Using class variable for Dict key
9025 var d = {hello: 'abc'}
9026 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009027 END
9028 v9.CheckSourceSuccess(lines)
9029enddef
9030
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009031" Test for checking the type of the key used to access an object dict member.
9032def Test_dict_member_key_type_check()
9033 var lines =<< trim END
9034 vim9script
9035
9036 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01009037 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009038 endclass
9039
9040 class Test extends State
9041 def ObjMethodTests()
9042 var cursor: number = 0
9043 var z: number = 0
9044 [this.numbers[cursor]] = ['zero.1']
9045 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9046 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9047 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9048 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9049 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9050 [this.numbers[cursor], z] = ['zero.4', 1]
9051 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9052 [z, this.numbers[cursor]] = [1, 'zero.5']
9053 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9054 enddef
9055
9056 static def ClassMethodTests(that: State)
9057 var cursor: number = 0
9058 var z: number = 0
9059 [that.numbers[cursor]] = ['zero.1']
9060 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9061 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9062 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9063 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9064 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9065 [that.numbers[cursor], z] = ['zero.4', 1]
9066 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9067 [z, that.numbers[cursor]] = [1, 'zero.5']
9068 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9069 enddef
9070
9071 def new()
9072 enddef
9073
9074 def newMethodTests()
9075 var cursor: number = 0
9076 var z: number
9077 [this.numbers[cursor]] = ['zero.1']
9078 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9079 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9080 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9081 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9082 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9083 [this.numbers[cursor], z] = ['zero.4', 1]
9084 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9085 [z, this.numbers[cursor]] = [1, 'zero.5']
9086 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9087 enddef
9088 endclass
9089
9090 def DefFuncTests(that: Test)
9091 var cursor: number = 0
9092 var z: number
9093 [that.numbers[cursor]] = ['zero.1']
9094 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9095 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9096 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9097 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9098 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9099 [that.numbers[cursor], z] = ['zero.4', 1]
9100 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9101 [z, that.numbers[cursor]] = [1, 'zero.5']
9102 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9103 enddef
9104
9105 Test.newMethodTests()
9106 Test.new().ObjMethodTests()
9107 Test.ClassMethodTests(Test.new())
9108 DefFuncTests(Test.new())
9109
9110 const test: Test = Test.new()
9111 var cursor: number = 0
9112 [test.numbers[cursor], cursor] = ['zero', 1]
9113 [cursor, test.numbers[cursor]] = [1, 'one']
9114 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
9115 END
9116 v9.CheckSourceSuccess(lines)
9117
9118 lines =<< trim END
9119 vim9script
9120
9121 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009122 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009123
9124 def new()
9125 enddef
9126
9127 def Foo()
9128 var z: number
9129 [this.numbers.a, z] = [{}, 10]
9130 enddef
9131 endclass
9132
9133 var a = A.new()
9134 a.Foo()
9135 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009136 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009137
9138 lines =<< trim END
9139 vim9script
9140
9141 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009142 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009143
9144 def new()
9145 enddef
9146
9147 def Foo()
9148 var x: string = 'a'
9149 var y: number
9150 [this.numbers[x], y] = [{}, 10]
9151 enddef
9152 endclass
9153
9154 var a = A.new()
9155 a.Foo()
9156 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009157 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009158enddef
9159
mityua5550692023-11-25 15:41:20 +01009160def Test_compile_many_def_functions_in_funcref_instr()
9161 # This used to crash Vim. This is reproducible only when run on new instance
9162 # of Vim.
9163 var lines =<< trim END
9164 vim9script
9165
9166 class A
9167 def new()
9168 this.TakeFunc(this.F00)
9169 enddef
9170
9171 def TakeFunc(F: func)
9172 enddef
9173
9174 def F00()
9175 this.F01()
9176 this.F02()
9177 this.F03()
9178 this.F04()
9179 this.F05()
9180 this.F06()
9181 this.F07()
9182 this.F08()
9183 this.F09()
9184 this.F10()
9185 this.F11()
9186 this.F12()
9187 this.F13()
9188 this.F14()
9189 this.F15()
9190 this.F16()
9191 this.F17()
9192 this.F18()
9193 this.F19()
9194 this.F20()
9195 this.F21()
9196 this.F22()
9197 this.F23()
9198 this.F24()
9199 this.F25()
9200 this.F26()
9201 this.F27()
9202 this.F28()
9203 this.F29()
9204 this.F30()
9205 this.F31()
9206 this.F32()
9207 this.F33()
9208 this.F34()
9209 this.F35()
9210 this.F36()
9211 this.F37()
9212 this.F38()
9213 this.F39()
9214 this.F40()
9215 this.F41()
9216 this.F42()
9217 this.F43()
9218 this.F44()
9219 this.F45()
9220 this.F46()
9221 this.F47()
9222 enddef
9223
9224 def F01()
9225 enddef
9226 def F02()
9227 enddef
9228 def F03()
9229 enddef
9230 def F04()
9231 enddef
9232 def F05()
9233 enddef
9234 def F06()
9235 enddef
9236 def F07()
9237 enddef
9238 def F08()
9239 enddef
9240 def F09()
9241 enddef
9242 def F10()
9243 enddef
9244 def F11()
9245 enddef
9246 def F12()
9247 enddef
9248 def F13()
9249 enddef
9250 def F14()
9251 enddef
9252 def F15()
9253 enddef
9254 def F16()
9255 enddef
9256 def F17()
9257 enddef
9258 def F18()
9259 enddef
9260 def F19()
9261 enddef
9262 def F20()
9263 enddef
9264 def F21()
9265 enddef
9266 def F22()
9267 enddef
9268 def F23()
9269 enddef
9270 def F24()
9271 enddef
9272 def F25()
9273 enddef
9274 def F26()
9275 enddef
9276 def F27()
9277 enddef
9278 def F28()
9279 enddef
9280 def F29()
9281 enddef
9282 def F30()
9283 enddef
9284 def F31()
9285 enddef
9286 def F32()
9287 enddef
9288 def F33()
9289 enddef
9290 def F34()
9291 enddef
9292 def F35()
9293 enddef
9294 def F36()
9295 enddef
9296 def F37()
9297 enddef
9298 def F38()
9299 enddef
9300 def F39()
9301 enddef
9302 def F40()
9303 enddef
9304 def F41()
9305 enddef
9306 def F42()
9307 enddef
9308 def F43()
9309 enddef
9310 def F44()
9311 enddef
9312 def F45()
9313 enddef
9314 def F46()
9315 enddef
9316 def F47()
9317 enddef
9318 endclass
9319
9320 A.new()
9321 END
9322 writefile(lines, 'Xscript', 'D')
9323 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9324 assert_equal(0, v:shell_error)
9325enddef
9326
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009327" Test for 'final' class and object variables
9328def Test_final_class_object_variable()
9329 # Test for changing a final object variable from an object function
9330 var lines =<< trim END
9331 vim9script
9332 class A
9333 final foo: string = "abc"
9334 def Foo()
9335 this.foo = "def"
9336 enddef
9337 endclass
9338 defcompile A.Foo
9339 END
9340 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9341
9342 # Test for changing a final object variable from the 'new' function
9343 lines =<< trim END
9344 vim9script
9345 class A
9346 final s1: string
9347 final s2: string
9348 def new(this.s1)
9349 this.s2 = 'def'
9350 enddef
9351 endclass
9352 var a = A.new('abc')
9353 assert_equal('abc', a.s1)
9354 assert_equal('def', a.s2)
9355 END
9356 v9.CheckSourceSuccess(lines)
9357
9358 # Test for a final class variable
9359 lines =<< trim END
9360 vim9script
9361 class A
9362 static final s1: string = "abc"
9363 endclass
9364 assert_equal('abc', A.s1)
9365 END
9366 v9.CheckSourceSuccess(lines)
9367
9368 # Test for changing a final class variable from a class function
9369 lines =<< trim END
9370 vim9script
9371 class A
9372 static final s1: string = "abc"
9373 static def Foo()
9374 s1 = "def"
9375 enddef
9376 endclass
9377 A.Foo()
9378 END
9379 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9380
9381 # Test for changing a public final class variable at script level
9382 lines =<< trim END
9383 vim9script
9384 class A
9385 public static final s1: string = "abc"
9386 endclass
9387 assert_equal('abc', A.s1)
9388 A.s1 = 'def'
9389 END
9390 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9391
9392 # Test for changing a public final class variable from a class function
9393 lines =<< trim END
9394 vim9script
9395 class A
9396 public static final s1: string = "abc"
9397 static def Foo()
9398 s1 = "def"
9399 enddef
9400 endclass
9401 A.Foo()
9402 END
9403 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9404
9405 # Test for changing a public final class variable from a function
9406 lines =<< trim END
9407 vim9script
9408 class A
9409 public static final s1: string = "abc"
9410 endclass
9411 def Foo()
9412 A.s1 = 'def'
9413 enddef
9414 defcompile
9415 END
9416 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9417
9418 # Test for using a final variable of composite type
9419 lines =<< trim END
9420 vim9script
9421 class A
9422 public final l: list<number>
9423 def new()
9424 this.l = [1, 2]
9425 enddef
9426 def Foo()
9427 this.l[0] = 3
9428 this.l->add(4)
9429 enddef
9430 endclass
9431 var a = A.new()
9432 assert_equal([1, 2], a.l)
9433 a.Foo()
9434 assert_equal([3, 2, 4], a.l)
9435 END
9436 v9.CheckSourceSuccess(lines)
9437
9438 # Test for changing a final variable of composite type from another object
9439 # function
9440 lines =<< trim END
9441 vim9script
9442 class A
9443 public final l: list<number> = [1, 2]
9444 def Foo()
9445 this.l = [3, 4]
9446 enddef
9447 endclass
9448 var a = A.new()
9449 a.Foo()
9450 END
9451 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9452
9453 # Test for modifying a final variable of composite type at script level
9454 lines =<< trim END
9455 vim9script
9456 class A
9457 public final l: list<number> = [1, 2]
9458 endclass
9459 var a = A.new()
9460 a.l[0] = 3
9461 a.l->add(4)
9462 assert_equal([3, 2, 4], a.l)
9463 END
9464 v9.CheckSourceSuccess(lines)
9465
9466 # Test for modifying a final variable of composite type from a function
9467 lines =<< trim END
9468 vim9script
9469 class A
9470 public final l: list<number> = [1, 2]
9471 endclass
9472 def Foo()
9473 var a = A.new()
9474 a.l[0] = 3
9475 a.l->add(4)
9476 assert_equal([3, 2, 4], a.l)
9477 enddef
9478 Foo()
9479 END
9480 v9.CheckSourceSuccess(lines)
9481
9482 # Test for modifying a final variable of composite type from another object
9483 # function
9484 lines =<< trim END
9485 vim9script
9486 class A
9487 public final l: list<number> = [1, 2]
9488 def Foo()
9489 this.l[0] = 3
9490 this.l->add(4)
9491 enddef
9492 endclass
9493 var a = A.new()
9494 a.Foo()
9495 assert_equal([3, 2, 4], a.l)
9496 END
9497 v9.CheckSourceSuccess(lines)
9498
9499 # Test for assigning a new value to a final variable of composite type at
9500 # script level
9501 lines =<< trim END
9502 vim9script
9503 class A
9504 public final l: list<number> = [1, 2]
9505 endclass
9506 var a = A.new()
9507 a.l = [3, 4]
9508 END
9509 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9510
9511 # Test for assigning a new value to a final variable of composite type from
9512 # another object function
9513 lines =<< trim END
9514 vim9script
9515 class A
9516 public final l: list<number> = [1, 2]
9517 def Foo()
9518 this.l = [3, 4]
9519 enddef
9520 endclass
9521 var a = A.new()
9522 a.Foo()
9523 END
9524 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9525
9526 # Test for assigning a new value to a final variable of composite type from
9527 # another function
9528 lines =<< trim END
9529 vim9script
9530 class A
9531 public final l: list<number> = [1, 2]
9532 endclass
9533 def Foo()
9534 var a = A.new()
9535 a.l = [3, 4]
9536 enddef
9537 Foo()
9538 END
9539 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9540
9541 # Error case: Use 'final' with just a variable name
9542 lines =<< trim END
9543 vim9script
9544 class A
9545 final foo
9546 endclass
9547 var a = A.new()
9548 END
9549 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9550
9551 # Error case: Use 'final' followed by 'public'
9552 lines =<< trim END
9553 vim9script
9554 class A
9555 final public foo: number
9556 endclass
9557 var a = A.new()
9558 END
9559 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9560
9561 # Error case: Use 'final' followed by 'static'
9562 lines =<< trim END
9563 vim9script
9564 class A
9565 final static foo: number
9566 endclass
9567 var a = A.new()
9568 END
9569 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9570
9571 # Error case: 'final' cannot be used in an interface
9572 lines =<< trim END
9573 vim9script
9574 interface A
9575 final foo: number = 10
9576 endinterface
9577 END
9578 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9579
9580 # Error case: 'final' not supported for an object method
9581 lines =<< trim END
9582 vim9script
9583 class A
9584 final def Foo()
9585 enddef
9586 endclass
9587 END
9588 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9589
9590 # Error case: 'final' not supported for a class method
9591 lines =<< trim END
9592 vim9script
9593 class A
9594 static final def Foo()
9595 enddef
9596 endclass
9597 END
9598 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9599enddef
9600
9601" Test for 'const' class and object variables
9602def Test_const_class_object_variable()
9603 # Test for changing a const object variable from an object function
9604 var lines =<< trim END
9605 vim9script
9606 class A
9607 const foo: string = "abc"
9608 def Foo()
9609 this.foo = "def"
9610 enddef
9611 endclass
9612 defcompile A.Foo
9613 END
9614 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9615
9616 # Test for changing a const object variable from the 'new' function
9617 lines =<< trim END
9618 vim9script
9619 class A
9620 const s1: string
9621 const s2: string
9622 def new(this.s1)
9623 this.s2 = 'def'
9624 enddef
9625 endclass
9626 var a = A.new('abc')
9627 assert_equal('abc', a.s1)
9628 assert_equal('def', a.s2)
9629 END
9630 v9.CheckSourceSuccess(lines)
9631
9632 # Test for changing a const object variable from an object method called from
9633 # the 'new' function
9634 lines =<< trim END
9635 vim9script
9636 class A
9637 const s1: string = 'abc'
9638 def new()
9639 this.ChangeStr()
9640 enddef
9641 def ChangeStr()
9642 this.s1 = 'def'
9643 enddef
9644 endclass
9645 var a = A.new()
9646 END
9647 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9648
9649 # Test for a const class variable
9650 lines =<< trim END
9651 vim9script
9652 class A
9653 static const s1: string = "abc"
9654 endclass
9655 assert_equal('abc', A.s1)
9656 END
9657 v9.CheckSourceSuccess(lines)
9658
9659 # Test for changing a const class variable from a class function
9660 lines =<< trim END
9661 vim9script
9662 class A
9663 static const s1: string = "abc"
9664 static def Foo()
9665 s1 = "def"
9666 enddef
9667 endclass
9668 A.Foo()
9669 END
9670 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9671
9672 # Test for changing a public const class variable at script level
9673 lines =<< trim END
9674 vim9script
9675 class A
9676 public static const s1: string = "abc"
9677 endclass
9678 assert_equal('abc', A.s1)
9679 A.s1 = 'def'
9680 END
9681 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9682
9683 # Test for changing a public const class variable from a class function
9684 lines =<< trim END
9685 vim9script
9686 class A
9687 public static const s1: string = "abc"
9688 static def Foo()
9689 s1 = "def"
9690 enddef
9691 endclass
9692 A.Foo()
9693 END
9694 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9695
9696 # Test for changing a public const class variable from a function
9697 lines =<< trim END
9698 vim9script
9699 class A
9700 public static const s1: string = "abc"
9701 endclass
9702 def Foo()
9703 A.s1 = 'def'
9704 enddef
9705 defcompile
9706 END
9707 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9708
9709 # Test for changing a const List item from an object function
9710 lines =<< trim END
9711 vim9script
9712 class A
9713 public const l: list<number>
9714 def new()
9715 this.l = [1, 2]
9716 enddef
9717 def Foo()
9718 this.l[0] = 3
9719 enddef
9720 endclass
9721 var a = A.new()
9722 assert_equal([1, 2], a.l)
9723 a.Foo()
9724 END
9725 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9726
9727 # Test for adding a value to a const List from an object function
9728 lines =<< trim END
9729 vim9script
9730 class A
9731 public const l: list<number>
9732 def new()
9733 this.l = [1, 2]
9734 enddef
9735 def Foo()
9736 this.l->add(3)
9737 enddef
9738 endclass
9739 var a = A.new()
9740 a.Foo()
9741 END
9742 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9743
9744 # Test for reassigning a const List from an object function
9745 lines =<< trim END
9746 vim9script
9747 class A
9748 public const l: list<number> = [1, 2]
9749 def Foo()
9750 this.l = [3, 4]
9751 enddef
9752 endclass
9753 var a = A.new()
9754 a.Foo()
9755 END
9756 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9757
9758 # Test for changing a const List item at script level
9759 lines =<< trim END
9760 vim9script
9761 class A
9762 public const l: list<number> = [1, 2]
9763 endclass
9764 var a = A.new()
9765 a.l[0] = 3
9766 END
9767 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9768
9769 # Test for adding a value to a const List item at script level
9770 lines =<< trim END
9771 vim9script
9772 class A
9773 public const l: list<number> = [1, 2]
9774 endclass
9775 var a = A.new()
9776 a.l->add(4)
9777 END
9778 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9779
9780 # Test for changing a const List item from a function
9781 lines =<< trim END
9782 vim9script
9783 class A
9784 public const l: list<number> = [1, 2]
9785 endclass
9786 def Foo()
9787 var a = A.new()
9788 a.l[0] = 3
9789 enddef
9790 Foo()
9791 END
9792 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9793
9794 # Test for adding a value to a const List item from a function
9795 lines =<< trim END
9796 vim9script
9797 class A
9798 public const l: list<number> = [1, 2]
9799 endclass
9800 def Foo()
9801 var a = A.new()
9802 a.l->add(4)
9803 enddef
9804 Foo()
9805 END
9806 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9807
9808 # Test for changing a const List item from an object method
9809 lines =<< trim END
9810 vim9script
9811 class A
9812 public const l: list<number> = [1, 2]
9813 def Foo()
9814 this.l[0] = 3
9815 enddef
9816 endclass
9817 var a = A.new()
9818 a.Foo()
9819 END
9820 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9821
9822 # Test for adding a value to a const List item from an object method
9823 lines =<< trim END
9824 vim9script
9825 class A
9826 public const l: list<number> = [1, 2]
9827 def Foo()
9828 this.l->add(4)
9829 enddef
9830 endclass
9831 var a = A.new()
9832 a.Foo()
9833 END
9834 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9835
9836 # Test for reassigning a const List object variable at script level
9837 lines =<< trim END
9838 vim9script
9839 class A
9840 public const l: list<number> = [1, 2]
9841 endclass
9842 var a = A.new()
9843 a.l = [3, 4]
9844 END
9845 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9846
9847 # Test for reassigning a const List object variable from an object method
9848 lines =<< trim END
9849 vim9script
9850 class A
9851 public const l: list<number> = [1, 2]
9852 def Foo()
9853 this.l = [3, 4]
9854 enddef
9855 endclass
9856 var a = A.new()
9857 a.Foo()
9858 END
9859 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9860
9861 # Test for reassigning a const List object variable from another function
9862 lines =<< trim END
9863 vim9script
9864 class A
9865 public const l: list<number> = [1, 2]
9866 endclass
9867 def Foo()
9868 var a = A.new()
9869 a.l = [3, 4]
9870 enddef
9871 Foo()
9872 END
9873 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9874
9875 # Error case: Use 'const' with just a variable name
9876 lines =<< trim END
9877 vim9script
9878 class A
9879 const foo
9880 endclass
9881 var a = A.new()
9882 END
9883 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9884
9885 # Error case: Use 'const' followed by 'public'
9886 lines =<< trim END
9887 vim9script
9888 class A
9889 const public foo: number
9890 endclass
9891 var a = A.new()
9892 END
9893 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9894
9895 # Error case: Use 'const' followed by 'static'
9896 lines =<< trim END
9897 vim9script
9898 class A
9899 const static foo: number
9900 endclass
9901 var a = A.new()
9902 END
9903 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9904
9905 # Error case: 'const' cannot be used in an interface
9906 lines =<< trim END
9907 vim9script
9908 interface A
9909 const foo: number = 10
9910 endinterface
9911 END
9912 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9913
9914 # Error case: 'const' not supported for an object method
9915 lines =<< trim END
9916 vim9script
9917 class A
9918 const def Foo()
9919 enddef
9920 endclass
9921 END
9922 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9923
9924 # Error case: 'const' not supported for a class method
9925 lines =<< trim END
9926 vim9script
9927 class A
9928 static const def Foo()
9929 enddef
9930 endclass
9931 END
9932 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9933enddef
9934
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009935" Test for compiling class/object methods using :defcompile
9936def Test_defcompile_class()
9937 # defcompile all the classes in the current script
9938 var lines =<< trim END
9939 vim9script
9940 class A
9941 def Foo()
9942 var i = 10
9943 enddef
9944 endclass
9945 class B
9946 def Bar()
9947 var i = 20
9948 xxx
9949 enddef
9950 endclass
9951 defcompile
9952 END
9953 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9954
9955 # defcompile a specific class
9956 lines =<< trim END
9957 vim9script
9958 class A
9959 def Foo()
9960 xxx
9961 enddef
9962 endclass
9963 class B
9964 def Bar()
9965 yyy
9966 enddef
9967 endclass
9968 defcompile B
9969 END
9970 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9971
9972 # defcompile a non-class
9973 lines =<< trim END
9974 vim9script
9975 class A
9976 def Foo()
9977 enddef
9978 endclass
9979 var X: list<number> = []
9980 defcompile X
9981 END
9982 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9983
9984 # defcompile a class twice
9985 lines =<< trim END
9986 vim9script
9987 class A
9988 def new()
9989 enddef
9990 endclass
9991 defcompile A
9992 defcompile A
9993 assert_equal('Function A.new does not need compiling', v:statusmsg)
9994 END
9995 v9.CheckSourceSuccess(lines)
9996
9997 # defcompile should not compile an imported class
9998 lines =<< trim END
9999 vim9script
10000 export class A
10001 def Foo()
10002 xxx
10003 enddef
10004 endclass
10005 END
10006 writefile(lines, 'Xdefcompileimport.vim', 'D')
10007 lines =<< trim END
10008 vim9script
10009
10010 import './Xdefcompileimport.vim'
10011 class B
10012 endclass
10013 defcompile
10014 END
10015 v9.CheckScriptSuccess(lines)
10016enddef
10017
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +010010018" Test for cases common to all the object builtin methods
10019def Test_object_builtin_method()
10020 var lines =<< trim END
10021 vim9script
10022 class A
10023 def abc()
10024 enddef
10025 endclass
10026 END
10027 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
10028
10029 for funcname in ["len", "string", "empty"]
10030 lines =<< trim eval END
10031 vim9script
10032 class A
10033 static def {funcname}(): number
10034 enddef
10035 endclass
10036 END
10037 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
10038 endfor
10039enddef
10040
10041" Test for using the empty() builtin method with an object
10042" This is a legacy function to use the test_garbagecollect_now() function.
10043func Test_object_empty()
10044 let lines =<< trim END
10045 vim9script
10046 class A
10047 def empty(): bool
10048 return true
10049 enddef
10050 endclass
10051
10052 def Foo()
10053 var afoo = A.new()
10054 assert_equal(true, empty(afoo))
10055 assert_equal(true, afoo->empty())
10056 enddef
10057
10058 var a = A.new()
10059 assert_equal(1, empty(a))
10060 assert_equal(1, a->empty())
10061 test_garbagecollect_now()
10062 assert_equal(1, empty(a))
10063 Foo()
10064 test_garbagecollect_now()
10065 Foo()
10066 END
10067 call v9.CheckSourceSuccess(lines)
10068
10069 " empty() should return 1 without a builtin method
10070 let lines =<< trim END
10071 vim9script
10072 class A
10073 endclass
10074
10075 def Foo()
10076 var afoo = A.new()
10077 assert_equal(1, empty(afoo))
10078 enddef
10079
10080 var a = A.new()
10081 assert_equal(1, empty(a))
10082 Foo()
10083 END
10084 call v9.CheckSourceSuccess(lines)
10085
10086 " Unsupported signature for the empty() method
10087 let lines =<< trim END
10088 vim9script
10089 class A
10090 def empty()
10091 enddef
10092 endclass
10093 END
10094 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
10095
10096 " Error when calling the empty() method
10097 let lines =<< trim END
10098 vim9script
10099 class A
10100 def empty(): bool
10101 throw "Failed to check emptiness"
10102 enddef
10103 endclass
10104
10105 def Foo()
10106 var afoo = A.new()
10107 var i = empty(afoo)
10108 enddef
10109
10110 var a = A.new()
10111 assert_fails('empty(a)', 'Failed to check emptiness')
10112 assert_fails('Foo()', 'Failed to check emptiness')
10113 END
10114 call v9.CheckSourceSuccess(lines)
10115
10116 " call empty() using an object from a script
10117 let lines =<< trim END
10118 vim9script
10119 class A
10120 def empty(): bool
10121 return true
10122 enddef
10123 endclass
10124 var afoo = A.new()
10125 assert_equal(true, afoo.empty())
10126 END
10127 call v9.CheckSourceSuccess(lines)
10128
10129 " call empty() using an object from a method
10130 let lines =<< trim END
10131 vim9script
10132 class A
10133 def empty(): bool
10134 return true
10135 enddef
10136 endclass
10137 def Foo()
10138 var afoo = A.new()
10139 assert_equal(true, afoo.empty())
10140 enddef
10141 Foo()
10142 END
10143 call v9.CheckSourceSuccess(lines)
10144
10145 " call empty() using "this" from an object method
10146 let lines =<< trim END
10147 vim9script
10148 class A
10149 def empty(): bool
10150 return true
10151 enddef
10152 def Foo(): bool
10153 return this.empty()
10154 enddef
10155 endclass
10156 def Bar()
10157 var abar = A.new()
10158 assert_equal(true, abar.Foo())
10159 enddef
10160 Bar()
10161 END
10162 call v9.CheckSourceSuccess(lines)
10163
10164 " Call empty() from a derived object
10165 let lines =<< trim END
10166 vim9script
10167 class A
10168 def empty(): bool
10169 return false
10170 enddef
10171 endclass
10172 class B extends A
10173 def empty(): bool
10174 return true
10175 enddef
10176 endclass
10177 def Foo(afoo: A)
10178 assert_equal(true, empty(afoo))
10179 var bfoo = B.new()
10180 assert_equal(true, empty(bfoo))
10181 enddef
10182 var b = B.new()
10183 assert_equal(1, empty(b))
10184 Foo(b)
10185 END
10186 call v9.CheckSourceSuccess(lines)
10187
10188 " Invoking empty method using an interface
10189 let lines =<< trim END
10190 vim9script
10191 interface A
10192 def empty(): bool
10193 endinterface
10194 class B implements A
10195 def empty(): bool
10196 return false
10197 enddef
10198 endclass
10199 def Foo(a: A)
10200 assert_equal(false, empty(a))
10201 enddef
10202 var b = B.new()
10203 Foo(b)
10204 END
10205 call v9.CheckSourceSuccess(lines)
10206endfunc
10207
10208" Test for using the len() builtin method with an object
10209" This is a legacy function to use the test_garbagecollect_now() function.
10210func Test_object_length()
10211 let lines =<< trim END
10212 vim9script
10213 class A
10214 var mylen: number = 0
10215 def new(n: number)
10216 this.mylen = n
10217 enddef
10218 def len(): number
10219 return this.mylen
10220 enddef
10221 endclass
10222
10223 def Foo()
10224 var afoo = A.new(12)
10225 assert_equal(12, len(afoo))
10226 assert_equal(12, afoo->len())
10227 enddef
10228
10229 var a = A.new(22)
10230 assert_equal(22, len(a))
10231 assert_equal(22, a->len())
10232 test_garbagecollect_now()
10233 assert_equal(22, len(a))
10234 Foo()
10235 test_garbagecollect_now()
10236 Foo()
10237 END
10238 call v9.CheckSourceSuccess(lines)
10239
10240 " len() should return 0 without a builtin method
10241 let lines =<< trim END
10242 vim9script
10243 class A
10244 endclass
10245
10246 def Foo()
10247 var afoo = A.new()
10248 assert_equal(0, len(afoo))
10249 enddef
10250
10251 var a = A.new()
10252 assert_equal(0, len(a))
10253 Foo()
10254 END
10255 call v9.CheckSourceSuccess(lines)
10256
10257 " Unsupported signature for the len() method
10258 let lines =<< trim END
10259 vim9script
10260 class A
10261 def len()
10262 enddef
10263 endclass
10264 END
10265 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10266
10267 " Error when calling the len() method
10268 let lines =<< trim END
10269 vim9script
10270 class A
10271 def len(): number
10272 throw "Failed to compute length"
10273 enddef
10274 endclass
10275
10276 def Foo()
10277 var afoo = A.new()
10278 var i = len(afoo)
10279 enddef
10280
10281 var a = A.new()
10282 assert_fails('len(a)', 'Failed to compute length')
10283 assert_fails('Foo()', 'Failed to compute length')
10284 END
10285 call v9.CheckSourceSuccess(lines)
10286
10287 " call len() using an object from a script
10288 let lines =<< trim END
10289 vim9script
10290 class A
10291 def len(): number
10292 return 5
10293 enddef
10294 endclass
10295 var afoo = A.new()
10296 assert_equal(5, afoo.len())
10297 END
10298 call v9.CheckSourceSuccess(lines)
10299
10300 " call len() using an object from a method
10301 let lines =<< trim END
10302 vim9script
10303 class A
10304 def len(): number
10305 return 5
10306 enddef
10307 endclass
10308 def Foo()
10309 var afoo = A.new()
10310 assert_equal(5, afoo.len())
10311 enddef
10312 Foo()
10313 END
10314 call v9.CheckSourceSuccess(lines)
10315
10316 " call len() using "this" from an object method
10317 let lines =<< trim END
10318 vim9script
10319 class A
10320 def len(): number
10321 return 8
10322 enddef
10323 def Foo(): number
10324 return this.len()
10325 enddef
10326 endclass
10327 def Bar()
10328 var abar = A.new()
10329 assert_equal(8, abar.Foo())
10330 enddef
10331 Bar()
10332 END
10333 call v9.CheckSourceSuccess(lines)
10334
10335 " Call len() from a derived object
10336 let lines =<< trim END
10337 vim9script
10338 class A
10339 def len(): number
10340 return 10
10341 enddef
10342 endclass
10343 class B extends A
10344 def len(): number
10345 return 20
10346 enddef
10347 endclass
10348 def Foo(afoo: A)
10349 assert_equal(20, len(afoo))
10350 var bfoo = B.new()
10351 assert_equal(20, len(bfoo))
10352 enddef
10353 var b = B.new()
10354 assert_equal(20, len(b))
10355 Foo(b)
10356 END
10357 call v9.CheckSourceSuccess(lines)
10358
10359 " Invoking len method using an interface
10360 let lines =<< trim END
10361 vim9script
10362 interface A
10363 def len(): number
10364 endinterface
10365 class B implements A
10366 def len(): number
10367 return 123
10368 enddef
10369 endclass
10370 def Foo(a: A)
10371 assert_equal(123, len(a))
10372 enddef
10373 var b = B.new()
10374 Foo(b)
10375 END
10376 call v9.CheckSourceSuccess(lines)
10377endfunc
10378
10379" Test for using the string() builtin method with an object
10380" This is a legacy function to use the test_garbagecollect_now() function.
10381func Test_object_string()
10382 let lines =<< trim END
10383 vim9script
10384 class A
10385 var name: string
10386 def string(): string
10387 return this.name
10388 enddef
10389 endclass
10390
10391 def Foo()
10392 var afoo = A.new("foo-A")
10393 assert_equal('foo-A', string(afoo))
10394 assert_equal('foo-A', afoo->string())
10395 enddef
10396
10397 var a = A.new("script-A")
10398 assert_equal('script-A', string(a))
10399 assert_equal('script-A', a->string())
10400 assert_equal(['script-A'], execute('echo a')->split("\n"))
10401 test_garbagecollect_now()
10402 assert_equal('script-A', string(a))
10403 Foo()
10404 test_garbagecollect_now()
10405 Foo()
10406 END
10407 call v9.CheckSourceSuccess(lines)
10408
10409 " string() should return "object of A {}" without a builtin method
10410 let lines =<< trim END
10411 vim9script
10412 class A
10413 endclass
10414
10415 def Foo()
10416 var afoo = A.new()
10417 assert_equal('object of A {}', string(afoo))
10418 enddef
10419
10420 var a = A.new()
10421 assert_equal('object of A {}', string(a))
10422 Foo()
10423 END
10424 call v9.CheckSourceSuccess(lines)
10425
10426 " Unsupported signature for the string() method
10427 let lines =<< trim END
10428 vim9script
10429 class A
10430 def string()
10431 enddef
10432 endclass
10433 END
10434 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10435
10436 " Error when calling the string() method
10437 let lines =<< trim END
10438 vim9script
10439 class A
10440 def string(): string
10441 throw "Failed to get text"
10442 enddef
10443 endclass
10444
10445 def Foo()
10446 var afoo = A.new()
10447 var i = string(afoo)
10448 enddef
10449
10450 var a = A.new()
10451 assert_fails('string(a)', 'Failed to get text')
10452 assert_fails('Foo()', 'Failed to get text')
10453 END
10454 call v9.CheckSourceSuccess(lines)
10455
10456 " call string() using an object from a script
10457 let lines =<< trim END
10458 vim9script
10459 class A
10460 def string(): string
10461 return 'A'
10462 enddef
10463 endclass
10464 var afoo = A.new()
10465 assert_equal('A', afoo.string())
10466 END
10467 call v9.CheckSourceSuccess(lines)
10468
10469 " call string() using an object from a method
10470 let lines =<< trim END
10471 vim9script
10472 class A
10473 def string(): string
10474 return 'A'
10475 enddef
10476 endclass
10477 def Foo()
10478 var afoo = A.new()
10479 assert_equal('A', afoo.string())
10480 enddef
10481 Foo()
10482 END
10483 call v9.CheckSourceSuccess(lines)
10484
10485 " call string() using "this" from an object method
10486 let lines =<< trim END
10487 vim9script
10488 class A
10489 def string(): string
10490 return 'A'
10491 enddef
10492 def Foo(): string
10493 return this.string()
10494 enddef
10495 endclass
10496 def Bar()
10497 var abar = A.new()
10498 assert_equal('A', abar.string())
10499 enddef
10500 Bar()
10501 END
10502 call v9.CheckSourceSuccess(lines)
10503
10504 " Call string() from a derived object
10505 let lines =<< trim END
10506 vim9script
10507 class A
10508 def string(): string
10509 return 'A'
10510 enddef
10511 endclass
10512 class B extends A
10513 def string(): string
10514 return 'B'
10515 enddef
10516 endclass
10517 def Foo(afoo: A)
10518 assert_equal('B', string(afoo))
10519 var bfoo = B.new()
10520 assert_equal('B', string(bfoo))
10521 enddef
10522 var b = B.new()
10523 assert_equal('B', string(b))
10524 Foo(b)
10525 END
10526 call v9.CheckSourceSuccess(lines)
10527
10528 " Invoking string method using an interface
10529 let lines =<< trim END
10530 vim9script
10531 interface A
10532 def string(): string
10533 endinterface
10534 class B implements A
10535 def string(): string
10536 return 'B'
10537 enddef
10538 endclass
10539 def Foo(a: A)
10540 assert_equal('B', string(a))
10541 enddef
10542 var b = B.new()
10543 Foo(b)
10544 END
10545 call v9.CheckSourceSuccess(lines)
10546endfunc
10547
Ernie Rael9d779c52024-07-07 20:41:44 +020010548" Test for using the string() builtin method with an object's method
10549def Test_method_string()
10550 var lines =<< trim END
10551 vim9script
10552 class A
10553 def F()
10554 enddef
10555 endclass
10556 assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F))
10557 END
10558 v9.CheckScriptSuccess(lines)
10559enddef
10560
10561
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010562" Test for using a class in the class definition
10563def Test_Ref_Class_Within_Same_Class()
10564 var lines =<< trim END
10565 vim9script
10566 class A
10567 var n: number = 0
10568 def Equals(other: A): bool
10569 return this.n == other.n
10570 enddef
10571 endclass
10572
10573 var a1 = A.new(10)
10574 var a2 = A.new(10)
10575 var a3 = A.new(20)
10576 assert_equal(true, a1.Equals(a2))
10577 assert_equal(false, a2.Equals(a3))
10578 END
10579 v9.CheckScriptSuccess(lines)
10580
10581 lines =<< trim END
10582 vim9script
10583
10584 class Foo
10585 var num: number
10586 def Clone(): Foo
10587 return Foo.new(this.num)
10588 enddef
10589 endclass
10590
10591 var f1 = Foo.new(1)
10592
10593 def F()
10594 var f2: Foo = f1.Clone()
10595 assert_equal(false, f2 is f1)
10596 assert_equal(true, f2.num == f1.num)
10597 enddef
10598 F()
10599
10600 var f3: Foo = f1.Clone()
10601 assert_equal(false, f3 is f1)
10602 assert_equal(true, f3.num == f1.num)
10603 END
10604 v9.CheckScriptSuccess(lines)
10605
10606 # Test for trying to use a class to extend when defining the same class
10607 lines =<< trim END
10608 vim9script
10609 class A extends A
10610 endclass
10611 END
10612 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10613
10614 # Test for trying to use a class to implement when defining the same class
10615 lines =<< trim END
10616 vim9script
10617 class A implements A
10618 endclass
10619 END
10620 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10621enddef
10622
Ernie Raelf0e69142024-06-22 11:12:00 +020010623" Test for comparing a class referencing itself
10624def Test_Object_Compare_With_Recursive_Class_Ref()
10625 var lines =<< trim END
10626 vim9script
10627
10628 class C
10629 public var nest: C
10630 endclass
10631
10632 var o1 = C.new()
10633 o1.nest = o1
10634
10635 var result = o1 == o1
10636 assert_equal(true, result)
10637 END
10638 v9.CheckScriptSuccess(lines)
Ernie Rael86257142024-06-23 09:54:45 +020010639
10640 lines =<< trim END
10641 vim9script
10642
10643 class C
10644 public var nest: C
10645 endclass
10646 var o1 = C.new()
10647 var o2 = C.new(C.new())
10648
10649 var result = o1 == o2
10650 assert_equal(false, result)
10651 END
10652 v9.CheckScriptSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +020010653
10654 lines =<< trim END
10655 vim9script
10656 class C
10657 var nest1: C
10658 var nest2: C
10659 def Init(n1: C, n2: C)
10660 this.nest1 = n1
10661 this.nest2 = n2
10662 enddef
10663 endclass
10664
10665 var o1 = C.new()
10666 var o2 = C.new()
10667 o1.Init(o1, o2)
10668 o2.Init(o2, o1)
10669
10670 var result = o1 == o2
10671 assert_equal(true, result)
10672 END
10673 v9.CheckScriptSuccess(lines)
Ernie Raelf0e69142024-06-22 11:12:00 +020010674enddef
10675
Ernie Raelf3975492024-07-06 11:44:37 +020010676" Test for comparing a class with nesting objects
10677def Test_Object_Compare_With_Nesting_Objects()
10678 # On a compare, after vim equal recurses 1000 times, not finding an unequal,
10679 # return the compare is equal.
10680 # Test that limit
10681
10682 var lines =<< trim END
10683 vim9script
10684 class C
10685 public var n: number
10686 public var nest: C
10687
10688 # Create a "C" that chains/nests to indicated depth.
10689 # return {head: firstC, tail: lastC}
10690 static def CreateNested(depth: number): dict<C>
10691 var first = C.new(1, null_object)
10692 var last = first
10693 for i in range(2, depth)
10694 last.nest = C.new(i, null_object)
10695 last = last.nest
10696 endfor
10697 return {head: first, tail: last}
10698 enddef
10699
10700 # Return pointer to nth item in chain.
10701 def GetLink(depth: number): C
10702 var count = 1
10703 var p: C = this
10704 while count < depth
10705 p = p.nest
10706 if p == null
10707 throw "too deep"
10708 endif
10709 count += 1
10710 endwhile
10711 return p
10712 enddef
10713
10714 # Return the length of the chain
10715 def len(): number
10716 var count = 1
10717 var p: C = this
10718 while p.nest != null
10719 p = p.nest
10720 count += 1
10721 endwhile
10722 return count
10723 enddef
10724 endclass
10725
10726 var chain = C.CreateNested(3)
10727 var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}"
10728 assert_equal(s, string(chain.head))
10729 assert_equal(3, chain.head->len())
10730
10731 var chain1 = C.CreateNested(100)
10732 var chain2 = C.CreateNested(100)
10733 assert_true(chain1.head == chain2.head)
10734
10735 # modify the tail of chain2, compare not equal
10736 chain2.tail.n = 123456
10737 assert_true(chain1.head != chain2.head)
10738
10739 # a tail of a different length compares not equal
10740 chain2 = C.CreateNested(101)
10741 assert_true(chain1.head != chain2.head)
10742
10743 chain1 = C.CreateNested(1000)
10744 chain2 = C.CreateNested(1000)
10745 assert_true(chain1.head == chain2.head)
10746
10747 # modify the tail of chain2, compare not equal
10748 chain2.tail.n = 123456
10749 assert_true(chain1.head != chain2.head)
10750
10751 # try a chain longer that the limit
10752 chain1 = C.CreateNested(1001)
10753 chain2 = C.CreateNested(1001)
10754 assert_true(chain1.head == chain2.head)
10755
10756 # modify the tail, but still equal
10757 chain2.tail.n = 123456
10758 assert_true(chain1.head == chain2.head)
10759
10760 # remove 2 items from front, shorten the chain by two.
10761 chain1.head = chain1.head.GetLink(3)
10762 chain2.head = chain2.head.GetLink(3)
10763 assert_equal(3, chain1.head.n)
10764 assert_equal(3, chain2.head.n)
10765 assert_equal(999, chain1.head->len())
10766 assert_equal(999, chain2.head->len())
10767 # Now less than the limit, compare not equal
10768 assert_true(chain1.head != chain2.head)
10769 END
10770 v9.CheckScriptSuccess(lines)
10771enddef
10772
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010773" Test for using a compound operator from a lambda function in an object method
10774def Test_compound_op_in_objmethod_lambda()
10775 # Test using the "+=" operator
10776 var lines =<< trim END
10777 vim9script
10778 class A
10779 var n: number = 10
10780 def Foo()
10781 var Fn = () => {
10782 this.n += 1
10783 }
10784 Fn()
10785 enddef
10786 endclass
10787
10788 var a = A.new()
10789 a.Foo()
10790 assert_equal(11, a.n)
10791 END
10792 v9.CheckScriptSuccess(lines)
10793
10794 # Test using the "..=" operator
10795 lines =<< trim END
10796 vim9script
10797 class A
10798 var s: string = "a"
10799 def Foo()
10800 var Fn = () => {
10801 this.s ..= "a"
10802 }
10803 Fn()
10804 enddef
10805 endclass
10806
10807 var a = A.new()
10808 a.Foo()
10809 a.Foo()
10810 assert_equal("aaa", a.s)
10811 END
10812 v9.CheckScriptSuccess(lines)
10813enddef
10814
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010815" Test for using test_refcount() with a class and an object
10816def Test_class_object_refcount()
10817 var lines =<< trim END
10818 vim9script
10819 class A
10820 endclass
10821 var a: A = A.new()
10822 assert_equal(2, test_refcount(A))
10823 assert_equal(1, test_refcount(a))
10824 var b = a
10825 assert_equal(2, test_refcount(A))
10826 assert_equal(2, test_refcount(a))
10827 assert_equal(2, test_refcount(b))
10828 END
10829 v9.CheckScriptSuccess(lines)
10830enddef
10831
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010832" call a lambda function in one object from another object
10833def Test_lambda_invocation_across_classes()
10834 var lines =<< trim END
10835 vim9script
10836 class A
10837 var s: string = "foo"
10838 def GetFn(): func
10839 var Fn = (): string => {
10840 return this.s
10841 }
10842 return Fn
10843 enddef
10844 endclass
10845
10846 class B
10847 var s: string = "bar"
10848 def GetFn(): func
10849 var a = A.new()
10850 return a.GetFn()
10851 enddef
10852 endclass
10853
10854 var b = B.new()
10855 var Fn = b.GetFn()
10856 assert_equal("foo", Fn())
10857 END
10858 v9.CheckScriptSuccess(lines)
10859enddef
10860
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010861" Test for using a class member which is an object of the current class
10862def Test_current_class_object_class_member()
10863 var lines =<< trim END
10864 vim9script
10865 class A
10866 public static var obj1: A = A.new(10)
10867 var n: number
10868 endclass
10869 defcompile
10870 assert_equal(10, A.obj1.n)
10871 END
10872 v9.CheckScriptSuccess(lines)
10873enddef
10874
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020010875" Test for updating a base class variable from a base class method without the
10876" class name. This used to crash Vim (Github issue #14352).
10877def Test_use_base_class_variable_from_base_class_method()
10878 var lines =<< trim END
10879 vim9script
10880
10881 class DictKeyClass
10882 static var _obj_id_count = 1
10883 def _GenerateKey()
10884 _obj_id_count += 1
10885 enddef
10886 static def GetIdCount(): number
10887 return _obj_id_count
10888 enddef
10889 endclass
10890
10891 class C extends DictKeyClass
10892 def F()
10893 this._GenerateKey()
10894 enddef
10895 endclass
10896
10897 C.new().F()
10898 assert_equal(2, DictKeyClass.GetIdCount())
10899 END
10900 v9.CheckScriptSuccess(lines)
10901enddef
10902
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020010903" Test for accessing protected funcref object and class variables
10904def Test_protected_funcref()
10905 # protected funcref object variable
10906 var lines =<< trim END
10907 vim9script
10908 class Test1
10909 const _Id: func(any): any = (v) => v
10910 endclass
10911 var n = Test1.new()._Id(1)
10912 END
10913 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
10914
10915 # protected funcref class variable
10916 lines =<< trim END
10917 vim9script
10918 class Test2
10919 static const _Id: func(any): any = (v) => v
10920 endclass
10921 var n = Test2._Id(2)
10922 END
10923 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
10924enddef
10925
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020010926" Test for using lambda block in classes
10927def Test_lambda_block_in_class()
10928 # This used to crash Vim
10929 var lines =<< trim END
10930 vim9script
10931 class IdClass1
10932 const Id: func(number): number = (num: number): number => {
10933 # Return a ID
10934 return num * 10
10935 }
10936 endclass
10937 var id = IdClass1.new()
10938 assert_equal(20, id.Id(2))
10939 END
10940 v9.CheckScriptSuccess(lines)
10941
10942 # This used to crash Vim
10943 lines =<< trim END
10944 vim9script
10945 class IdClass2
10946 static const Id: func(number): number = (num: number): number => {
10947 # Return a ID
10948 return num * 2
10949 }
10950 endclass
10951 assert_equal(16, IdClass2.Id(8))
10952 END
10953 v9.CheckScriptSuccess(lines)
10954enddef
10955
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020010956" Test for defcompiling an abstract method
10957def Test_abstract_method_defcompile()
10958 # Compile an abstract class with abstract object methods
10959 var lines =<< trim END
10960 vim9script
10961 abstract class A
10962 abstract def Foo(): string
10963 abstract def Bar(): list<string>
10964 endclass
10965 defcompile
10966 END
10967 v9.CheckScriptSuccess(lines)
10968
10969 # Compile a concrete object method in an abstract class
10970 lines =<< trim END
10971 vim9script
10972 abstract class A
10973 abstract def Foo(): string
10974 abstract def Bar(): list<string>
10975 def Baz(): string
10976 pass
10977 enddef
10978 endclass
10979 defcompile
10980 END
10981 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10982
10983 # Compile a concrete class method in an abstract class
10984 lines =<< trim END
10985 vim9script
10986 abstract class A
10987 abstract def Foo(): string
10988 abstract def Bar(): list<string>
10989 static def Baz(): string
10990 pass
10991 enddef
10992 endclass
10993 defcompile
10994 END
10995 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10996enddef
10997
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020010998" Test for defining a class in a function
10999def Test_class_definition_in_a_function()
11000 var lines =<< trim END
11001 vim9script
11002 def Foo()
11003 class A
11004 endclass
11005 enddef
11006 defcompile
11007 END
11008 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
11009enddef
11010
Yegappan Lakshmanandbac0da2024-05-25 20:23:54 +020011011" Test for using [] with a class and an object
11012def Test_class_object_index()
11013 var lines =<< trim END
11014 vim9script
11015 class A
11016 endclass
11017 A[10] = 1
11018 END
11019 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a class: A[10] = 1', 4)
11020
11021 lines =<< trim END
11022 vim9script
11023 class A
11024 endclass
11025 var a = A.new()
11026 a[10] = 1
11027 END
11028 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5)
11029enddef
11030
LemonBoyf4af3312024-07-04 13:43:12 +020011031def Test_class_member_init_typecheck()
11032 # Ensure the class member is assigned its declared type.
11033 var lines =<< trim END
11034 vim9script
11035 class S
11036 static var l: list<string> = []
11037 endclass
11038 S.l->add(123)
11039 END
11040 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5)
11041
11042 # Ensure the initializer value and the declared type match.
11043 lines =<< trim END
11044 vim9script
11045 class S
11046 var l: list<string> = [1, 2, 3]
11047 endclass
11048 var o = S.new()
11049 END
11050 v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>')
11051
11052 # Ensure the class member is assigned its declared type.
11053 lines =<< trim END
11054 vim9script
11055 class S
11056 var l: list<string> = []
11057 endclass
11058 var o = S.new()
11059 o.l->add(123)
11060 END
11061 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6)
11062enddef
11063
LemonBoy50d48542024-07-04 17:03:17 +020011064def Test_class_cast()
11065 var lines =<< trim END
11066 vim9script
11067 class A
11068 endclass
11069 class B extends A
11070 var mylen: number
11071 endclass
11072 def F(o: A): number
11073 return (<B>o).mylen
11074 enddef
11075
11076 defcompile F
11077 END
11078 v9.CheckScriptSuccess(lines)
11079enddef
11080
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011081" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker