blob: 4654598465c7d68022c5b0f14f43f6c53e743108 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +010038 # Only the complete word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmananac773182024-04-27 11:36:12 +020070 # Additional command after "class name"
71 lines =<< trim END
72 vim9script
73 class Something | var x = 10
74 endclass
75 END
76 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
77
78 # Additional command after "object variable"
79 lines =<< trim END
80 vim9script
81 class Something
82 var l: list<number> = [] | var y = 10
83 endclass
84 END
85 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
86
87 # Additional command after "class variable"
88 lines =<< trim END
89 vim9script
90 class Something
91 static var d = {a: 10} | var y = 10
92 endclass
93 END
94 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
95
96 # Additional command after "object method"
97 lines =<< trim END
98 vim9script
99 class Something
100 def Foo() | var y = 10
101 enddef
102 endclass
103 END
104 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
105
Yegappan Lakshmananfe55c312024-04-28 09:54:09 +0200106 # Comments are allowed after an inline block
107 lines =<< trim END
108 vim9script
109 class Foo
110 static const bar = { # {{{
111 baz: 'qux'
112 } # }}}
113 endclass
114 assert_equal({baz: 'qux'}, Foo.bar)
115 END
116 v9.CheckSourceSuccess(lines)
117
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +0100118 # Try to define a class with the same name as an existing variable
119 lines =<< trim END
120 vim9script
121 var Something: list<number> = [1]
122 class Thing
123 endclass
124 interface Api
125 endinterface
126 class Something extends Thing implements Api
127 var v1: string = ''
128 def Foo()
129 enddef
130 endclass
131 END
132 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 7)
133
zeertzjqe7102202024-02-13 20:32:04 +0100134 # Use old "this." prefixed member variable declaration syntax (without initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100135 lines =<< trim END
136 vim9script
137 class Something
138 this.count: number
139 endclass
140 END
141 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
142
zeertzjqe7102202024-02-13 20:32:04 +0100143 # Use old "this." prefixed member variable declaration syntax (with initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100144 lines =<< trim END
145 vim9script
146 class Something
147 this.count: number = 42
148 endclass
149 END
150 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
151
152 # Use old "this." prefixed member variable declaration syntax (type inferred)
153 lines =<< trim END
154 vim9script
155 class Something
156 this.count = 42
157 endclass
158 END
159 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
160
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200161 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000162 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 vim9script
164 class Something
165 this
166 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000167 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100168 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000169
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200170 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000171 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200172 vim9script
173 class Something
174 this.
175 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000176 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100177 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000178
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200179 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000180 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200181 vim9script
182 class Something
183 this .count
184 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000185 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100186 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000187
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200188 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000189 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200190 vim9script
191 class Something
192 this. count
193 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000194 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100195 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000196
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200197 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000198 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200199 vim9script
200 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100201 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200202 that.count
203 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200205 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000206
Doug Kearns74da0ee2023-12-14 20:26:26 +0100207 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000208 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200209 vim9script
210 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100211 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000213 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100214 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
215
216 # Use "variable" instead of "var" for member variable declaration (with initialization)
217 lines =<< trim END
218 vim9script
219 class Something
220 variable count: number = 42
221 endclass
222 END
223 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
224
225 # Use "variable" instead of "var" for member variable declaration (type inferred)
226 lines =<< trim END
227 vim9script
228 class Something
229 variable count = 42
230 endclass
231 END
232 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000233
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200234 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000235 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200236 vim9script
237 class Something
238 def new()
239 this.state = 0
240 enddef
241 endclass
242 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000243 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200244 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000245
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200246 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000247 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200248 vim9script
249 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100250 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200251 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000252 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200253 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000254
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200255 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000256 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200257 vim9script
258 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100259 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200260 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000261 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200262 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000263
Doug Kearns74da0ee2023-12-14 20:26:26 +0100264 # Missing ":var" in a "var" member variable declaration (without initialization)
265 lines =<< trim END
266 vim9script
267 class Something
268 var: number
269 endclass
270 END
271 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
272
273 # Missing ":var" in a "var" member variable declaration (with initialization)
274 lines =<< trim END
275 vim9script
276 class Something
277 var: number = 42
278 endclass
279 END
280 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
281
282 # Missing ":var" in a "var" member variable declaration (type inferred)
283 lines =<< trim END
284 vim9script
285 class Something
286 var = 42
287 endclass
288 END
289 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
290
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200291 # Test for unsupported comment specifier
292 lines =<< trim END
293 vim9script
294 class Something
295 # comment
296 #{
297 endclass
298 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200299 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200300
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200301 # Test for using class as a bool
302 lines =<< trim END
303 vim9script
304 class A
305 endclass
306 if A
307 endif
308 END
Ernie Raele75fde62023-12-21 17:18:54 +0100309 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200310
311 # Test for using object as a bool
312 lines =<< trim END
313 vim9script
314 class A
315 endclass
316 var a = A.new()
317 if a
318 endif
319 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200320 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200321
322 # Test for using class as a float
323 lines =<< trim END
324 vim9script
325 class A
326 endclass
327 sort([1.1, A], 'f')
328 END
Ernie Raelfa831102023-12-14 20:06:39 +0100329 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200330
331 # Test for using object as a float
332 lines =<< trim END
333 vim9script
334 class A
335 endclass
336 var a = A.new()
337 sort([1.1, a], 'f')
338 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200339 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200340
341 # Test for using class as a string
342 lines =<< trim END
343 vim9script
344 class A
345 endclass
346 :exe 'call ' .. A
347 END
Ernie Raele75fde62023-12-21 17:18:54 +0100348 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200349
350 # Test for using object as a string
351 lines =<< trim END
352 vim9script
353 class A
354 endclass
355 var a = A.new()
356 :exe 'call ' .. a
357 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200358 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200359
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200360 # Test creating a class with member variables and methods, calling a object
361 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000362 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200363 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000364
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200365 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100366 var lnum: number
367 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000368
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200369 # make a nicely formatted string
370 def ToString(): string
371 return $'({this.lnum}, {this.col})'
372 enddef
373 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000374
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200375 # use the automatically generated new() method
376 var pos = TextPosition.new(2, 12)
377 assert_equal(2, pos.lnum)
378 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000379
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200380 # call an object method
381 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000382
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200383 assert_equal(v:t_class, type(TextPosition))
384 assert_equal(v:t_object, type(pos))
385 assert_equal('class<TextPosition>', typename(TextPosition))
386 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000387 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200388 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200389
390 # When referencing object methods, space cannot be used after a "."
391 lines =<< trim END
392 vim9script
393 class A
394 def Foo(): number
395 return 10
396 enddef
397 endclass
398 var a = A.new()
399 var v = a. Foo()
400 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200401 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200402
403 # Using an object without specifying a method or a member variable
404 lines =<< trim END
405 vim9script
406 class A
407 def Foo(): number
408 return 10
409 enddef
410 endclass
411 var a = A.new()
412 var v = a.
413 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200414 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200415
416 # Error when parsing the arguments of an object method.
417 lines =<< trim END
418 vim9script
419 class A
420 def Foo()
421 enddef
422 endclass
423 var a = A.new()
424 var v = a.Foo(,)
425 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200426 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200427
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200428 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200429 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200430 vim9script
431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100432 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200433 X: 1
434 }
435 endclass
436 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200437 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200438 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000439enddef
440
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200441" Tests for object/class methods in a class
442def Test_class_def_method()
443 # Using the "public" keyword when defining an object method
444 var lines =<< trim END
445 vim9script
446 class A
447 public def Foo()
448 enddef
449 endclass
450 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200451 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200452
453 # Using the "public" keyword when defining a class method
454 lines =<< trim END
455 vim9script
456 class A
457 public static def Foo()
458 enddef
459 endclass
460 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200461 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200462
Ernie Rael03042a22023-11-11 08:53:32 +0100463 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200464 lines =<< trim END
465 vim9script
466 class A
467 public def _Foo()
468 enddef
469 endclass
470 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200471 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200472
Ernie Rael03042a22023-11-11 08:53:32 +0100473 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200474 lines =<< trim END
475 vim9script
476 class A
477 public static def _Foo()
478 enddef
479 endclass
480 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200481 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200482
483 # Using a "def" keyword without an object method name
484 lines =<< trim END
485 vim9script
486 class A
487 def
488 enddef
489 endclass
490 END
491 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
492
493 # Using a "def" keyword without a class method name
494 lines =<< trim END
495 vim9script
496 class A
497 static def
498 enddef
499 endclass
500 END
501 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
502enddef
503
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000504def Test_class_defined_twice()
505 # class defined twice should fail
506 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200507 vim9script
508 class There
509 endclass
510 class There
511 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000512 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200513 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000514
515 # one class, reload same script twice is OK
516 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 vim9script
518 class There
519 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000520 END
521 writefile(lines, 'XclassTwice.vim', 'D')
522 source XclassTwice.vim
523 source XclassTwice.vim
524enddef
525
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000526def Test_returning_null_object()
527 # this was causing an internal error
528 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200529 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000530
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200531 class BufferList
532 def Current(): any
533 return null_object
534 enddef
535 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000536
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200537 var buffers = BufferList.new()
538 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000539 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200540 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000541enddef
542
Bram Moolenaard13dd302023-03-11 20:56:35 +0000543def Test_using_null_class()
544 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200545 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200547 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200548
549 # Test for using a null class as a value
550 lines =<< trim END
551 vim9script
552 echo empty(null_class)
553 END
554 v9.CheckSourceFailure(lines, 'E1405: Class "" cannot be used as a value', 2)
555
556 # Test for using a null class with string()
557 lines =<< trim END
558 vim9script
559 assert_equal('class [unknown]', string(null_class))
560 END
561 v9.CheckSourceSuccess(lines)
562
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +0200563 # Test for using a null class with type() and typename()
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200564 lines =<< trim END
565 vim9script
566 assert_equal(12, type(null_class))
567 assert_equal('class<Unknown>', typename(null_class))
568 END
569 v9.CheckSourceSuccess(lines)
570enddef
571
Bram Moolenaar657aea72023-01-27 13:16:19 +0000572def Test_class_interface_wrong_end()
573 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200574 vim9script
575 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100576 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200577 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200579 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000580
581 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200582 vim9script
583 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100584 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200585 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000586 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200587 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000588enddef
589
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000590def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200591 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000592 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200593 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000594
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200595 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100596 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200597 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200599 var state: State
600 var db = {'xyz': 789}
601 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200603 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000604
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200605 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000606 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200607 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000608
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200609 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100610 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200611 def Method1()
612 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000613 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200614 endclass
615
616 var obj: Class
617 def Func()
618 obj.Method1()
619 enddef
620 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000621 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200622 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000623
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200624 # Pass an uninitialized object variable to a "new" function and try to call an
625 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000626 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200627 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000628
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200629 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100630 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200631 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000632
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200633 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100634 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200636 def GetBackground(): string
637 return this._bg.background
638 enddef
639 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000640
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200641 var bg: Background # UNINITIALIZED
642 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200644 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000645
646 # TODO: this should not give an error but be handled at runtime
647 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200648 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000649
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200650 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100651 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200652 def Method1()
653 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000654 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200655 endclass
656
657 var obj = null_object
658 def Func()
659 obj.Method1()
660 enddef
661 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000662 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200663 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000664enddef
665
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200666" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200667def Test_null_object_assign_compare()
668 var lines =<< trim END
669 vim9script
670
671 var nullo = null_object
672 def F(): any
673 return nullo
674 enddef
675 assert_equal('object<Unknown>', typename(F()))
676
677 var o0 = F()
678 assert_true(o0 == null_object)
679 assert_true(o0 == null)
680
681 var o1: any = nullo
682 assert_true(o1 == null_object)
683 assert_true(o1 == null)
684
685 def G()
686 var x = null_object
687 enddef
688
689 class C
690 endclass
691 var o2: C
692 assert_true(o2 == null_object)
693 assert_true(o2 == null)
694
695 o2 = null_object
696 assert_true(o2 == null)
697
698 o2 = C.new()
699 assert_true(o2 != null)
700
701 o2 = null_object
702 assert_true(o2 == null)
703 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200704 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200705enddef
706
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200707" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000708def Test_class_member_initializer()
709 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200710 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000711
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200712 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100713 var lnum: number = 1
714 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000715
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200716 # constructor with only the line number
717 def new(lnum: number)
718 this.lnum = lnum
719 enddef
720 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200722 var pos = TextPosition.new(3)
723 assert_equal(3, pos.lnum)
724 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000725
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200726 var instr = execute('disassemble TextPosition.new')
727 assert_match('new\_s*' ..
728 '0 NEW TextPosition size \d\+\_s*' ..
729 '\d PUSHNR 1\_s*' ..
730 '\d STORE_THIS 0\_s*' ..
731 '\d PUSHNR 1\_s*' ..
732 '\d STORE_THIS 1\_s*' ..
733 'this.lnum = lnum\_s*' ..
734 '\d LOAD arg\[-1]\_s*' ..
735 '\d PUSHNR 0\_s*' ..
736 '\d LOAD $0\_s*' ..
737 '\d\+ STOREINDEX object\_s*' ..
738 '\d\+ RETURN object.*',
739 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000740 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200741 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000742enddef
743
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000744def Test_member_any_used_as_object()
745 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200746 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000747
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200748 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100749 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200750 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000751
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200752 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100753 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200754 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000755
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200756 def F(outer: Outer)
757 outer.inner.value = 1
758 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200760 var inner_obj = Inner.new(0)
761 var outer_obj = Outer.new(inner_obj)
762 F(outer_obj)
763 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000764 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200765 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000766
Ernie Rael03042a22023-11-11 08:53:32 +0100767 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200768 lines =<< trim END
769 vim9script
770
771 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100772 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200773 endclass
774
775 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100776 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200777 endclass
778
779 def F(outer: Outer)
780 outer.inner._value = 'b'
781 enddef
782
783 var inner_obj = Inner.new('a')
784 var outer_obj = Outer.new(inner_obj)
785 F(outer_obj)
786 END
Ernie Rael03042a22023-11-11 08:53:32 +0100787 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200788
789 # Try modifying a non-existing variable using an "any" object
790 lines =<< trim END
791 vim9script
792
793 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100794 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200795 endclass
796
797 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100798 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200799 endclass
800
801 def F(outer: Outer)
802 outer.inner.someval = 'b'
803 enddef
804
805 var inner_obj = Inner.new('a')
806 var outer_obj = Outer.new(inner_obj)
807 F(outer_obj)
808 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200809 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000810enddef
811
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200812" Nested assignment to a object variable which is of another class type
813def Test_assignment_nested_type()
814 var lines =<< trim END
815 vim9script
816
817 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100818 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200819 endclass
820
821 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100822 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200823 endclass
824
825 def F(outer: Outer)
826 outer.inner.value = 1
827 enddef
828
829 def Test_assign_to_nested_typed_member()
830 var inner = Inner.new(0)
831 var outer = Outer.new(inner)
832 F(outer)
833 assert_equal(1, inner.value)
834 enddef
835
836 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200837
838 var script_inner = Inner.new(0)
839 var script_outer = Outer.new(script_inner)
840 script_outer.inner.value = 1
841 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200842 END
843 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200844
845 # Assignment where target item is read only in :def
846 lines =<< trim END
847 vim9script
848
849 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100850 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200851 endclass
852
853 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100854 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200855 endclass
856
857 def F(outer: Outer)
858 outer.inner.value = 1
859 enddef
860
861 def Test_assign_to_nested_typed_member()
862 var inner = Inner.new(0)
863 var outer = Outer.new(inner)
864 F(outer)
865 assert_equal(1, inner.value)
866 enddef
867
868 Test_assign_to_nested_typed_member()
869 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200870 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200871
872 # Assignment where target item is read only script level
873 lines =<< trim END
874 vim9script
875
876 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100877 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200878 endclass
879
880 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100881 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200882 endclass
883
884 def F(outer: Outer)
885 outer.inner.value = 1
886 enddef
887
888 var script_inner = Inner.new(0)
889 var script_outer = Outer.new(script_inner)
890 script_outer.inner.value = 1
891 assert_equal(1, script_inner.value)
892 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200893 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200894enddef
895
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000896def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200897 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000898 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200899 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000900
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200901 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100902 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000903
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200904 def Add(n: number)
905 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100906 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200907 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100908
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200909 var f = Foo.new(3)
910 f.Add(17)
911 assert_equal(20, f.x)
912
913 def AddToFoo(obj: Foo)
914 obj.x += 3
915 enddef
916
917 AddToFoo(f)
918 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000919 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200920 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000921enddef
922
Bram Moolenaarf4508042023-01-15 16:54:57 +0000923def Test_list_of_objects()
924 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200925 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000926
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200927 class Foo
928 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000929 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200930 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000931
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200932 def ProcessList(fooList: list<Foo>)
933 for foo in fooList
934 foo.Add()
935 endfor
936 enddef
937
938 var l: list<Foo> = [Foo.new()]
939 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000940 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200941 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000942enddef
943
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000944def Test_expr_after_using_object()
945 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200946 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000947
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200948 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100949 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200950 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000951
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200952 def Foo(): Something
953 var v = Something.new()
954 echo 'in Foo(): ' .. typename(v)
955 return v
956 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000957
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200958 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000959 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200960 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000961enddef
962
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000963def Test_class_default_new()
964 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200965 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000966
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200967 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100968 var lnum: number = 1
969 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200970 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000971
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200972 var pos = TextPosition.new()
973 assert_equal(1, pos.lnum)
974 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000975
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200976 pos = TextPosition.new(v:none, v:none)
977 assert_equal(1, pos.lnum)
978 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000979
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200980 pos = TextPosition.new(3, 22)
981 assert_equal(3, pos.lnum)
982 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000983
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200984 pos = TextPosition.new(v:none, 33)
985 assert_equal(1, pos.lnum)
986 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000987 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200988 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000989
990 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200991 vim9script
992 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100993 var name: string
994 var age: number = 42
995 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000996
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200997 def new(this.name, this.age = v:none, this.education = v:none)
998 enddef
999 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001000
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001001 var piet = Person.new("Piet")
1002 assert_equal("Piet", piet.name)
1003 assert_equal(42, piet.age)
1004 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001005
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001006 var chris = Person.new("Chris", 4, "none")
1007 assert_equal("Chris", chris.name)
1008 assert_equal(4, chris.age)
1009 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001010 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001011 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001012
1013 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001014 vim9script
1015 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001016 var name: string
1017 var age: number = 42
1018 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +00001019
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001020 def new(this.name, this.age = v:none, this.education = v:none)
1021 enddef
1022 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001023
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001024 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +00001025 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001026 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001027
1028 # Using a specific value to initialize an instance variable in the new()
1029 # method.
1030 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001031 vim9script
1032 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001033 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001034 def new(this.val = 'a')
1035 enddef
1036 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001037 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001038 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001039enddef
1040
h-east2261c892023-08-16 21:49:54 +09001041def Test_class_new_with_object_member()
1042 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001043 vim9script
h-east2261c892023-08-16 21:49:54 +09001044
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001045 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001046 var str: string
1047 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001048 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +09001049 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001050 def newVals(this.str, this.num)
1051 enddef
1052 endclass
h-east2261c892023-08-16 21:49:54 +09001053
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001054 def Check()
1055 try
1056 var c = C.new('cats', 2)
1057 assert_equal('cats', c.str)
1058 assert_equal(2, c.num)
1059
1060 c = C.newVals('dogs', 4)
1061 assert_equal('dogs', c.str)
1062 assert_equal(4, c.num)
1063 catch
1064 assert_report($'Unexpected exception was caught: {v:exception}')
1065 endtry
1066 enddef
1067
1068 Check()
h-east2261c892023-08-16 21:49:54 +09001069 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001070 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001071
1072 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001073 vim9script
1074
1075 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001076 var str: string
1077 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001078 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001079 enddef
1080 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001081
1082 def Check()
1083 try
1084 var c = C.new(1, 2)
1085 catch
1086 assert_report($'Unexpected exception was caught: {v:exception}')
1087 endtry
1088 enddef
1089
1090 Check()
h-eastdb385522023-09-28 22:18:19 +02001091 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001092 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001093
1094 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001095 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001096
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001097 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001098 var str: string
1099 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001100 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001101 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001102 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001103
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001104 def Check()
1105 try
1106 var c = C.newVals('dogs', 'apes')
1107 catch
1108 assert_report($'Unexpected exception was caught: {v:exception}')
1109 endtry
1110 enddef
1111
1112 Check()
1113 END
1114 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1115
1116 lines =<< trim END
1117 vim9script
1118
1119 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001120 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001121 def new(str: any)
1122 enddef
1123 endclass
1124
1125 def Check()
1126 try
1127 var c = C.new(1)
1128 catch
1129 assert_report($'Unexpected exception was caught: {v:exception}')
1130 endtry
1131 enddef
1132
1133 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001134 END
1135 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001136
1137 # Try using "this." argument in a class method
1138 lines =<< trim END
1139 vim9script
1140 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001141 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001142 static def Foo(this.val: number)
1143 enddef
1144 endclass
1145 END
1146 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1147
1148 # Try using "this." argument in an object method
1149 lines =<< trim END
1150 vim9script
1151 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001152 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001153 def Foo(this.val: number)
1154 enddef
1155 endclass
1156 END
1157 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001158enddef
1159
Bram Moolenaar74e12742022-12-13 21:14:28 +00001160def Test_class_object_member_inits()
1161 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001162 vim9script
1163 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001164 var lnum: number
1165 var col = 1
1166 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001167 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001168
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001169 var pos = TextPosition.new()
1170 assert_equal(0, pos.lnum)
1171 assert_equal(1, pos.col)
1172 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001173 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001174 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001175
1176 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001177 vim9script
1178 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001179 var lnum
1180 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001181 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001182 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001183 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001184
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001185 # If the type is not specified for a member, then it should be set during
1186 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001187 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001188 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001189
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001190 var init_count = 0
1191 def Init(): string
1192 init_count += 1
1193 return 'foo'
1194 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001195
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001196 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001197 var str1 = Init()
1198 var str2: string = Init()
1199 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001200 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001201
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001202 assert_equal(init_count, 0)
1203 var a = A.new()
1204 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001205 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001206 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001207
1208 # Test for initializing an object member with an unknown variable/type
1209 lines =<< trim END
1210 vim9script
1211 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001212 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001213 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001214 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001215 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001216 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001217
1218 # Test for initializing an object member with an special type
1219 lines =<< trim END
1220 vim9script
1221 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001222 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001223 endclass
1224 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001225 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001226enddef
1227
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001228" Test for instance variable access
1229def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001230 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001231 vim9script
1232 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001233 var _one = 1
1234 var two = 2
1235 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001236
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001237 def GetOne(): number
1238 return this._one
1239 enddef
1240 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001241
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001242 var trip = Triple.new()
1243 assert_equal(1, trip.GetOne())
1244 assert_equal(2, trip.two)
1245 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001246 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001247
Ernie Rael03042a22023-11-11 08:53:32 +01001248 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001249 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1250 trip.three = 33
1251 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001252
Ernie Raeld4802ec2023-10-20 11:59:00 +02001253 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001254 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001255 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001256
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001257 # Test for a public member variable name beginning with an underscore
1258 lines =<< trim END
1259 vim9script
1260 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001261 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001262 endclass
1263 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001264 v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001265
Bram Moolenaar590162c2022-12-24 21:24:06 +00001266 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001267 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001268
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001269 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001270 var make: string
1271 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001272
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001273 def new(make_arg: string)
1274 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001275 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001276
1277 def GetMake(): string
1278 return $"make = {this.make}"
1279 enddef
1280 def GetAge(): number
1281 return this.age
1282 enddef
1283 endclass
1284
1285 var c = MyCar.new("abc")
1286 assert_equal('make = abc', c.GetMake())
1287
1288 c = MyCar.new("def")
1289 assert_equal('make = def', c.GetMake())
1290
1291 var c2 = MyCar.new("123")
1292 assert_equal('make = 123', c2.GetMake())
1293
1294 def CheckCar()
1295 assert_equal("make = def", c.GetMake())
1296 assert_equal(5, c.GetAge())
1297 enddef
1298 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001299 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001300 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001301
1302 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001303 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001304
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001305 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001306 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001307
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001308 def new(make_arg: string)
1309 this.make = make_arg
1310 enddef
1311 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001312
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001313 var c = MyCar.new("abc")
1314 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001315 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001316 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001317
1318 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001319 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001320
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001321 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001322 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001323
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001324 def Add(n: number): any
1325 this.x->add(n)
1326 return this
1327 enddef
1328 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001329
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001330 echo Foo.new().Add(1).Add(2).x
1331 echo Foo.new().Add(1).Add(2)
1332 .x
1333 echo Foo.new().Add(1)
1334 .Add(2).x
1335 echo Foo.new()
1336 .Add(1).Add(2).x
1337 echo Foo.new()
1338 .Add(1)
1339 .Add(2)
1340 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001341 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001342 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001343
1344 # Test for "public" cannot be abbreviated
1345 lines =<< trim END
1346 vim9script
1347 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001348 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001349 endclass
1350 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001351 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001352
Doug Kearns74da0ee2023-12-14 20:26:26 +01001353 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001354 lines =<< trim END
1355 vim9script
1356 class Something
1357 public val = 1
1358 endclass
1359 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001360 v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001361
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001362 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001363 lines =<< trim END
1364 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001365 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001366 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001367 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001368 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001369 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001370 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001371
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001372 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001373 lines =<< trim END
1374 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001375 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001376 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001377 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001378 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001379 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001380 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001381
1382 # Modify a instance variable using the class name in a def function
1383 lines =<< trim END
1384 vim9script
1385 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001386 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001387 endclass
1388 def T()
1389 A.val = 1
1390 enddef
1391 T()
1392 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001393 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001394
1395 # Read a instance variable using the class name in a def function
1396 lines =<< trim END
1397 vim9script
1398 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001399 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001400 endclass
1401 def T()
1402 var i = A.val
1403 enddef
1404 T()
1405 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001406 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001407
1408 # Access from child class extending a class:
1409 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001410 vim9script
1411 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001412 var ro_obj_var = 10
1413 public var rw_obj_var = 20
1414 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001415 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001416
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001417 class B extends A
1418 def Foo()
1419 var x: number
1420 x = this.ro_obj_var
1421 this.ro_obj_var = 0
1422 x = this.rw_obj_var
1423 this.rw_obj_var = 0
1424 x = this._priv_obj_var
1425 this._priv_obj_var = 0
1426 enddef
1427 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001428
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001429 var b = B.new()
1430 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001431 END
1432 v9.CheckSourceSuccess(lines)
1433enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001434
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001435" Test for class variable access
1436def Test_class_variable_access()
1437 # Test for "static" cannot be abbreviated
1438 var lines =<< trim END
1439 vim9script
1440 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001441 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001442 endclass
1443 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001444 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001445
1446 # Test for "static" cannot be followed by "public".
1447 lines =<< trim END
1448 vim9script
1449 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001450 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001451 endclass
1452 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001453 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001454
1455 # A readonly class variable cannot be modified from a child class
1456 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001457 vim9script
1458 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001459 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001460 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001461
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001462 class B extends A
1463 def Foo()
1464 A.ro_class_var = 50
1465 enddef
1466 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001467
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001468 var b = B.new()
1469 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001470 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001471 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001472
Ernie Rael03042a22023-11-11 08:53:32 +01001473 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001474 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001475 vim9script
1476 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001477 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001478 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001479
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001480 class B extends A
1481 def Foo()
1482 var i = A._priv_class_var
1483 enddef
1484 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001485
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001486 var b = B.new()
1487 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001488 END
Ernie Rael03042a22023-11-11 08:53:32 +01001489 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001490
Ernie Rael03042a22023-11-11 08:53:32 +01001491 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001492 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001493 vim9script
1494 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001495 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001496 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001497
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 class B extends A
1499 def Foo()
1500 A._priv_class_var = 0
1501 enddef
1502 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001503
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001504 var b = B.new()
1505 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001506 END
Ernie Rael03042a22023-11-11 08:53:32 +01001507 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001508
1509 # Access from child class extending a class and from script context
1510 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001511 vim9script
1512 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001513 static var ro_class_var = 10
1514 public static var rw_class_var = 20
1515 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001516 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001517
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001518 class B extends A
1519 def Foo()
1520 var x: number
1521 x = A.ro_class_var
1522 assert_equal(10, x)
1523 x = A.rw_class_var
1524 assert_equal(25, x)
1525 A.rw_class_var = 20
1526 assert_equal(20, A.rw_class_var)
1527 enddef
1528 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001529
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001530 assert_equal(10, A.ro_class_var)
1531 assert_equal(20, A.rw_class_var)
1532 A.rw_class_var = 25
1533 assert_equal(25, A.rw_class_var)
1534 var b = B.new()
1535 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001536 END
1537 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001538enddef
1539
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001540def Test_class_object_compare()
1541 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001542 vim9script
1543 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001544 var nr = 0
1545 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001546 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001547 END
1548
1549 # used at the script level and in a compiled function
1550 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001551 var i1 = Item.new()
1552 assert_equal(i1, i1)
1553 assert_true(i1 is i1)
1554 var i2 = Item.new()
1555 assert_equal(i1, i2)
1556 assert_false(i1 is i2)
1557 var i3 = Item.new(0, 'xx')
1558 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001559
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001560 var io1 = Item.new(1, 'xx')
1561 assert_notequal(i1, io1)
1562 var io2 = Item.new(0, 'yy')
1563 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001564 END
1565
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001566 v9.CheckSourceSuccess(class_lines + test_lines)
1567 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001568 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001569
1570 for op in ['>', '>=', '<', '<=', '=~', '!~']
1571 var op_lines = [
1572 'var i1 = Item.new()',
1573 'var i2 = Item.new()',
1574 'echo i1 ' .. op .. ' i2',
1575 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001576 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001577 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001578 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001579 endfor
1580enddef
1581
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001582def Test_object_type()
1583 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001584 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001585
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001586 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001587 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001588 endclass
1589 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001590 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001591 endclass
1592 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001593 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001594 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001595
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001596 var o: One = One.new()
1597 var t: Two = Two.new()
1598 var m: TwoMore = TwoMore.new()
1599 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001600
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001601 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001602 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001603 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001604
1605 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001606 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001607
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001608 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001609 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001610 endclass
1611 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001612 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001613 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001614
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001615 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001616 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001617 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001618
1619 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001620 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001621
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001622 interface One
1623 def GetMember(): number
1624 endinterface
1625 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001626 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001627 def GetMember(): number
1628 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001629 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001630 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001631
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001632 var o: One = Two.new(5)
1633 assert_equal(5, o.GetMember())
1634 END
1635 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001636
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001637 lines =<< trim END
1638 vim9script
1639
1640 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001641 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001642 endclass
1643
1644 def Ref(name: string): func(Num): Num
1645 return (arg: Num): Num => {
1646 return eval(name)(arg)
1647 }
1648 enddef
1649
1650 const Fn = Ref('Double')
1651 var Double = (m: Num): Num => Num.new(m.n * 2)
1652
1653 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001654 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001655 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001656enddef
1657
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001658def Test_class_member()
1659 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001660 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001661 vim9script
1662 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001663 var lnum = 1
1664 var col = 1
1665 static var counter = 0
1666 static var _secret = 7
1667 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001668
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001669 static def AddToCounter(nr: number)
1670 counter += nr
1671 enddef
1672 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001673
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001674 assert_equal(0, TextPos.counter)
1675 TextPos.AddToCounter(3)
1676 assert_equal(3, TextPos.counter)
1677 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001678
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001679 def GetCounter(): number
1680 return TextPos.counter
1681 enddef
1682 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001683
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001684 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1685 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1686 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001687
Ernie Rael03042a22023-11-11 08:53:32 +01001688 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1689 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001690
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001691 assert_equal(42, TextPos.anybody)
1692 TextPos.anybody = 12
1693 assert_equal(12, TextPos.anybody)
1694 TextPos.anybody += 5
1695 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001696 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001697 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001698
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001699 # example in the help
1700 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001701 vim9script
1702 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001703 var size: number
1704 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001705
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001706 def new(this.size)
1707 totalSize += this.size
1708 enddef
1709 endclass
1710 assert_equal(0, OtherThing.totalSize)
1711 var to3 = OtherThing.new(3)
1712 assert_equal(3, OtherThing.totalSize)
1713 var to7 = OtherThing.new(7)
1714 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001715 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001716 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001717
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001718 # using static class member twice
1719 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001720 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001722 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001723 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001724
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001725 static def MacroSubstitute(s: string): string
1726 return substitute(s, '{{author}}', author, 'gi')
1727 enddef
1728 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001729
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001730 assert_equal('some text', HTML.MacroSubstitute('some text'))
1731 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001732 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001733 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001734
Ernie Rael03042a22023-11-11 08:53:32 +01001735 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001736 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001737 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001738
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001739 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001740 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001741
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001742 def Add(n: number): number
1743 const F = (): number => this._x + n
1744 return F()
1745 enddef
1746 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001747
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001748 var foo = Foo.new()
1749 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001750 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001751 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001752
Ernie Rael03042a22023-11-11 08:53:32 +01001753 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001754 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001755 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001756
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001757 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001758 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001760 def Add(n: number): number
1761 var Lam = () => {
1762 this._x = this._x + n
1763 }
1764 Lam()
1765 return this._x
1766 enddef
1767 endclass
h-east2bd6a092023-05-19 19:01:17 +01001768
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001769 var foo = Foo.new()
1770 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001771 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001772 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001773
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001774 # check shadowing
1775 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001776 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001777
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001778 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001779 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001780 def Method(count: number)
1781 echo count
1782 enddef
1783 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001784
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001785 var s = Some.new()
1786 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001787 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001788 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001789
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001790 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001791 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001792 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001794 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001795 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001796 def Method(arg: number)
1797 var count = 3
1798 echo arg count
1799 enddef
1800 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001801
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001802 var s = Some.new()
1803 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001804 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001805 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001806
1807 # Test for using an invalid type for a member variable
1808 lines =<< trim END
1809 vim9script
1810 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001811 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001812 endclass
1813 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001814 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001815
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001816 # Test for setting a member on a null object
1817 lines =<< trim END
1818 vim9script
1819 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001820 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001821 endclass
1822
1823 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001824 var obj: A
1825 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001826 enddef
1827 F()
1828 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001829 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001830
1831 # Test for accessing a member on a null object
1832 lines =<< trim END
1833 vim9script
1834 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001835 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001836 endclass
1837
1838 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001839 var obj: A
1840 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001841 enddef
1842 F()
1843 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001844 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001845
1846 # Test for setting a member on a null object, at script level
1847 lines =<< trim END
1848 vim9script
1849 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001850 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001851 endclass
1852
1853 var obj: A
1854 obj.val = ""
1855 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001856 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001857
1858 # Test for accessing a member on a null object, at script level
1859 lines =<< trim END
1860 vim9script
1861 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001862 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001863 endclass
1864
1865 var obj: A
1866 echo obj.val
1867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001868 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001869
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001870 # Test for no space before or after the '=' when initializing a member
1871 # variable
1872 lines =<< trim END
1873 vim9script
1874 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001875 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001876 endclass
1877 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001878 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001879 lines =<< trim END
1880 vim9script
1881 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001882 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001883 endclass
1884 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001885 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001886
1887 # Access a non-existing member
1888 lines =<< trim END
1889 vim9script
1890 class A
1891 endclass
1892 var a = A.new()
1893 var v = a.bar
1894 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001895 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001896enddef
1897
Ernie Raele6c9aa52023-10-06 19:55:52 +02001898" These messages should show the defining class of the variable (base class),
1899" not the class that did the reference (super class)
1900def Test_defining_class_message()
1901 var lines =<< trim END
1902 vim9script
1903
1904 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001905 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001906 endclass
1907
1908 class Child extends Base
1909 endclass
1910
1911 var o = Child.new()
1912 var x = o._v1
1913 END
Ernie Rael03042a22023-11-11 08:53:32 +01001914 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001915 lines =<< trim END
1916 vim9script
1917
1918 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001919 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001920 endclass
1921
1922 class Child extends Base
1923 endclass
1924
1925 def F()
1926 var o = Child.new()
1927 var x = o._v1
1928 enddef
1929 F()
1930 END
Ernie Rael03042a22023-11-11 08:53:32 +01001931 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001932 lines =<< trim END
1933 vim9script
1934
1935 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001936 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001937 endclass
1938
1939 class Child extends Base
1940 endclass
1941
1942 var o = Child.new()
1943 o.v1 = []
1944 END
1945 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1946 lines =<< trim END
1947 vim9script
1948
1949 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001950 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001951 endclass
1952
1953 class Child extends Base
1954 endclass
1955
1956 def F()
1957 var o = Child.new()
1958 o.v1 = []
1959 enddef
1960 F()
1961 END
1962
Ernie Rael03042a22023-11-11 08:53:32 +01001963 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001964 # of the class hierarchy.
1965 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1966 lines =<< trim END
1967 vim9script
1968
1969 class Base0
1970 endclass
1971
1972 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01001973 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001974 endclass
1975
1976 class Child extends Base
1977 endclass
1978
1979 def F()
1980 var o = Child.new()
1981 var x = o._v1
1982 enddef
1983 F()
1984 END
Ernie Rael03042a22023-11-11 08:53:32 +01001985 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001986
Ernie Rael03042a22023-11-11 08:53:32 +01001987 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02001988 # of the class hierarchy.
1989 lines =<< trim END
1990 vim9script
1991
1992 class Base0
1993 endclass
1994
1995 class Base extends Base0
1996 endclass
1997
1998 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001999 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002000 endclass
2001
2002 def F()
2003 var o = Child.new()
2004 var x = o._v1
2005 enddef
2006 F()
2007 END
Ernie Rael03042a22023-11-11 08:53:32 +01002008 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002009enddef
2010
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002011func Test_class_garbagecollect()
2012 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002013 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002014
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002015 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002016 var p = [2, 3]
2017 static var pl = ['a', 'b']
2018 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002019 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002020
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002021 echo Point.pl Point.pd
2022 call test_garbagecollect_now()
2023 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002024 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002025 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002026
2027 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002028 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002029
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002030 interface View
2031 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002032
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002033 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01002034 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002035 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002036
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002037 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01002038 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002039
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002040 def new()
2041 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01002042 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002043 enddef
2044 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002045
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002046 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002047
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002048 # overwrite "view", will be garbage-collected next
2049 view = MyView.new()
2050 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002051 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002052 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002053endfunc
2054
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002055" Test interface garbage collection
2056func Test_interface_garbagecollect()
2057 let lines =<< trim END
2058 vim9script
2059
2060 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002061 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002062
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002063 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002064 endinterface
2065
2066 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002067 static var ro_class_var: number = 10
2068 public static var rw_class_var: number = 20
2069 static var _priv_class_var: number = 30
2070 var ro_obj_var: number = 40
2071 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002072
2073 static def _ClassBar(): number
2074 return _priv_class_var
2075 enddef
2076
2077 static def ClassFoo(): number
2078 return ro_class_var + rw_class_var + A._ClassBar()
2079 enddef
2080
2081 def _ObjBar(): number
2082 return this._priv_obj_var
2083 enddef
2084
2085 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002086 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002087 enddef
2088 endclass
2089
2090 assert_equal(60, A.ClassFoo())
2091 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002092 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002093 test_garbagecollect_now()
2094 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002095 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002096 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002097 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002098endfunc
2099
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002100def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002101 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002102 vim9script
2103 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002104 var value = 0
2105 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002106
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002107 def new(v: number)
2108 this.value = v
2109 ++objects
2110 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002111
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002112 static def GetCount(): number
2113 return objects
2114 enddef
2115 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002116
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002117 assert_equal(0, Value.GetCount())
2118 var v1 = Value.new(2)
2119 assert_equal(1, Value.GetCount())
2120 var v2 = Value.new(7)
2121 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002122 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002123 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002124
2125 # Test for cleaning up after a class definition failure when using class
2126 # functions.
2127 lines =<< trim END
2128 vim9script
2129 class A
2130 static def Foo()
2131 enddef
2132 aaa
2133 endclass
2134 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002135 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002136
2137 # Test for calling a class method from another class method without the class
2138 # name prefix.
2139 lines =<< trim END
2140 vim9script
2141 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002142 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002143 static def Foo(n: number)
2144 myList->add(n)
2145 enddef
2146 static def Bar()
2147 Foo(2)
2148 enddef
2149 def Baz()
2150 Foo(3)
2151 enddef
2152 endclass
2153 A.Bar()
2154 var a = A.new()
2155 a.Baz()
2156 assert_equal([1, 2, 3], A.myList)
2157 END
2158 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002159enddef
2160
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002161def Test_class_defcompile()
2162 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002163 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002164
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002165 class C
2166 def Fo(i: number): string
2167 return i
2168 enddef
2169 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002170
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002171 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002172 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002173 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002174
2175 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002176 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002177
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002178 class C
2179 static def Fc(): number
2180 return 'x'
2181 enddef
2182 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002183
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002184 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002185 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002186 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002187
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002188 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002189 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002190
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002191 class C
2192 static def new()
2193 enddef
2194 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002195
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002196 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002197 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002198 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002199
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002200 # Trying to compile a function using a non-existing class variable
2201 lines =<< trim END
2202 vim9script
2203 defcompile x.Foo()
2204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002205 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002206
2207 # Trying to compile a function using a variable which is not a class
2208 lines =<< trim END
2209 vim9script
2210 var x: number
2211 defcompile x.Foo()
2212 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002213 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002214
2215 # Trying to compile a function without specifying the name
2216 lines =<< trim END
2217 vim9script
2218 class A
2219 endclass
2220 defcompile A.
2221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002222 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002223
2224 # Trying to compile a non-existing class object member function
2225 lines =<< trim END
2226 vim9script
2227 class A
2228 endclass
2229 var a = A.new()
2230 defcompile a.Foo()
2231 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002232 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002233enddef
2234
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002235def Test_class_object_to_string()
2236 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002237 vim9script
2238 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002239 var lnum = 1
2240 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002241 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002242
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002243 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002244
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002245 var pos = TextPosition.new()
2246 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002247 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002248 v9.CheckSourceSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +02002249
2250 # check string() with object nesting
2251 lines =<< trim END
2252 vim9script
2253 class C
2254 var nest1: C
2255 var nest2: C
2256 def Init(n1: C, n2: C)
2257 this.nest1 = n1
2258 this.nest2 = n2
2259 enddef
2260 endclass
2261
2262 var o1 = C.new()
2263 var o2 = C.new()
2264 o1.Init(o1, o2)
2265 o2.Init(o2, o1)
2266
2267 # The following previously put's vim into an infinite loop.
2268
2269 var expect = "object of C {nest1: object of C {...}, nest2: object of C {nest1: object of C {...}, nest2: object of C {...}}}"
2270 assert_equal(expect, string(o1))
2271 END
2272 v9.CheckSourceSuccess(lines)
2273
2274 lines =<< trim END
2275 vim9script
2276
2277 class B
2278 endclass
2279
2280 class C
2281 var b: B
2282 var c: C
2283 endclass
2284
2285 var o1 = C.new(B.new(), C.new(B.new()))
2286 var expect = "object of C {b: object of B {}, c: object of C {b: object of B {}, c: object of [unknown]}}"
2287 assert_equal(expect, string(o1))
2288 END
2289 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002290enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002291
Bram Moolenaar554d0312023-01-05 19:59:18 +00002292def Test_interface_basics()
2293 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002294 vim9script
2295 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002296 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002297 def GetCount(): number
2298 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002299 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002300 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002301
2302 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002303 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002304 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002305 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002306 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002307 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002308
2309 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002310 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002311
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002312 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002313 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002314 def Method(value: number)
2315 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002316 END
h-east61378a12023-04-18 19:07:29 +01002317 # The argument name and the object member name are the same, but this is not a
2318 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002319 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002320
2321 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002322 vim9script
2323 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002324 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002325 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002326 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002327 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002328
2329 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002330 vim9script
2331 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002332 var value: string
2333 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002334 def GetCount(): number
2335 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002336 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002337 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002338
2339 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002340 vim9script
2341 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002342 var value: string
2343 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002344 def GetCount(): number
2345 return 5
2346 enddef
2347 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002348 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002349 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002350
Yegappan Lakshmananac773182024-04-27 11:36:12 +02002351 # Additional commands after "interface name"
2352 lines =<< trim END
2353 vim9script
2354 interface Something | var x = 10 | var y = 20
2355 endinterface
2356 END
2357 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
2358
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002359 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002360 vim9script
2361 export interface EnterExit
2362 def Enter(): void
2363 def Exit(): void
2364 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002365 END
2366 writefile(lines, 'XdefIntf.vim', 'D')
2367
2368 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002369 vim9script
2370 import './XdefIntf.vim' as defIntf
2371 export def With(ee: defIntf.EnterExit, F: func)
2372 ee.Enter()
2373 try
2374 F()
2375 finally
2376 ee.Exit()
2377 endtry
2378 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002379 END
2380 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002381
2382 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002383 vim9script
2384 export abstract class EnterExit
2385 def Enter(): void
2386 enddef
2387 def Exit(): void
2388 enddef
2389 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002390 END
2391 writefile(imported, 'XdefIntf2.vim', 'D')
2392
2393 lines[1] = " import './XdefIntf2.vim' as defIntf"
2394 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002395enddef
2396
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002397" Test for using string() with an interface
2398def Test_interface_to_string()
2399 var lines =<< trim END
2400 vim9script
2401 interface Intf
2402 def Method(nr: number)
2403 endinterface
2404 assert_equal("interface Intf", string(Intf))
2405 END
2406 v9.CheckSourceSuccess(lines)
2407enddef
2408
Bram Moolenaar94674f22023-01-06 18:42:20 +00002409def Test_class_implements_interface()
2410 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002411 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002412
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002413 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002414 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002415 def Method(nr: number)
2416 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002417
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002418 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002419 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002420 def Method(nr: number)
2421 echo nr
2422 enddef
2423 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002424
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002425 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002426 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002427 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002428
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002429 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002430 var member = 'abc'
2431 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002432 def Method(nr: number)
2433 echo nr
2434 enddef
2435 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002436 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002437 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002438
2439 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002440 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002441
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002442 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002443 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002444 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002445
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002446 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002447 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002448 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002449 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002450 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002451
2452 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002453 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002454
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002455 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002456 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002457 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002458
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002459 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002460 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002461 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002462 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002463 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002464
2465 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002466 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002467
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002468 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002469 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002470 def Method(nr: number)
2471 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002472
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002473 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002474 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002475 def Method(nr: number)
2476 echo nr
2477 enddef
2478 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002479 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002480 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002481
2482 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002483 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002484
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002485 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002486 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002487 def Methods(nr: number)
2488 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002489
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002490 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002491 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002492 def Method(nr: number)
2493 echo nr
2494 enddef
2495 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002496 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002497 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002498
2499 # Check different order of members in class and interface works.
2500 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002501 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002502
2503 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002504 var label: string
2505 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002506 endinterface
2507
2508 # order of members is opposite of interface
2509 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002510 public var lnum: number = 5
2511 var errpos: number = 42
2512 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002513 endclass
2514
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002515 def Test()
2516 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002517
2518 assert_equal('label', result.label)
2519 assert_equal(42, result.errpos)
2520 enddef
2521
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002522 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002523 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002524 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002525
2526 # Interface name after "extends" doesn't end in a space or NUL character
2527 lines =<< trim END
2528 vim9script
2529 interface A
2530 endinterface
2531 class B extends A"
2532 endclass
2533 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002534 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002535
2536 # Trailing characters after a class name
2537 lines =<< trim END
2538 vim9script
2539 class A bbb
2540 endclass
2541 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002542 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002543
2544 # using "implements" with a non-existing class
2545 lines =<< trim END
2546 vim9script
2547 class A implements B
2548 endclass
2549 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002550 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002551
2552 # using "implements" with a regular class
2553 lines =<< trim END
2554 vim9script
2555 class A
2556 endclass
2557 class B implements A
2558 endclass
2559 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002560 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002561
2562 # using "implements" with a variable
2563 lines =<< trim END
2564 vim9script
2565 var T: number = 10
2566 class A implements T
2567 endclass
2568 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002569 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002570
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002571 # implements should be followed by a white space
2572 lines =<< trim END
2573 vim9script
2574 interface A
2575 endinterface
2576 class B implements A;
2577 endclass
2578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002579 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002580
LemonBoyc5d27442023-08-19 13:02:35 +02002581 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002582 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002583
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002584 interface One
2585 def IsEven(nr: number): bool
2586 endinterface
2587 class Two implements One
2588 def IsEven(nr: number): string
2589 enddef
2590 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002591 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002592 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002593
2594 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002595 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002596
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002597 interface One
2598 def IsEven(nr: number): bool
2599 endinterface
2600 class Two implements One
2601 def IsEven(nr: bool): bool
2602 enddef
2603 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002604 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002605 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002606
2607 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002608 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002609
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002610 interface One
2611 def IsEven(nr: number): bool
2612 endinterface
2613 class Two implements One
2614 def IsEven(nr: number, ...extra: list<number>): bool
2615 enddef
2616 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002617 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002618 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 +02002619
2620 # access superclass interface members from subclass, mix variable order
2621 lines =<< trim END
2622 vim9script
2623
2624 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002625 var mvar1: number
2626 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002627 endinterface
2628
2629 # NOTE: the order is swapped
2630 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002631 var mvar2: number
2632 var mvar1: number
2633 public static var svar2: number
2634 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002635 def new()
2636 svar1 = 11
2637 svar2 = 12
2638 this.mvar1 = 111
2639 this.mvar2 = 112
2640 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002641 endclass
2642
2643 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002644 def new()
2645 this.mvar1 = 121
2646 this.mvar2 = 122
2647 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002648 endclass
2649
2650 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002651 def new()
2652 this.mvar1 = 131
2653 this.mvar2 = 132
2654 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002655 endclass
2656
Ernie Raelcf138d42023-09-06 20:45:03 +02002657 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002658 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002659 enddef
2660
2661 var oa = A.new()
2662 var ob = B.new()
2663 var oc = C.new()
2664
Ernie Raelcf138d42023-09-06 20:45:03 +02002665 assert_equal([111, 112], F2(oa))
2666 assert_equal([121, 122], F2(ob))
2667 assert_equal([131, 132], F2(oc))
2668 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002669 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002670
2671 # Access superclass interface members from subclass, mix variable order.
2672 # Two interfaces, one on A, one on B; each has both kinds of variables
2673 lines =<< trim END
2674 vim9script
2675
2676 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002677 var mvar1: number
2678 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002679 endinterface
2680
2681 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002682 var mvar3: number
2683 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002684 endinterface
2685
2686 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002687 public static var svar1: number
2688 public static var svar2: number
2689 var mvar1: number
2690 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002691 def new()
2692 svar1 = 11
2693 svar2 = 12
2694 this.mvar1 = 111
2695 this.mvar2 = 112
2696 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002697 endclass
2698
2699 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002700 static var svar3: number
2701 static var svar4: number
2702 var mvar3: number
2703 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002704 def new()
2705 svar3 = 23
2706 svar4 = 24
2707 this.mvar1 = 121
2708 this.mvar2 = 122
2709 this.mvar3 = 123
2710 this.mvar4 = 124
2711 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002712 endclass
2713
2714 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002715 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002716 def new()
2717 svar5 = 1001
2718 this.mvar1 = 131
2719 this.mvar2 = 132
2720 this.mvar3 = 133
2721 this.mvar4 = 134
2722 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002723 endclass
2724
Ernie Raelcf138d42023-09-06 20:45:03 +02002725 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002726 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002727 enddef
2728
Ernie Raelcf138d42023-09-06 20:45:03 +02002729 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002730 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002731 enddef
2732
Ernie Raelcf138d42023-09-06 20:45:03 +02002733 var oa = A.new()
2734 var ob = B.new()
2735 var oc = C.new()
2736
Ernie Raelcf138d42023-09-06 20:45:03 +02002737 assert_equal([[111, 112]], [F2(oa)])
2738 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2739 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002740 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002741 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002742
2743 # Using two interface names without a space after the ","
2744 lines =<< trim END
2745 vim9script
2746 interface A
2747 endinterface
2748 interface B
2749 endinterface
2750 class C implements A,B
2751 endclass
2752 END
2753 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2754
2755 # No interface name after a comma
2756 lines =<< trim END
2757 vim9script
2758 interface A
2759 endinterface
2760 class B implements A,
2761 endclass
2762 END
2763 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2764
2765 # No interface name after implements
2766 lines =<< trim END
2767 vim9script
2768 class A implements
2769 endclass
2770 END
2771 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002772enddef
2773
Bram Moolenaard0200c82023-01-28 15:19:40 +00002774def Test_call_interface_method()
2775 var lines =<< trim END
2776 vim9script
2777 interface Base
2778 def Enter(): void
2779 endinterface
2780
2781 class Child implements Base
2782 def Enter(): void
2783 g:result ..= 'child'
2784 enddef
2785 endclass
2786
2787 def F(obj: Base)
2788 obj.Enter()
2789 enddef
2790
2791 g:result = ''
2792 F(Child.new())
2793 assert_equal('child', g:result)
2794 unlet g:result
2795 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002796 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002797
2798 lines =<< trim END
2799 vim9script
2800 class Base
2801 def Enter(): void
2802 g:result ..= 'base'
2803 enddef
2804 endclass
2805
2806 class Child extends Base
2807 def Enter(): void
2808 g:result ..= 'child'
2809 enddef
2810 endclass
2811
2812 def F(obj: Base)
2813 obj.Enter()
2814 enddef
2815
2816 g:result = ''
2817 F(Child.new())
2818 assert_equal('child', g:result)
2819 unlet g:result
2820 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002821 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002822
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002823 # method of interface returns a value
2824 lines =<< trim END
2825 vim9script
2826 interface Base
2827 def Enter(): string
2828 endinterface
2829
2830 class Child implements Base
2831 def Enter(): string
2832 g:result ..= 'child'
2833 return "/resource"
2834 enddef
2835 endclass
2836
2837 def F(obj: Base)
2838 var r = obj.Enter()
2839 g:result ..= r
2840 enddef
2841
2842 g:result = ''
2843 F(Child.new())
2844 assert_equal('child/resource', g:result)
2845 unlet g:result
2846 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002847 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002848
2849 lines =<< trim END
2850 vim9script
2851 class Base
2852 def Enter(): string
2853 return null_string
2854 enddef
2855 endclass
2856
2857 class Child extends Base
2858 def Enter(): string
2859 g:result ..= 'child'
2860 return "/resource"
2861 enddef
2862 endclass
2863
2864 def F(obj: Base)
2865 var r = obj.Enter()
2866 g:result ..= r
2867 enddef
2868
2869 g:result = ''
2870 F(Child.new())
2871 assert_equal('child/resource', g:result)
2872 unlet g:result
2873 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002874 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002875
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002876 # No class that implements the interface.
2877 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002878 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002879
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002880 interface IWithEE
2881 def Enter(): any
2882 def Exit(): void
2883 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002884
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002885 def With1(ee: IWithEE, F: func)
2886 var r = ee.Enter()
2887 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002888
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002889 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002890 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002891 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002892enddef
2893
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002894def Test_class_used_as_type()
2895 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002896 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002897
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002898 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002899 var x = 0
2900 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002901 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002902
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002903 var p: Point
2904 p = Point.new(2, 33)
2905 assert_equal(2, p.x)
2906 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002907 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002908 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002909
2910 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002911 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002912
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002913 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002914 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002915 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002916
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002917 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002918 var x = 0
2919 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002920 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002921
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002922 var p: Point
2923 p = Point.new(2, 33)
2924 var hx = p
2925 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002926 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002927 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002928
2929 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002930 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002931
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002932 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002933 var x = 0
2934 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002935 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002936
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002937 var p: Point
2938 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002939 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002940 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002941enddef
2942
Bram Moolenaar83677162023-01-08 19:54:10 +00002943def Test_class_extends()
2944 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002945 vim9script
2946 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002947 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002948 def GetOne(): number
2949 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002950 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002951 endclass
2952 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002953 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002954 def GetTotal(): number
2955 return this.one + this.two
2956 enddef
2957 endclass
2958 var o = Child.new()
2959 assert_equal(1, o.one)
2960 assert_equal(2, o.two)
2961 assert_equal(1, o.GetOne())
2962 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002963 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002964 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002965
2966 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002967 vim9script
2968 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002969 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002970 endclass
2971 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002972 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002973 endclass
2974 var o = Child.new(3, 44)
2975 assert_equal(3, o.one)
2976 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002977 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002978 v9.CheckSourceSuccess(lines)
2979
2980 lines =<< trim END
2981 vim9script
2982 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002983 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002984 endclass
2985 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002986 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002987 endclass
2988 END
2989 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2990
2991 lines =<< trim END
2992 vim9script
2993 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01002994 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002995 endclass
2996 END
2997 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2998
2999 lines =<< trim END
3000 vim9script
3001 var SomeVar = 99
3002 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01003003 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003004 endclass
3005 END
3006 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
3007
3008 lines =<< trim END
3009 vim9script
3010 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003011 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003012 def ToString(): string
3013 return this.name
3014 enddef
3015 endclass
3016
3017 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003018 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003019 def ToString(): string
3020 return super.ToString() .. ': ' .. this.age
3021 enddef
3022 endclass
3023
3024 var o = Child.new('John', 42)
3025 assert_equal('John: 42', o.ToString())
3026 END
3027 v9.CheckSourceSuccess(lines)
3028
3029 lines =<< trim END
3030 vim9script
3031 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003032 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003033 def ToString(): number
3034 return this.age
3035 enddef
3036 def ToString(): string
3037 return this.age
3038 enddef
3039 endclass
3040 END
3041 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
3042
3043 lines =<< trim END
3044 vim9script
3045 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003046 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003047 def ToString(): string
3048 return super .ToString() .. ': ' .. this.age
3049 enddef
3050 endclass
3051 var o = Child.new(42)
3052 echo o.ToString()
3053 END
3054 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
3055
3056 lines =<< trim END
3057 vim9script
3058 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003059 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003060 def ToString(): string
3061 return this.name
3062 enddef
3063 endclass
3064
3065 var age = 42
3066 def ToString(): string
3067 return super.ToString() .. ': ' .. age
3068 enddef
3069 echo ToString()
3070 END
3071 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
3072
3073 lines =<< trim END
3074 vim9script
3075 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003076 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003077 def ToString(): string
3078 return super.ToString() .. ': ' .. this.age
3079 enddef
3080 endclass
3081 var o = Child.new(42)
3082 echo o.ToString()
3083 END
3084 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
3085
3086 lines =<< trim END
3087 vim9script
3088 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003089 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003090 static def ToString(): string
3091 return 'Base class'
3092 enddef
3093 endclass
3094
3095 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003096 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003097 def ToString(): string
3098 return Base.ToString() .. ': ' .. this.age
3099 enddef
3100 endclass
3101
3102 var o = Child.new('John', 42)
3103 assert_equal('Base class: 42', o.ToString())
3104 END
3105 v9.CheckSourceSuccess(lines)
3106
3107 lines =<< trim END
3108 vim9script
3109 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003110 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003111 def new(init: number)
3112 this.value = number + 1
3113 enddef
3114 endclass
3115 class Child extends Base
3116 def new()
3117 this.new(3)
3118 enddef
3119 endclass
3120 var c = Child.new()
3121 END
3122 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003123
3124 # base class with more than one object member
3125 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003126 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003127
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003128 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003129 var success: bool
3130 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003131 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003132
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003133 class Success extends Result
3134 def new(this.value = v:none)
3135 this.success = true
3136 enddef
3137 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003138
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003139 var v = Success.new('asdf')
3140 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003141 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003142 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003143
3144 # class name after "extends" doesn't end in a space or NUL character
3145 lines =<< trim END
3146 vim9script
3147 class A
3148 endclass
3149 class B extends A"
3150 endclass
3151 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003152 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003153enddef
3154
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003155def Test_using_base_class()
3156 var lines =<< trim END
3157 vim9script
3158
3159 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003160 def Enter(): any
3161 return null
3162 enddef
3163 def Exit(resource: any): void
3164 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003165 endclass
3166
3167 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003168 def Enter(): any
3169 return 42
3170 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003171
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003172 def Exit(resource: number): void
3173 g:result ..= '/exit'
3174 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003175 endclass
3176
3177 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003178 var r = ee.Enter()
3179 try
3180 g:result ..= r
3181 finally
3182 g:result ..= '/finally'
3183 ee.Exit(r)
3184 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003185 enddef
3186
3187 g:result = ''
3188 With(ChildEE.new())
3189 assert_equal('42/finally/exit', g:result)
3190 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003191 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003192 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003193
3194 # Using super, Child invokes Base method which has optional arg. #12471
3195 lines =<< trim END
3196 vim9script
3197
3198 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003199 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003200 def Method(arg = 0)
3201 this.success = true
3202 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003203 endclass
3204
3205 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003206 def new()
3207 super.Method()
3208 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003209 endclass
3210
3211 var obj = Child.new()
3212 assert_equal(true, obj.success)
3213 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003214 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003215enddef
3216
Bram Moolenaara86655a2023-01-12 17:06:27 +00003217def Test_class_import()
3218 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003219 vim9script
3220 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003221 var kind: string
3222 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003223 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003224 END
3225 writefile(lines, 'Xanimal.vim', 'D')
3226
3227 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003228 vim9script
3229 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003230
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003231 var a: animal.Animal
3232 a = animal.Animal.new('fish', 'Eric')
3233 assert_equal('fish', a.kind)
3234 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003235
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003236 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3237 assert_equal('cat', b.kind)
3238 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003239 END
3240 v9.CheckScriptSuccess(lines)
3241enddef
3242
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003243" Test for importing a class into a legacy script and calling the class method
3244def Test_class_method_from_legacy_script()
3245 var lines =<< trim END
3246 vim9script
3247 export class A
3248 static var name: string = 'a'
3249 static def SetName(n: string)
3250 name = n
3251 enddef
3252 endclass
3253 END
3254 writefile(lines, 'Xvim9export.vim', 'D')
3255
3256 lines =<< trim END
3257 import './Xvim9export.vim' as vim9
3258
3259 call s:vim9.A.SetName('b')
3260 call assert_equal('b', s:vim9.A.name)
3261 END
3262 v9.CheckScriptSuccess(lines)
3263enddef
3264
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003265" Test for implementing an imported interface
3266def Test_implement_imported_interface()
3267 var lines =<< trim END
3268 vim9script
3269 export interface Imp_Intf1
3270 def Fn1(): number
3271 endinterface
3272 export interface Imp_Intf2
3273 def Fn2(): number
3274 endinterface
3275 END
3276 writefile(lines, 'Ximportinterface.vim', 'D')
3277
3278 lines =<< trim END
3279 vim9script
3280 import './Ximportinterface.vim' as Xintf
3281
3282 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3283 def Fn1(): number
3284 return 10
3285 enddef
3286 def Fn2(): number
3287 return 20
3288 enddef
3289 endclass
3290 var a = A.new()
3291 assert_equal(10, a.Fn1())
3292 assert_equal(20, a.Fn2())
3293 END
3294 v9.CheckScriptSuccess(lines)
3295enddef
3296
3297" Test for extending an imported class
3298def Test_extend_imported_class()
3299 var lines =<< trim END
3300 vim9script
3301 export class Imp_C1
3302 def Fn1(): number
3303 return 5
3304 enddef
3305 endclass
3306 END
3307 writefile(lines, 'Xextendimportclass.vim', 'D')
3308
3309 lines =<< trim END
3310 vim9script
3311 import './Xextendimportclass.vim' as XClass
3312
3313 class A extends XClass.Imp_C1
3314 endclass
3315 var a = A.new()
3316 assert_equal(5, a.Fn1())
3317 END
3318 v9.CheckScriptSuccess(lines)
3319enddef
3320
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003321def Test_abstract_class()
3322 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003323 vim9script
3324 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003325 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003326 endclass
3327 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003328 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003329 endclass
3330 var p: Base = Person.new('Peter', 42)
3331 assert_equal('Peter', p.name)
3332 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003333 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003334 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003335
3336 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003337 vim9script
3338 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003339 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003340 endclass
3341 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003342 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003343 endclass
3344 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003345 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003346 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003347
3348 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003349 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003350 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003351 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003352 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003353 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003354
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003355 # Additional commands after "abstract class"
3356 lines =<< trim END
3357 vim9script
3358 abstract class Something | var x = []
3359 endclass
3360 END
3361 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3362
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003363 # Abstract class cannot have a "new" function
3364 lines =<< trim END
3365 vim9script
3366 abstract class Base
3367 def new()
3368 enddef
3369 endclass
3370 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003371 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003372
3373 # extending an abstract class with class methods and variables
3374 lines =<< trim END
3375 vim9script
3376 abstract class A
3377 static var s: string = 'vim'
3378 static def Fn(): list<number>
3379 return [10]
3380 enddef
3381 endclass
3382 class B extends A
3383 endclass
3384 var b = B.new()
3385 assert_equal('vim', A.s)
3386 assert_equal([10], A.Fn())
3387 END
3388 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003389enddef
3390
Bram Moolenaar486fc252023-01-18 14:51:07 +00003391def Test_closure_in_class()
3392 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003393 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003394
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003395 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003396 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003397
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003398 def new()
3399 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3400 enddef
3401 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003402
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003403 Foo.new()
3404 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003405 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003406 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003407enddef
3408
Ernie Rael9ed53752023-12-11 17:40:46 +01003409def Test_construct_object_from_legacy()
3410 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003411 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003412 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003413
Ernie Rael9ed53752023-12-11 17:40:46 +01003414 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003415
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003416 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003417 def new(arg: string)
3418 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003419 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003420 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003421
Ernie Rael9ed53752023-12-11 17:40:46 +01003422 export def CreateA(...args: list<any>): A
3423 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003424 enddef
3425
Ernie Rael9ed53752023-12-11 17:40:46 +01003426 g:P = CreateA
3427 legacy call g:P('some_arg')
3428 assert_equal(true, newCalled)
3429 unlet g:P
3430 END
3431 v9.CheckSourceSuccess(lines)
3432
3433 lines =<< trim END
3434 vim9script
3435
3436 var newCalled = false
3437
3438 class A
3439 static def CreateA(options = {}): any
3440 return A.new()
3441 enddef
3442 def new()
3443 newCalled = true
3444 enddef
3445 endclass
3446
3447 g:P = A.CreateA
3448 legacy call g:P()
3449 assert_equal(true, newCalled)
3450 unlet g:P
3451 END
3452 v9.CheckSourceSuccess(lines)
3453
3454 # This also tests invoking "new()" with "call"
3455 lines =<< trim END
3456 vim9script
3457
3458 var createdObject: any
3459
3460 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003461 var val1: number
3462 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003463 static def CreateA(...args: list<any>): any
3464 createdObject = call(A.new, args)
3465 return createdObject
3466 enddef
3467 endclass
3468
3469 g:P = A.CreateA
3470 legacy call g:P(3, 5)
3471 assert_equal(3, createdObject.val1)
3472 assert_equal(5, createdObject.val2)
3473 legacy call g:P()
3474 assert_equal(0, createdObject.val1)
3475 assert_equal(0, createdObject.val2)
3476 legacy call g:P(7)
3477 assert_equal(7, createdObject.val1)
3478 assert_equal(0, createdObject.val2)
3479 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003480 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003481 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003482enddef
3483
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003484def Test_defer_with_object()
3485 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003486 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003487
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003488 class CWithEE
3489 def Enter()
3490 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003491 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003492 def Exit()
3493 g:result ..= "exited"
3494 enddef
3495 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003496
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003497 def With(ee: CWithEE, F: func)
3498 ee.Enter()
3499 defer ee.Exit()
3500 F()
3501 enddef
3502
3503 g:result = ''
3504 var obj = CWithEE.new()
3505 obj->With(() => {
3506 g:result ..= "called/"
3507 })
3508 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003509 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003510 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003511 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003512
3513 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003514 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003515
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003516 class BaseWithEE
3517 def Enter()
3518 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003519 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003520 def Exit()
3521 g:result ..= "exited-base"
3522 enddef
3523 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003524
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003525 class CWithEE extends BaseWithEE
3526 def Enter()
3527 g:result ..= "entered-child/"
3528 enddef
3529 def Exit()
3530 g:result ..= "exited-child"
3531 enddef
3532 endclass
3533
3534 def With(ee: BaseWithEE, F: func)
3535 ee.Enter()
3536 defer ee.Exit()
3537 F()
3538 enddef
3539
3540 g:result = ''
3541 var obj = CWithEE.new()
3542 obj->With(() => {
3543 g:result ..= "called/"
3544 })
3545 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003546 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003547 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003548 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003549enddef
3550
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003551" The following test used to crash Vim (Github issue #12676)
3552def Test_extends_method_crashes_vim()
3553 var lines =<< trim END
3554 vim9script
3555
3556 class Observer
3557 endclass
3558
3559 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003560 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003561
3562 def Set(v: any)
3563 if v != this.value
3564 this.value = v
3565 endif
3566 enddef
3567
3568 def Register(observer: Observer)
3569 enddef
3570 endclass
3571
3572 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003573 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003574 endclass
3575
3576 def Observe(obj: Property, who: Observer)
3577 obj.Register(who)
3578 enddef
3579
3580 var p = Bool.new(false)
3581 var myObserver = Observer.new()
3582
3583 Observe(p, myObserver)
3584
3585 p.Set(true)
3586 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003587 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003588enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003589
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003590" Test for calling a method in a class that is extended
3591def Test_call_method_in_extended_class()
3592 var lines =<< trim END
3593 vim9script
3594
3595 var prop_init_called = false
3596 var prop_register_called = false
3597
3598 class Property
3599 def Init()
3600 prop_init_called = true
3601 enddef
3602
3603 def Register()
3604 prop_register_called = true
3605 enddef
3606 endclass
3607
3608 class Bool extends Property
3609 endclass
3610
3611 def Observe(obj: Property)
3612 obj.Register()
3613 enddef
3614
3615 var p = Property.new()
3616 Observe(p)
3617
3618 p.Init()
3619 assert_true(prop_init_called)
3620 assert_true(prop_register_called)
3621 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003622 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003623enddef
3624
LemonBoyafe04662023-08-23 21:08:11 +02003625def Test_instanceof()
3626 var lines =<< trim END
3627 vim9script
3628
3629 class Base1
3630 endclass
3631
3632 class Base2 extends Base1
3633 endclass
3634
3635 interface Intf1
3636 endinterface
3637
3638 class Mix1 implements Intf1
3639 endclass
3640
3641 class Base3 extends Mix1
3642 endclass
3643
Ernie Rael2025af12023-12-12 16:58:00 +01003644 type AliasBase1 = Base1
3645 type AliasBase2 = Base2
3646 type AliasIntf1 = Intf1
3647 type AliasMix1 = Mix1
3648
LemonBoyafe04662023-08-23 21:08:11 +02003649 var b1 = Base1.new()
3650 var b2 = Base2.new()
3651 var b3 = Base3.new()
3652
3653 assert_true(instanceof(b1, Base1))
3654 assert_true(instanceof(b2, Base1))
3655 assert_false(instanceof(b1, Base2))
3656 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003657 assert_true(instanceof(b3, Base1, Base2, Intf1))
3658
3659 assert_true(instanceof(b1, AliasBase1))
3660 assert_true(instanceof(b2, AliasBase1))
3661 assert_false(instanceof(b1, AliasBase2))
3662 assert_true(instanceof(b3, AliasMix1))
3663 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003664
3665 def Foo()
3666 var a1 = Base1.new()
3667 var a2 = Base2.new()
3668 var a3 = Base3.new()
3669
3670 assert_true(instanceof(a1, Base1))
3671 assert_true(instanceof(a2, Base1))
3672 assert_false(instanceof(a1, Base2))
3673 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003674 assert_true(instanceof(a3, Base1, Base2, Intf1))
3675
3676 assert_true(instanceof(a1, AliasBase1))
3677 assert_true(instanceof(a2, AliasBase1))
3678 assert_false(instanceof(a1, AliasBase2))
3679 assert_true(instanceof(a3, AliasMix1))
3680 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003681 enddef
3682 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003683
3684 var o_null: Base1
3685 assert_false(instanceof(o_null, Base1))
3686
LemonBoyafe04662023-08-23 21:08:11 +02003687 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003688 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003689
3690 lines =<< trim END
3691 vim9script
3692
3693 class Base1
3694 endclass
3695 instanceof(Base1.new())
3696 END
3697 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3698
3699 lines =<< trim END
3700 vim9script
3701
3702 class Base1
3703 endclass
3704 def F()
3705 instanceof(Base1.new())
3706 enddef
3707 F()
3708 END
3709 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3710
3711 lines =<< trim END
3712 vim9script
3713
3714 class Base1
3715 endclass
3716
3717 class Base2
3718 endclass
3719
3720 var o = Base2.new()
3721 instanceof(o, Base1, Base2, 3)
3722 END
3723 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3724
3725 lines =<< trim END
3726 vim9script
3727
3728 class Base1
3729 endclass
3730
3731 class Base2
3732 endclass
3733
3734 def F()
3735 var o = Base2.new()
3736 instanceof(o, Base1, Base2, 3)
3737 enddef
3738 F()
3739 END
3740 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003741enddef
3742
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003743" Test for calling a method in the parent class that is extended partially.
3744" This used to fail with the 'E118: Too many arguments for function: Text' error
3745" message (Github issue #12524).
3746def Test_call_method_in_parent_class()
3747 var lines =<< trim END
3748 vim9script
3749
3750 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003751 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003752
3753 def SetY(lnum: number)
3754 this._lnum = lnum
3755 enddef
3756
3757 def Text(): string
3758 return ''
3759 enddef
3760 endclass
3761
3762 class Foo extends Widget
3763 def Text(): string
3764 return '<Foo>'
3765 enddef
3766 endclass
3767
3768 def Stack(w1: Widget, w2: Widget): list<Widget>
3769 w1.SetY(1)
3770 w2.SetY(2)
3771 return [w1, w2]
3772 enddef
3773
3774 var foo1 = Foo.new()
3775 var foo2 = Foo.new()
3776 var l = Stack(foo1, foo2)
3777 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003778 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003779enddef
3780
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003781" Test for calling methods from three levels of classes
3782def Test_multi_level_method_call()
3783 var lines =<< trim END
3784 vim9script
3785
3786 var A_func1: number = 0
3787 var A_func2: number = 0
3788 var A_func3: number = 0
3789 var B_func2: number = 0
3790 var B_func3: number = 0
3791 var C_func3: number = 0
3792
3793 class A
3794 def Func1()
3795 A_func1 += 1
3796 enddef
3797
3798 def Func2()
3799 A_func2 += 1
3800 enddef
3801
3802 def Func3()
3803 A_func3 += 1
3804 enddef
3805 endclass
3806
3807 class B extends A
3808 def Func2()
3809 B_func2 += 1
3810 enddef
3811
3812 def Func3()
3813 B_func3 += 1
3814 enddef
3815 endclass
3816
3817 class C extends B
3818 def Func3()
3819 C_func3 += 1
3820 enddef
3821 endclass
3822
3823 def A_CallFuncs(a: A)
3824 a.Func1()
3825 a.Func2()
3826 a.Func3()
3827 enddef
3828
3829 def B_CallFuncs(b: B)
3830 b.Func1()
3831 b.Func2()
3832 b.Func3()
3833 enddef
3834
3835 def C_CallFuncs(c: C)
3836 c.Func1()
3837 c.Func2()
3838 c.Func3()
3839 enddef
3840
3841 var cobj = C.new()
3842 A_CallFuncs(cobj)
3843 B_CallFuncs(cobj)
3844 C_CallFuncs(cobj)
3845 assert_equal(3, A_func1)
3846 assert_equal(0, A_func2)
3847 assert_equal(0, A_func3)
3848 assert_equal(3, B_func2)
3849 assert_equal(0, B_func3)
3850 assert_equal(3, C_func3)
3851 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003852 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003853enddef
3854
3855" Test for using members from three levels of classes
3856def Test_multi_level_member_access()
3857 var lines =<< trim END
3858 vim9script
3859
3860 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003861 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003862 endclass
3863
3864 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003865 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003866 endclass
3867
3868 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003869 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003870 endclass
3871
3872 def A_members(a: A)
3873 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003874 enddef
3875
3876 def B_members(b: B)
3877 b.val1 += 1
3878 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003879 enddef
3880
3881 def C_members(c: C)
3882 c.val1 += 1
3883 c.val2 += 1
3884 c.val3 += 1
3885 enddef
3886
3887 var cobj = C.new()
3888 A_members(cobj)
3889 B_members(cobj)
3890 C_members(cobj)
3891 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003892 assert_equal(2, cobj.val2)
3893 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003894 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003895 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003896enddef
3897
LemonBoy0ffc17a2023-08-20 18:09:11 +02003898" Test expansion of <stack> with class methods.
3899def Test_stack_expansion_with_methods()
3900 var lines =<< trim END
3901 vim9script
3902
3903 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003904 def M1()
3905 F0()
3906 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003907 endclass
3908
3909 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02003910 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02003911 enddef
3912
3913 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003914 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003915 enddef
3916
3917 F()
3918 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003919 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003920enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003921
3922" Test the return type of the new() constructor
3923def Test_new_return_type()
3924 # new() uses the default return type and there is no return statement
3925 var lines =<< trim END
3926 vim9script
3927
3928 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003929 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003930
3931 def new(this._bufnr)
3932 if !bufexists(this._bufnr)
3933 this._bufnr = -1
3934 endif
3935 enddef
3936 endclass
3937
3938 var c = C.new(12345)
3939 assert_equal('object<C>', typename(c))
3940
3941 var v1: C
3942 v1 = C.new(12345)
3943 assert_equal('object<C>', typename(v1))
3944
3945 def F()
3946 var v2: C
3947 v2 = C.new(12345)
3948 assert_equal('object<C>', typename(v2))
3949 enddef
3950 F()
3951 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003952 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003953
3954 # new() uses the default return type and an empty 'return' statement
3955 lines =<< trim END
3956 vim9script
3957
3958 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003959 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003960
3961 def new(this._bufnr)
3962 if !bufexists(this._bufnr)
3963 this._bufnr = -1
3964 return
3965 endif
3966 enddef
3967 endclass
3968
3969 var c = C.new(12345)
3970 assert_equal('object<C>', typename(c))
3971
3972 var v1: C
3973 v1 = C.new(12345)
3974 assert_equal('object<C>', typename(v1))
3975
3976 def F()
3977 var v2: C
3978 v2 = C.new(12345)
3979 assert_equal('object<C>', typename(v2))
3980 enddef
3981 F()
3982 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003983 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003984
3985 # new() uses "any" return type and returns "this"
3986 lines =<< trim END
3987 vim9script
3988
3989 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003990 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003991
3992 def new(this._bufnr): any
3993 if !bufexists(this._bufnr)
3994 this._bufnr = -1
3995 return this
3996 endif
3997 enddef
3998 endclass
3999 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004000 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004001
4002 # new() uses 'Dict' return type and returns a Dict
4003 lines =<< trim END
4004 vim9script
4005
4006 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004007 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004008
4009 def new(): dict<any>
4010 this._state = {}
4011 return this._state
4012 enddef
4013 endclass
4014
4015 var c = C.new()
4016 assert_equal('object<C>', typename(c))
4017 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004018 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004019enddef
4020
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004021" Test for checking a member initialization type at run time.
4022def Test_runtime_type_check_for_member_init()
4023 var lines =<< trim END
4024 vim9script
4025
4026 var retnum: bool = false
4027
4028 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004029 retnum = !retnum
4030 if retnum
4031 return 1
4032 else
4033 return "hello"
4034 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004035 enddef
4036
4037 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004038 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004039 endclass
4040
4041 var c1 = C.new()
4042 var c2 = C.new()
4043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004044 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004045enddef
4046
4047" Test for locking a variable referring to an object and reassigning to another
4048" object.
Ernie Raelee865f32023-09-29 19:53:55 +02004049def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004050 var lines =<< trim END
4051 vim9script
4052
4053 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004054 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004055 def new(this.val)
4056 enddef
4057 endclass
4058
4059 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
4060 lockvar 2 some_dict
4061
4062 var current: C
4063 current = some_dict['c']
4064 assert_equal(3, current.val)
4065 current = some_dict['b']
4066 assert_equal(2, current.val)
4067
4068 def F()
4069 current = some_dict['c']
4070 enddef
4071
4072 def G()
4073 current = some_dict['b']
4074 enddef
4075
4076 F()
4077 assert_equal(3, current.val)
4078 G()
4079 assert_equal(2, current.val)
4080 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004081 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004082enddef
4083
Ernie Raelee865f32023-09-29 19:53:55 +02004084" Test trying to lock an object variable from various places
4085def Test_lockvar_object_variable()
4086 # An object variable lockvar has several cases:
4087 # object method, scriptlevel, scriplevel from :def, :def arg
4088 # method arg, static method arg.
4089 # Also different depths
4090
Ernie Raelee865f32023-09-29 19:53:55 +02004091 #
4092 # lockvar of read-only object variable
4093 #
4094
4095 # read-only lockvar from object method
4096 var lines =<< trim END
4097 vim9script
4098
4099 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004100 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004101 def Lock()
4102 lockvar this.val1
4103 enddef
4104 endclass
4105 var o = C.new(3)
4106 o.Lock()
4107 END
Ernie Rael64885642023-10-04 20:16:22 +02004108 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004109
4110 # read-only lockvar from scriptlevel
4111 lines =<< trim END
4112 vim9script
4113
4114 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004115 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004116 endclass
4117 var o = C.new(3)
4118 lockvar o.val2
4119 END
4120 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4121
4122 # read-only lockvar of scriptlevel variable from def
4123 lines =<< trim END
4124 vim9script
4125
4126 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004127 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004128 endclass
4129 var o = C.new(3)
4130 def Lock()
4131 lockvar o.val3
4132 enddef
4133 Lock()
4134 END
4135 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4136
4137 # read-only lockvar of def argument variable
4138 lines =<< trim END
4139 vim9script
4140
4141 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004142 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004143 endclass
4144 def Lock(o: C)
4145 lockvar o.val4
4146 enddef
4147 Lock(C.new(3))
4148 END
4149 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4150
4151 # TODO: the following tests use type "any" for argument. Need a run time
4152 # check for access. Probably OK as is for now.
4153
4154 # read-only lockvar from object method arg
4155 lines =<< trim END
4156 vim9script
4157
4158 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004159 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004160 def Lock(o_any: any)
4161 lockvar o_any.val5
4162 enddef
4163 endclass
4164 var o = C.new(3)
4165 o.Lock(C.new(5))
4166 END
Ernie Rael64885642023-10-04 20:16:22 +02004167 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004168
4169 # read-only lockvar from class method arg
4170 lines =<< trim END
4171 vim9script
4172
4173 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004174 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004175 static def Lock(o_any: any)
4176 lockvar o_any.val6
4177 enddef
4178 endclass
4179 var o = C.new(3)
4180 C.Lock(o)
4181 END
Ernie Rael64885642023-10-04 20:16:22 +02004182 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004183
4184 #
4185 # lockvar of public object variable
4186 #
4187
4188 # lockvar from object method
4189 lines =<< trim END
4190 vim9script
4191
4192 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004193 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004194 def Lock()
4195 lockvar this.val1
4196 enddef
4197 endclass
4198 var o = C.new(3)
4199 o.Lock()
4200 END
4201 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4202
4203 # lockvar from scriptlevel
4204 lines =<< trim END
4205 vim9script
4206
4207 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004208 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004209 endclass
4210 var o = C.new(3)
4211 lockvar o.val2
4212 END
4213 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4214
4215 # lockvar of scriptlevel variable from def
4216 lines =<< trim END
4217 vim9script
4218
4219 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004220 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004221 endclass
4222 var o = C.new(3)
4223 def Lock()
4224 lockvar o.val3
4225 enddef
4226 Lock()
4227 END
4228 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4229
4230 # lockvar of def argument variable
4231 lines =<< trim END
4232 vim9script
4233
4234 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004235 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004236 endclass
4237 def Lock(o: C)
4238 lockvar o.val4
4239 enddef
4240 Lock(C.new(3))
4241 END
4242 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4243
4244 # lockvar from object method arg
4245 lines =<< trim END
4246 vim9script
4247
4248 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004249 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004250 def Lock(o_any: any)
4251 lockvar o_any.val5
4252 enddef
4253 endclass
4254 var o = C.new(3)
4255 o.Lock(C.new(5))
4256 END
4257 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4258
4259 # lockvar from class method arg
4260 lines =<< trim END
4261 vim9script
4262
4263 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004264 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004265 static def Lock(o_any: any)
4266 lockvar o_any.val6
4267 enddef
4268 endclass
4269 var o = C.new(3)
4270 C.Lock(o)
4271 END
4272 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4273enddef
4274
4275" Test trying to lock a class variable from various places
4276def Test_lockvar_class_variable()
4277
4278 # lockvar bare static from object method
4279 var lines =<< trim END
4280 vim9script
4281
4282 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004283 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004284 def Lock()
4285 lockvar sval1
4286 enddef
4287 endclass
4288 var o = C.new()
4289 o.Lock()
4290 END
4291 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4292
4293 # lockvar C.static from object method
4294 lines =<< trim END
4295 vim9script
4296
4297 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004298 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004299 def Lock()
4300 lockvar C.sval2
4301 enddef
4302 endclass
4303 var o = C.new()
4304 o.Lock()
4305 END
4306 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4307
4308 # lockvar bare static from class method
4309 lines =<< trim END
4310 vim9script
4311
4312 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004313 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004314 static def Lock()
4315 lockvar sval3
4316 enddef
4317 endclass
4318 C.Lock()
4319 END
4320 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4321
4322 # lockvar C.static from class method
4323 lines =<< trim END
4324 vim9script
4325
4326 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004327 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004328 static def Lock()
4329 lockvar C.sval4
4330 enddef
4331 endclass
4332 C.Lock()
4333 END
4334 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4335
4336 # lockvar C.static from script level
4337 lines =<< trim END
4338 vim9script
4339
4340 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004341 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004342 endclass
4343 lockvar C.sval5
4344 END
4345 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4346
4347 # lockvar o.static from script level
4348 lines =<< trim END
4349 vim9script
4350
4351 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004352 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004353 endclass
4354 var o = C.new()
4355 lockvar o.sval6
4356 END
4357 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4358enddef
4359
4360" Test locking an argument to :def
4361def Test_lockvar_argument()
4362 # Lockvar a function arg
4363 var lines =<< trim END
4364 vim9script
4365
4366 def Lock(val: any)
4367 lockvar val
4368 enddef
4369
4370 var d = {a: 1, b: 2}
4371 Lock(d)
4372
4373 d->extend({c: 3})
4374 END
4375 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4376
4377 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4378 # class member in "C". This tests lval_root_is_arg.
4379 lines =<< trim END
4380 vim9script
4381
4382 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004383 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004384 endclass
4385
4386 def Lock2(sval: any)
4387 lockvar sval
4388 enddef
4389
4390 var o = C.new()
4391 Lock2(o)
4392 END
4393 v9.CheckSourceSuccess(lines)
4394
4395 # Lock a class.
4396 lines =<< trim END
4397 vim9script
4398
4399 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004400 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004401 endclass
4402
4403 def Lock2(sval: any)
4404 lockvar sval
4405 enddef
4406
4407 Lock2(C)
4408 END
Ernie Raelb077b582023-12-14 20:11:44 +01004409 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004410
4411 # Lock an object.
4412 lines =<< trim END
4413 vim9script
4414
4415 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004416 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004417 endclass
4418
4419 def Lock2(sval: any)
4420 lockvar sval
4421 enddef
4422
4423 Lock2(C.new())
4424 END
4425 v9.CheckSourceSuccess(lines)
4426
4427 # In this case (unlike previous) "lockvar sval" is a class member.
4428 lines =<< trim END
4429 vim9script
4430
4431 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004432 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004433 def Lock2()
4434 lockvar sval
4435 enddef
4436 endclass
4437
4438
4439 var o = C.new()
4440 o.Lock2()
4441 END
4442 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4443enddef
4444
4445" Test that this can be locked without error
4446def Test_lockvar_this()
4447 # lockvar this
4448 var lines =<< trim END
4449 vim9script
4450 class C
4451 def TLock()
4452 lockvar this
4453 enddef
4454 endclass
4455 var o = C.new()
4456 o.TLock()
4457 END
4458 v9.CheckSourceSuccess(lines)
4459
4460 # lockvar four (four letter word, but not this)
4461 lines =<< trim END
4462 vim9script
4463 class C
4464 def TLock4()
4465 var four: number
4466 lockvar four
4467 enddef
4468 endclass
4469 var o = C.new()
4470 o.TLock4()
4471 END
4472 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4473
4474 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4475 lines =<< trim END
4476 vim9script
4477 class C
4478 def TLock5()
4479 var this5: number
4480 lockvar this5
4481 enddef
4482 endclass
4483 var o = C.new()
4484 o.TLock5()
4485 END
4486 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4487enddef
4488
4489" Test some general lockvar cases
4490def Test_lockvar_general()
4491 # lockvar an object and a class. It does nothing
4492 var lines =<< trim END
4493 vim9script
4494 class C
4495 endclass
4496 var o = C.new()
4497 lockvar o
4498 lockvar C
4499 END
4500 v9.CheckSourceSuccess(lines)
4501
4502 # Lock a list element that's nested in an object variable from a :def
4503 lines =<< trim END
4504 vim9script
4505
4506 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004507 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004508 endclass
4509 def Lock2(obj: any)
4510 lockvar obj.val[1]
4511 enddef
4512
4513 var o = C.new()
4514 Lock2(o)
4515 o.val[0] = [9]
4516 assert_equal([ [9], [2], [3] ], o.val)
4517 try
4518 o.val[1] = [999]
4519 call assert_false(true, 'assign should have failed')
4520 catch
4521 assert_exception('E741:')
4522 endtry
4523 o.val[2] = [8]
4524 assert_equal([ [9], [2], [8] ], o.val)
4525 END
4526 v9.CheckSourceSuccess(lines)
4527
4528 # Lock a list element that's nested in an object variable from scriptlevel
4529 lines =<< trim END
4530 vim9script
4531
4532 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004533 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004534 endclass
4535
4536 var o = C.new()
4537 lockvar o.val[1]
4538 o.val[0] = [9]
4539 assert_equal([ [9], [2], [3] ], o.val)
4540 try
4541 o.val[1] = [999]
4542 call assert_false(true, 'assign should have failed')
4543 catch
4544 assert_exception('E741:')
4545 endtry
4546 o.val[2] = [8]
4547 assert_equal([ [9], [2], [8] ], o.val)
4548 END
4549 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004550
4551 # lock a script level variable from an object method
4552 lines =<< trim END
4553 vim9script
4554
4555 class C
4556 def Lock()
4557 lockvar l
4558 enddef
4559 endclass
4560
4561 var l = [1]
4562 C.new().Lock()
4563 l[0] = 11
4564 END
4565 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4566
Ernie Rael03042a22023-11-11 08:53:32 +01004567 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004568 # in an object fetched via a script level list
4569 lines =<< trim END
4570 vim9script
4571
4572 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004573 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004574 def Lock()
4575 lockvar lc[0]._v1[1]
4576 enddef
4577 endclass
4578
4579 var l = [[1], [2], [3]]
4580 var o = C.new(l)
4581 var lc: list<C> = [ o ]
4582
4583 o.Lock()
4584 l[0] = [22]
4585 l[1] = [33]
4586 END
4587 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4588
4589 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004590 # in a class that does not own the protected variable.
4591 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004592 # the same name.
4593 lines =<< trim END
4594 vim9script
4595
4596 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004597 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004598 def Lock(obj: any)
4599 lockvar lc[0]._v1[1]
4600 enddef
4601 endclass
4602
4603 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004604 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004605 endclass
4606
4607 var l = [[1], [2], [3]]
4608 var o = C.new(l)
4609 var lc: list<C> = [ o ]
4610
4611 var o2 = C2.new()
4612 o2.Lock(o)
4613 END
Ernie Rael03042a22023-11-11 08:53:32 +01004614 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004615enddef
4616
Ernie Rael9771b2a2023-10-07 22:05:40 +02004617" Test builtin islocked()
4618def Test_lockvar_islocked()
4619 # Can't lock class/object variable
4620 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004621 # Lock item of variable's value (a list item)
4622 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004623 var lines =<< trim END
4624 vim9script
4625
4626 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004627 var o0: list<list<number>> = [ [0], [1], [2]]
4628 var o1: list<list<number>> = [[10], [11], [12]]
4629 static var c0: list<list<number>> = [[20], [21], [22]]
4630 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004631 endclass
4632
4633 def LockIt(arg: any)
4634 lockvar arg
4635 enddef
4636
4637 def UnlockIt(arg: any)
4638 unlockvar arg
4639 enddef
4640
4641 var obj = C.new()
4642 #lockvar obj.o1 # can't lock something you can't write to
4643
4644 try
4645 lockvar obj.o1 # can't lock something you can't write to
4646 call assert_false(1, '"lockvar obj.o1" should have failed')
4647 catch
4648 call assert_exception('E1335:')
4649 endtry
4650
4651 LockIt(obj.o1) # but can lock it's value
4652 assert_equal(1, islocked("obj.o1"))
4653 assert_equal(1, islocked("obj.o1[0]"))
4654 assert_equal(1, islocked("obj.o1[1]"))
4655 UnlockIt(obj.o1)
4656 assert_equal(0, islocked("obj.o1"))
4657 assert_equal(0, islocked("obj.o1[0]"))
4658
4659 lockvar obj.o1[0]
4660 assert_equal(0, islocked("obj.o1"))
4661 assert_equal(1, islocked("obj.o1[0]"))
4662 assert_equal(0, islocked("obj.o1[1]"))
4663 unlockvar obj.o1[0]
4664 assert_equal(0, islocked("obj.o1"))
4665 assert_equal(0, islocked("obj.o1[0]"))
4666
4667 # Same thing, but with a static
4668
4669 try
4670 lockvar C.c1 # can't lock something you can't write to
4671 call assert_false(1, '"lockvar C.c1" should have failed')
4672 catch
4673 call assert_exception('E1335:')
4674 endtry
4675
4676 LockIt(C.c1) # but can lock it's value
4677 assert_equal(1, islocked("C.c1"))
4678 assert_equal(1, islocked("C.c1[0]"))
4679 assert_equal(1, islocked("C.c1[1]"))
4680 UnlockIt(C.c1)
4681 assert_equal(0, islocked("C.c1"))
4682 assert_equal(0, islocked("C.c1[0]"))
4683
4684 lockvar C.c1[0]
4685 assert_equal(0, islocked("C.c1"))
4686 assert_equal(1, islocked("C.c1[0]"))
4687 assert_equal(0, islocked("C.c1[1]"))
4688 unlockvar C.c1[0]
4689 assert_equal(0, islocked("C.c1"))
4690 assert_equal(0, islocked("C.c1[0]"))
4691 END
4692 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004693
4694 # Do islocked() from an object method
4695 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004696 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004697 vim9script
4698
4699 var l0o0 = [ [0], [1], [2]]
4700 var l0o1 = [ [10], [11], [12]]
4701 var l0c0 = [[120], [121], [122]]
4702 var l0c1 = [[130], [131], [132]]
4703
4704 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004705 var o0: list<list<number>> = l0o0
4706 var o1: list<list<number>> = l0o1
4707 static var c0: list<list<number>> = l0c0
4708 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004709 def Islocked(arg: string): number
4710 return islocked(arg)
4711 enddef
4712 static def SIslocked(arg: string): number
4713 return islocked(arg)
4714 enddef
4715 endclass
4716
4717 var l2o0 = [[20000], [20001], [20002]]
4718 var l2o1 = [[20010], [20011], [20012]]
4719 var l2c0 = [[20120], [20121], [20122]]
4720 var l2c1 = [[20130], [20131], [20132]]
4721
4722 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004723 var o0: list<list<number>> = l2o0
4724 var o1: list<list<number>> = l2o1
4725 static var c0: list<list<number>> = l2c0
4726 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004727 def Islocked(arg: string): number
4728 return islocked(arg)
4729 enddef
4730 static def SIslocked(arg: string): number
4731 return islocked(arg)
4732 enddef
4733 endclass
4734
4735 var obj0 = C0.new()
4736 var obj2 = C2.new()
4737
4738 var l = [ obj0, null_object, obj2 ]
4739
4740 # lock list, object func access through script var expr
4741 assert_equal(0, obj0.Islocked("l[0].o0"))
4742 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4743 lockvar l0o0
4744 assert_equal(1, obj0.Islocked("l[0].o0"))
4745 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4746
4747 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4748
4749 # lock list element, object func access through script var expr
4750 lockvar l0o1[1]
4751 assert_equal(0, obj0.Islocked("this.o1[0]"))
4752 assert_equal(1, obj0.Islocked("this.o1[1]"))
4753
4754 assert_equal(0, obj0.Islocked("this.o1"))
4755 lockvar l0o1
4756 assert_equal(1, obj0.Islocked("this.o1"))
4757 unlockvar l0o1
4758
4759 lockvar l0c1[1]
4760
4761 # static by class name member expr from same class
4762 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4763 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4764 # static by bare name member expr from same class
4765 assert_equal(0, obj0.Islocked("c1[0]"))
4766 assert_equal(1, obj0.Islocked("c1[1]"))
4767
4768 # static by class name member expr from other class
4769 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4770 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4771 # static by bare name member expr from other class
4772 assert_equal(0, obj2.Islocked("c1[0]"))
4773 assert_equal(0, obj2.Islocked("c1[1]"))
4774
4775
4776 # static by bare name in same class
4777 assert_equal(0, obj0.Islocked("c0"))
4778 lockvar l0c0
4779 assert_equal(1, obj0.Islocked("c0"))
4780
4781 #
4782 # similar stuff, but use static method
4783 #
4784
4785 unlockvar l0o0
4786
4787 # lock list, object func access through script var expr
4788 assert_equal(0, C0.SIslocked("l[0].o0"))
4789 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4790 lockvar l0o0
4791 assert_equal(1, C0.SIslocked("l[0].o0"))
4792 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4793
4794 unlockvar l0o1
4795
4796 # can't access "this" from class method
4797 try
4798 C0.SIslocked("this.o1[0]")
4799 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4800 catch
4801 call assert_exception('E121: Undefined variable: this')
4802 endtry
4803
4804 lockvar l0c1[1]
4805
4806 # static by class name member expr from same class
4807 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4808 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4809 # static by bare name member expr from same class
4810 assert_equal(0, C0.SIslocked("c1[0]"))
4811 assert_equal(1, C0.SIslocked("c1[1]"))
4812
4813 # static by class name member expr from other class
4814 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4815 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4816 # static by bare name member expr from other class
4817 assert_equal(0, C2.SIslocked("c1[0]"))
4818 assert_equal(0, C2.SIslocked("c1[1]"))
4819
4820
4821 # static by bare name in same class
4822 unlockvar l0c0
4823 assert_equal(0, C0.SIslocked("c0"))
4824 lockvar l0c0
4825 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004826 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004827 v9.CheckSourceSuccess(lines)
4828
4829 # Check islocked class/object from various places.
4830 lines =<< trim END
4831 vim9script
4832
4833 class C
4834 def Islocked(arg: string): number
4835 return islocked(arg)
4836 enddef
4837 static def SIslocked(arg: string): number
4838 return islocked(arg)
4839 enddef
4840 endclass
4841 var obj = C.new()
4842
4843 # object method
4844 assert_equal(0, obj.Islocked("this"))
4845 assert_equal(0, obj.Islocked("C"))
4846
4847 # class method
4848 ### assert_equal(0, C.SIslocked("this"))
4849 assert_equal(0, C.SIslocked("C"))
4850
4851 #script level
4852 var v: number
4853 v = islocked("C")
4854 assert_equal(0, v)
4855 v = islocked("obj")
4856 assert_equal(0, v)
4857 END
4858 v9.CheckSourceSuccess(lines)
4859enddef
4860
4861def Test_lockvar_islocked_notfound()
4862 # Try non-existent things
4863 var lines =<< trim END
4864 vim9script
4865
4866 class C
4867 def Islocked(arg: string): number
4868 return islocked(arg)
4869 enddef
4870 static def SIslocked(arg: string): number
4871 return islocked(arg)
4872 enddef
4873 endclass
4874 var obj = C.new()
4875 assert_equal(-1, obj.Islocked("anywhere"))
4876 assert_equal(-1, C.SIslocked("notanywhere"))
4877 END
4878 v9.CheckSourceSuccess(lines)
4879
4880 # Something not found of the form "name1.name2" is an error
4881 lines =<< trim END
4882 vim9script
4883
4884 islocked("one.two")
4885 END
4886 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4887
4888 lines =<< trim END
4889 vim9script
4890
4891 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004892 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004893 def Islocked(arg: string): number
4894 return islocked(arg)
4895 enddef
4896 endclass
4897 var obj = C.new()
4898 obj.Islocked("this.val.not_there"))
4899 END
4900 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4901
4902 lines =<< trim END
4903 vim9script
4904
4905 class C
4906 def Islocked(arg: string): number
4907 return islocked(arg)
4908 enddef
4909 endclass
4910 var obj = C.new()
4911 obj.Islocked("this.notobjmember")
4912 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004913 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004914
4915 # access a script variable through methods
4916 lines =<< trim END
4917 vim9script
4918
4919 var l = [1]
4920 class C
4921 def Islocked(arg: string): number
4922 return islocked(arg)
4923 enddef
4924 static def SIslocked(arg: string): number
4925 return islocked(arg)
4926 enddef
4927 endclass
4928 var obj = C.new()
4929 assert_equal(0, obj.Islocked("l"))
4930 assert_equal(0, C.SIslocked("l"))
4931 lockvar l
4932 assert_equal(1, obj.Islocked("l"))
4933 assert_equal(1, C.SIslocked("l"))
4934 END
4935 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004936enddef
4937
Ernie Rael03042a22023-11-11 08:53:32 +01004938" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004939def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004940 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004941 var lines =<< trim END
4942 vim9script
4943
4944 class A
4945 def _Foo(): number
4946 return 1234
4947 enddef
4948 endclass
4949 var a = A.new()
4950 a._Foo()
4951 END
Ernie Rael03042a22023-11-11 08:53:32 +01004952 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004953
Ernie Rael03042a22023-11-11 08:53:32 +01004954 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004955 lines =<< trim END
4956 vim9script
4957
4958 class A
4959 def _Foo(): number
4960 return 1234
4961 enddef
4962 endclass
4963 def T()
4964 var a = A.new()
4965 a._Foo()
4966 enddef
4967 T()
4968 END
Ernie Rael03042a22023-11-11 08:53:32 +01004969 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004970
Ernie Rael03042a22023-11-11 08:53:32 +01004971 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004972 lines =<< trim END
4973 vim9script
4974
4975 class A
4976 def _Foo(): number
4977 return 1234
4978 enddef
4979 def Bar(): number
4980 return this._Foo()
4981 enddef
4982 endclass
4983 var a = A.new()
4984 assert_equal(1234, a.Bar())
4985 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004986 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004987
Ernie Rael03042a22023-11-11 08:53:32 +01004988 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004989 lines =<< trim END
4990 vim9script
4991
4992 class A
4993 def _Foo(): number
4994 return 1234
4995 enddef
4996 def Bar(): number
4997 return this._Foo()
4998 enddef
4999 endclass
5000 def T()
5001 var a = A.new()
5002 assert_equal(1234, a.Bar())
5003 enddef
5004 T()
5005 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005006 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005007
Ernie Rael03042a22023-11-11 08:53:32 +01005008 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005009 lines =<< trim END
5010 vim9script
5011
5012 class A
5013 def _Foo(): number
5014 return 1234
5015 enddef
5016 def Bar(): number
5017 return _Foo()
5018 enddef
5019 endclass
5020 var a = A.new()
5021 a.Bar()
5022 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005023 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005024
Ernie Rael03042a22023-11-11 08:53:32 +01005025 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005026 lines =<< trim END
5027 vim9script
5028
5029 class A
5030 def _Foo(): number
5031 return 1234
5032 enddef
5033 endclass
5034 A._Foo()
5035 END
Ernie Rael03042a22023-11-11 08:53:32 +01005036 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005037
Ernie Rael03042a22023-11-11 08:53:32 +01005038 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005039 lines =<< trim END
5040 vim9script
5041
5042 class A
5043 def _Foo()
5044 enddef
5045 def _Foo()
5046 enddef
5047 endclass
5048 var a = A.new()
5049 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005050 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005051
Ernie Rael03042a22023-11-11 08:53:32 +01005052 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005053 lines =<< trim END
5054 vim9script
5055
5056 class A
5057 def _Foo()
5058 enddef
5059 def Foo()
5060 enddef
5061 endclass
5062 var a = A.new()
5063 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005064 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005065
Ernie Rael03042a22023-11-11 08:53:32 +01005066 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005067 lines =<< trim END
5068 vim9script
5069
5070 class A
5071 def Foo()
5072 enddef
5073 def _Foo()
5074 enddef
5075 endclass
5076 var a = A.new()
5077 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005078 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005079
Ernie Rael03042a22023-11-11 08:53:32 +01005080 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005081 lines =<< trim END
5082 vim9script
5083
5084 class A
5085 def Foo(): number
5086 return 100
5087 enddef
5088 def _Bar(): number
5089 return 200
5090 enddef
5091 def _Baz()
5092 assert_equal(100, this.Foo())
5093 assert_equal(200, this._Bar())
5094 enddef
5095 def T()
5096 this._Baz()
5097 enddef
5098 endclass
5099 var a = A.new()
5100 a.T()
5101 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005102 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005103
Ernie Rael03042a22023-11-11 08:53:32 +01005104 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005105 lines =<< trim END
5106 vim9script
5107
5108 class A
5109 def _Foo(): number
5110 return 100
5111 enddef
5112 endclass
5113 class B
5114 def Foo(): number
5115 var a = A.new()
5116 a._Foo()
5117 enddef
5118 endclass
5119 var b = B.new()
5120 b.Foo()
5121 END
Ernie Rael03042a22023-11-11 08:53:32 +01005122 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005123
Ernie Rael03042a22023-11-11 08:53:32 +01005124 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005125 lines =<< trim END
5126 vim9script
5127 class A
5128 def _Foo(): number
5129 return 1234
5130 enddef
5131 endclass
5132 class B extends A
5133 def Bar()
5134 enddef
5135 endclass
5136 class C extends B
5137 def Baz(): number
5138 return this._Foo()
5139 enddef
5140 endclass
5141 var c = C.new()
5142 assert_equal(1234, c.Baz())
5143 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005144 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005145
Ernie Rael03042a22023-11-11 08:53:32 +01005146 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005147 lines =<< trim END
5148 vim9script
5149 class A
5150 def _Foo(): number
5151 return 1234
5152 enddef
5153 endclass
5154 class B extends A
5155 def Bar()
5156 enddef
5157 endclass
5158 class C extends B
5159 def Baz(): number
5160 enddef
5161 endclass
5162 var c = C.new()
5163 assert_equal(1234, c._Foo())
5164 END
Ernie Rael03042a22023-11-11 08:53:32 +01005165 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005166
5167 # Using "_" prefix in a method name should fail outside of a class
5168 lines =<< trim END
5169 vim9script
5170 def _Foo(): number
5171 return 1234
5172 enddef
5173 var a = _Foo()
5174 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005175 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005176enddef
5177
Ernie Rael03042a22023-11-11 08:53:32 +01005178" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005179def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005180 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005181 var lines =<< trim END
5182 vim9script
5183
5184 class A
5185 static def _Foo(): number
5186 return 1234
5187 enddef
5188 endclass
5189 A._Foo()
5190 END
Ernie Rael03042a22023-11-11 08:53:32 +01005191 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005192
Ernie Rael03042a22023-11-11 08:53:32 +01005193 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005194 lines =<< trim END
5195 vim9script
5196
5197 class A
5198 static def _Foo(): number
5199 return 1234
5200 enddef
5201 endclass
5202 def T()
5203 A._Foo()
5204 enddef
5205 T()
5206 END
Ernie Rael03042a22023-11-11 08:53:32 +01005207 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005208
Ernie Rael03042a22023-11-11 08:53:32 +01005209 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005210 lines =<< trim END
5211 vim9script
5212
5213 class A
5214 static def _Foo(): number
5215 return 1234
5216 enddef
5217 endclass
5218 var a = A.new()
5219 a._Foo()
5220 END
Ernie Rael03042a22023-11-11 08:53:32 +01005221 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005222
Ernie Rael03042a22023-11-11 08:53:32 +01005223 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005224 lines =<< trim END
5225 vim9script
5226
5227 class A
5228 static def _Foo(): number
5229 return 1234
5230 enddef
5231 endclass
5232 def T()
5233 var a = A.new()
5234 a._Foo()
5235 enddef
5236 T()
5237 END
Ernie Rael03042a22023-11-11 08:53:32 +01005238 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005239
Ernie Rael03042a22023-11-11 08:53:32 +01005240 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005241 lines =<< trim END
5242 vim9script
5243
5244 class A
5245 static def _Foo(): number
5246 return 1234
5247 enddef
5248 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005249 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005250 enddef
5251 endclass
5252 var a = A.new()
5253 a.Bar()
5254 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005255 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005256
Ernie Rael03042a22023-11-11 08:53:32 +01005257 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005258 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005259 lines =<< trim END
5260 vim9script
5261
5262 class A
5263 static def _Foo1(): number
5264 return 1234
5265 enddef
5266 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005267 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005268 enddef
5269 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005270 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005271 enddef
5272 endclass
5273 var a = A.new()
5274 a.Bar()
5275 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005276 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005277
Ernie Rael03042a22023-11-11 08:53:32 +01005278 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005279 lines =<< trim END
5280 vim9script
5281
5282 class A
5283 static def _Foo()
5284 enddef
5285 static def Foo()
5286 enddef
5287 endclass
5288 var a = A.new()
5289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005290 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005291
Ernie Rael03042a22023-11-11 08:53:32 +01005292 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005293 lines =<< trim END
5294 vim9script
5295
5296 class A
5297 static def _Foo(): number
5298 return 1234
5299 enddef
5300 endclass
5301 class B
5302 def Foo(): number
5303 return A._Foo()
5304 enddef
5305 endclass
5306 var b = B.new()
5307 assert_equal(1234, b.Foo())
5308 END
Ernie Rael03042a22023-11-11 08:53:32 +01005309 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005310
Ernie Rael03042a22023-11-11 08:53:32 +01005311 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005312 lines =<< trim END
5313 vim9script
5314 class A
5315 static def _Foo(): number
5316 return 1234
5317 enddef
5318 endclass
5319 class B extends A
5320 def Bar()
5321 enddef
5322 endclass
5323 class C extends B
5324 def Baz(): number
5325 return A._Foo()
5326 enddef
5327 endclass
5328 var c = C.new()
5329 assert_equal(1234, c.Baz())
5330 END
Ernie Rael03042a22023-11-11 08:53:32 +01005331 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005332
Ernie Rael03042a22023-11-11 08:53:32 +01005333 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005334 lines =<< trim END
5335 vim9script
5336 class A
5337 static def _Foo(): number
5338 return 1234
5339 enddef
5340 endclass
5341 class B extends A
5342 def Bar()
5343 enddef
5344 endclass
5345 class C extends B
5346 static def Baz(): number
5347 return A._Foo()
5348 enddef
5349 endclass
5350 assert_equal(1234, C.Baz())
5351 END
Ernie Rael03042a22023-11-11 08:53:32 +01005352 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005353
Ernie Rael03042a22023-11-11 08:53:32 +01005354 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005355 lines =<< trim END
5356 vim9script
5357 class A
5358 static def _Foo(): number
5359 return 1234
5360 enddef
5361 endclass
5362 class B extends A
5363 def Bar()
5364 enddef
5365 endclass
5366 class C extends B
5367 def Baz(): number
5368 enddef
5369 endclass
5370 var c = C.new()
5371 assert_equal(1234, C._Foo())
5372 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005373 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005374enddef
5375
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005376" Test for using the return value of a class/object method as a function
5377" argument.
5378def Test_objmethod_funcarg()
5379 var lines =<< trim END
5380 vim9script
5381
5382 class C
5383 def Foo(): string
5384 return 'foo'
5385 enddef
5386 endclass
5387
5388 def Bar(a: number, s: string): string
5389 return s
5390 enddef
5391
5392 def Baz(c: C)
5393 assert_equal('foo', Bar(10, c.Foo()))
5394 enddef
5395
5396 var t = C.new()
5397 Baz(t)
5398 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005399 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005400
5401 lines =<< trim END
5402 vim9script
5403
5404 class C
5405 static def Foo(): string
5406 return 'foo'
5407 enddef
5408 endclass
5409
5410 def Bar(a: number, s: string): string
5411 return s
5412 enddef
5413
5414 def Baz()
5415 assert_equal('foo', Bar(10, C.Foo()))
5416 enddef
5417
5418 Baz()
5419 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005420 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005421enddef
5422
Ernie Raelcf138d42023-09-06 20:45:03 +02005423def Test_static_inheritence()
5424 # subclasses get their own static copy
5425 var lines =<< trim END
5426 vim9script
5427
5428 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005429 static var _svar: number
5430 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005431 def new()
5432 _svar = 1
5433 this._mvar = 101
5434 enddef
5435 def AccessObject(): number
5436 return this._mvar
5437 enddef
5438 def AccessStaticThroughObject(): number
5439 return _svar
5440 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005441 endclass
5442
5443 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005444 def new()
5445 this._mvar = 102
5446 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005447 endclass
5448
5449 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005450 def new()
5451 this._mvar = 103
5452 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005453
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005454 def AccessPrivateStaticThroughClassName(): number
5455 assert_equal(1, A._svar)
5456 return 444
5457 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005458 endclass
5459
5460 var oa = A.new()
5461 var ob = B.new()
5462 var oc = C.new()
5463 assert_equal(101, oa.AccessObject())
5464 assert_equal(102, ob.AccessObject())
5465 assert_equal(103, oc.AccessObject())
5466
Ernie Rael03042a22023-11-11 08:53:32 +01005467 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005468
5469 # verify object properly resolves to correct static
5470 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005471 assert_equal(1, ob.AccessStaticThroughObject())
5472 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005473 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005474 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005475enddef
5476
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005477" Test for declaring duplicate object and class members
5478def Test_dup_member_variable()
5479 # Duplicate member variable
5480 var lines =<< trim END
5481 vim9script
5482 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005483 var val = 10
5484 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005485 endclass
5486 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005487 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005488
Ernie Rael03042a22023-11-11 08:53:32 +01005489 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005490 lines =<< trim END
5491 vim9script
5492 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005493 var _val = 10
5494 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005495 endclass
5496 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005497 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005498
5499 # Duplicate public member variable
5500 lines =<< trim END
5501 vim9script
5502 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005503 public var val = 10
5504 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005505 endclass
5506 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005507 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005508
Ernie Rael03042a22023-11-11 08:53:32 +01005509 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005510 lines =<< trim END
5511 vim9script
5512 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005513 var val = 10
5514 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005515 endclass
5516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005517 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005518
Ernie Rael03042a22023-11-11 08:53:32 +01005519 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005520 lines =<< trim END
5521 vim9script
5522 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005523 var _val = 20
5524 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005525 endclass
5526 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005527 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005528
5529 # Duplicate class member variable
5530 lines =<< trim END
5531 vim9script
5532 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005533 static var s: string = "abc"
5534 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005535 endclass
5536 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005537 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005538
Ernie Rael03042a22023-11-11 08:53:32 +01005539 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005540 lines =<< trim END
5541 vim9script
5542 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005543 public static var s: string = "abc"
5544 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005545 endclass
5546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005547 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005548
5549 # Duplicate class and object member variable
5550 lines =<< trim END
5551 vim9script
5552 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005553 static var val = 10
5554 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005555 def new()
5556 enddef
5557 endclass
5558 var c = C.new()
5559 assert_equal(10, C.val)
5560 assert_equal(20, c.val)
5561 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005562 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005563
5564 # Duplicate object member variable in a derived class
5565 lines =<< trim END
5566 vim9script
5567 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005568 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005569 endclass
5570 class B extends A
5571 endclass
5572 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005573 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005574 endclass
5575 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005576 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005577
Ernie Rael03042a22023-11-11 08:53:32 +01005578 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005579 lines =<< trim END
5580 vim9script
5581 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005582 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005583 endclass
5584 class B extends A
5585 endclass
5586 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005587 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005588 endclass
5589 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005590 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005591
Ernie Rael03042a22023-11-11 08:53:32 +01005592 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005593 lines =<< trim END
5594 vim9script
5595 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005596 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005597 endclass
5598 class B extends A
5599 endclass
5600 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005601 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005602 endclass
5603 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005604 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005605
5606 # Duplicate object member variable in a derived class
5607 lines =<< trim END
5608 vim9script
5609 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005610 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005611 endclass
5612 class B extends A
5613 endclass
5614 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005615 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005616 endclass
5617 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005618 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005619
5620 # Two member variables with a common prefix
5621 lines =<< trim END
5622 vim9script
5623 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005624 public static var svar2: number
5625 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005626 endclass
5627 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005628 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005629enddef
5630
Ernie Rael03042a22023-11-11 08:53:32 +01005631" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005632def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005633 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005634 var lines =<< trim END
5635 vim9script
5636 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005637 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005638 def GetVal(): number
5639 return this._val
5640 enddef
5641 endclass
5642 def T()
5643 var a = A.new()
5644 a._val = 20
5645 enddef
5646 T()
5647 END
Ernie Rael03042a22023-11-11 08:53:32 +01005648 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005649
Ernie Rael03042a22023-11-11 08:53:32 +01005650 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005651 lines =<< trim END
5652 vim9script
5653 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005654 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005655 endclass
5656 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005657 var a = A.new()
5658 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005659 enddef
5660 T()
5661 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005662 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005663
Ernie Rael03042a22023-11-11 08:53:32 +01005664 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005665 lines =<< trim END
5666 vim9script
5667 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005668 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005669 endclass
5670 def T()
5671 var a = A.new()
5672 var x = a._val
5673 enddef
5674 T()
5675 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005676 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005677
Ernie Rael03042a22023-11-11 08:53:32 +01005678 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005679 lines =<< trim END
5680 vim9script
5681 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005682 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005683 endclass
5684 def T()
5685 var a = A.new()
5686 a._val = 3
5687 enddef
5688 T()
5689 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005690 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005691
Ernie Rael03042a22023-11-11 08:53:32 +01005692 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005693 lines =<< trim END
5694 vim9script
5695 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005696 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005697 endclass
5698 def T()
5699 var x = A._val
5700 enddef
5701 T()
5702 END
Ernie Rael03042a22023-11-11 08:53:32 +01005703 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005704
Ernie Rael03042a22023-11-11 08:53:32 +01005705 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005706 lines =<< trim END
5707 vim9script
5708 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005709 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005710 endclass
5711 def T()
5712 A._val = 3
5713 enddef
5714 T()
5715 END
Ernie Rael03042a22023-11-11 08:53:32 +01005716 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005717enddef
5718
5719" Test for changing the member access of an interface in a implementation class
5720def Test_change_interface_member_access()
5721 var lines =<< trim END
5722 vim9script
5723 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005724 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005725 endinterface
5726 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005727 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005728 endclass
5729 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005730 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005731
5732 lines =<< trim END
5733 vim9script
5734 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005735 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005736 endinterface
5737 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005738 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005739 endclass
5740 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005741 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005742enddef
5743
5744" Test for trying to change a readonly member from a def function
5745def Test_readonly_member_change_in_def_func()
5746 var lines =<< trim END
5747 vim9script
5748 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005749 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005750 endclass
5751 def T()
5752 var a = A.new()
5753 a.val = 20
5754 enddef
5755 T()
5756 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005757 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005758enddef
5759
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005760" Test for reading and writing a class member from a def function
5761def Test_modify_class_member_from_def_function()
5762 var lines =<< trim END
5763 vim9script
5764 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005765 var var1: number = 10
5766 public static var var2: list<number> = [1, 2]
5767 public static var var3: dict<number> = {a: 1, b: 2}
5768 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005769 endclass
5770 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005771 assert_equal([1, 2], A.var2)
5772 assert_equal({a: 1, b: 2}, A.var3)
5773 A.var2 = [3, 4]
5774 A.var3 = {c: 3, d: 4}
5775 assert_equal([3, 4], A.var2)
5776 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005777 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005778 enddef
5779 T()
5780 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005781 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005782enddef
5783
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005784" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005785def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005786 var lines =<< trim END
5787 vim9script
5788 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005789 public static var svar1: list<number> = [1]
5790 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005791 endclass
5792
5793 A.svar1->add(3)
5794 A.svar2->add(4)
5795 assert_equal([1, 3], A.svar1)
5796 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005797
5798 def Foo()
5799 A.svar1->add(7)
5800 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005801 assert_equal([1, 3, 7], A.svar1)
5802 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005803 enddef
5804 Foo()
5805 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005806 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005807
5808 # Cannot read from a class variable using an object in script context
5809 lines =<< trim END
5810 vim9script
5811 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005812 public var var1: number
5813 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005814 endclass
5815
5816 var a = A.new()
5817 echo a.svar2
5818 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005819 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005820
5821 # Cannot write to a class variable using an object in script context
5822 lines =<< trim END
5823 vim9script
5824 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005825 public var var1: number
5826 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005827 endclass
5828
5829 var a = A.new()
5830 a.svar2 = [2]
5831 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005832 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005833
5834 # Cannot read from a class variable using an object in def method context
5835 lines =<< trim END
5836 vim9script
5837 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005838 public var var1: number
5839 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005840 endclass
5841
5842 def T()
5843 var a = A.new()
5844 echo a.svar2
5845 enddef
5846 T()
5847 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005848 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005849
5850 # Cannot write to a class variable using an object in def method context
5851 lines =<< trim END
5852 vim9script
5853 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005854 public var var1: number
5855 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005856 endclass
5857
5858 def T()
5859 var a = A.new()
5860 a.svar2 = [2]
5861 enddef
5862 T()
5863 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005864 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005865enddef
5866
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005867" Test for using a interface method using a child object
5868def Test_interface_method_from_child()
5869 var lines =<< trim END
5870 vim9script
5871
5872 interface A
5873 def Foo(): string
5874 endinterface
5875
5876 class B implements A
5877 def Foo(): string
5878 return 'foo'
5879 enddef
5880 endclass
5881
5882 class C extends B
5883 def Bar(): string
5884 return 'bar'
5885 enddef
5886 endclass
5887
5888 def T1(a: A)
5889 assert_equal('foo', a.Foo())
5890 enddef
5891
5892 def T2(b: B)
5893 assert_equal('foo', b.Foo())
5894 enddef
5895
5896 var c = C.new()
5897 T1(c)
5898 T2(c)
5899 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005900 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005901enddef
5902
5903" Test for using an interface method using a child object when it is overridden
5904" by the child class.
5905" FIXME: This test fails.
5906" def Test_interface_overridden_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 'b-foo'
5917" enddef
5918" endclass
5919"
5920" class C extends B
5921" def Bar(): string
5922" return 'bar'
5923" enddef
5924" def Foo(): string
5925" return 'c-foo'
5926" enddef
5927" endclass
5928"
5929" def T1(a: A)
5930" assert_equal('c-foo', a.Foo())
5931" enddef
5932"
5933" def T2(b: B)
5934" assert_equal('c-foo', b.Foo())
5935" enddef
5936"
5937" var c = C.new()
5938" T1(c)
5939" T2(c)
5940" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005941" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005942" enddef
5943
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005944" Test for abstract methods
5945def Test_abstract_method()
5946 # Use two abstract methods
5947 var lines =<< trim END
5948 vim9script
5949 abstract class A
5950 def M1(): number
5951 return 10
5952 enddef
5953 abstract def M2(): number
5954 abstract def M3(): number
5955 endclass
5956 class B extends A
5957 def M2(): number
5958 return 20
5959 enddef
5960 def M3(): number
5961 return 30
5962 enddef
5963 endclass
5964 var b = B.new()
5965 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5966 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005967 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005968
5969 # Don't define an abstract method
5970 lines =<< trim END
5971 vim9script
5972 abstract class A
5973 abstract def Foo()
5974 endclass
5975 class B extends A
5976 endclass
5977 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005978 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005979
5980 # Use abstract method in a concrete class
5981 lines =<< trim END
5982 vim9script
5983 class A
5984 abstract def Foo()
5985 endclass
5986 class B extends A
5987 endclass
5988 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005989 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005990
5991 # Use abstract method in an interface
5992 lines =<< trim END
5993 vim9script
5994 interface A
5995 abstract def Foo()
5996 endinterface
5997 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005998 def Foo()
5999 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006000 endclass
6001 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01006002 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6003
6004 # Use abstract static method in an interface
6005 lines =<< trim END
6006 vim9script
6007 interface A
6008 abstract static def Foo()
6009 enddef
6010 endinterface
6011 END
6012 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6013
6014 # Use abstract static variable in an interface
6015 lines =<< trim END
6016 vim9script
6017 interface A
6018 abstract static foo: number = 10
6019 endinterface
6020 END
6021 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006022
6023 # Abbreviate the "abstract" keyword
6024 lines =<< trim END
6025 vim9script
6026 class A
6027 abs def Foo()
6028 endclass
6029 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006030 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006031
6032 # Use "abstract" with a member variable
6033 lines =<< trim END
6034 vim9script
6035 abstract class A
6036 abstract this.val = 10
6037 endclass
6038 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006039 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006040
6041 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01006042 lines =<< trim END
6043 vim9script
6044 abstract class A
6045 abstract static def Foo(): number
6046 endclass
6047 END
6048 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006049
6050 # Type mismatch between abstract method and concrete method
6051 lines =<< trim END
6052 vim9script
6053 abstract class A
6054 abstract def Foo(a: string, b: number): list<number>
6055 endclass
6056 class B extends A
6057 def Foo(a: number, b: string): list<string>
6058 return []
6059 enddef
6060 endclass
6061 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006062 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 +02006063
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006064 # Invoke an abstract method from a def function
6065 lines =<< trim END
6066 vim9script
6067 abstract class A
6068 abstract def Foo(): list<number>
6069 endclass
6070 class B extends A
6071 def Foo(): list<number>
6072 return [3, 5]
6073 enddef
6074 endclass
6075 def Bar(c: B)
6076 assert_equal([3, 5], c.Foo())
6077 enddef
6078 var b = B.new()
6079 Bar(b)
6080 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006081 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006082
6083 # Use a static method in an abstract class
6084 lines =<< trim END
6085 vim9script
6086 abstract class A
6087 static def Foo(): string
6088 return 'foo'
6089 enddef
6090 endclass
6091 assert_equal('foo', A.Foo())
6092 END
6093 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006094enddef
6095
6096" Test for calling a class method from a subclass
6097def Test_class_method_call_from_subclass()
6098 # class method call from a subclass
6099 var lines =<< trim END
6100 vim9script
6101
6102 class A
6103 static def Foo()
6104 echo "foo"
6105 enddef
6106 endclass
6107
6108 class B extends A
6109 def Bar()
6110 Foo()
6111 enddef
6112 endclass
6113
6114 var b = B.new()
6115 b.Bar()
6116 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006117 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006118enddef
6119
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006120" Test for calling a class method using an object in a def function context and
6121" script context.
6122def Test_class_method_call_using_object()
6123 # script context
6124 var lines =<< trim END
6125 vim9script
6126 class A
6127 static def Foo(): list<string>
6128 return ['a', 'b']
6129 enddef
6130 def Bar()
6131 assert_equal(['a', 'b'], A.Foo())
6132 assert_equal(['a', 'b'], Foo())
6133 enddef
6134 endclass
6135
6136 def T()
6137 assert_equal(['a', 'b'], A.Foo())
6138 var t_a = A.new()
6139 t_a.Bar()
6140 enddef
6141
6142 assert_equal(['a', 'b'], A.Foo())
6143 var a = A.new()
6144 a.Bar()
6145 T()
6146 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006147 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006148
6149 # script context
6150 lines =<< trim END
6151 vim9script
6152 class A
6153 static def Foo(): string
6154 return 'foo'
6155 enddef
6156 endclass
6157
6158 var a = A.new()
6159 assert_equal('foo', a.Foo())
6160 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006161 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006162
6163 # def function context
6164 lines =<< trim END
6165 vim9script
6166 class A
6167 static def Foo(): string
6168 return 'foo'
6169 enddef
6170 endclass
6171
6172 def T()
6173 var a = A.new()
6174 assert_equal('foo', a.Foo())
6175 enddef
6176 T()
6177 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006178 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006179enddef
6180
6181def Test_class_variable()
6182 var lines =<< trim END
6183 vim9script
6184
6185 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006186 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006187 static def ClassFunc()
6188 assert_equal(10, val)
6189 enddef
6190 def ObjFunc()
6191 assert_equal(10, val)
6192 enddef
6193 endclass
6194
6195 class B extends A
6196 endclass
6197
6198 assert_equal(10, A.val)
6199 A.ClassFunc()
6200 var a = A.new()
6201 a.ObjFunc()
6202 var b = B.new()
6203 b.ObjFunc()
6204
6205 def T1(a1: A)
6206 a1.ObjFunc()
6207 A.ClassFunc()
6208 enddef
6209 T1(b)
6210
6211 A.val = 20
6212 assert_equal(20, A.val)
6213 END
6214 v9.CheckSourceSuccess(lines)
6215
6216 # Modifying a parent class variable from a child class method
6217 lines =<< trim END
6218 vim9script
6219
6220 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006221 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006222 endclass
6223
6224 class B extends A
6225 static def ClassFunc()
6226 val = 20
6227 enddef
6228 endclass
6229 B.ClassFunc()
6230 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006231 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006232
6233 # Reading a parent class variable from a child class method
6234 lines =<< trim END
6235 vim9script
6236
6237 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006238 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006239 endclass
6240
6241 class B extends A
6242 static def ClassFunc()
6243 var i = val
6244 enddef
6245 endclass
6246 B.ClassFunc()
6247 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006248 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006249
6250 # Modifying a parent class variable from a child object method
6251 lines =<< trim END
6252 vim9script
6253
6254 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006255 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006256 endclass
6257
6258 class B extends A
6259 def ObjFunc()
6260 val = 20
6261 enddef
6262 endclass
6263 var b = B.new()
6264 b.ObjFunc()
6265 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006266 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006267
6268 # Reading a parent class variable from a child object method
6269 lines =<< trim END
6270 vim9script
6271
6272 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006273 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006274 endclass
6275
6276 class B extends A
6277 def ObjFunc()
6278 var i = val
6279 enddef
6280 endclass
6281 var b = B.new()
6282 b.ObjFunc()
6283 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006284 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006285
6286 # Modifying a class variable using an object at script level
6287 lines =<< trim END
6288 vim9script
6289
6290 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006291 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006292 endclass
6293 var a = A.new()
6294 a.val = 20
6295 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006296 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006297
6298 # Reading a class variable using an object at script level
6299 lines =<< trim END
6300 vim9script
6301
6302 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006303 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006304 endclass
6305 var a = A.new()
6306 var i = a.val
6307 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006308 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006309
6310 # Modifying a class variable using an object at function level
6311 lines =<< trim END
6312 vim9script
6313
6314 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006315 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006316 endclass
6317
6318 def T()
6319 var a = A.new()
6320 a.val = 20
6321 enddef
6322 T()
6323 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006324 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006325
6326 # Reading a class variable using an object at function level
6327 lines =<< trim END
6328 vim9script
6329
6330 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006331 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006332 endclass
6333 def T()
6334 var a = A.new()
6335 var i = a.val
6336 enddef
6337 T()
6338 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006339 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006340
6341 # Use old implicit var declaration syntax (without initialization)
6342 lines =<< trim END
6343 vim9script
6344
6345 class A
6346 static val: number
6347 endclass
6348 END
6349 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6350
6351 # Use old implicit var declaration syntax (with initialization)
6352 lines =<< trim END
6353 vim9script
6354
6355 class A
6356 static val: number = 10
6357 endclass
6358 END
6359 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6360
6361 # Use old implicit var declaration syntax (type inferred)
6362 lines =<< trim END
6363 vim9script
6364
6365 class A
6366 static val = 10
6367 endclass
6368 END
6369 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6370
6371 # Missing ":var" in "var" class variable declaration (without initialization)
6372 lines =<< trim END
6373 vim9script
6374
6375 class A
6376 static var: number
6377 endclass
6378 END
6379 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6380
6381 # Missing ":var" in "var" class variable declaration (with initialization)
6382 lines =<< trim END
6383 vim9script
6384
6385 class A
6386 static var: number = 10
6387 endclass
6388 END
6389 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6390
6391 # Missing ":var" in "var" class variable declaration (type inferred)
6392 lines =<< trim END
6393 vim9script
6394
6395 class A
6396 static var = 10
6397 endclass
6398 END
6399 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6400
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006401enddef
6402
6403" Test for using a duplicate class method and class variable in a child class
6404def Test_dup_class_member()
6405 # duplicate class variable, class method and overridden object method
6406 var lines =<< trim END
6407 vim9script
6408 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006409 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006410 static def Check()
6411 assert_equal(100, sval)
6412 enddef
6413 def GetVal(): number
6414 return sval
6415 enddef
6416 endclass
6417
6418 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006419 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006420 static def Check()
6421 assert_equal(200, sval)
6422 enddef
6423 def GetVal(): number
6424 return sval
6425 enddef
6426 endclass
6427
6428 def T1(aa: A): number
6429 return aa.GetVal()
6430 enddef
6431
6432 def T2(bb: B): number
6433 return bb.GetVal()
6434 enddef
6435
6436 assert_equal(100, A.sval)
6437 assert_equal(200, B.sval)
6438 var a = A.new()
6439 assert_equal(100, a.GetVal())
6440 var b = B.new()
6441 assert_equal(200, b.GetVal())
6442 assert_equal(200, T1(b))
6443 assert_equal(200, T2(b))
6444 END
6445 v9.CheckSourceSuccess(lines)
6446
6447 # duplicate class variable and class method
6448 lines =<< trim END
6449 vim9script
6450 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006451 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006452 static def Check()
6453 assert_equal(100, sval)
6454 enddef
6455 def GetVal(): number
6456 return sval
6457 enddef
6458 endclass
6459
6460 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006461 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006462 static def Check()
6463 assert_equal(200, sval)
6464 enddef
6465 endclass
6466
6467 def T1(aa: A): number
6468 return aa.GetVal()
6469 enddef
6470
6471 def T2(bb: B): number
6472 return bb.GetVal()
6473 enddef
6474
6475 assert_equal(100, A.sval)
6476 assert_equal(200, B.sval)
6477 var a = A.new()
6478 assert_equal(100, a.GetVal())
6479 var b = B.new()
6480 assert_equal(100, b.GetVal())
6481 assert_equal(100, T1(b))
6482 assert_equal(100, T2(b))
6483 END
6484 v9.CheckSourceSuccess(lines)
6485enddef
6486
6487" Test for calling an instance method using the class
6488def Test_instance_method_call_using_class()
6489 # Invoke an object method using a class in script context
6490 var lines =<< trim END
6491 vim9script
6492 class A
6493 def Foo()
6494 echo "foo"
6495 enddef
6496 endclass
6497 A.Foo()
6498 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006499 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006500
6501 # Invoke an object method using a class in def function context
6502 lines =<< trim END
6503 vim9script
6504 class A
6505 def Foo()
6506 echo "foo"
6507 enddef
6508 endclass
6509 def T()
6510 A.Foo()
6511 enddef
6512 T()
6513 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006514 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006515enddef
6516
6517" Test for duplicate class method and instance method
6518def Test_dup_classmethod_objmethod()
6519 # Duplicate instance method
6520 var lines =<< trim END
6521 vim9script
6522 class A
6523 static def Foo()
6524 enddef
6525 def Foo()
6526 enddef
6527 endclass
6528 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006529 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006530
Ernie Rael03042a22023-11-11 08:53:32 +01006531 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006532 lines =<< trim END
6533 vim9script
6534 class A
6535 static def Foo()
6536 enddef
6537 def _Foo()
6538 enddef
6539 endclass
6540 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006541 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006542
6543 # Duplicate class method
6544 lines =<< trim END
6545 vim9script
6546 class A
6547 def Foo()
6548 enddef
6549 static def Foo()
6550 enddef
6551 endclass
6552 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006553 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006554
Ernie Rael03042a22023-11-11 08:53:32 +01006555 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006556 lines =<< trim END
6557 vim9script
6558 class A
6559 def Foo()
6560 enddef
6561 static def _Foo()
6562 enddef
6563 endclass
6564 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006565 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006566
Ernie Rael03042a22023-11-11 08:53:32 +01006567 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006568 lines =<< trim END
6569 vim9script
6570 class A
6571 def _Foo()
6572 enddef
6573 static def _Foo()
6574 enddef
6575 endclass
6576 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006577 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006578enddef
6579
6580" Test for an instance method access level comparison with parent instance
6581" methods.
6582def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006583 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006584 var lines =<< trim END
6585 vim9script
6586 class A
6587 def Foo()
6588 enddef
6589 endclass
6590 class B extends A
6591 endclass
6592 class C extends B
6593 def _Foo()
6594 enddef
6595 endclass
6596 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006597 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006598
6599 # Public method in subclass
6600 lines =<< trim END
6601 vim9script
6602 class A
6603 def _Foo()
6604 enddef
6605 endclass
6606 class B extends A
6607 endclass
6608 class C extends B
6609 def Foo()
6610 enddef
6611 endclass
6612 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006613 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006614enddef
6615
6616def Test_extend_empty_class()
6617 var lines =<< trim END
6618 vim9script
6619 class A
6620 endclass
6621 class B extends A
6622 endclass
6623 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006624 public static var rw_class_var = 1
6625 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006626 static def ClassMethod(): number
6627 return 3
6628 enddef
6629 def ObjMethod(): number
6630 return 4
6631 enddef
6632 endclass
6633 assert_equal(1, C.rw_class_var)
6634 assert_equal(3, C.ClassMethod())
6635 var c = C.new()
6636 assert_equal(2, c.rw_obj_var)
6637 assert_equal(4, c.ObjMethod())
6638 END
6639 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006640enddef
6641
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006642" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006643" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006644def Test_interface_with_unsupported_members()
6645 var lines =<< trim END
6646 vim9script
6647 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006648 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006649 endinterface
6650 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006651 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006652
6653 lines =<< trim END
6654 vim9script
6655 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006656 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006657 endinterface
6658 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006659 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006660
6661 lines =<< trim END
6662 vim9script
6663 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006664 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006665 endinterface
6666 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006667 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006668
6669 lines =<< trim END
6670 vim9script
6671 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006672 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006673 endinterface
6674 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006675 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006676
6677 lines =<< trim END
6678 vim9script
6679 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006680 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006681 endinterface
6682 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006683 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006684
6685 lines =<< trim END
6686 vim9script
6687 interface A
6688 static def Foo(d: dict<any>): list<string>
6689 endinterface
6690 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006691 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006692
6693 lines =<< trim END
6694 vim9script
6695 interface A
6696 static def _Foo(d: dict<any>): list<string>
6697 endinterface
6698 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006699 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006700
6701 lines =<< trim END
6702 vim9script
6703 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006704 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006705 endinterface
6706 END
Ernie Rael03042a22023-11-11 08:53:32 +01006707 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006708
6709 lines =<< trim END
6710 vim9script
6711 interface A
6712 def _Foo(d: dict<any>): list<string>
6713 endinterface
6714 END
Ernie Rael03042a22023-11-11 08:53:32 +01006715 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006716enddef
6717
6718" Test for extending an interface
6719def Test_extend_interface()
6720 var lines =<< trim END
6721 vim9script
6722 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006723 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006724 def Foo()
6725 endinterface
6726 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006727 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006728 def Bar()
6729 endinterface
6730 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006731 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006732 def Foo()
6733 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006734 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006735 def Bar()
6736 enddef
6737 endclass
6738 END
6739 v9.CheckSourceSuccess(lines)
6740
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006741 # extending empty interface
6742 lines =<< trim END
6743 vim9script
6744 interface A
6745 endinterface
6746 interface B extends A
6747 endinterface
6748 class C implements B
6749 endclass
6750 END
6751 v9.CheckSourceSuccess(lines)
6752
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006753 lines =<< trim END
6754 vim9script
6755 interface A
6756 def Foo()
6757 endinterface
6758 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006759 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006760 endinterface
6761 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006762 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006763 endclass
6764 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006765 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006766
6767 lines =<< trim END
6768 vim9script
6769 interface A
6770 def Foo()
6771 endinterface
6772 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006773 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006774 endinterface
6775 class C implements A, B
6776 def Foo()
6777 enddef
6778 endclass
6779 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006780 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006781
6782 # interface cannot extend a class
6783 lines =<< trim END
6784 vim9script
6785 class A
6786 endclass
6787 interface B extends A
6788 endinterface
6789 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006790 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006791
6792 # class cannot extend an interface
6793 lines =<< trim END
6794 vim9script
6795 interface A
6796 endinterface
6797 class B extends A
6798 endclass
6799 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006800 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006801
6802 # interface cannot implement another interface
6803 lines =<< trim END
6804 vim9script
6805 interface A
6806 endinterface
6807 interface B implements A
6808 endinterface
6809 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006810 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006811
6812 # interface cannot extend multiple interfaces
6813 lines =<< trim END
6814 vim9script
6815 interface A
6816 endinterface
6817 interface B
6818 endinterface
6819 interface C extends A, B
6820 endinterface
6821 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006822 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006823
6824 # Variable type in an extended interface is of different type
6825 lines =<< trim END
6826 vim9script
6827 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006828 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006829 endinterface
6830 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006831 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006832 endinterface
6833 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006834 var val1: string
6835 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006836 endinterface
6837 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006838 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006839enddef
6840
6841" Test for a child class implementing an interface when some of the methods are
6842" defined in the parent class.
6843def Test_child_class_implements_interface()
6844 var lines =<< trim END
6845 vim9script
6846
6847 interface Intf
6848 def F1(): list<list<number>>
6849 def F2(): list<list<number>>
6850 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006851 var var1: list<dict<number>>
6852 var var2: list<dict<number>>
6853 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006854 endinterface
6855
6856 class A
6857 def A1()
6858 enddef
6859 def F3(): list<list<number>>
6860 return [[3]]
6861 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006862 var v1: list<list<number>> = [[0]]
6863 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006864 endclass
6865
6866 class B extends A
6867 def B1()
6868 enddef
6869 def F2(): list<list<number>>
6870 return [[2]]
6871 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006872 var v2: list<list<number>> = [[0]]
6873 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006874 endclass
6875
6876 class C extends B implements Intf
6877 def C1()
6878 enddef
6879 def F1(): list<list<number>>
6880 return [[1]]
6881 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006882 var v3: list<list<number>> = [[0]]
6883 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006884 endclass
6885
6886 def T(if: Intf)
6887 assert_equal([[1]], if.F1())
6888 assert_equal([[2]], if.F2())
6889 assert_equal([[3]], if.F3())
6890 assert_equal([{a: 10}], if.var1)
6891 assert_equal([{b: 20}], if.var2)
6892 assert_equal([{c: 30}], if.var3)
6893 enddef
6894
6895 var c = C.new()
6896 T(c)
6897 assert_equal([[1]], c.F1())
6898 assert_equal([[2]], c.F2())
6899 assert_equal([[3]], c.F3())
6900 assert_equal([{a: 10}], c.var1)
6901 assert_equal([{b: 20}], c.var2)
6902 assert_equal([{c: 30}], c.var3)
6903 END
6904 v9.CheckSourceSuccess(lines)
6905
6906 # One of the interface methods is not found
6907 lines =<< trim END
6908 vim9script
6909
6910 interface Intf
6911 def F1()
6912 def F2()
6913 def F3()
6914 endinterface
6915
6916 class A
6917 def A1()
6918 enddef
6919 endclass
6920
6921 class B extends A
6922 def B1()
6923 enddef
6924 def F2()
6925 enddef
6926 endclass
6927
6928 class C extends B implements Intf
6929 def C1()
6930 enddef
6931 def F1()
6932 enddef
6933 endclass
6934 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006935 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006936
6937 # One of the interface methods is of different type
6938 lines =<< trim END
6939 vim9script
6940
6941 interface Intf
6942 def F1()
6943 def F2()
6944 def F3()
6945 endinterface
6946
6947 class A
6948 def F3(): number
6949 return 0
6950 enddef
6951 def A1()
6952 enddef
6953 endclass
6954
6955 class B extends A
6956 def B1()
6957 enddef
6958 def F2()
6959 enddef
6960 endclass
6961
6962 class C extends B implements Intf
6963 def C1()
6964 enddef
6965 def F1()
6966 enddef
6967 endclass
6968 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006969 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006970
6971 # One of the interface variables is not present
6972 lines =<< trim END
6973 vim9script
6974
6975 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006976 var var1: list<dict<number>>
6977 var var2: list<dict<number>>
6978 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006979 endinterface
6980
6981 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006982 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006983 endclass
6984
6985 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006986 var v2: list<list<number>> = [[0]]
6987 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006988 endclass
6989
6990 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006991 var v3: list<list<number>> = [[0]]
6992 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006993 endclass
6994 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006995 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006996
6997 # One of the interface variables is of different type
6998 lines =<< trim END
6999 vim9script
7000
7001 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007002 var var1: list<dict<number>>
7003 var var2: list<dict<number>>
7004 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007005 endinterface
7006
7007 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007008 var v1: list<list<number>> = [[0]]
7009 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007010 endclass
7011
7012 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007013 var v2: list<list<number>> = [[0]]
7014 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007015 endclass
7016
7017 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007018 var v3: list<list<number>> = [[0]]
7019 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007020 endclass
7021 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007022 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 +02007023enddef
7024
7025" Test for extending an interface with duplicate variables and methods
7026def Test_interface_extends_with_dup_members()
7027 var lines =<< trim END
7028 vim9script
7029 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007030 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007031 def Foo1(): number
7032 endinterface
7033 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007034 var n2: number
7035 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007036 def Foo2(): number
7037 def Foo1(): number
7038 endinterface
7039 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007040 var n1 = 10
7041 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007042 def Foo1(): number
7043 return 30
7044 enddef
7045 def Foo2(): number
7046 return 40
7047 enddef
7048 endclass
7049 def T1(a: A)
7050 assert_equal(10, a.n1)
7051 assert_equal(30, a.Foo1())
7052 enddef
7053 def T2(b: B)
7054 assert_equal(10, b.n1)
7055 assert_equal(20, b.n2)
7056 assert_equal(30, b.Foo1())
7057 assert_equal(40, b.Foo2())
7058 enddef
7059 var c = C.new()
7060 T1(c)
7061 T2(c)
7062 END
7063 v9.CheckSourceSuccess(lines)
7064enddef
7065
7066" Test for using "any" type for a variable in a sub-class while it has a
7067" concrete type in the interface
7068def Test_implements_using_var_type_any()
7069 var lines =<< trim END
7070 vim9script
7071 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007072 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007073 endinterface
7074 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007075 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007076 endclass
7077 var b = B.new()
7078 assert_equal([{a: '1'}, {b: '2'}], b.val)
7079 END
7080 v9.CheckSourceSuccess(lines)
7081
7082 # initialize instance variable using a different type
7083 lines =<< trim END
7084 vim9script
7085 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007086 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007087 endinterface
7088 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007089 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007090 endclass
7091 var b = B.new()
7092 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007093 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007094enddef
7095
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007096" Test for assigning to a member variable in a nested class
7097def Test_nested_object_assignment()
7098 var lines =<< trim END
7099 vim9script
7100
7101 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007102 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007103 endclass
7104
7105 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007106 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007107 endclass
7108
7109 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007110 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007111 endclass
7112
7113 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007114 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007115 endclass
7116
7117 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007118 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007119 enddef
7120
7121 var d = D.new()
7122 T(d)
7123 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007124 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007125enddef
7126
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007127" Test for calling methods using a null object
7128def Test_null_object_method_call()
7129 # Calling a object method using a null object in script context
7130 var lines =<< trim END
7131 vim9script
7132
7133 class C
7134 def Foo()
7135 assert_report('This method should not be executed')
7136 enddef
7137 endclass
7138
7139 var o: C
7140 o.Foo()
7141 END
7142 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7143
7144 # Calling a object method using a null object in def function context
7145 lines =<< trim END
7146 vim9script
7147
7148 class C
7149 def Foo()
7150 assert_report('This method should not be executed')
7151 enddef
7152 endclass
7153
7154 def T()
7155 var o: C
7156 o.Foo()
7157 enddef
7158 T()
7159 END
7160 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7161
7162 # Calling a object method through another class method using a null object in
7163 # script context
7164 lines =<< trim END
7165 vim9script
7166
7167 class C
7168 def Foo()
7169 assert_report('This method should not be executed')
7170 enddef
7171
7172 static def Bar(o_any: any)
7173 var o_typed: C = o_any
7174 o_typed.Foo()
7175 enddef
7176 endclass
7177
7178 var o: C
7179 C.Bar(o)
7180 END
7181 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7182
7183 # Calling a object method through another class method using a null object in
7184 # def function context
7185 lines =<< trim END
7186 vim9script
7187
7188 class C
7189 def Foo()
7190 assert_report('This method should not be executed')
7191 enddef
7192
7193 static def Bar(o_any: any)
7194 var o_typed: C = o_any
7195 o_typed.Foo()
7196 enddef
7197 endclass
7198
7199 def T()
7200 var o: C
7201 C.Bar(o)
7202 enddef
7203 T()
7204 END
7205 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7206enddef
7207
7208" Test for using a dict as an object member
7209def Test_dict_object_member()
7210 var lines =<< trim END
7211 vim9script
7212
7213 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007214 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007215 def GetState(): dict<number>
7216 return this.state
7217 enddef
7218 endclass
7219
7220 var ctx = Context.new()
7221 ctx.state->extend({a: 1})
7222 ctx.state['b'] = 2
7223 assert_equal({a: 1, b: 2}, ctx.GetState())
7224
7225 def F()
7226 ctx.state['c'] = 3
7227 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7228 enddef
7229 F()
7230 assert_equal(3, ctx.state.c)
7231 ctx.state.c = 4
7232 assert_equal(4, ctx.state.c)
7233 END
7234 v9.CheckSourceSuccess(lines)
7235enddef
7236
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007237" The following test was failing after 9.0.1914. This was caused by using a
7238" freed object from a previous method call.
7239def Test_freed_object_from_previous_method_call()
7240 var lines =<< trim END
7241 vim9script
7242
7243 class Context
7244 endclass
7245
7246 class Result
7247 endclass
7248
7249 def Failure(): Result
7250 return Result.new()
7251 enddef
7252
7253 def GetResult(ctx: Context): Result
7254 return Failure()
7255 enddef
7256
7257 def Test_GetResult()
7258 var ctx = Context.new()
7259 var result = GetResult(ctx)
7260 enddef
7261
7262 Test_GetResult()
7263 END
7264 v9.CheckSourceSuccess(lines)
7265enddef
7266
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007267" Test for duplicate object and class variable
7268def Test_duplicate_variable()
7269 # Object variable name is same as the class variable name
7270 var lines =<< trim END
7271 vim9script
7272 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007273 public static var sval: number
7274 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007275 endclass
7276 var a = A.new()
7277 END
7278 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7279
7280 # Duplicate variable name and calling a class method
7281 lines =<< trim END
7282 vim9script
7283 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007284 public static var sval: number
7285 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007286 def F1()
7287 echo this.sval
7288 enddef
7289 static def F2()
7290 echo sval
7291 enddef
7292 endclass
7293 A.F2()
7294 END
7295 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7296
7297 # Duplicate variable with an empty constructor
7298 lines =<< trim END
7299 vim9script
7300 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007301 public static var sval: number
7302 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007303 def new()
7304 enddef
7305 endclass
7306 var a = A.new()
7307 END
7308 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7309enddef
7310
7311" Test for using a reserved keyword as a variable name
7312def Test_reserved_varname()
7313 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7314 'null_function', 'null_list', 'null_partial', 'null_string',
7315 'null_channel', 'null_job', 'super', 'this']
7316
7317 var lines =<< trim eval END
7318 vim9script
7319 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007320 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007321 endclass
7322 var o = C.new()
7323 END
7324 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7325
7326 lines =<< trim eval END
7327 vim9script
7328 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007329 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007330 def new()
7331 enddef
7332 endclass
7333 var o = C.new()
7334 END
7335 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7336
7337 lines =<< trim eval END
7338 vim9script
7339 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007340 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007341 def new()
7342 enddef
7343 def F()
7344 echo this.{kword}
7345 enddef
7346 endclass
7347 var o = C.new()
7348 o.F()
7349 END
7350 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007351
7352 # class variable name
7353 if kword != 'this'
7354 lines =<< trim eval END
7355 vim9script
7356 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007357 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007358 endclass
7359 END
7360 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7361 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007362 endfor
7363enddef
7364
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007365" Test for checking the type of the arguments and the return value of a object
7366" method in an extended class.
7367def Test_extended_obj_method_type_check()
7368 var lines =<< trim END
7369 vim9script
7370
7371 class A
7372 endclass
7373 class B extends A
7374 endclass
7375 class C extends B
7376 endclass
7377
7378 class Foo
7379 def Doit(p: B): B
7380 return B.new()
7381 enddef
7382 endclass
7383
7384 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007385 def Doit(p: C): B
7386 return B.new()
7387 enddef
7388 endclass
7389 END
7390 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7391
7392 lines =<< trim END
7393 vim9script
7394
7395 class A
7396 endclass
7397 class B extends A
7398 endclass
7399 class C extends B
7400 endclass
7401
7402 class Foo
7403 def Doit(p: B): B
7404 return B.new()
7405 enddef
7406 endclass
7407
7408 class Bar extends Foo
7409 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007410 return C.new()
7411 enddef
7412 endclass
7413 END
7414 v9.CheckSourceSuccess(lines)
7415
7416 lines =<< trim END
7417 vim9script
7418
7419 class A
7420 endclass
7421 class B extends A
7422 endclass
7423 class C extends B
7424 endclass
7425
7426 class Foo
7427 def Doit(p: B): B
7428 return B.new()
7429 enddef
7430 endclass
7431
7432 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007433 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007434 return B.new()
7435 enddef
7436 endclass
7437 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007438 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 +02007439
7440 lines =<< trim END
7441 vim9script
7442
7443 class A
7444 endclass
7445 class B extends A
7446 endclass
7447 class C extends B
7448 endclass
7449
7450 class Foo
7451 def Doit(p: B): B
7452 return B.new()
7453 enddef
7454 endclass
7455
7456 class Bar extends Foo
7457 def Doit(p: B): A
7458 return A.new()
7459 enddef
7460 endclass
7461 END
7462 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 +02007463
7464 # check varargs type mismatch
7465 lines =<< trim END
7466 vim9script
7467
7468 class B
7469 def F(...xxx: list<any>)
7470 enddef
7471 endclass
7472 class C extends B
7473 def F(xxx: list<any>)
7474 enddef
7475 endclass
7476 END
7477 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 +02007478enddef
7479
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007480" Test type checking for class variable in assignments
7481func Test_class_variable_complex_type_check()
7482 " class variable with a specific type. Try assigning a different type at
7483 " script level.
7484 let lines =<< trim END
7485 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007486 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007487 return {}
7488 enddef
7489 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007490 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007491 endclass
7492 test_garbagecollect_now()
7493 A.Fn = "abc"
7494 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007495 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 +02007496
7497 " class variable with a specific type. Try assigning a different type at
7498 " class def method level.
7499 let lines =<< trim END
7500 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007501 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007502 return {}
7503 enddef
7504 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007505 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007506 def Bar()
7507 Fn = "abc"
7508 enddef
7509 endclass
7510 var a = A.new()
7511 test_garbagecollect_now()
7512 a.Bar()
7513 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007514 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 +02007515
7516 " class variable with a specific type. Try assigning a different type at
7517 " script def method level.
7518 let lines =<< trim END
7519 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007520 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007521 return {}
7522 enddef
7523 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007524 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007525 endclass
7526 def Bar()
7527 A.Fn = "abc"
7528 enddef
7529 test_garbagecollect_now()
7530 Bar()
7531 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007532 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 +02007533
7534 " class variable without any type. Should be set to the initialization
7535 " expression type. Try assigning a different type from script level.
7536 let lines =<< trim END
7537 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007538 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007539 return {}
7540 enddef
7541 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007542 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007543 endclass
7544 test_garbagecollect_now()
7545 A.Fn = "abc"
7546 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007547 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 +02007548
7549 " class variable without any type. Should be set to the initialization
7550 " expression type. Try assigning a different type at class def level.
7551 let lines =<< trim END
7552 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007553 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007554 return {}
7555 enddef
7556 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007557 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007558 def Bar()
7559 Fn = "abc"
7560 enddef
7561 endclass
7562 var a = A.new()
7563 test_garbagecollect_now()
7564 a.Bar()
7565 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007566 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 +02007567
7568 " class variable without any type. Should be set to the initialization
7569 " expression type. Try assigning a different type at script def level.
7570 let lines =<< trim END
7571 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007572 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007573 return {}
7574 enddef
7575 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007576 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007577 endclass
7578 def Bar()
7579 A.Fn = "abc"
7580 enddef
7581 test_garbagecollect_now()
7582 Bar()
7583 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007584 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 +02007585
7586 " class variable with 'any" type. Can be assigned different types.
7587 let lines =<< trim END
7588 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007589 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007590 return {}
7591 enddef
7592 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007593 public static var Fn: any = Foo
7594 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007595 endclass
7596 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007597 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007598 A.Fn = "abc"
7599 test_garbagecollect_now()
7600 assert_equal('string', typename(A.Fn))
7601 A.Fn2 = Foo
7602 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007603 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007604 A.Fn2 = "xyz"
7605 test_garbagecollect_now()
7606 assert_equal('string', typename(A.Fn2))
7607 END
7608 call v9.CheckSourceSuccess(lines)
7609
7610 " class variable with 'any" type. Can be assigned different types.
7611 let lines =<< trim END
7612 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007613 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007614 return {}
7615 enddef
7616 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007617 public static var Fn: any = Foo
7618 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007619
7620 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007621 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007622 Fn = "abc"
7623 assert_equal('string', typename(Fn))
7624 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007625 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007626 Fn2 = "xyz"
7627 assert_equal('string', typename(Fn2))
7628 enddef
7629 endclass
7630 var a = A.new()
7631 test_garbagecollect_now()
7632 a.Bar()
7633 test_garbagecollect_now()
7634 A.Fn = Foo
7635 a.Bar()
7636 END
7637 call v9.CheckSourceSuccess(lines)
7638
7639 " class variable with 'any" type. Can be assigned different types.
7640 let lines =<< trim END
7641 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007642 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007643 return {}
7644 enddef
7645 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007646 public static var Fn: any = Foo
7647 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007648 endclass
7649
7650 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007651 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007652 A.Fn = "abc"
7653 assert_equal('string', typename(A.Fn))
7654 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007655 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007656 A.Fn2 = "xyz"
7657 assert_equal('string', typename(A.Fn2))
7658 enddef
7659 Bar()
7660 test_garbagecollect_now()
7661 A.Fn = Foo
7662 Bar()
7663 END
7664 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007665
7666 let lines =<< trim END
7667 vim9script
7668 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007669 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007670 endclass
7671 assert_equal([0z10, 0z20], A.foo)
7672 A.foo = [0z30]
7673 assert_equal([0z30], A.foo)
7674 var a = A.foo
7675 assert_equal([0z30], a)
7676 END
7677 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007678endfunc
7679
7680" Test type checking for object variable in assignments
7681func Test_object_variable_complex_type_check()
7682 " object variable with a specific type. Try assigning a different type at
7683 " script level.
7684 let lines =<< trim END
7685 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007686 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007687 return {}
7688 enddef
7689 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007690 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007691 endclass
7692 var a = A.new()
7693 test_garbagecollect_now()
7694 a.Fn = "abc"
7695 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007696 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 +02007697
7698 " object variable with a specific type. Try assigning a different type at
7699 " object def method level.
7700 let lines =<< trim END
7701 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007702 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007703 return {}
7704 enddef
7705 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007706 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007707 def Bar()
7708 this.Fn = "abc"
7709 this.Fn = Foo
7710 enddef
7711 endclass
7712 var a = A.new()
7713 test_garbagecollect_now()
7714 a.Bar()
7715 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007716 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 +02007717
7718 " object variable with a specific type. Try assigning a different type at
7719 " script def method level.
7720 let lines =<< trim END
7721 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007722 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007723 return {}
7724 enddef
7725 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007726 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007727 endclass
7728 def Bar()
7729 var a = A.new()
7730 a.Fn = "abc"
7731 a.Fn = Foo
7732 enddef
7733 test_garbagecollect_now()
7734 Bar()
7735 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007736 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 +02007737
7738 " object variable without any type. Should be set to the initialization
7739 " expression type. Try assigning a different type from script level.
7740 let lines =<< trim END
7741 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007742 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007743 return {}
7744 enddef
7745 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007746 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007747 endclass
7748 var a = A.new()
7749 test_garbagecollect_now()
7750 a.Fn = "abc"
7751 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007752 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 10)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007753
7754 " object variable without any type. Should be set to the initialization
7755 " expression type. Try assigning a different type at object def level.
7756 let lines =<< trim END
7757 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007758 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007759 return {}
7760 enddef
7761 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007762 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007763 def Bar()
7764 this.Fn = "abc"
7765 this.Fn = Foo
7766 enddef
7767 endclass
7768 var a = A.new()
7769 test_garbagecollect_now()
7770 a.Bar()
7771 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007772 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 +02007773
7774 " object variable without any type. Should be set to the initialization
7775 " expression type. Try assigning a different type at script def level.
7776 let lines =<< trim END
7777 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007778 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007779 return {}
7780 enddef
7781 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007782 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007783 endclass
7784 def Bar()
7785 var a = A.new()
7786 a.Fn = "abc"
7787 a.Fn = Foo
7788 enddef
7789 test_garbagecollect_now()
7790 Bar()
7791 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007792 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 +02007793
7794 " object variable with 'any" type. Can be assigned different types.
7795 let lines =<< trim END
7796 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007797 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007798 return {}
7799 enddef
7800 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007801 public var Fn: any = Foo
7802 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007803 endclass
7804
7805 var a = A.new()
7806 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007807 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007808 a.Fn = "abc"
7809 test_garbagecollect_now()
7810 assert_equal('string', typename(a.Fn))
7811 a.Fn2 = Foo
7812 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007813 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007814 a.Fn2 = "xyz"
7815 test_garbagecollect_now()
7816 assert_equal('string', typename(a.Fn2))
7817 END
7818 call v9.CheckSourceSuccess(lines)
7819
7820 " object variable with 'any" type. Can be assigned different types.
7821 let lines =<< trim END
7822 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007823 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007824 return {}
7825 enddef
7826 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007827 public var Fn: any = Foo
7828 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007829
7830 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007831 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007832 this.Fn = "abc"
7833 assert_equal('string', typename(this.Fn))
7834 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007835 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007836 this.Fn2 = "xyz"
7837 assert_equal('string', typename(this.Fn2))
7838 enddef
7839 endclass
7840
7841 var a = A.new()
7842 test_garbagecollect_now()
7843 a.Bar()
7844 test_garbagecollect_now()
7845 a.Fn = Foo
7846 a.Bar()
7847 END
7848 call v9.CheckSourceSuccess(lines)
7849
7850 " object variable with 'any" type. Can be assigned different types.
7851 let lines =<< trim END
7852 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007853 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007854 return {}
7855 enddef
7856 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007857 public var Fn: any = Foo
7858 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007859 endclass
7860
7861 def Bar()
7862 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007863 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007864 a.Fn = "abc"
7865 assert_equal('string', typename(a.Fn))
7866 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007867 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007868 a.Fn2 = "xyz"
7869 assert_equal('string', typename(a.Fn2))
7870 enddef
7871 test_garbagecollect_now()
7872 Bar()
7873 test_garbagecollect_now()
7874 Bar()
7875 END
7876 call v9.CheckSourceSuccess(lines)
7877endfunc
7878
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007879" Test for recursively calling an object method. This used to cause an
7880" use-after-free error.
7881def Test_recursive_object_method_call()
7882 var lines =<< trim END
7883 vim9script
7884 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007885 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007886 def Foo(): number
7887 if this.val >= 90
7888 return this.val
7889 endif
7890 this.val += 1
7891 return this.Foo()
7892 enddef
7893 endclass
7894 var a = A.new()
7895 assert_equal(90, a.Foo())
7896 END
7897 v9.CheckSourceSuccess(lines)
7898enddef
7899
7900" Test for recursively calling a class method.
7901def Test_recursive_class_method_call()
7902 var lines =<< trim END
7903 vim9script
7904 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007905 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007906 static def Foo(): number
7907 if val >= 90
7908 return val
7909 endif
7910 val += 1
7911 return Foo()
7912 enddef
7913 endclass
7914 assert_equal(90, A.Foo())
7915 END
7916 v9.CheckSourceSuccess(lines)
7917enddef
7918
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007919" Test for checking the argument types and the return type when assigning a
7920" funcref to make sure the invariant class type is used.
7921def Test_funcref_argtype_returntype_check()
7922 var lines =<< trim END
7923 vim9script
7924 class A
7925 endclass
7926 class B extends A
7927 endclass
7928
7929 def Foo(p: B): B
7930 return B.new()
7931 enddef
7932
7933 var Bar: func(A): A = Foo
7934 END
7935 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7936
7937 lines =<< trim END
7938 vim9script
7939 class A
7940 endclass
7941 class B extends A
7942 endclass
7943
7944 def Foo(p: B): B
7945 return B.new()
7946 enddef
7947
7948 def Baz()
7949 var Bar: func(A): A = Foo
7950 enddef
7951 Baz()
7952 END
7953 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7954enddef
7955
Ernie Rael96952b22023-10-17 18:15:01 +02007956def Test_funcref_argtype_invariance_check()
7957 var lines =<< trim END
7958 vim9script
7959
7960 class A
7961 endclass
7962 class B extends A
7963 endclass
7964 class C extends B
7965 endclass
7966
7967 var Func: func(B): number
7968 Func = (o: B): number => 3
7969 assert_equal(3, Func(B.new()))
7970 END
7971 v9.CheckSourceSuccess(lines)
7972
7973 lines =<< trim END
7974 vim9script
7975
7976 class A
7977 endclass
7978 class B extends A
7979 endclass
7980 class C extends B
7981 endclass
7982
7983 var Func: func(B): number
7984 Func = (o: A): number => 3
7985 END
7986 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7987
7988 lines =<< trim END
7989 vim9script
7990
7991 class A
7992 endclass
7993 class B extends A
7994 endclass
7995 class C extends B
7996 endclass
7997
7998 var Func: func(B): number
7999 Func = (o: C): number => 3
8000 END
8001 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
8002enddef
8003
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008004" Test for using an operator (e.g. +) with an assignment
8005def Test_op_and_assignment()
8006 # Using += with a class variable
8007 var lines =<< trim END
8008 vim9script
8009 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008010 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008011 static def Foo(): list<number>
8012 val += [1]
8013 return val
8014 enddef
8015 endclass
8016 def Bar(): list<number>
8017 A.val += [2]
8018 return A.val
8019 enddef
8020 assert_equal([1], A.Foo())
8021 assert_equal([1, 2], Bar())
8022 A.val += [3]
8023 assert_equal([1, 2, 3], A.val)
8024 END
8025 v9.CheckSourceSuccess(lines)
8026
8027 # Using += with an object variable
8028 lines =<< trim END
8029 vim9script
8030 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008031 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008032 def Foo(): list<number>
8033 this.val += [1]
8034 return this.val
8035 enddef
8036 endclass
8037 def Bar(bar_a: A): list<number>
8038 bar_a.val += [2]
8039 return bar_a.val
8040 enddef
8041 var a = A.new()
8042 assert_equal([1], a.Foo())
8043 assert_equal([1, 2], Bar(a))
8044 a.val += [3]
8045 assert_equal([1, 2, 3], a.val)
8046 END
8047 v9.CheckSourceSuccess(lines)
8048enddef
8049
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008050" Test for using an object method as a funcref
8051def Test_object_funcref()
8052 # Using object method funcref from a def function
8053 var lines =<< trim END
8054 vim9script
8055 class A
8056 def Foo(): list<number>
8057 return [3, 2, 1]
8058 enddef
8059 endclass
8060 def Bar()
8061 var a = A.new()
8062 var Fn = a.Foo
8063 assert_equal([3, 2, 1], Fn())
8064 enddef
8065 Bar()
8066 END
8067 v9.CheckSourceSuccess(lines)
8068
8069 # Using object method funcref at the script level
8070 lines =<< trim END
8071 vim9script
8072 class A
8073 def Foo(): dict<number>
8074 return {a: 1, b: 2}
8075 enddef
8076 endclass
8077 var a = A.new()
8078 var Fn = a.Foo
8079 assert_equal({a: 1, b: 2}, Fn())
8080 END
8081 v9.CheckSourceSuccess(lines)
8082
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008083 # Using object method funcref at the script level
8084 lines =<< trim END
8085 vim9script
8086 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008087 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008088 def Foo(): number
8089 return this.val
8090 enddef
8091 endclass
8092 var a = A.new(345)
8093 var Fn = a.Foo
8094 assert_equal(345, Fn())
8095 END
8096 v9.CheckSourceSuccess(lines)
8097
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008098 # Using object method funcref from another object method
8099 lines =<< trim END
8100 vim9script
8101 class A
8102 def Foo(): list<number>
8103 return [3, 2, 1]
8104 enddef
8105 def Bar()
8106 var Fn = this.Foo
8107 assert_equal([3, 2, 1], Fn())
8108 enddef
8109 endclass
8110 var a = A.new()
8111 a.Bar()
8112 END
8113 v9.CheckSourceSuccess(lines)
8114
8115 # Using function() to get a object method funcref
8116 lines =<< trim END
8117 vim9script
8118 class A
8119 def Foo(l: list<any>): list<any>
8120 return l
8121 enddef
8122 endclass
8123 var a = A.new()
8124 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8125 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8126 END
8127 v9.CheckSourceSuccess(lines)
8128
8129 # Use an object method with a function returning a funcref and then call the
8130 # funcref.
8131 lines =<< trim END
8132 vim9script
8133
8134 def Map(F: func(number): number): func(number): number
8135 return (n: number) => F(n)
8136 enddef
8137
8138 class Math
8139 def Double(n: number): number
8140 return 2 * n
8141 enddef
8142 endclass
8143
8144 const math = Math.new()
8145 assert_equal(48, Map(math.Double)(24))
8146 END
8147 v9.CheckSourceSuccess(lines)
8148
Ernie Rael03042a22023-11-11 08:53:32 +01008149 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008150 lines =<< trim END
8151 vim9script
8152 class A
8153 def _Foo()
8154 enddef
8155 endclass
8156 def Bar()
8157 var a = A.new()
8158 var Fn = a._Foo
8159 enddef
8160 Bar()
8161 END
Ernie Rael03042a22023-11-11 08:53:32 +01008162 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008163
Ernie Rael03042a22023-11-11 08:53:32 +01008164 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008165 lines =<< trim END
8166 vim9script
8167 class A
8168 def _Foo()
8169 enddef
8170 endclass
8171 var a = A.new()
8172 var Fn = a._Foo
8173 END
Ernie Rael03042a22023-11-11 08:53:32 +01008174 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008175
Ernie Rael03042a22023-11-11 08:53:32 +01008176 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008177 lines =<< trim END
8178 vim9script
8179 class A
8180 def _Foo(): list<number>
8181 return [3, 2, 1]
8182 enddef
8183 def Bar()
8184 var Fn = this._Foo
8185 assert_equal([3, 2, 1], Fn())
8186 enddef
8187 endclass
8188 var a = A.new()
8189 a.Bar()
8190 END
8191 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008192
8193 # Using object method funcref using call()
8194 lines =<< trim END
8195 vim9script
8196 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008197 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008198 def Foo(): number
8199 return this.val
8200 enddef
8201 endclass
8202
8203 def Bar(obj: A)
8204 assert_equal(123, call(obj.Foo, []))
8205 enddef
8206
8207 var a = A.new(123)
8208 Bar(a)
8209 assert_equal(123, call(a.Foo, []))
8210 END
8211 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008212enddef
8213
8214" Test for using a class method as a funcref
8215def Test_class_funcref()
8216 # Using class method funcref in a def function
8217 var lines =<< trim END
8218 vim9script
8219 class A
8220 static def Foo(): list<number>
8221 return [3, 2, 1]
8222 enddef
8223 endclass
8224 def Bar()
8225 var Fn = A.Foo
8226 assert_equal([3, 2, 1], Fn())
8227 enddef
8228 Bar()
8229 END
8230 v9.CheckSourceSuccess(lines)
8231
8232 # Using class method funcref at script level
8233 lines =<< trim END
8234 vim9script
8235 class A
8236 static def Foo(): dict<number>
8237 return {a: 1, b: 2}
8238 enddef
8239 endclass
8240 var Fn = A.Foo
8241 assert_equal({a: 1, b: 2}, Fn())
8242 END
8243 v9.CheckSourceSuccess(lines)
8244
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008245 # Using class method funcref at the script level
8246 lines =<< trim END
8247 vim9script
8248 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008249 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008250 static def Foo(): number
8251 return val
8252 enddef
8253 endclass
8254 A.val = 567
8255 var Fn = A.Foo
8256 assert_equal(567, Fn())
8257 END
8258 v9.CheckSourceSuccess(lines)
8259
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008260 # Using function() to get a class method funcref
8261 lines =<< trim END
8262 vim9script
8263 class A
8264 static def Foo(l: list<any>): list<any>
8265 return l
8266 enddef
8267 endclass
8268 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8269 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8270 END
8271 v9.CheckSourceSuccess(lines)
8272
8273 # Using a class method funcref from another class method
8274 lines =<< trim END
8275 vim9script
8276 class A
8277 static def Foo(): list<number>
8278 return [3, 2, 1]
8279 enddef
8280 static def Bar()
8281 var Fn = Foo
8282 assert_equal([3, 2, 1], Fn())
8283 enddef
8284 endclass
8285 A.Bar()
8286 END
8287 v9.CheckSourceSuccess(lines)
8288
8289 # Use a class method with a function returning a funcref and then call the
8290 # funcref.
8291 lines =<< trim END
8292 vim9script
8293
8294 def Map(F: func(number): number): func(number): number
8295 return (n: number) => F(n)
8296 enddef
8297
8298 class Math
8299 static def StaticDouble(n: number): number
8300 return 2 * n
8301 enddef
8302 endclass
8303
8304 assert_equal(48, Map(Math.StaticDouble)(24))
8305 END
8306 v9.CheckSourceSuccess(lines)
8307
Ernie Rael03042a22023-11-11 08:53:32 +01008308 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008309 lines =<< trim END
8310 vim9script
8311 class A
8312 static def _Foo()
8313 enddef
8314 endclass
8315 def Bar()
8316 var Fn = A._Foo
8317 enddef
8318 Bar()
8319 END
Ernie Rael03042a22023-11-11 08:53:32 +01008320 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008321
Ernie Rael03042a22023-11-11 08:53:32 +01008322 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008323 lines =<< trim END
8324 vim9script
8325 class A
8326 static def _Foo()
8327 enddef
8328 endclass
8329 var Fn = A._Foo
8330 END
Ernie Rael03042a22023-11-11 08:53:32 +01008331 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008332
Ernie Rael03042a22023-11-11 08:53:32 +01008333 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008334 lines =<< trim END
8335 vim9script
8336 class A
8337 static def _Foo(): list<number>
8338 return [3, 2, 1]
8339 enddef
8340 static def Bar()
8341 var Fn = _Foo
8342 assert_equal([3, 2, 1], Fn())
8343 enddef
8344 endclass
8345 A.Bar()
8346 END
8347 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008348
8349 # Using class method funcref using call()
8350 lines =<< trim END
8351 vim9script
8352 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008353 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008354 static def Foo(): number
8355 return val
8356 enddef
8357 endclass
8358
8359 def Bar()
8360 A.val = 468
8361 assert_equal(468, call(A.Foo, []))
8362 enddef
8363 Bar()
8364 assert_equal(468, call(A.Foo, []))
8365 END
8366 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008367enddef
8368
8369" Test for using an object member as a funcref
8370def Test_object_member_funcref()
8371 # Using a funcref object variable in an object method
8372 var lines =<< trim END
8373 vim9script
8374 def Foo(n: number): number
8375 return n * 10
8376 enddef
8377
8378 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008379 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008380 def Bar()
8381 assert_equal(200, this.Cb(20))
8382 enddef
8383 endclass
8384
8385 var a = A.new()
8386 a.Bar()
8387 END
8388 v9.CheckSourceSuccess(lines)
8389
8390 # Using a funcref object variable in a def method
8391 lines =<< trim END
8392 vim9script
8393 def Foo(n: number): number
8394 return n * 10
8395 enddef
8396
8397 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008398 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008399 endclass
8400
8401 def Bar()
8402 var a = A.new()
8403 assert_equal(200, a.Cb(20))
8404 enddef
8405 Bar()
8406 END
8407 v9.CheckSourceSuccess(lines)
8408
8409 # Using a funcref object variable at script level
8410 lines =<< trim END
8411 vim9script
8412 def Foo(n: number): number
8413 return n * 10
8414 enddef
8415
8416 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008417 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008418 endclass
8419
8420 var a = A.new()
8421 assert_equal(200, a.Cb(20))
8422 END
8423 v9.CheckSourceSuccess(lines)
8424
8425 # Using a funcref object variable pointing to an object method in an object
8426 # method.
8427 lines =<< trim END
8428 vim9script
8429 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008430 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008431 def Foo(n: number): number
8432 return n * 10
8433 enddef
8434 def Bar()
8435 assert_equal(200, this.Cb(20))
8436 enddef
8437 endclass
8438
8439 var a = A.new()
8440 a.Bar()
8441 END
8442 v9.CheckSourceSuccess(lines)
8443
8444 # Using a funcref object variable pointing to an object method in a def
8445 # method.
8446 lines =<< trim END
8447 vim9script
8448 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008449 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008450 def Foo(n: number): number
8451 return n * 10
8452 enddef
8453 endclass
8454
8455 def Bar()
8456 var a = A.new()
8457 assert_equal(200, a.Cb(20))
8458 enddef
8459 Bar()
8460 END
8461 v9.CheckSourceSuccess(lines)
8462
8463 # Using a funcref object variable pointing to an object method at script
8464 # level.
8465 lines =<< trim END
8466 vim9script
8467 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008468 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008469 def Foo(n: number): number
8470 return n * 10
8471 enddef
8472 endclass
8473
8474 var a = A.new()
8475 assert_equal(200, a.Cb(20))
8476 END
8477 v9.CheckSourceSuccess(lines)
8478enddef
8479
8480" Test for using a class member as a funcref
8481def Test_class_member_funcref()
8482 # Using a funcref class variable in a class method
8483 var lines =<< trim END
8484 vim9script
8485 def Foo(n: number): number
8486 return n * 10
8487 enddef
8488
8489 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008490 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008491 static def Bar()
8492 assert_equal(200, Cb(20))
8493 enddef
8494 endclass
8495
8496 A.Bar()
8497 END
8498 v9.CheckSourceSuccess(lines)
8499
8500 # Using a funcref class variable in a def method
8501 lines =<< trim END
8502 vim9script
8503 def Foo(n: number): number
8504 return n * 10
8505 enddef
8506
8507 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008508 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008509 endclass
8510
8511 def Bar()
8512 assert_equal(200, A.Cb(20))
8513 enddef
8514 Bar()
8515 END
8516 v9.CheckSourceSuccess(lines)
8517
8518 # Using a funcref class variable at script level
8519 lines =<< trim END
8520 vim9script
8521 def Foo(n: number): number
8522 return n * 10
8523 enddef
8524
8525 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008526 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008527 endclass
8528
8529 assert_equal(200, A.Cb(20))
8530 END
8531 v9.CheckSourceSuccess(lines)
8532
8533 # Using a funcref class variable pointing to a class method in a class
8534 # method.
8535 lines =<< trim END
8536 vim9script
8537 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008538 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008539 static def Foo(n: number): number
8540 return n * 10
8541 enddef
8542 static def Init()
8543 Cb = Foo
8544 enddef
8545 static def Bar()
8546 assert_equal(200, Cb(20))
8547 enddef
8548 endclass
8549
8550 A.Init()
8551 A.Bar()
8552 END
8553 v9.CheckSourceSuccess(lines)
8554
8555 # Using a funcref class variable pointing to a class method in a def method.
8556 lines =<< trim END
8557 vim9script
8558 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008559 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008560 static def Foo(n: number): number
8561 return n * 10
8562 enddef
8563 static def Init()
8564 Cb = Foo
8565 enddef
8566 endclass
8567
8568 def Bar()
8569 A.Init()
8570 assert_equal(200, A.Cb(20))
8571 enddef
8572 Bar()
8573 END
8574 v9.CheckSourceSuccess(lines)
8575
8576 # Using a funcref class variable pointing to a class method at script level.
8577 lines =<< trim END
8578 vim9script
8579 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008580 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008581 static def Foo(n: number): number
8582 return n * 10
8583 enddef
8584 static def Init()
8585 Cb = Foo
8586 enddef
8587 endclass
8588
8589 A.Init()
8590 assert_equal(200, A.Cb(20))
8591 END
8592 v9.CheckSourceSuccess(lines)
8593enddef
8594
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008595" Test for using object methods as popup callback functions
8596def Test_objmethod_popup_callback()
8597 # Use the popup from the script level
8598 var lines =<< trim END
8599 vim9script
8600
8601 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008602 var selection: number = -1
8603 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008604
8605 def PopupFilter(id: number, key: string): bool
8606 add(this.filterkeys, key)
8607 return popup_filter_yesno(id, key)
8608 enddef
8609
8610 def PopupCb(id: number, result: number)
8611 this.selection = result ? 100 : 200
8612 enddef
8613 endclass
8614
8615 var a = A.new()
8616 feedkeys('', 'xt')
8617 var winid = popup_create('Y/N?',
8618 {filter: a.PopupFilter, callback: a.PopupCb})
8619 feedkeys('y', 'xt')
8620 popup_close(winid)
8621 assert_equal(100, a.selection)
8622 assert_equal(['y'], a.filterkeys)
8623 feedkeys('', 'xt')
8624 winid = popup_create('Y/N?',
8625 {filter: a.PopupFilter, callback: a.PopupCb})
8626 feedkeys('n', 'xt')
8627 popup_close(winid)
8628 assert_equal(200, a.selection)
8629 assert_equal(['y', 'n'], a.filterkeys)
8630 END
8631 v9.CheckSourceSuccess(lines)
8632
8633 # Use the popup from a def function
8634 lines =<< trim END
8635 vim9script
8636
8637 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008638 var selection: number = -1
8639 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008640
8641 def PopupFilter(id: number, key: string): bool
8642 add(this.filterkeys, key)
8643 return popup_filter_yesno(id, key)
8644 enddef
8645
8646 def PopupCb(id: number, result: number)
8647 this.selection = result ? 100 : 200
8648 enddef
8649 endclass
8650
8651 def Foo()
8652 var a = A.new()
8653 feedkeys('', 'xt')
8654 var winid = popup_create('Y/N?',
8655 {filter: a.PopupFilter, callback: a.PopupCb})
8656 feedkeys('y', 'xt')
8657 popup_close(winid)
8658 assert_equal(100, a.selection)
8659 assert_equal(['y'], a.filterkeys)
8660 feedkeys('', 'xt')
8661 winid = popup_create('Y/N?',
8662 {filter: a.PopupFilter, callback: a.PopupCb})
8663 feedkeys('n', 'xt')
8664 popup_close(winid)
8665 assert_equal(200, a.selection)
8666 assert_equal(['y', 'n'], a.filterkeys)
8667 enddef
8668 Foo()
8669 END
8670 v9.CheckSourceSuccess(lines)
8671enddef
8672
8673" Test for using class methods as popup callback functions
8674def Test_classmethod_popup_callback()
8675 # Use the popup from the script level
8676 var lines =<< trim END
8677 vim9script
8678
8679 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008680 static var selection: number = -1
8681 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008682
8683 static def PopupFilter(id: number, key: string): bool
8684 add(filterkeys, key)
8685 return popup_filter_yesno(id, key)
8686 enddef
8687
8688 static def PopupCb(id: number, result: number)
8689 selection = result ? 100 : 200
8690 enddef
8691 endclass
8692
8693 feedkeys('', 'xt')
8694 var winid = popup_create('Y/N?',
8695 {filter: A.PopupFilter, callback: A.PopupCb})
8696 feedkeys('y', 'xt')
8697 popup_close(winid)
8698 assert_equal(100, A.selection)
8699 assert_equal(['y'], A.filterkeys)
8700 feedkeys('', 'xt')
8701 winid = popup_create('Y/N?',
8702 {filter: A.PopupFilter, callback: A.PopupCb})
8703 feedkeys('n', 'xt')
8704 popup_close(winid)
8705 assert_equal(200, A.selection)
8706 assert_equal(['y', 'n'], A.filterkeys)
8707 END
8708 v9.CheckSourceSuccess(lines)
8709
8710 # Use the popup from a def function
8711 lines =<< trim END
8712 vim9script
8713
8714 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008715 static var selection: number = -1
8716 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008717
8718 static def PopupFilter(id: number, key: string): bool
8719 add(filterkeys, key)
8720 return popup_filter_yesno(id, key)
8721 enddef
8722
8723 static def PopupCb(id: number, result: number)
8724 selection = result ? 100 : 200
8725 enddef
8726 endclass
8727
8728 def Foo()
8729 feedkeys('', 'xt')
8730 var winid = popup_create('Y/N?',
8731 {filter: A.PopupFilter, callback: A.PopupCb})
8732 feedkeys('y', 'xt')
8733 popup_close(winid)
8734 assert_equal(100, A.selection)
8735 assert_equal(['y'], A.filterkeys)
8736 feedkeys('', 'xt')
8737 winid = popup_create('Y/N?',
8738 {filter: A.PopupFilter, callback: A.PopupCb})
8739 feedkeys('n', 'xt')
8740 popup_close(winid)
8741 assert_equal(200, A.selection)
8742 assert_equal(['y', 'n'], A.filterkeys)
8743 enddef
8744 Foo()
8745 END
8746 v9.CheckSourceSuccess(lines)
8747enddef
8748
8749" Test for using an object method as a timer callback function
8750def Test_objmethod_timer_callback()
8751 # Use the timer callback from script level
8752 var lines =<< trim END
8753 vim9script
8754
8755 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008756 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008757 def TimerCb(timerID: number)
8758 this.timerTick = 6
8759 enddef
8760 endclass
8761
8762 var a = A.new()
8763 timer_start(0, a.TimerCb)
8764 var maxWait = 5
8765 while maxWait > 0 && a.timerTick == -1
8766 :sleep 10m
8767 maxWait -= 1
8768 endwhile
8769 assert_equal(6, a.timerTick)
8770 END
8771 v9.CheckSourceSuccess(lines)
8772
8773 # Use the timer callback from a def function
8774 lines =<< trim END
8775 vim9script
8776
8777 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008778 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008779 def TimerCb(timerID: number)
8780 this.timerTick = 6
8781 enddef
8782 endclass
8783
8784 def Foo()
8785 var a = A.new()
8786 timer_start(0, a.TimerCb)
8787 var maxWait = 5
8788 while maxWait > 0 && a.timerTick == -1
8789 :sleep 10m
8790 maxWait -= 1
8791 endwhile
8792 assert_equal(6, a.timerTick)
8793 enddef
8794 Foo()
8795 END
8796 v9.CheckSourceSuccess(lines)
8797enddef
8798
8799" Test for using a class method as a timer callback function
8800def Test_classmethod_timer_callback()
8801 # Use the timer callback from script level
8802 var lines =<< trim END
8803 vim9script
8804
8805 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008806 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008807 static def TimerCb(timerID: number)
8808 timerTick = 6
8809 enddef
8810 endclass
8811
8812 timer_start(0, A.TimerCb)
8813 var maxWait = 5
8814 while maxWait > 0 && A.timerTick == -1
8815 :sleep 10m
8816 maxWait -= 1
8817 endwhile
8818 assert_equal(6, A.timerTick)
8819 END
8820 v9.CheckSourceSuccess(lines)
8821
8822 # Use the timer callback from a def function
8823 lines =<< trim END
8824 vim9script
8825
8826 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008827 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008828 static def TimerCb(timerID: number)
8829 timerTick = 6
8830 enddef
8831 endclass
8832
8833 def Foo()
8834 timer_start(0, A.TimerCb)
8835 var maxWait = 5
8836 while maxWait > 0 && A.timerTick == -1
8837 :sleep 10m
8838 maxWait -= 1
8839 endwhile
8840 assert_equal(6, A.timerTick)
8841 enddef
8842 Foo()
8843 END
8844 v9.CheckSourceSuccess(lines)
8845enddef
8846
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008847" Test for using a class variable as the first and/or second operand of a binary
8848" operator.
8849def Test_class_variable_as_operands()
8850 var lines =<< trim END
8851 vim9script
8852 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008853 static var truthy: bool = true
8854 public static var TruthyFn: func
8855 static var list: list<any> = []
8856 static var four: number = 4
8857 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008858
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008859 static def Str(): string
8860 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008861 enddef
8862
8863 static def Four(): number
8864 return four
8865 enddef
8866
8867 static def List(): list<any>
8868 return list
8869 enddef
8870
8871 static def Truthy(): bool
8872 return truthy
8873 enddef
8874
8875 def TestOps()
8876 assert_true(Tests.truthy == truthy)
8877 assert_true(truthy == Tests.truthy)
8878 assert_true(Tests.list isnot [])
8879 assert_true([] isnot Tests.list)
8880 assert_equal(2, Tests.four >> 1)
8881 assert_equal(16, 1 << Tests.four)
8882 assert_equal(8, Tests.four + four)
8883 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008884 assert_equal('hellohello', Tests.str .. str)
8885 assert_equal('hellohello', str .. Tests.str)
8886
8887 # Using class variable for list indexing
8888 var l = range(10)
8889 assert_equal(4, l[Tests.four])
8890 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8891
8892 # Using class variable for Dict key
8893 var d = {hello: 'abc'}
8894 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008895 enddef
8896 endclass
8897
8898 def TestOps2()
8899 assert_true(Tests.truthy == Tests.Truthy())
8900 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008901 assert_true(Tests.truthy == Tests.TruthyFn())
8902 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008903 assert_true(Tests.list is Tests.List())
8904 assert_true(Tests.List() is Tests.list)
8905 assert_equal(2, Tests.four >> 1)
8906 assert_equal(16, 1 << Tests.four)
8907 assert_equal(8, Tests.four + Tests.Four())
8908 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008909 assert_equal('hellohello', Tests.str .. Tests.Str())
8910 assert_equal('hellohello', Tests.Str() .. Tests.str)
8911
8912 # Using class variable for list indexing
8913 var l = range(10)
8914 assert_equal(4, l[Tests.four])
8915 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8916
8917 # Using class variable for Dict key
8918 var d = {hello: 'abc'}
8919 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008920 enddef
8921
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008922 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008923 var t = Tests.new()
8924 t.TestOps()
8925 TestOps2()
8926
8927 assert_true(Tests.truthy == Tests.Truthy())
8928 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008929 assert_true(Tests.truthy == Tests.TruthyFn())
8930 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008931 assert_true(Tests.list is Tests.List())
8932 assert_true(Tests.List() is Tests.list)
8933 assert_equal(2, Tests.four >> 1)
8934 assert_equal(16, 1 << Tests.four)
8935 assert_equal(8, Tests.four + Tests.Four())
8936 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008937 assert_equal('hellohello', Tests.str .. Tests.Str())
8938 assert_equal('hellohello', Tests.Str() .. Tests.str)
8939
8940 # Using class variable for list indexing
8941 var l = range(10)
8942 assert_equal(4, l[Tests.four])
8943 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8944
8945 # Using class variable for Dict key
8946 var d = {hello: 'abc'}
8947 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008948 END
8949 v9.CheckSourceSuccess(lines)
8950enddef
8951
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008952" Test for checking the type of the key used to access an object dict member.
8953def Test_dict_member_key_type_check()
8954 var lines =<< trim END
8955 vim9script
8956
8957 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01008958 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008959 endclass
8960
8961 class Test extends State
8962 def ObjMethodTests()
8963 var cursor: number = 0
8964 var z: number = 0
8965 [this.numbers[cursor]] = ['zero.1']
8966 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8967 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8968 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8969 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8970 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8971 [this.numbers[cursor], z] = ['zero.4', 1]
8972 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8973 [z, this.numbers[cursor]] = [1, 'zero.5']
8974 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8975 enddef
8976
8977 static def ClassMethodTests(that: State)
8978 var cursor: number = 0
8979 var z: number = 0
8980 [that.numbers[cursor]] = ['zero.1']
8981 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8982 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8983 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8984 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8985 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8986 [that.numbers[cursor], z] = ['zero.4', 1]
8987 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8988 [z, that.numbers[cursor]] = [1, 'zero.5']
8989 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8990 enddef
8991
8992 def new()
8993 enddef
8994
8995 def newMethodTests()
8996 var cursor: number = 0
8997 var z: number
8998 [this.numbers[cursor]] = ['zero.1']
8999 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9000 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9001 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9002 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9003 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9004 [this.numbers[cursor], z] = ['zero.4', 1]
9005 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9006 [z, this.numbers[cursor]] = [1, 'zero.5']
9007 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9008 enddef
9009 endclass
9010
9011 def DefFuncTests(that: Test)
9012 var cursor: number = 0
9013 var z: number
9014 [that.numbers[cursor]] = ['zero.1']
9015 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9016 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9017 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9018 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9019 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9020 [that.numbers[cursor], z] = ['zero.4', 1]
9021 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9022 [z, that.numbers[cursor]] = [1, 'zero.5']
9023 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9024 enddef
9025
9026 Test.newMethodTests()
9027 Test.new().ObjMethodTests()
9028 Test.ClassMethodTests(Test.new())
9029 DefFuncTests(Test.new())
9030
9031 const test: Test = Test.new()
9032 var cursor: number = 0
9033 [test.numbers[cursor], cursor] = ['zero', 1]
9034 [cursor, test.numbers[cursor]] = [1, 'one']
9035 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
9036 END
9037 v9.CheckSourceSuccess(lines)
9038
9039 lines =<< trim END
9040 vim9script
9041
9042 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009043 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009044
9045 def new()
9046 enddef
9047
9048 def Foo()
9049 var z: number
9050 [this.numbers.a, z] = [{}, 10]
9051 enddef
9052 endclass
9053
9054 var a = A.new()
9055 a.Foo()
9056 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009057 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009058
9059 lines =<< trim END
9060 vim9script
9061
9062 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009063 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009064
9065 def new()
9066 enddef
9067
9068 def Foo()
9069 var x: string = 'a'
9070 var y: number
9071 [this.numbers[x], y] = [{}, 10]
9072 enddef
9073 endclass
9074
9075 var a = A.new()
9076 a.Foo()
9077 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009078 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009079enddef
9080
mityua5550692023-11-25 15:41:20 +01009081def Test_compile_many_def_functions_in_funcref_instr()
9082 # This used to crash Vim. This is reproducible only when run on new instance
9083 # of Vim.
9084 var lines =<< trim END
9085 vim9script
9086
9087 class A
9088 def new()
9089 this.TakeFunc(this.F00)
9090 enddef
9091
9092 def TakeFunc(F: func)
9093 enddef
9094
9095 def F00()
9096 this.F01()
9097 this.F02()
9098 this.F03()
9099 this.F04()
9100 this.F05()
9101 this.F06()
9102 this.F07()
9103 this.F08()
9104 this.F09()
9105 this.F10()
9106 this.F11()
9107 this.F12()
9108 this.F13()
9109 this.F14()
9110 this.F15()
9111 this.F16()
9112 this.F17()
9113 this.F18()
9114 this.F19()
9115 this.F20()
9116 this.F21()
9117 this.F22()
9118 this.F23()
9119 this.F24()
9120 this.F25()
9121 this.F26()
9122 this.F27()
9123 this.F28()
9124 this.F29()
9125 this.F30()
9126 this.F31()
9127 this.F32()
9128 this.F33()
9129 this.F34()
9130 this.F35()
9131 this.F36()
9132 this.F37()
9133 this.F38()
9134 this.F39()
9135 this.F40()
9136 this.F41()
9137 this.F42()
9138 this.F43()
9139 this.F44()
9140 this.F45()
9141 this.F46()
9142 this.F47()
9143 enddef
9144
9145 def F01()
9146 enddef
9147 def F02()
9148 enddef
9149 def F03()
9150 enddef
9151 def F04()
9152 enddef
9153 def F05()
9154 enddef
9155 def F06()
9156 enddef
9157 def F07()
9158 enddef
9159 def F08()
9160 enddef
9161 def F09()
9162 enddef
9163 def F10()
9164 enddef
9165 def F11()
9166 enddef
9167 def F12()
9168 enddef
9169 def F13()
9170 enddef
9171 def F14()
9172 enddef
9173 def F15()
9174 enddef
9175 def F16()
9176 enddef
9177 def F17()
9178 enddef
9179 def F18()
9180 enddef
9181 def F19()
9182 enddef
9183 def F20()
9184 enddef
9185 def F21()
9186 enddef
9187 def F22()
9188 enddef
9189 def F23()
9190 enddef
9191 def F24()
9192 enddef
9193 def F25()
9194 enddef
9195 def F26()
9196 enddef
9197 def F27()
9198 enddef
9199 def F28()
9200 enddef
9201 def F29()
9202 enddef
9203 def F30()
9204 enddef
9205 def F31()
9206 enddef
9207 def F32()
9208 enddef
9209 def F33()
9210 enddef
9211 def F34()
9212 enddef
9213 def F35()
9214 enddef
9215 def F36()
9216 enddef
9217 def F37()
9218 enddef
9219 def F38()
9220 enddef
9221 def F39()
9222 enddef
9223 def F40()
9224 enddef
9225 def F41()
9226 enddef
9227 def F42()
9228 enddef
9229 def F43()
9230 enddef
9231 def F44()
9232 enddef
9233 def F45()
9234 enddef
9235 def F46()
9236 enddef
9237 def F47()
9238 enddef
9239 endclass
9240
9241 A.new()
9242 END
9243 writefile(lines, 'Xscript', 'D')
9244 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9245 assert_equal(0, v:shell_error)
9246enddef
9247
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009248" Test for 'final' class and object variables
9249def Test_final_class_object_variable()
9250 # Test for changing a final object variable from an object function
9251 var lines =<< trim END
9252 vim9script
9253 class A
9254 final foo: string = "abc"
9255 def Foo()
9256 this.foo = "def"
9257 enddef
9258 endclass
9259 defcompile A.Foo
9260 END
9261 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9262
9263 # Test for changing a final object variable from the 'new' function
9264 lines =<< trim END
9265 vim9script
9266 class A
9267 final s1: string
9268 final s2: string
9269 def new(this.s1)
9270 this.s2 = 'def'
9271 enddef
9272 endclass
9273 var a = A.new('abc')
9274 assert_equal('abc', a.s1)
9275 assert_equal('def', a.s2)
9276 END
9277 v9.CheckSourceSuccess(lines)
9278
9279 # Test for a final class variable
9280 lines =<< trim END
9281 vim9script
9282 class A
9283 static final s1: string = "abc"
9284 endclass
9285 assert_equal('abc', A.s1)
9286 END
9287 v9.CheckSourceSuccess(lines)
9288
9289 # Test for changing a final class variable from a class function
9290 lines =<< trim END
9291 vim9script
9292 class A
9293 static final s1: string = "abc"
9294 static def Foo()
9295 s1 = "def"
9296 enddef
9297 endclass
9298 A.Foo()
9299 END
9300 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9301
9302 # Test for changing a public final class variable at script level
9303 lines =<< trim END
9304 vim9script
9305 class A
9306 public static final s1: string = "abc"
9307 endclass
9308 assert_equal('abc', A.s1)
9309 A.s1 = 'def'
9310 END
9311 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9312
9313 # Test for changing a public final class variable from a class function
9314 lines =<< trim END
9315 vim9script
9316 class A
9317 public static final s1: string = "abc"
9318 static def Foo()
9319 s1 = "def"
9320 enddef
9321 endclass
9322 A.Foo()
9323 END
9324 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9325
9326 # Test for changing a public final class variable from a function
9327 lines =<< trim END
9328 vim9script
9329 class A
9330 public static final s1: string = "abc"
9331 endclass
9332 def Foo()
9333 A.s1 = 'def'
9334 enddef
9335 defcompile
9336 END
9337 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9338
9339 # Test for using a final variable of composite type
9340 lines =<< trim END
9341 vim9script
9342 class A
9343 public final l: list<number>
9344 def new()
9345 this.l = [1, 2]
9346 enddef
9347 def Foo()
9348 this.l[0] = 3
9349 this.l->add(4)
9350 enddef
9351 endclass
9352 var a = A.new()
9353 assert_equal([1, 2], a.l)
9354 a.Foo()
9355 assert_equal([3, 2, 4], a.l)
9356 END
9357 v9.CheckSourceSuccess(lines)
9358
9359 # Test for changing a final variable of composite type from another object
9360 # function
9361 lines =<< trim END
9362 vim9script
9363 class A
9364 public final l: list<number> = [1, 2]
9365 def Foo()
9366 this.l = [3, 4]
9367 enddef
9368 endclass
9369 var a = A.new()
9370 a.Foo()
9371 END
9372 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9373
9374 # Test for modifying a final variable of composite type at script level
9375 lines =<< trim END
9376 vim9script
9377 class A
9378 public final l: list<number> = [1, 2]
9379 endclass
9380 var a = A.new()
9381 a.l[0] = 3
9382 a.l->add(4)
9383 assert_equal([3, 2, 4], a.l)
9384 END
9385 v9.CheckSourceSuccess(lines)
9386
9387 # Test for modifying a final variable of composite type from a function
9388 lines =<< trim END
9389 vim9script
9390 class A
9391 public final l: list<number> = [1, 2]
9392 endclass
9393 def Foo()
9394 var a = A.new()
9395 a.l[0] = 3
9396 a.l->add(4)
9397 assert_equal([3, 2, 4], a.l)
9398 enddef
9399 Foo()
9400 END
9401 v9.CheckSourceSuccess(lines)
9402
9403 # Test for modifying a final variable of composite type from another object
9404 # function
9405 lines =<< trim END
9406 vim9script
9407 class A
9408 public final l: list<number> = [1, 2]
9409 def Foo()
9410 this.l[0] = 3
9411 this.l->add(4)
9412 enddef
9413 endclass
9414 var a = A.new()
9415 a.Foo()
9416 assert_equal([3, 2, 4], a.l)
9417 END
9418 v9.CheckSourceSuccess(lines)
9419
9420 # Test for assigning a new value to a final variable of composite type at
9421 # script level
9422 lines =<< trim END
9423 vim9script
9424 class A
9425 public final l: list<number> = [1, 2]
9426 endclass
9427 var a = A.new()
9428 a.l = [3, 4]
9429 END
9430 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9431
9432 # Test for assigning a new value to a final variable of composite type from
9433 # another object function
9434 lines =<< trim END
9435 vim9script
9436 class A
9437 public final l: list<number> = [1, 2]
9438 def Foo()
9439 this.l = [3, 4]
9440 enddef
9441 endclass
9442 var a = A.new()
9443 a.Foo()
9444 END
9445 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9446
9447 # Test for assigning a new value to a final variable of composite type from
9448 # another function
9449 lines =<< trim END
9450 vim9script
9451 class A
9452 public final l: list<number> = [1, 2]
9453 endclass
9454 def Foo()
9455 var a = A.new()
9456 a.l = [3, 4]
9457 enddef
9458 Foo()
9459 END
9460 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9461
9462 # Error case: Use 'final' with just a variable name
9463 lines =<< trim END
9464 vim9script
9465 class A
9466 final foo
9467 endclass
9468 var a = A.new()
9469 END
9470 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9471
9472 # Error case: Use 'final' followed by 'public'
9473 lines =<< trim END
9474 vim9script
9475 class A
9476 final public foo: number
9477 endclass
9478 var a = A.new()
9479 END
9480 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9481
9482 # Error case: Use 'final' followed by 'static'
9483 lines =<< trim END
9484 vim9script
9485 class A
9486 final static foo: number
9487 endclass
9488 var a = A.new()
9489 END
9490 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9491
9492 # Error case: 'final' cannot be used in an interface
9493 lines =<< trim END
9494 vim9script
9495 interface A
9496 final foo: number = 10
9497 endinterface
9498 END
9499 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9500
9501 # Error case: 'final' not supported for an object method
9502 lines =<< trim END
9503 vim9script
9504 class A
9505 final def Foo()
9506 enddef
9507 endclass
9508 END
9509 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9510
9511 # Error case: 'final' not supported for a class method
9512 lines =<< trim END
9513 vim9script
9514 class A
9515 static final def Foo()
9516 enddef
9517 endclass
9518 END
9519 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9520enddef
9521
9522" Test for 'const' class and object variables
9523def Test_const_class_object_variable()
9524 # Test for changing a const object variable from an object function
9525 var lines =<< trim END
9526 vim9script
9527 class A
9528 const foo: string = "abc"
9529 def Foo()
9530 this.foo = "def"
9531 enddef
9532 endclass
9533 defcompile A.Foo
9534 END
9535 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9536
9537 # Test for changing a const object variable from the 'new' function
9538 lines =<< trim END
9539 vim9script
9540 class A
9541 const s1: string
9542 const s2: string
9543 def new(this.s1)
9544 this.s2 = 'def'
9545 enddef
9546 endclass
9547 var a = A.new('abc')
9548 assert_equal('abc', a.s1)
9549 assert_equal('def', a.s2)
9550 END
9551 v9.CheckSourceSuccess(lines)
9552
9553 # Test for changing a const object variable from an object method called from
9554 # the 'new' function
9555 lines =<< trim END
9556 vim9script
9557 class A
9558 const s1: string = 'abc'
9559 def new()
9560 this.ChangeStr()
9561 enddef
9562 def ChangeStr()
9563 this.s1 = 'def'
9564 enddef
9565 endclass
9566 var a = A.new()
9567 END
9568 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9569
9570 # Test for a const class variable
9571 lines =<< trim END
9572 vim9script
9573 class A
9574 static const s1: string = "abc"
9575 endclass
9576 assert_equal('abc', A.s1)
9577 END
9578 v9.CheckSourceSuccess(lines)
9579
9580 # Test for changing a const class variable from a class function
9581 lines =<< trim END
9582 vim9script
9583 class A
9584 static const s1: string = "abc"
9585 static def Foo()
9586 s1 = "def"
9587 enddef
9588 endclass
9589 A.Foo()
9590 END
9591 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9592
9593 # Test for changing a public const class variable at script level
9594 lines =<< trim END
9595 vim9script
9596 class A
9597 public static const s1: string = "abc"
9598 endclass
9599 assert_equal('abc', A.s1)
9600 A.s1 = 'def'
9601 END
9602 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9603
9604 # Test for changing a public const class variable from a class function
9605 lines =<< trim END
9606 vim9script
9607 class A
9608 public static const s1: string = "abc"
9609 static def Foo()
9610 s1 = "def"
9611 enddef
9612 endclass
9613 A.Foo()
9614 END
9615 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9616
9617 # Test for changing a public const class variable from a function
9618 lines =<< trim END
9619 vim9script
9620 class A
9621 public static const s1: string = "abc"
9622 endclass
9623 def Foo()
9624 A.s1 = 'def'
9625 enddef
9626 defcompile
9627 END
9628 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9629
9630 # Test for changing a const List item from an object function
9631 lines =<< trim END
9632 vim9script
9633 class A
9634 public const l: list<number>
9635 def new()
9636 this.l = [1, 2]
9637 enddef
9638 def Foo()
9639 this.l[0] = 3
9640 enddef
9641 endclass
9642 var a = A.new()
9643 assert_equal([1, 2], a.l)
9644 a.Foo()
9645 END
9646 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9647
9648 # Test for adding a value to a const List from an object function
9649 lines =<< trim END
9650 vim9script
9651 class A
9652 public const l: list<number>
9653 def new()
9654 this.l = [1, 2]
9655 enddef
9656 def Foo()
9657 this.l->add(3)
9658 enddef
9659 endclass
9660 var a = A.new()
9661 a.Foo()
9662 END
9663 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9664
9665 # Test for reassigning a const List from an object function
9666 lines =<< trim END
9667 vim9script
9668 class A
9669 public const l: list<number> = [1, 2]
9670 def Foo()
9671 this.l = [3, 4]
9672 enddef
9673 endclass
9674 var a = A.new()
9675 a.Foo()
9676 END
9677 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9678
9679 # Test for changing a const List item at script level
9680 lines =<< trim END
9681 vim9script
9682 class A
9683 public const l: list<number> = [1, 2]
9684 endclass
9685 var a = A.new()
9686 a.l[0] = 3
9687 END
9688 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9689
9690 # Test for adding a value to a const List item at script level
9691 lines =<< trim END
9692 vim9script
9693 class A
9694 public const l: list<number> = [1, 2]
9695 endclass
9696 var a = A.new()
9697 a.l->add(4)
9698 END
9699 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9700
9701 # Test for changing a const List item from a function
9702 lines =<< trim END
9703 vim9script
9704 class A
9705 public const l: list<number> = [1, 2]
9706 endclass
9707 def Foo()
9708 var a = A.new()
9709 a.l[0] = 3
9710 enddef
9711 Foo()
9712 END
9713 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9714
9715 # Test for adding a value to a const List item from a function
9716 lines =<< trim END
9717 vim9script
9718 class A
9719 public const l: list<number> = [1, 2]
9720 endclass
9721 def Foo()
9722 var a = A.new()
9723 a.l->add(4)
9724 enddef
9725 Foo()
9726 END
9727 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9728
9729 # Test for changing a const List item from an object method
9730 lines =<< trim END
9731 vim9script
9732 class A
9733 public const l: list<number> = [1, 2]
9734 def Foo()
9735 this.l[0] = 3
9736 enddef
9737 endclass
9738 var a = A.new()
9739 a.Foo()
9740 END
9741 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9742
9743 # Test for adding a value to a const List item from an object method
9744 lines =<< trim END
9745 vim9script
9746 class A
9747 public const l: list<number> = [1, 2]
9748 def Foo()
9749 this.l->add(4)
9750 enddef
9751 endclass
9752 var a = A.new()
9753 a.Foo()
9754 END
9755 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9756
9757 # Test for reassigning a const List object variable at script level
9758 lines =<< trim END
9759 vim9script
9760 class A
9761 public const l: list<number> = [1, 2]
9762 endclass
9763 var a = A.new()
9764 a.l = [3, 4]
9765 END
9766 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9767
9768 # Test for reassigning a const List object variable from an object method
9769 lines =<< trim END
9770 vim9script
9771 class A
9772 public const l: list<number> = [1, 2]
9773 def Foo()
9774 this.l = [3, 4]
9775 enddef
9776 endclass
9777 var a = A.new()
9778 a.Foo()
9779 END
9780 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9781
9782 # Test for reassigning a const List object variable from another function
9783 lines =<< trim END
9784 vim9script
9785 class A
9786 public const l: list<number> = [1, 2]
9787 endclass
9788 def Foo()
9789 var a = A.new()
9790 a.l = [3, 4]
9791 enddef
9792 Foo()
9793 END
9794 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9795
9796 # Error case: Use 'const' with just a variable name
9797 lines =<< trim END
9798 vim9script
9799 class A
9800 const foo
9801 endclass
9802 var a = A.new()
9803 END
9804 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9805
9806 # Error case: Use 'const' followed by 'public'
9807 lines =<< trim END
9808 vim9script
9809 class A
9810 const public foo: number
9811 endclass
9812 var a = A.new()
9813 END
9814 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9815
9816 # Error case: Use 'const' followed by 'static'
9817 lines =<< trim END
9818 vim9script
9819 class A
9820 const static foo: number
9821 endclass
9822 var a = A.new()
9823 END
9824 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9825
9826 # Error case: 'const' cannot be used in an interface
9827 lines =<< trim END
9828 vim9script
9829 interface A
9830 const foo: number = 10
9831 endinterface
9832 END
9833 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9834
9835 # Error case: 'const' not supported for an object method
9836 lines =<< trim END
9837 vim9script
9838 class A
9839 const def Foo()
9840 enddef
9841 endclass
9842 END
9843 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9844
9845 # Error case: 'const' not supported for a class method
9846 lines =<< trim END
9847 vim9script
9848 class A
9849 static const def Foo()
9850 enddef
9851 endclass
9852 END
9853 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9854enddef
9855
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009856" Test for compiling class/object methods using :defcompile
9857def Test_defcompile_class()
9858 # defcompile all the classes in the current script
9859 var lines =<< trim END
9860 vim9script
9861 class A
9862 def Foo()
9863 var i = 10
9864 enddef
9865 endclass
9866 class B
9867 def Bar()
9868 var i = 20
9869 xxx
9870 enddef
9871 endclass
9872 defcompile
9873 END
9874 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9875
9876 # defcompile a specific class
9877 lines =<< trim END
9878 vim9script
9879 class A
9880 def Foo()
9881 xxx
9882 enddef
9883 endclass
9884 class B
9885 def Bar()
9886 yyy
9887 enddef
9888 endclass
9889 defcompile B
9890 END
9891 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9892
9893 # defcompile a non-class
9894 lines =<< trim END
9895 vim9script
9896 class A
9897 def Foo()
9898 enddef
9899 endclass
9900 var X: list<number> = []
9901 defcompile X
9902 END
9903 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9904
9905 # defcompile a class twice
9906 lines =<< trim END
9907 vim9script
9908 class A
9909 def new()
9910 enddef
9911 endclass
9912 defcompile A
9913 defcompile A
9914 assert_equal('Function A.new does not need compiling', v:statusmsg)
9915 END
9916 v9.CheckSourceSuccess(lines)
9917
9918 # defcompile should not compile an imported class
9919 lines =<< trim END
9920 vim9script
9921 export class A
9922 def Foo()
9923 xxx
9924 enddef
9925 endclass
9926 END
9927 writefile(lines, 'Xdefcompileimport.vim', 'D')
9928 lines =<< trim END
9929 vim9script
9930
9931 import './Xdefcompileimport.vim'
9932 class B
9933 endclass
9934 defcompile
9935 END
9936 v9.CheckScriptSuccess(lines)
9937enddef
9938
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +01009939" Test for cases common to all the object builtin methods
9940def Test_object_builtin_method()
9941 var lines =<< trim END
9942 vim9script
9943 class A
9944 def abc()
9945 enddef
9946 endclass
9947 END
9948 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
9949
9950 for funcname in ["len", "string", "empty"]
9951 lines =<< trim eval END
9952 vim9script
9953 class A
9954 static def {funcname}(): number
9955 enddef
9956 endclass
9957 END
9958 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
9959 endfor
9960enddef
9961
9962" Test for using the empty() builtin method with an object
9963" This is a legacy function to use the test_garbagecollect_now() function.
9964func Test_object_empty()
9965 let lines =<< trim END
9966 vim9script
9967 class A
9968 def empty(): bool
9969 return true
9970 enddef
9971 endclass
9972
9973 def Foo()
9974 var afoo = A.new()
9975 assert_equal(true, empty(afoo))
9976 assert_equal(true, afoo->empty())
9977 enddef
9978
9979 var a = A.new()
9980 assert_equal(1, empty(a))
9981 assert_equal(1, a->empty())
9982 test_garbagecollect_now()
9983 assert_equal(1, empty(a))
9984 Foo()
9985 test_garbagecollect_now()
9986 Foo()
9987 END
9988 call v9.CheckSourceSuccess(lines)
9989
9990 " empty() should return 1 without a builtin method
9991 let lines =<< trim END
9992 vim9script
9993 class A
9994 endclass
9995
9996 def Foo()
9997 var afoo = A.new()
9998 assert_equal(1, empty(afoo))
9999 enddef
10000
10001 var a = A.new()
10002 assert_equal(1, empty(a))
10003 Foo()
10004 END
10005 call v9.CheckSourceSuccess(lines)
10006
10007 " Unsupported signature for the empty() method
10008 let lines =<< trim END
10009 vim9script
10010 class A
10011 def empty()
10012 enddef
10013 endclass
10014 END
10015 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
10016
10017 " Error when calling the empty() method
10018 let lines =<< trim END
10019 vim9script
10020 class A
10021 def empty(): bool
10022 throw "Failed to check emptiness"
10023 enddef
10024 endclass
10025
10026 def Foo()
10027 var afoo = A.new()
10028 var i = empty(afoo)
10029 enddef
10030
10031 var a = A.new()
10032 assert_fails('empty(a)', 'Failed to check emptiness')
10033 assert_fails('Foo()', 'Failed to check emptiness')
10034 END
10035 call v9.CheckSourceSuccess(lines)
10036
10037 " call empty() using an object from a script
10038 let lines =<< trim END
10039 vim9script
10040 class A
10041 def empty(): bool
10042 return true
10043 enddef
10044 endclass
10045 var afoo = A.new()
10046 assert_equal(true, afoo.empty())
10047 END
10048 call v9.CheckSourceSuccess(lines)
10049
10050 " call empty() using an object from a method
10051 let lines =<< trim END
10052 vim9script
10053 class A
10054 def empty(): bool
10055 return true
10056 enddef
10057 endclass
10058 def Foo()
10059 var afoo = A.new()
10060 assert_equal(true, afoo.empty())
10061 enddef
10062 Foo()
10063 END
10064 call v9.CheckSourceSuccess(lines)
10065
10066 " call empty() using "this" from an object method
10067 let lines =<< trim END
10068 vim9script
10069 class A
10070 def empty(): bool
10071 return true
10072 enddef
10073 def Foo(): bool
10074 return this.empty()
10075 enddef
10076 endclass
10077 def Bar()
10078 var abar = A.new()
10079 assert_equal(true, abar.Foo())
10080 enddef
10081 Bar()
10082 END
10083 call v9.CheckSourceSuccess(lines)
10084
10085 " Call empty() from a derived object
10086 let lines =<< trim END
10087 vim9script
10088 class A
10089 def empty(): bool
10090 return false
10091 enddef
10092 endclass
10093 class B extends A
10094 def empty(): bool
10095 return true
10096 enddef
10097 endclass
10098 def Foo(afoo: A)
10099 assert_equal(true, empty(afoo))
10100 var bfoo = B.new()
10101 assert_equal(true, empty(bfoo))
10102 enddef
10103 var b = B.new()
10104 assert_equal(1, empty(b))
10105 Foo(b)
10106 END
10107 call v9.CheckSourceSuccess(lines)
10108
10109 " Invoking empty method using an interface
10110 let lines =<< trim END
10111 vim9script
10112 interface A
10113 def empty(): bool
10114 endinterface
10115 class B implements A
10116 def empty(): bool
10117 return false
10118 enddef
10119 endclass
10120 def Foo(a: A)
10121 assert_equal(false, empty(a))
10122 enddef
10123 var b = B.new()
10124 Foo(b)
10125 END
10126 call v9.CheckSourceSuccess(lines)
10127endfunc
10128
10129" Test for using the len() builtin method with an object
10130" This is a legacy function to use the test_garbagecollect_now() function.
10131func Test_object_length()
10132 let lines =<< trim END
10133 vim9script
10134 class A
10135 var mylen: number = 0
10136 def new(n: number)
10137 this.mylen = n
10138 enddef
10139 def len(): number
10140 return this.mylen
10141 enddef
10142 endclass
10143
10144 def Foo()
10145 var afoo = A.new(12)
10146 assert_equal(12, len(afoo))
10147 assert_equal(12, afoo->len())
10148 enddef
10149
10150 var a = A.new(22)
10151 assert_equal(22, len(a))
10152 assert_equal(22, a->len())
10153 test_garbagecollect_now()
10154 assert_equal(22, len(a))
10155 Foo()
10156 test_garbagecollect_now()
10157 Foo()
10158 END
10159 call v9.CheckSourceSuccess(lines)
10160
10161 " len() should return 0 without a builtin method
10162 let lines =<< trim END
10163 vim9script
10164 class A
10165 endclass
10166
10167 def Foo()
10168 var afoo = A.new()
10169 assert_equal(0, len(afoo))
10170 enddef
10171
10172 var a = A.new()
10173 assert_equal(0, len(a))
10174 Foo()
10175 END
10176 call v9.CheckSourceSuccess(lines)
10177
10178 " Unsupported signature for the len() method
10179 let lines =<< trim END
10180 vim9script
10181 class A
10182 def len()
10183 enddef
10184 endclass
10185 END
10186 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10187
10188 " Error when calling the len() method
10189 let lines =<< trim END
10190 vim9script
10191 class A
10192 def len(): number
10193 throw "Failed to compute length"
10194 enddef
10195 endclass
10196
10197 def Foo()
10198 var afoo = A.new()
10199 var i = len(afoo)
10200 enddef
10201
10202 var a = A.new()
10203 assert_fails('len(a)', 'Failed to compute length')
10204 assert_fails('Foo()', 'Failed to compute length')
10205 END
10206 call v9.CheckSourceSuccess(lines)
10207
10208 " call len() using an object from a script
10209 let lines =<< trim END
10210 vim9script
10211 class A
10212 def len(): number
10213 return 5
10214 enddef
10215 endclass
10216 var afoo = A.new()
10217 assert_equal(5, afoo.len())
10218 END
10219 call v9.CheckSourceSuccess(lines)
10220
10221 " call len() using an object from a method
10222 let lines =<< trim END
10223 vim9script
10224 class A
10225 def len(): number
10226 return 5
10227 enddef
10228 endclass
10229 def Foo()
10230 var afoo = A.new()
10231 assert_equal(5, afoo.len())
10232 enddef
10233 Foo()
10234 END
10235 call v9.CheckSourceSuccess(lines)
10236
10237 " call len() using "this" from an object method
10238 let lines =<< trim END
10239 vim9script
10240 class A
10241 def len(): number
10242 return 8
10243 enddef
10244 def Foo(): number
10245 return this.len()
10246 enddef
10247 endclass
10248 def Bar()
10249 var abar = A.new()
10250 assert_equal(8, abar.Foo())
10251 enddef
10252 Bar()
10253 END
10254 call v9.CheckSourceSuccess(lines)
10255
10256 " Call len() from a derived object
10257 let lines =<< trim END
10258 vim9script
10259 class A
10260 def len(): number
10261 return 10
10262 enddef
10263 endclass
10264 class B extends A
10265 def len(): number
10266 return 20
10267 enddef
10268 endclass
10269 def Foo(afoo: A)
10270 assert_equal(20, len(afoo))
10271 var bfoo = B.new()
10272 assert_equal(20, len(bfoo))
10273 enddef
10274 var b = B.new()
10275 assert_equal(20, len(b))
10276 Foo(b)
10277 END
10278 call v9.CheckSourceSuccess(lines)
10279
10280 " Invoking len method using an interface
10281 let lines =<< trim END
10282 vim9script
10283 interface A
10284 def len(): number
10285 endinterface
10286 class B implements A
10287 def len(): number
10288 return 123
10289 enddef
10290 endclass
10291 def Foo(a: A)
10292 assert_equal(123, len(a))
10293 enddef
10294 var b = B.new()
10295 Foo(b)
10296 END
10297 call v9.CheckSourceSuccess(lines)
10298endfunc
10299
10300" Test for using the string() builtin method with an object
10301" This is a legacy function to use the test_garbagecollect_now() function.
10302func Test_object_string()
10303 let lines =<< trim END
10304 vim9script
10305 class A
10306 var name: string
10307 def string(): string
10308 return this.name
10309 enddef
10310 endclass
10311
10312 def Foo()
10313 var afoo = A.new("foo-A")
10314 assert_equal('foo-A', string(afoo))
10315 assert_equal('foo-A', afoo->string())
10316 enddef
10317
10318 var a = A.new("script-A")
10319 assert_equal('script-A', string(a))
10320 assert_equal('script-A', a->string())
10321 assert_equal(['script-A'], execute('echo a')->split("\n"))
10322 test_garbagecollect_now()
10323 assert_equal('script-A', string(a))
10324 Foo()
10325 test_garbagecollect_now()
10326 Foo()
10327 END
10328 call v9.CheckSourceSuccess(lines)
10329
10330 " string() should return "object of A {}" without a builtin method
10331 let lines =<< trim END
10332 vim9script
10333 class A
10334 endclass
10335
10336 def Foo()
10337 var afoo = A.new()
10338 assert_equal('object of A {}', string(afoo))
10339 enddef
10340
10341 var a = A.new()
10342 assert_equal('object of A {}', string(a))
10343 Foo()
10344 END
10345 call v9.CheckSourceSuccess(lines)
10346
10347 " Unsupported signature for the string() method
10348 let lines =<< trim END
10349 vim9script
10350 class A
10351 def string()
10352 enddef
10353 endclass
10354 END
10355 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10356
10357 " Error when calling the string() method
10358 let lines =<< trim END
10359 vim9script
10360 class A
10361 def string(): string
10362 throw "Failed to get text"
10363 enddef
10364 endclass
10365
10366 def Foo()
10367 var afoo = A.new()
10368 var i = string(afoo)
10369 enddef
10370
10371 var a = A.new()
10372 assert_fails('string(a)', 'Failed to get text')
10373 assert_fails('Foo()', 'Failed to get text')
10374 END
10375 call v9.CheckSourceSuccess(lines)
10376
10377 " call string() using an object from a script
10378 let lines =<< trim END
10379 vim9script
10380 class A
10381 def string(): string
10382 return 'A'
10383 enddef
10384 endclass
10385 var afoo = A.new()
10386 assert_equal('A', afoo.string())
10387 END
10388 call v9.CheckSourceSuccess(lines)
10389
10390 " call string() using an object from a method
10391 let lines =<< trim END
10392 vim9script
10393 class A
10394 def string(): string
10395 return 'A'
10396 enddef
10397 endclass
10398 def Foo()
10399 var afoo = A.new()
10400 assert_equal('A', afoo.string())
10401 enddef
10402 Foo()
10403 END
10404 call v9.CheckSourceSuccess(lines)
10405
10406 " call string() using "this" from an object method
10407 let lines =<< trim END
10408 vim9script
10409 class A
10410 def string(): string
10411 return 'A'
10412 enddef
10413 def Foo(): string
10414 return this.string()
10415 enddef
10416 endclass
10417 def Bar()
10418 var abar = A.new()
10419 assert_equal('A', abar.string())
10420 enddef
10421 Bar()
10422 END
10423 call v9.CheckSourceSuccess(lines)
10424
10425 " Call string() from a derived object
10426 let lines =<< trim END
10427 vim9script
10428 class A
10429 def string(): string
10430 return 'A'
10431 enddef
10432 endclass
10433 class B extends A
10434 def string(): string
10435 return 'B'
10436 enddef
10437 endclass
10438 def Foo(afoo: A)
10439 assert_equal('B', string(afoo))
10440 var bfoo = B.new()
10441 assert_equal('B', string(bfoo))
10442 enddef
10443 var b = B.new()
10444 assert_equal('B', string(b))
10445 Foo(b)
10446 END
10447 call v9.CheckSourceSuccess(lines)
10448
10449 " Invoking string method using an interface
10450 let lines =<< trim END
10451 vim9script
10452 interface A
10453 def string(): string
10454 endinterface
10455 class B implements A
10456 def string(): string
10457 return 'B'
10458 enddef
10459 endclass
10460 def Foo(a: A)
10461 assert_equal('B', string(a))
10462 enddef
10463 var b = B.new()
10464 Foo(b)
10465 END
10466 call v9.CheckSourceSuccess(lines)
10467endfunc
10468
Ernie Rael9d779c52024-07-07 20:41:44 +020010469" Test for using the string() builtin method with an object's method
10470def Test_method_string()
10471 var lines =<< trim END
10472 vim9script
10473 class A
10474 def F()
10475 enddef
10476 endclass
10477 assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F))
10478 END
10479 v9.CheckScriptSuccess(lines)
10480enddef
10481
10482
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010483" Test for using a class in the class definition
10484def Test_Ref_Class_Within_Same_Class()
10485 var lines =<< trim END
10486 vim9script
10487 class A
10488 var n: number = 0
10489 def Equals(other: A): bool
10490 return this.n == other.n
10491 enddef
10492 endclass
10493
10494 var a1 = A.new(10)
10495 var a2 = A.new(10)
10496 var a3 = A.new(20)
10497 assert_equal(true, a1.Equals(a2))
10498 assert_equal(false, a2.Equals(a3))
10499 END
10500 v9.CheckScriptSuccess(lines)
10501
10502 lines =<< trim END
10503 vim9script
10504
10505 class Foo
10506 var num: number
10507 def Clone(): Foo
10508 return Foo.new(this.num)
10509 enddef
10510 endclass
10511
10512 var f1 = Foo.new(1)
10513
10514 def F()
10515 var f2: Foo = f1.Clone()
10516 assert_equal(false, f2 is f1)
10517 assert_equal(true, f2.num == f1.num)
10518 enddef
10519 F()
10520
10521 var f3: Foo = f1.Clone()
10522 assert_equal(false, f3 is f1)
10523 assert_equal(true, f3.num == f1.num)
10524 END
10525 v9.CheckScriptSuccess(lines)
10526
10527 # Test for trying to use a class to extend when defining the same class
10528 lines =<< trim END
10529 vim9script
10530 class A extends A
10531 endclass
10532 END
10533 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10534
10535 # Test for trying to use a class to implement when defining the same class
10536 lines =<< trim END
10537 vim9script
10538 class A implements A
10539 endclass
10540 END
10541 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10542enddef
10543
Ernie Raelf0e69142024-06-22 11:12:00 +020010544" Test for comparing a class referencing itself
10545def Test_Object_Compare_With_Recursive_Class_Ref()
10546 var lines =<< trim END
10547 vim9script
10548
10549 class C
10550 public var nest: C
10551 endclass
10552
10553 var o1 = C.new()
10554 o1.nest = o1
10555
10556 var result = o1 == o1
10557 assert_equal(true, result)
10558 END
10559 v9.CheckScriptSuccess(lines)
Ernie Rael86257142024-06-23 09:54:45 +020010560
10561 lines =<< trim END
10562 vim9script
10563
10564 class C
10565 public var nest: C
10566 endclass
10567 var o1 = C.new()
10568 var o2 = C.new(C.new())
10569
10570 var result = o1 == o2
10571 assert_equal(false, result)
10572 END
10573 v9.CheckScriptSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +020010574
10575 lines =<< trim END
10576 vim9script
10577 class C
10578 var nest1: C
10579 var nest2: C
10580 def Init(n1: C, n2: C)
10581 this.nest1 = n1
10582 this.nest2 = n2
10583 enddef
10584 endclass
10585
10586 var o1 = C.new()
10587 var o2 = C.new()
10588 o1.Init(o1, o2)
10589 o2.Init(o2, o1)
10590
10591 var result = o1 == o2
10592 assert_equal(true, result)
10593 END
10594 v9.CheckScriptSuccess(lines)
Ernie Raelf0e69142024-06-22 11:12:00 +020010595enddef
10596
Ernie Raelf3975492024-07-06 11:44:37 +020010597" Test for comparing a class with nesting objects
10598def Test_Object_Compare_With_Nesting_Objects()
10599 # On a compare, after vim equal recurses 1000 times, not finding an unequal,
10600 # return the compare is equal.
10601 # Test that limit
10602
10603 var lines =<< trim END
10604 vim9script
10605 class C
10606 public var n: number
10607 public var nest: C
10608
10609 # Create a "C" that chains/nests to indicated depth.
10610 # return {head: firstC, tail: lastC}
10611 static def CreateNested(depth: number): dict<C>
10612 var first = C.new(1, null_object)
10613 var last = first
10614 for i in range(2, depth)
10615 last.nest = C.new(i, null_object)
10616 last = last.nest
10617 endfor
10618 return {head: first, tail: last}
10619 enddef
10620
10621 # Return pointer to nth item in chain.
10622 def GetLink(depth: number): C
10623 var count = 1
10624 var p: C = this
10625 while count < depth
10626 p = p.nest
10627 if p == null
10628 throw "too deep"
10629 endif
10630 count += 1
10631 endwhile
10632 return p
10633 enddef
10634
10635 # Return the length of the chain
10636 def len(): number
10637 var count = 1
10638 var p: C = this
10639 while p.nest != null
10640 p = p.nest
10641 count += 1
10642 endwhile
10643 return count
10644 enddef
10645 endclass
10646
10647 var chain = C.CreateNested(3)
10648 var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}"
10649 assert_equal(s, string(chain.head))
10650 assert_equal(3, chain.head->len())
10651
10652 var chain1 = C.CreateNested(100)
10653 var chain2 = C.CreateNested(100)
10654 assert_true(chain1.head == chain2.head)
10655
10656 # modify the tail of chain2, compare not equal
10657 chain2.tail.n = 123456
10658 assert_true(chain1.head != chain2.head)
10659
10660 # a tail of a different length compares not equal
10661 chain2 = C.CreateNested(101)
10662 assert_true(chain1.head != chain2.head)
10663
10664 chain1 = C.CreateNested(1000)
10665 chain2 = C.CreateNested(1000)
10666 assert_true(chain1.head == chain2.head)
10667
10668 # modify the tail of chain2, compare not equal
10669 chain2.tail.n = 123456
10670 assert_true(chain1.head != chain2.head)
10671
10672 # try a chain longer that the limit
10673 chain1 = C.CreateNested(1001)
10674 chain2 = C.CreateNested(1001)
10675 assert_true(chain1.head == chain2.head)
10676
10677 # modify the tail, but still equal
10678 chain2.tail.n = 123456
10679 assert_true(chain1.head == chain2.head)
10680
10681 # remove 2 items from front, shorten the chain by two.
10682 chain1.head = chain1.head.GetLink(3)
10683 chain2.head = chain2.head.GetLink(3)
10684 assert_equal(3, chain1.head.n)
10685 assert_equal(3, chain2.head.n)
10686 assert_equal(999, chain1.head->len())
10687 assert_equal(999, chain2.head->len())
10688 # Now less than the limit, compare not equal
10689 assert_true(chain1.head != chain2.head)
10690 END
10691 v9.CheckScriptSuccess(lines)
10692enddef
10693
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010694" Test for using a compound operator from a lambda function in an object method
10695def Test_compound_op_in_objmethod_lambda()
10696 # Test using the "+=" operator
10697 var lines =<< trim END
10698 vim9script
10699 class A
10700 var n: number = 10
10701 def Foo()
10702 var Fn = () => {
10703 this.n += 1
10704 }
10705 Fn()
10706 enddef
10707 endclass
10708
10709 var a = A.new()
10710 a.Foo()
10711 assert_equal(11, a.n)
10712 END
10713 v9.CheckScriptSuccess(lines)
10714
10715 # Test using the "..=" operator
10716 lines =<< trim END
10717 vim9script
10718 class A
10719 var s: string = "a"
10720 def Foo()
10721 var Fn = () => {
10722 this.s ..= "a"
10723 }
10724 Fn()
10725 enddef
10726 endclass
10727
10728 var a = A.new()
10729 a.Foo()
10730 a.Foo()
10731 assert_equal("aaa", a.s)
10732 END
10733 v9.CheckScriptSuccess(lines)
10734enddef
10735
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010736" Test for using test_refcount() with a class and an object
10737def Test_class_object_refcount()
10738 var lines =<< trim END
10739 vim9script
10740 class A
10741 endclass
10742 var a: A = A.new()
10743 assert_equal(2, test_refcount(A))
10744 assert_equal(1, test_refcount(a))
10745 var b = a
10746 assert_equal(2, test_refcount(A))
10747 assert_equal(2, test_refcount(a))
10748 assert_equal(2, test_refcount(b))
10749 END
10750 v9.CheckScriptSuccess(lines)
10751enddef
10752
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010753" call a lambda function in one object from another object
10754def Test_lambda_invocation_across_classes()
10755 var lines =<< trim END
10756 vim9script
10757 class A
10758 var s: string = "foo"
10759 def GetFn(): func
10760 var Fn = (): string => {
10761 return this.s
10762 }
10763 return Fn
10764 enddef
10765 endclass
10766
10767 class B
10768 var s: string = "bar"
10769 def GetFn(): func
10770 var a = A.new()
10771 return a.GetFn()
10772 enddef
10773 endclass
10774
10775 var b = B.new()
10776 var Fn = b.GetFn()
10777 assert_equal("foo", Fn())
10778 END
10779 v9.CheckScriptSuccess(lines)
10780enddef
10781
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010782" Test for using a class member which is an object of the current class
10783def Test_current_class_object_class_member()
10784 var lines =<< trim END
10785 vim9script
10786 class A
10787 public static var obj1: A = A.new(10)
10788 var n: number
10789 endclass
10790 defcompile
10791 assert_equal(10, A.obj1.n)
10792 END
10793 v9.CheckScriptSuccess(lines)
10794enddef
10795
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020010796" Test for updating a base class variable from a base class method without the
10797" class name. This used to crash Vim (Github issue #14352).
10798def Test_use_base_class_variable_from_base_class_method()
10799 var lines =<< trim END
10800 vim9script
10801
10802 class DictKeyClass
10803 static var _obj_id_count = 1
10804 def _GenerateKey()
10805 _obj_id_count += 1
10806 enddef
10807 static def GetIdCount(): number
10808 return _obj_id_count
10809 enddef
10810 endclass
10811
10812 class C extends DictKeyClass
10813 def F()
10814 this._GenerateKey()
10815 enddef
10816 endclass
10817
10818 C.new().F()
10819 assert_equal(2, DictKeyClass.GetIdCount())
10820 END
10821 v9.CheckScriptSuccess(lines)
10822enddef
10823
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020010824" Test for accessing protected funcref object and class variables
10825def Test_protected_funcref()
10826 # protected funcref object variable
10827 var lines =<< trim END
10828 vim9script
10829 class Test1
10830 const _Id: func(any): any = (v) => v
10831 endclass
10832 var n = Test1.new()._Id(1)
10833 END
10834 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
10835
10836 # protected funcref class variable
10837 lines =<< trim END
10838 vim9script
10839 class Test2
10840 static const _Id: func(any): any = (v) => v
10841 endclass
10842 var n = Test2._Id(2)
10843 END
10844 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
10845enddef
10846
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020010847" Test for using lambda block in classes
10848def Test_lambda_block_in_class()
10849 # This used to crash Vim
10850 var lines =<< trim END
10851 vim9script
10852 class IdClass1
10853 const Id: func(number): number = (num: number): number => {
10854 # Return a ID
10855 return num * 10
10856 }
10857 endclass
10858 var id = IdClass1.new()
10859 assert_equal(20, id.Id(2))
10860 END
10861 v9.CheckScriptSuccess(lines)
10862
10863 # This used to crash Vim
10864 lines =<< trim END
10865 vim9script
10866 class IdClass2
10867 static const Id: func(number): number = (num: number): number => {
10868 # Return a ID
10869 return num * 2
10870 }
10871 endclass
10872 assert_equal(16, IdClass2.Id(8))
10873 END
10874 v9.CheckScriptSuccess(lines)
10875enddef
10876
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020010877" Test for defcompiling an abstract method
10878def Test_abstract_method_defcompile()
10879 # Compile an abstract class with abstract object methods
10880 var lines =<< trim END
10881 vim9script
10882 abstract class A
10883 abstract def Foo(): string
10884 abstract def Bar(): list<string>
10885 endclass
10886 defcompile
10887 END
10888 v9.CheckScriptSuccess(lines)
10889
10890 # Compile a concrete object method in an abstract class
10891 lines =<< trim END
10892 vim9script
10893 abstract class A
10894 abstract def Foo(): string
10895 abstract def Bar(): list<string>
10896 def Baz(): string
10897 pass
10898 enddef
10899 endclass
10900 defcompile
10901 END
10902 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10903
10904 # Compile a concrete class method in an abstract class
10905 lines =<< trim END
10906 vim9script
10907 abstract class A
10908 abstract def Foo(): string
10909 abstract def Bar(): list<string>
10910 static def Baz(): string
10911 pass
10912 enddef
10913 endclass
10914 defcompile
10915 END
10916 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10917enddef
10918
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020010919" Test for defining a class in a function
10920def Test_class_definition_in_a_function()
10921 var lines =<< trim END
10922 vim9script
10923 def Foo()
10924 class A
10925 endclass
10926 enddef
10927 defcompile
10928 END
10929 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
10930enddef
10931
Yegappan Lakshmanandbac0da2024-05-25 20:23:54 +020010932" Test for using [] with a class and an object
10933def Test_class_object_index()
10934 var lines =<< trim END
10935 vim9script
10936 class A
10937 endclass
10938 A[10] = 1
10939 END
10940 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a class: A[10] = 1', 4)
10941
10942 lines =<< trim END
10943 vim9script
10944 class A
10945 endclass
10946 var a = A.new()
10947 a[10] = 1
10948 END
10949 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5)
10950enddef
10951
LemonBoyf4af3312024-07-04 13:43:12 +020010952def Test_class_member_init_typecheck()
10953 # Ensure the class member is assigned its declared type.
10954 var lines =<< trim END
10955 vim9script
10956 class S
10957 static var l: list<string> = []
10958 endclass
10959 S.l->add(123)
10960 END
10961 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5)
10962
10963 # Ensure the initializer value and the declared type match.
10964 lines =<< trim END
10965 vim9script
10966 class S
10967 var l: list<string> = [1, 2, 3]
10968 endclass
10969 var o = S.new()
10970 END
10971 v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>')
10972
10973 # Ensure the class member is assigned its declared type.
10974 lines =<< trim END
10975 vim9script
10976 class S
10977 var l: list<string> = []
10978 endclass
10979 var o = S.new()
10980 o.l->add(123)
10981 END
10982 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6)
10983enddef
10984
LemonBoy50d48542024-07-04 17:03:17 +020010985def Test_class_cast()
10986 var lines =<< trim END
10987 vim9script
10988 class A
10989 endclass
10990 class B extends A
10991 var mylen: number
10992 endclass
10993 def F(o: A): number
10994 return (<B>o).mylen
10995 enddef
10996
10997 defcompile F
10998 END
10999 v9.CheckScriptSuccess(lines)
11000enddef
11001
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011002" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker