blob: 0a48b822df0d6d4b8c5d0a41159804e587c92b37 [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
563 # Test for using a null class with string()
564 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
572def Test_using_null_object()
573 # Test for using a null object as a value
574 var lines =<< trim END
575 vim9script
576 assert_equal(1, empty(null_object))
577 END
578 v9.CheckSourceSuccess(lines)
579
580 # Test for using a null object with string()
581 lines =<< trim END
582 vim9script
583 assert_equal('object of [unknown]', string(null_object))
584 END
585 v9.CheckSourceSuccess(lines)
586
587 # Test for using a null object with string()
588 lines =<< trim END
589 vim9script
590 assert_equal(13, type(null_object))
591 assert_equal('object<Unknown>', typename(null_object))
592 END
593 v9.CheckSourceSuccess(lines)
Bram Moolenaard13dd302023-03-11 20:56:35 +0000594enddef
595
Bram Moolenaar657aea72023-01-27 13:16:19 +0000596def Test_class_interface_wrong_end()
597 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200598 vim9script
599 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100600 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200601 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200603 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000604
605 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200606 vim9script
607 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100608 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200609 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000610 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200611 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000612enddef
613
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000614def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200615 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000616 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200617 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000618
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200619 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100620 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200621 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000622
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200623 var state: State
624 var db = {'xyz': 789}
625 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000626 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200627 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000628
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200629 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000630 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200631 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000632
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200633 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100634 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200635 def Method1()
636 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000637 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200638 endclass
639
640 var obj: Class
641 def Func()
642 obj.Method1()
643 enddef
644 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000645 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200646 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000647
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200648 # Pass an uninitialized object variable to a "new" function and try to call an
649 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000650 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200651 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000652
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200653 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100654 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200655 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000656
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200657 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100658 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000659
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200660 def GetBackground(): string
661 return this._bg.background
662 enddef
663 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000664
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200665 var bg: Background # UNINITIALIZED
666 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000667 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200668 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000669
670 # TODO: this should not give an error but be handled at runtime
671 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200672 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000673
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200674 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100675 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200676 def Method1()
677 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000678 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200679 endclass
680
681 var obj = null_object
682 def Func()
683 obj.Method1()
684 enddef
685 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000686 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200687 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000688enddef
689
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200690" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200691def Test_null_object_assign_compare()
692 var lines =<< trim END
693 vim9script
694
695 var nullo = null_object
696 def F(): any
697 return nullo
698 enddef
699 assert_equal('object<Unknown>', typename(F()))
700
701 var o0 = F()
702 assert_true(o0 == null_object)
703 assert_true(o0 == null)
704
705 var o1: any = nullo
706 assert_true(o1 == null_object)
707 assert_true(o1 == null)
708
709 def G()
710 var x = null_object
711 enddef
712
713 class C
714 endclass
715 var o2: C
716 assert_true(o2 == null_object)
717 assert_true(o2 == null)
718
719 o2 = null_object
720 assert_true(o2 == null)
721
722 o2 = C.new()
723 assert_true(o2 != null)
724
725 o2 = null_object
726 assert_true(o2 == null)
727 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200728 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200729enddef
730
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200731" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000732def Test_class_member_initializer()
733 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200734 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000735
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200736 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100737 var lnum: number = 1
738 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000739
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200740 # constructor with only the line number
741 def new(lnum: number)
742 this.lnum = lnum
743 enddef
744 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000745
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200746 var pos = TextPosition.new(3)
747 assert_equal(3, pos.lnum)
748 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000749
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200750 var instr = execute('disassemble TextPosition.new')
751 assert_match('new\_s*' ..
752 '0 NEW TextPosition size \d\+\_s*' ..
753 '\d PUSHNR 1\_s*' ..
754 '\d STORE_THIS 0\_s*' ..
755 '\d PUSHNR 1\_s*' ..
756 '\d STORE_THIS 1\_s*' ..
757 'this.lnum = lnum\_s*' ..
758 '\d LOAD arg\[-1]\_s*' ..
759 '\d PUSHNR 0\_s*' ..
760 '\d LOAD $0\_s*' ..
761 '\d\+ STOREINDEX object\_s*' ..
762 '\d\+ RETURN object.*',
763 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000764 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200765 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000766enddef
767
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000768def Test_member_any_used_as_object()
769 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200770 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000771
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200772 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100773 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200774 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000775
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200776 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100777 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200778 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000779
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200780 def F(outer: Outer)
781 outer.inner.value = 1
782 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000783
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200784 var inner_obj = Inner.new(0)
785 var outer_obj = Outer.new(inner_obj)
786 F(outer_obj)
787 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200789 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000790
Ernie Rael03042a22023-11-11 08:53:32 +0100791 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200792 lines =<< trim END
793 vim9script
794
795 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100796 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200797 endclass
798
799 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100800 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200801 endclass
802
803 def F(outer: Outer)
804 outer.inner._value = 'b'
805 enddef
806
807 var inner_obj = Inner.new('a')
808 var outer_obj = Outer.new(inner_obj)
809 F(outer_obj)
810 END
Ernie Rael03042a22023-11-11 08:53:32 +0100811 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200812
813 # Try modifying a non-existing variable using an "any" object
814 lines =<< trim END
815 vim9script
816
817 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100818 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200819 endclass
820
821 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100822 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200823 endclass
824
825 def F(outer: Outer)
826 outer.inner.someval = 'b'
827 enddef
828
829 var inner_obj = Inner.new('a')
830 var outer_obj = Outer.new(inner_obj)
831 F(outer_obj)
832 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200833 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000834enddef
835
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200836" Nested assignment to a object variable which is of another class type
837def Test_assignment_nested_type()
838 var lines =<< trim END
839 vim9script
840
841 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100842 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200843 endclass
844
845 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100846 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200847 endclass
848
849 def F(outer: Outer)
850 outer.inner.value = 1
851 enddef
852
853 def Test_assign_to_nested_typed_member()
854 var inner = Inner.new(0)
855 var outer = Outer.new(inner)
856 F(outer)
857 assert_equal(1, inner.value)
858 enddef
859
860 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200861
862 var script_inner = Inner.new(0)
863 var script_outer = Outer.new(script_inner)
864 script_outer.inner.value = 1
865 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200866 END
867 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200868
869 # Assignment where target item is read only in :def
870 lines =<< trim END
871 vim9script
872
873 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100874 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200875 endclass
876
877 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100878 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200879 endclass
880
881 def F(outer: Outer)
882 outer.inner.value = 1
883 enddef
884
885 def Test_assign_to_nested_typed_member()
886 var inner = Inner.new(0)
887 var outer = Outer.new(inner)
888 F(outer)
889 assert_equal(1, inner.value)
890 enddef
891
892 Test_assign_to_nested_typed_member()
893 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200894 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200895
896 # Assignment where target item is read only script level
897 lines =<< trim END
898 vim9script
899
900 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100901 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200902 endclass
903
904 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100905 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200906 endclass
907
908 def F(outer: Outer)
909 outer.inner.value = 1
910 enddef
911
912 var script_inner = Inner.new(0)
913 var script_outer = Outer.new(script_inner)
914 script_outer.inner.value = 1
915 assert_equal(1, script_inner.value)
916 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200917 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200918enddef
919
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000920def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200921 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000922 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200923 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000924
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200925 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100926 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000927
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200928 def Add(n: number)
929 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100930 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200931 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100932
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200933 var f = Foo.new(3)
934 f.Add(17)
935 assert_equal(20, f.x)
936
937 def AddToFoo(obj: Foo)
938 obj.x += 3
939 enddef
940
941 AddToFoo(f)
942 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000943 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200944 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000945enddef
946
Bram Moolenaarf4508042023-01-15 16:54:57 +0000947def Test_list_of_objects()
948 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200949 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000950
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200951 class Foo
952 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000953 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200954 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000955
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200956 def ProcessList(fooList: list<Foo>)
957 for foo in fooList
958 foo.Add()
959 endfor
960 enddef
961
962 var l: list<Foo> = [Foo.new()]
963 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000964 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200965 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000966enddef
967
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000968def Test_expr_after_using_object()
969 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200970 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000971
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200972 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100973 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200974 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000975
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200976 def Foo(): Something
977 var v = Something.new()
978 echo 'in Foo(): ' .. typename(v)
979 return v
980 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000981
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200982 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000983 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200984 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000985enddef
986
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000987def Test_class_default_new()
988 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200989 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000990
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200991 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100992 var lnum: number = 1
993 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200994 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000995
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200996 var pos = TextPosition.new()
997 assert_equal(1, pos.lnum)
998 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000999
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001000 pos = TextPosition.new(v:none, v:none)
1001 assert_equal(1, pos.lnum)
1002 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001003
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001004 pos = TextPosition.new(3, 22)
1005 assert_equal(3, pos.lnum)
1006 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001007
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001008 pos = TextPosition.new(v:none, 33)
1009 assert_equal(1, pos.lnum)
1010 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001011 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001012 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001013
1014 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001015 vim9script
1016 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001017 var name: string
1018 var age: number = 42
1019 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001020
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001021 def new(this.name, this.age = v:none, this.education = v:none)
1022 enddef
1023 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001024
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001025 var piet = Person.new("Piet")
1026 assert_equal("Piet", piet.name)
1027 assert_equal(42, piet.age)
1028 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001029
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001030 var chris = Person.new("Chris", 4, "none")
1031 assert_equal("Chris", chris.name)
1032 assert_equal(4, chris.age)
1033 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001034 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001035 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001036
1037 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001038 vim9script
1039 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001040 var name: string
1041 var age: number = 42
1042 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +00001043
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001044 def new(this.name, this.age = v:none, this.education = v:none)
1045 enddef
1046 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001047
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001048 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +00001049 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001050 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001051
1052 # Using a specific value to initialize an instance variable in the new()
1053 # method.
1054 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001055 vim9script
1056 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001057 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001058 def new(this.val = 'a')
1059 enddef
1060 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001061 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001062 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001063enddef
1064
h-east2261c892023-08-16 21:49:54 +09001065def Test_class_new_with_object_member()
1066 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001067 vim9script
h-east2261c892023-08-16 21:49:54 +09001068
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001069 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001070 var str: string
1071 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001072 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +09001073 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001074 def newVals(this.str, this.num)
1075 enddef
1076 endclass
h-east2261c892023-08-16 21:49:54 +09001077
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001078 def Check()
1079 try
1080 var c = C.new('cats', 2)
1081 assert_equal('cats', c.str)
1082 assert_equal(2, c.num)
1083
1084 c = C.newVals('dogs', 4)
1085 assert_equal('dogs', c.str)
1086 assert_equal(4, c.num)
1087 catch
1088 assert_report($'Unexpected exception was caught: {v:exception}')
1089 endtry
1090 enddef
1091
1092 Check()
h-east2261c892023-08-16 21:49:54 +09001093 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001094 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001095
1096 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001097 vim9script
1098
1099 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001100 var str: string
1101 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001102 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001103 enddef
1104 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001105
1106 def Check()
1107 try
1108 var c = C.new(1, 2)
1109 catch
1110 assert_report($'Unexpected exception was caught: {v:exception}')
1111 endtry
1112 enddef
1113
1114 Check()
h-eastdb385522023-09-28 22:18:19 +02001115 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001116 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001117
1118 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001119 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001120
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001121 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001122 var str: string
1123 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001124 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001125 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001126 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001127
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001128 def Check()
1129 try
1130 var c = C.newVals('dogs', 'apes')
1131 catch
1132 assert_report($'Unexpected exception was caught: {v:exception}')
1133 endtry
1134 enddef
1135
1136 Check()
1137 END
1138 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1139
1140 lines =<< trim END
1141 vim9script
1142
1143 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001144 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001145 def new(str: any)
1146 enddef
1147 endclass
1148
1149 def Check()
1150 try
1151 var c = C.new(1)
1152 catch
1153 assert_report($'Unexpected exception was caught: {v:exception}')
1154 endtry
1155 enddef
1156
1157 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001158 END
1159 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001160
1161 # Try using "this." argument in a class method
1162 lines =<< trim END
1163 vim9script
1164 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001165 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001166 static def Foo(this.val: number)
1167 enddef
1168 endclass
1169 END
1170 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1171
1172 # Try using "this." argument in an object method
1173 lines =<< trim END
1174 vim9script
1175 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001176 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001177 def Foo(this.val: number)
1178 enddef
1179 endclass
1180 END
1181 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001182enddef
1183
Bram Moolenaar74e12742022-12-13 21:14:28 +00001184def Test_class_object_member_inits()
1185 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001186 vim9script
1187 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001188 var lnum: number
1189 var col = 1
1190 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001191 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001192
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001193 var pos = TextPosition.new()
1194 assert_equal(0, pos.lnum)
1195 assert_equal(1, pos.col)
1196 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001197 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001198 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001199
1200 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001201 vim9script
1202 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001203 var lnum
1204 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001205 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001206 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001207 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001208
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001209 # If the type is not specified for a member, then it should be set during
1210 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001211 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001212 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001213
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001214 var init_count = 0
1215 def Init(): string
1216 init_count += 1
1217 return 'foo'
1218 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001219
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001220 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001221 var str1 = Init()
1222 var str2: string = Init()
1223 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001224 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001225
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001226 assert_equal(init_count, 0)
1227 var a = A.new()
1228 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001229 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001230 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001231
1232 # Test for initializing an object member with an unknown variable/type
1233 lines =<< trim END
1234 vim9script
1235 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001236 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001237 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001238 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001239 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001240 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001241
1242 # Test for initializing an object member with an special type
1243 lines =<< trim END
1244 vim9script
1245 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001246 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001247 endclass
1248 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001249 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001250enddef
1251
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001252" Test for instance variable access
1253def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001254 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001255 vim9script
1256 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001257 var _one = 1
1258 var two = 2
1259 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001260
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001261 def GetOne(): number
1262 return this._one
1263 enddef
1264 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001265
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001266 var trip = Triple.new()
1267 assert_equal(1, trip.GetOne())
1268 assert_equal(2, trip.two)
1269 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001270 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001271
Ernie Rael03042a22023-11-11 08:53:32 +01001272 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001273 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1274 trip.three = 33
1275 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001276
Ernie Raeld4802ec2023-10-20 11:59:00 +02001277 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001278 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001279 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001280
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001281 # Test for a public member variable name beginning with an underscore
1282 lines =<< trim END
1283 vim9script
1284 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001285 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001286 endclass
1287 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001288 v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001289
Bram Moolenaar590162c2022-12-24 21:24:06 +00001290 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001291 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001292
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001293 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001294 var make: string
1295 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001296
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001297 def new(make_arg: string)
1298 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001299 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001300
1301 def GetMake(): string
1302 return $"make = {this.make}"
1303 enddef
1304 def GetAge(): number
1305 return this.age
1306 enddef
1307 endclass
1308
1309 var c = MyCar.new("abc")
1310 assert_equal('make = abc', c.GetMake())
1311
1312 c = MyCar.new("def")
1313 assert_equal('make = def', c.GetMake())
1314
1315 var c2 = MyCar.new("123")
1316 assert_equal('make = 123', c2.GetMake())
1317
1318 def CheckCar()
1319 assert_equal("make = def", c.GetMake())
1320 assert_equal(5, c.GetAge())
1321 enddef
1322 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001323 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001324 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001325
1326 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001327 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001328
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001329 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001330 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001331
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001332 def new(make_arg: string)
1333 this.make = make_arg
1334 enddef
1335 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001336
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001337 var c = MyCar.new("abc")
1338 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001339 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001340 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001341
1342 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001343 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001344
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001345 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001346 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001347
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001348 def Add(n: number): any
1349 this.x->add(n)
1350 return this
1351 enddef
1352 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001353
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001354 echo Foo.new().Add(1).Add(2).x
1355 echo Foo.new().Add(1).Add(2)
1356 .x
1357 echo Foo.new().Add(1)
1358 .Add(2).x
1359 echo Foo.new()
1360 .Add(1).Add(2).x
1361 echo Foo.new()
1362 .Add(1)
1363 .Add(2)
1364 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001365 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001366 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001367
1368 # Test for "public" cannot be abbreviated
1369 lines =<< trim END
1370 vim9script
1371 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001372 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001373 endclass
1374 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001375 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001376
Doug Kearns74da0ee2023-12-14 20:26:26 +01001377 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001378 lines =<< trim END
1379 vim9script
1380 class Something
1381 public val = 1
1382 endclass
1383 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001384 v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001385
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001386 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001387 lines =<< trim END
1388 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001389 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001390 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001391 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001392 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001393 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001394 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001395
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001396 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001397 lines =<< trim END
1398 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001399 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001400 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001401 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001402 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001403 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001404 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001405
1406 # Modify a instance variable using the class name in a def function
1407 lines =<< trim END
1408 vim9script
1409 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001410 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001411 endclass
1412 def T()
1413 A.val = 1
1414 enddef
1415 T()
1416 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001417 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001418
1419 # Read a instance variable using the class name in a def function
1420 lines =<< trim END
1421 vim9script
1422 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001423 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001424 endclass
1425 def T()
1426 var i = A.val
1427 enddef
1428 T()
1429 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001430 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001431
1432 # Access from child class extending a class:
1433 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001434 vim9script
1435 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001436 var ro_obj_var = 10
1437 public var rw_obj_var = 20
1438 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001439 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001440
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001441 class B extends A
1442 def Foo()
1443 var x: number
1444 x = this.ro_obj_var
1445 this.ro_obj_var = 0
1446 x = this.rw_obj_var
1447 this.rw_obj_var = 0
1448 x = this._priv_obj_var
1449 this._priv_obj_var = 0
1450 enddef
1451 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001452
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001453 var b = B.new()
1454 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001455 END
1456 v9.CheckSourceSuccess(lines)
1457enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001458
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001459" Test for class variable access
1460def Test_class_variable_access()
1461 # Test for "static" cannot be abbreviated
1462 var lines =<< trim END
1463 vim9script
1464 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001465 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001466 endclass
1467 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001468 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001469
1470 # Test for "static" cannot be followed by "public".
1471 lines =<< trim END
1472 vim9script
1473 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001474 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001475 endclass
1476 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001477 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001478
1479 # A readonly class variable cannot be modified from a child class
1480 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001481 vim9script
1482 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001483 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001484 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001485
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001486 class B extends A
1487 def Foo()
1488 A.ro_class_var = 50
1489 enddef
1490 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001491
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001492 var b = B.new()
1493 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001494 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001495 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001496
Ernie Rael03042a22023-11-11 08:53:32 +01001497 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001498 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001499 vim9script
1500 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001501 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001502 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001503
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001504 class B extends A
1505 def Foo()
1506 var i = A._priv_class_var
1507 enddef
1508 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001509
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001510 var b = B.new()
1511 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001512 END
Ernie Rael03042a22023-11-11 08:53:32 +01001513 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001514
Ernie Rael03042a22023-11-11 08:53:32 +01001515 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001516 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001517 vim9script
1518 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001519 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001520 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001521
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001522 class B extends A
1523 def Foo()
1524 A._priv_class_var = 0
1525 enddef
1526 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001527
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001528 var b = B.new()
1529 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001530 END
Ernie Rael03042a22023-11-11 08:53:32 +01001531 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001532
1533 # Access from child class extending a class and from script context
1534 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001535 vim9script
1536 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001537 static var ro_class_var = 10
1538 public static var rw_class_var = 20
1539 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001540 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001541
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001542 class B extends A
1543 def Foo()
1544 var x: number
1545 x = A.ro_class_var
1546 assert_equal(10, x)
1547 x = A.rw_class_var
1548 assert_equal(25, x)
1549 A.rw_class_var = 20
1550 assert_equal(20, A.rw_class_var)
1551 enddef
1552 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001554 assert_equal(10, A.ro_class_var)
1555 assert_equal(20, A.rw_class_var)
1556 A.rw_class_var = 25
1557 assert_equal(25, A.rw_class_var)
1558 var b = B.new()
1559 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001560 END
1561 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001562enddef
1563
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001564def Test_class_object_compare()
1565 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001566 vim9script
1567 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001568 var nr = 0
1569 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001570 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001571 END
1572
1573 # used at the script level and in a compiled function
1574 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001575 var i1 = Item.new()
1576 assert_equal(i1, i1)
1577 assert_true(i1 is i1)
1578 var i2 = Item.new()
1579 assert_equal(i1, i2)
1580 assert_false(i1 is i2)
1581 var i3 = Item.new(0, 'xx')
1582 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001583
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001584 var io1 = Item.new(1, 'xx')
1585 assert_notequal(i1, io1)
1586 var io2 = Item.new(0, 'yy')
1587 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001588 END
1589
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001590 v9.CheckSourceSuccess(class_lines + test_lines)
1591 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001592 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001593
1594 for op in ['>', '>=', '<', '<=', '=~', '!~']
1595 var op_lines = [
1596 'var i1 = Item.new()',
1597 'var i2 = Item.new()',
1598 'echo i1 ' .. op .. ' i2',
1599 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001600 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001601 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001602 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001603 endfor
1604enddef
1605
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001606def Test_object_type()
1607 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001608 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001609
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001610 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001611 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001612 endclass
1613 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001614 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001615 endclass
1616 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001617 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001618 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001619
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001620 var o: One = One.new()
1621 var t: Two = Two.new()
1622 var m: TwoMore = TwoMore.new()
1623 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001624
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001625 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001626 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001627 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001628
1629 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001630 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001631
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001632 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001633 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001634 endclass
1635 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001636 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001637 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001638
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001639 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001640 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001641 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001642
1643 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001644 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001645
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001646 interface One
1647 def GetMember(): number
1648 endinterface
1649 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001650 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001651 def GetMember(): number
1652 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001653 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001654 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001655
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001656 var o: One = Two.new(5)
1657 assert_equal(5, o.GetMember())
1658 END
1659 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001660
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001661 lines =<< trim END
1662 vim9script
1663
1664 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001665 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001666 endclass
1667
1668 def Ref(name: string): func(Num): Num
1669 return (arg: Num): Num => {
1670 return eval(name)(arg)
1671 }
1672 enddef
1673
1674 const Fn = Ref('Double')
1675 var Double = (m: Num): Num => Num.new(m.n * 2)
1676
1677 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001678 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001679 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001680enddef
1681
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001682def Test_class_member()
1683 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001684 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001685 vim9script
1686 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001687 var lnum = 1
1688 var col = 1
1689 static var counter = 0
1690 static var _secret = 7
1691 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001692
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001693 static def AddToCounter(nr: number)
1694 counter += nr
1695 enddef
1696 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001697
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001698 assert_equal(0, TextPos.counter)
1699 TextPos.AddToCounter(3)
1700 assert_equal(3, TextPos.counter)
1701 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001702
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001703 def GetCounter(): number
1704 return TextPos.counter
1705 enddef
1706 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001707
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001708 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1709 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1710 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001711
Ernie Rael03042a22023-11-11 08:53:32 +01001712 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1713 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001714
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001715 assert_equal(42, TextPos.anybody)
1716 TextPos.anybody = 12
1717 assert_equal(12, TextPos.anybody)
1718 TextPos.anybody += 5
1719 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001720 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001721 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001722
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001723 # example in the help
1724 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001725 vim9script
1726 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001727 var size: number
1728 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001729
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001730 def new(this.size)
1731 totalSize += this.size
1732 enddef
1733 endclass
1734 assert_equal(0, OtherThing.totalSize)
1735 var to3 = OtherThing.new(3)
1736 assert_equal(3, OtherThing.totalSize)
1737 var to7 = OtherThing.new(7)
1738 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001739 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001740 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001741
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001742 # using static class member twice
1743 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001744 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001745
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001746 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001747 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001748
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001749 static def MacroSubstitute(s: string): string
1750 return substitute(s, '{{author}}', author, 'gi')
1751 enddef
1752 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001753
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001754 assert_equal('some text', HTML.MacroSubstitute('some text'))
1755 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001756 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001757 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001758
Ernie Rael03042a22023-11-11 08:53:32 +01001759 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001760 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001761 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001762
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001763 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001764 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001765
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001766 def Add(n: number): number
1767 const F = (): number => this._x + n
1768 return F()
1769 enddef
1770 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001771
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001772 var foo = Foo.new()
1773 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001774 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001775 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001776
Ernie Rael03042a22023-11-11 08:53:32 +01001777 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001778 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001779 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001780
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001781 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001782 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001783
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001784 def Add(n: number): number
1785 var Lam = () => {
1786 this._x = this._x + n
1787 }
1788 Lam()
1789 return this._x
1790 enddef
1791 endclass
h-east2bd6a092023-05-19 19:01:17 +01001792
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001793 var foo = Foo.new()
1794 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001795 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001796 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001797
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001798 # check shadowing
1799 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001800 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001801
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001802 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001803 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001804 def Method(count: number)
1805 echo count
1806 enddef
1807 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001808
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001809 var s = Some.new()
1810 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001811 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001812 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001813
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001814 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001815 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001816 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001817
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001818 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001819 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001820 def Method(arg: number)
1821 var count = 3
1822 echo arg count
1823 enddef
1824 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001825
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001826 var s = Some.new()
1827 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001828 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001829 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001830
1831 # Test for using an invalid type for a member variable
1832 lines =<< trim END
1833 vim9script
1834 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001835 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001836 endclass
1837 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001838 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001839
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001840 # Test for setting a member on a null object
1841 lines =<< trim END
1842 vim9script
1843 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001844 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001845 endclass
1846
1847 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001848 var obj: A
1849 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001850 enddef
1851 F()
1852 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001853 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001854
1855 # Test for accessing a member on a null object
1856 lines =<< trim END
1857 vim9script
1858 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001859 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001860 endclass
1861
1862 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001863 var obj: A
1864 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001865 enddef
1866 F()
1867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001868 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001869
1870 # Test for setting a member on a null object, at script level
1871 lines =<< trim END
1872 vim9script
1873 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001874 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001875 endclass
1876
1877 var obj: A
1878 obj.val = ""
1879 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001880 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001881
1882 # Test for accessing a member on a null object, at script level
1883 lines =<< trim END
1884 vim9script
1885 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001886 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001887 endclass
1888
1889 var obj: A
1890 echo obj.val
1891 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001892 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001893
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001894 # Test for no space before or after the '=' when initializing a member
1895 # variable
1896 lines =<< trim END
1897 vim9script
1898 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001899 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001900 endclass
1901 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001902 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001903 lines =<< trim END
1904 vim9script
1905 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001906 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001907 endclass
1908 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001909 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001910
1911 # Access a non-existing member
1912 lines =<< trim END
1913 vim9script
1914 class A
1915 endclass
1916 var a = A.new()
1917 var v = a.bar
1918 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001919 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001920enddef
1921
Ernie Raele6c9aa52023-10-06 19:55:52 +02001922" These messages should show the defining class of the variable (base class),
1923" not the class that did the reference (super class)
1924def Test_defining_class_message()
1925 var lines =<< trim END
1926 vim9script
1927
1928 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001929 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001930 endclass
1931
1932 class Child extends Base
1933 endclass
1934
1935 var o = Child.new()
1936 var x = o._v1
1937 END
Ernie Rael03042a22023-11-11 08:53:32 +01001938 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001939 lines =<< trim END
1940 vim9script
1941
1942 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001943 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001944 endclass
1945
1946 class Child extends Base
1947 endclass
1948
1949 def F()
1950 var o = Child.new()
1951 var x = o._v1
1952 enddef
1953 F()
1954 END
Ernie Rael03042a22023-11-11 08:53:32 +01001955 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001956 lines =<< trim END
1957 vim9script
1958
1959 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001960 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001961 endclass
1962
1963 class Child extends Base
1964 endclass
1965
1966 var o = Child.new()
1967 o.v1 = []
1968 END
1969 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1970 lines =<< trim END
1971 vim9script
1972
1973 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001974 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001975 endclass
1976
1977 class Child extends Base
1978 endclass
1979
1980 def F()
1981 var o = Child.new()
1982 o.v1 = []
1983 enddef
1984 F()
1985 END
1986
Ernie Rael03042a22023-11-11 08:53:32 +01001987 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001988 # of the class hierarchy.
1989 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1990 lines =<< trim END
1991 vim9script
1992
1993 class Base0
1994 endclass
1995
1996 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01001997 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001998 endclass
1999
2000 class Child extends Base
2001 endclass
2002
2003 def F()
2004 var o = Child.new()
2005 var x = o._v1
2006 enddef
2007 F()
2008 END
Ernie Rael03042a22023-11-11 08:53:32 +01002009 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002010
Ernie Rael03042a22023-11-11 08:53:32 +01002011 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02002012 # of the class hierarchy.
2013 lines =<< trim END
2014 vim9script
2015
2016 class Base0
2017 endclass
2018
2019 class Base extends Base0
2020 endclass
2021
2022 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002023 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002024 endclass
2025
2026 def F()
2027 var o = Child.new()
2028 var x = o._v1
2029 enddef
2030 F()
2031 END
Ernie Rael03042a22023-11-11 08:53:32 +01002032 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002033enddef
2034
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002035func Test_class_garbagecollect()
2036 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002037 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002038
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002039 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002040 var p = [2, 3]
2041 static var pl = ['a', 'b']
2042 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002043 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002044
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002045 echo Point.pl Point.pd
2046 call test_garbagecollect_now()
2047 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002048 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002049 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002050
2051 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002052 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002053
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002054 interface View
2055 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002056
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002057 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01002058 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002059 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002060
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002061 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01002062 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002063
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002064 def new()
2065 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01002066 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002067 enddef
2068 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002069
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002070 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002071
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002072 # overwrite "view", will be garbage-collected next
2073 view = MyView.new()
2074 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002075 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002076 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002077endfunc
2078
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002079" Test interface garbage collection
2080func Test_interface_garbagecollect()
2081 let lines =<< trim END
2082 vim9script
2083
2084 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002085 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002086
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002087 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002088 endinterface
2089
2090 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002091 static var ro_class_var: number = 10
2092 public static var rw_class_var: number = 20
2093 static var _priv_class_var: number = 30
2094 var ro_obj_var: number = 40
2095 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002096
2097 static def _ClassBar(): number
2098 return _priv_class_var
2099 enddef
2100
2101 static def ClassFoo(): number
2102 return ro_class_var + rw_class_var + A._ClassBar()
2103 enddef
2104
2105 def _ObjBar(): number
2106 return this._priv_obj_var
2107 enddef
2108
2109 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002110 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002111 enddef
2112 endclass
2113
2114 assert_equal(60, A.ClassFoo())
2115 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002116 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002117 test_garbagecollect_now()
2118 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002119 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002120 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002121 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002122endfunc
2123
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002124def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002125 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002126 vim9script
2127 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002128 var value = 0
2129 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002130
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002131 def new(v: number)
2132 this.value = v
2133 ++objects
2134 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002135
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002136 static def GetCount(): number
2137 return objects
2138 enddef
2139 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002140
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002141 assert_equal(0, Value.GetCount())
2142 var v1 = Value.new(2)
2143 assert_equal(1, Value.GetCount())
2144 var v2 = Value.new(7)
2145 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002146 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002147 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002148
2149 # Test for cleaning up after a class definition failure when using class
2150 # functions.
2151 lines =<< trim END
2152 vim9script
2153 class A
2154 static def Foo()
2155 enddef
2156 aaa
2157 endclass
2158 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002159 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002160
2161 # Test for calling a class method from another class method without the class
2162 # name prefix.
2163 lines =<< trim END
2164 vim9script
2165 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002166 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002167 static def Foo(n: number)
2168 myList->add(n)
2169 enddef
2170 static def Bar()
2171 Foo(2)
2172 enddef
2173 def Baz()
2174 Foo(3)
2175 enddef
2176 endclass
2177 A.Bar()
2178 var a = A.new()
2179 a.Baz()
2180 assert_equal([1, 2, 3], A.myList)
2181 END
2182 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002183enddef
2184
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002185def Test_class_defcompile()
2186 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002187 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002188
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002189 class C
2190 def Fo(i: number): string
2191 return i
2192 enddef
2193 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002194
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002195 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002196 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002197 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002198
2199 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002200 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002201
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002202 class C
2203 static def Fc(): number
2204 return 'x'
2205 enddef
2206 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002207
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002208 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002209 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002210 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002211
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002212 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002213 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002214
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002215 class C
2216 static def new()
2217 enddef
2218 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002219
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002220 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002222 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002223
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002224 # Trying to compile a function using a non-existing class variable
2225 lines =<< trim END
2226 vim9script
2227 defcompile x.Foo()
2228 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002229 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002230
2231 # Trying to compile a function using a variable which is not a class
2232 lines =<< trim END
2233 vim9script
2234 var x: number
2235 defcompile x.Foo()
2236 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002237 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002238
2239 # Trying to compile a function without specifying the name
2240 lines =<< trim END
2241 vim9script
2242 class A
2243 endclass
2244 defcompile A.
2245 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002246 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002247
2248 # Trying to compile a non-existing class object member function
2249 lines =<< trim END
2250 vim9script
2251 class A
2252 endclass
2253 var a = A.new()
2254 defcompile a.Foo()
2255 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002256 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002257enddef
2258
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002259def Test_class_object_to_string()
2260 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002261 vim9script
2262 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002263 var lnum = 1
2264 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002265 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002266
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002267 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002268
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002269 var pos = TextPosition.new()
2270 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002271 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002272 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002273enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002274
Bram Moolenaar554d0312023-01-05 19:59:18 +00002275def Test_interface_basics()
2276 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002277 vim9script
2278 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002279 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002280 def GetCount(): number
2281 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002282 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002283 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002284
2285 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002286 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002287 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002288 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002290 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002291
2292 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002293 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002294
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002295 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002296 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002297 def Method(value: number)
2298 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002299 END
h-east61378a12023-04-18 19:07:29 +01002300 # The argument name and the object member name are the same, but this is not a
2301 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002302 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002303
2304 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002305 vim9script
2306 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002307 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002308 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002309 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002310 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002311
2312 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002313 vim9script
2314 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002315 var value: string
2316 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002317 def GetCount(): number
2318 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002319 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002320 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002321
2322 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002323 vim9script
2324 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002325 var value: string
2326 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002327 def GetCount(): number
2328 return 5
2329 enddef
2330 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002331 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002332 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002333
Yegappan Lakshmananac773182024-04-27 11:36:12 +02002334 # Additional commands after "interface name"
2335 lines =<< trim END
2336 vim9script
2337 interface Something | var x = 10 | var y = 20
2338 endinterface
2339 END
2340 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
2341
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002342 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002343 vim9script
2344 export interface EnterExit
2345 def Enter(): void
2346 def Exit(): void
2347 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002348 END
2349 writefile(lines, 'XdefIntf.vim', 'D')
2350
2351 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002352 vim9script
2353 import './XdefIntf.vim' as defIntf
2354 export def With(ee: defIntf.EnterExit, F: func)
2355 ee.Enter()
2356 try
2357 F()
2358 finally
2359 ee.Exit()
2360 endtry
2361 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002362 END
2363 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002364
2365 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002366 vim9script
2367 export abstract class EnterExit
2368 def Enter(): void
2369 enddef
2370 def Exit(): void
2371 enddef
2372 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002373 END
2374 writefile(imported, 'XdefIntf2.vim', 'D')
2375
2376 lines[1] = " import './XdefIntf2.vim' as defIntf"
2377 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002378enddef
2379
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002380" Test for using string() with an interface
2381def Test_interface_to_string()
2382 var lines =<< trim END
2383 vim9script
2384 interface Intf
2385 def Method(nr: number)
2386 endinterface
2387 assert_equal("interface Intf", string(Intf))
2388 END
2389 v9.CheckSourceSuccess(lines)
2390enddef
2391
Bram Moolenaar94674f22023-01-06 18:42:20 +00002392def Test_class_implements_interface()
2393 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002394 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002395
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002396 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002397 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002398 def Method(nr: number)
2399 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002400
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002401 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002402 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002403 def Method(nr: number)
2404 echo nr
2405 enddef
2406 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002407
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002408 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002409 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002410 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002411
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002412 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002413 var member = 'abc'
2414 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002415 def Method(nr: number)
2416 echo nr
2417 enddef
2418 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002419 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002420 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002421
2422 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002423 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002424
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002425 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002426 var count: number
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 SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002430 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002431 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002432 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002433 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002434
2435 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002436 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002437
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002438 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002439 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002440 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002441
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002442 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002443 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002444 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002445 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002446 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002447
2448 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002449 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002450
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002451 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002452 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002453 def Method(nr: number)
2454 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002455
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002456 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002457 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002458 def Method(nr: number)
2459 echo nr
2460 enddef
2461 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002462 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002463 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002464
2465 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002466 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002467
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002468 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002469 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002470 def Methods(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, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002481
2482 # Check different order of members in class and interface works.
2483 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002484 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002485
2486 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002487 var label: string
2488 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002489 endinterface
2490
2491 # order of members is opposite of interface
2492 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002493 public var lnum: number = 5
2494 var errpos: number = 42
2495 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002496 endclass
2497
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002498 def Test()
2499 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002500
2501 assert_equal('label', result.label)
2502 assert_equal(42, result.errpos)
2503 enddef
2504
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002505 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002506 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002507 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002508
2509 # Interface name after "extends" doesn't end in a space or NUL character
2510 lines =<< trim END
2511 vim9script
2512 interface A
2513 endinterface
2514 class B extends A"
2515 endclass
2516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002517 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002518
2519 # Trailing characters after a class name
2520 lines =<< trim END
2521 vim9script
2522 class A bbb
2523 endclass
2524 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002525 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002526
2527 # using "implements" with a non-existing class
2528 lines =<< trim END
2529 vim9script
2530 class A implements B
2531 endclass
2532 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002533 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002534
2535 # using "implements" with a regular class
2536 lines =<< trim END
2537 vim9script
2538 class A
2539 endclass
2540 class B implements A
2541 endclass
2542 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002543 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002544
2545 # using "implements" with a variable
2546 lines =<< trim END
2547 vim9script
2548 var T: number = 10
2549 class A implements T
2550 endclass
2551 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002552 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002553
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002554 # implements should be followed by a white space
2555 lines =<< trim END
2556 vim9script
2557 interface A
2558 endinterface
2559 class B implements A;
2560 endclass
2561 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002562 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002563
LemonBoyc5d27442023-08-19 13:02:35 +02002564 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002565 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002566
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002567 interface One
2568 def IsEven(nr: number): bool
2569 endinterface
2570 class Two implements One
2571 def IsEven(nr: number): string
2572 enddef
2573 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002574 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002575 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002576
2577 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002578 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002579
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002580 interface One
2581 def IsEven(nr: number): bool
2582 endinterface
2583 class Two implements One
2584 def IsEven(nr: bool): bool
2585 enddef
2586 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002587 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002588 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002589
2590 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002591 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002592
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002593 interface One
2594 def IsEven(nr: number): bool
2595 endinterface
2596 class Two implements One
2597 def IsEven(nr: number, ...extra: list<number>): bool
2598 enddef
2599 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002600 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002601 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 +02002602
2603 # access superclass interface members from subclass, mix variable order
2604 lines =<< trim END
2605 vim9script
2606
2607 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002608 var mvar1: number
2609 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002610 endinterface
2611
2612 # NOTE: the order is swapped
2613 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002614 var mvar2: number
2615 var mvar1: number
2616 public static var svar2: number
2617 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002618 def new()
2619 svar1 = 11
2620 svar2 = 12
2621 this.mvar1 = 111
2622 this.mvar2 = 112
2623 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002624 endclass
2625
2626 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002627 def new()
2628 this.mvar1 = 121
2629 this.mvar2 = 122
2630 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002631 endclass
2632
2633 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002634 def new()
2635 this.mvar1 = 131
2636 this.mvar2 = 132
2637 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002638 endclass
2639
Ernie Raelcf138d42023-09-06 20:45:03 +02002640 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002641 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002642 enddef
2643
2644 var oa = A.new()
2645 var ob = B.new()
2646 var oc = C.new()
2647
Ernie Raelcf138d42023-09-06 20:45:03 +02002648 assert_equal([111, 112], F2(oa))
2649 assert_equal([121, 122], F2(ob))
2650 assert_equal([131, 132], F2(oc))
2651 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002652 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002653
2654 # Access superclass interface members from subclass, mix variable order.
2655 # Two interfaces, one on A, one on B; each has both kinds of variables
2656 lines =<< trim END
2657 vim9script
2658
2659 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002660 var mvar1: number
2661 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002662 endinterface
2663
2664 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002665 var mvar3: number
2666 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002667 endinterface
2668
2669 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002670 public static var svar1: number
2671 public static var svar2: number
2672 var mvar1: number
2673 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002674 def new()
2675 svar1 = 11
2676 svar2 = 12
2677 this.mvar1 = 111
2678 this.mvar2 = 112
2679 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002680 endclass
2681
2682 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002683 static var svar3: number
2684 static var svar4: number
2685 var mvar3: number
2686 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002687 def new()
2688 svar3 = 23
2689 svar4 = 24
2690 this.mvar1 = 121
2691 this.mvar2 = 122
2692 this.mvar3 = 123
2693 this.mvar4 = 124
2694 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002695 endclass
2696
2697 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002698 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002699 def new()
2700 svar5 = 1001
2701 this.mvar1 = 131
2702 this.mvar2 = 132
2703 this.mvar3 = 133
2704 this.mvar4 = 134
2705 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002706 endclass
2707
Ernie Raelcf138d42023-09-06 20:45:03 +02002708 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002709 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002710 enddef
2711
Ernie Raelcf138d42023-09-06 20:45:03 +02002712 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002713 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002714 enddef
2715
Ernie Raelcf138d42023-09-06 20:45:03 +02002716 var oa = A.new()
2717 var ob = B.new()
2718 var oc = C.new()
2719
Ernie Raelcf138d42023-09-06 20:45:03 +02002720 assert_equal([[111, 112]], [F2(oa)])
2721 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2722 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002723 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002724 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002725
2726 # Using two interface names without a space after the ","
2727 lines =<< trim END
2728 vim9script
2729 interface A
2730 endinterface
2731 interface B
2732 endinterface
2733 class C implements A,B
2734 endclass
2735 END
2736 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2737
2738 # No interface name after a comma
2739 lines =<< trim END
2740 vim9script
2741 interface A
2742 endinterface
2743 class B implements A,
2744 endclass
2745 END
2746 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2747
2748 # No interface name after implements
2749 lines =<< trim END
2750 vim9script
2751 class A implements
2752 endclass
2753 END
2754 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002755enddef
2756
Bram Moolenaard0200c82023-01-28 15:19:40 +00002757def Test_call_interface_method()
2758 var lines =<< trim END
2759 vim9script
2760 interface Base
2761 def Enter(): void
2762 endinterface
2763
2764 class Child implements Base
2765 def Enter(): void
2766 g:result ..= 'child'
2767 enddef
2768 endclass
2769
2770 def F(obj: Base)
2771 obj.Enter()
2772 enddef
2773
2774 g:result = ''
2775 F(Child.new())
2776 assert_equal('child', g:result)
2777 unlet g:result
2778 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002779 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002780
2781 lines =<< trim END
2782 vim9script
2783 class Base
2784 def Enter(): void
2785 g:result ..= 'base'
2786 enddef
2787 endclass
2788
2789 class Child extends Base
2790 def Enter(): void
2791 g:result ..= 'child'
2792 enddef
2793 endclass
2794
2795 def F(obj: Base)
2796 obj.Enter()
2797 enddef
2798
2799 g:result = ''
2800 F(Child.new())
2801 assert_equal('child', g:result)
2802 unlet g:result
2803 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002804 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002805
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002806 # method of interface returns a value
2807 lines =<< trim END
2808 vim9script
2809 interface Base
2810 def Enter(): string
2811 endinterface
2812
2813 class Child implements Base
2814 def Enter(): string
2815 g:result ..= 'child'
2816 return "/resource"
2817 enddef
2818 endclass
2819
2820 def F(obj: Base)
2821 var r = obj.Enter()
2822 g:result ..= r
2823 enddef
2824
2825 g:result = ''
2826 F(Child.new())
2827 assert_equal('child/resource', g:result)
2828 unlet g:result
2829 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002830 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002831
2832 lines =<< trim END
2833 vim9script
2834 class Base
2835 def Enter(): string
2836 return null_string
2837 enddef
2838 endclass
2839
2840 class Child extends Base
2841 def Enter(): string
2842 g:result ..= 'child'
2843 return "/resource"
2844 enddef
2845 endclass
2846
2847 def F(obj: Base)
2848 var r = obj.Enter()
2849 g:result ..= r
2850 enddef
2851
2852 g:result = ''
2853 F(Child.new())
2854 assert_equal('child/resource', g:result)
2855 unlet g:result
2856 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002857 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002858
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002859 # No class that implements the interface.
2860 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002861 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002862
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002863 interface IWithEE
2864 def Enter(): any
2865 def Exit(): void
2866 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002867
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002868 def With1(ee: IWithEE, F: func)
2869 var r = ee.Enter()
2870 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002871
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002872 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002873 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002874 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002875enddef
2876
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002877def Test_class_used_as_type()
2878 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002879 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002880
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002881 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002882 var x = 0
2883 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002884 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002885
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002886 var p: Point
2887 p = Point.new(2, 33)
2888 assert_equal(2, p.x)
2889 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002890 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002891 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002892
2893 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002894 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002895
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002896 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002897 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002898 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002899
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002900 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002901 var x = 0
2902 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002903 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002904
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002905 var p: Point
2906 p = Point.new(2, 33)
2907 var hx = p
2908 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002909 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002910 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002911
2912 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002913 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002914
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002915 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002916 var x = 0
2917 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002918 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002919
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002920 var p: Point
2921 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002922 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002923 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002924enddef
2925
Bram Moolenaar83677162023-01-08 19:54:10 +00002926def Test_class_extends()
2927 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002928 vim9script
2929 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002930 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002931 def GetOne(): number
2932 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002933 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002934 endclass
2935 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002936 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002937 def GetTotal(): number
2938 return this.one + this.two
2939 enddef
2940 endclass
2941 var o = Child.new()
2942 assert_equal(1, o.one)
2943 assert_equal(2, o.two)
2944 assert_equal(1, o.GetOne())
2945 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002946 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002947 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002948
2949 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002950 vim9script
2951 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002952 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002953 endclass
2954 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002955 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002956 endclass
2957 var o = Child.new(3, 44)
2958 assert_equal(3, o.one)
2959 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002960 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002961 v9.CheckSourceSuccess(lines)
2962
2963 lines =<< trim END
2964 vim9script
2965 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002966 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002967 endclass
2968 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002969 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002970 endclass
2971 END
2972 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2973
2974 lines =<< trim END
2975 vim9script
2976 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01002977 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002978 endclass
2979 END
2980 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2981
2982 lines =<< trim END
2983 vim9script
2984 var SomeVar = 99
2985 class Child extends SomeVar
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, 'E1354: Cannot extend SomeVar', 5)
2990
2991 lines =<< trim END
2992 vim9script
2993 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002994 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002995 def ToString(): string
2996 return this.name
2997 enddef
2998 endclass
2999
3000 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003001 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003002 def ToString(): string
3003 return super.ToString() .. ': ' .. this.age
3004 enddef
3005 endclass
3006
3007 var o = Child.new('John', 42)
3008 assert_equal('John: 42', o.ToString())
3009 END
3010 v9.CheckSourceSuccess(lines)
3011
3012 lines =<< trim END
3013 vim9script
3014 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003015 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003016 def ToString(): number
3017 return this.age
3018 enddef
3019 def ToString(): string
3020 return this.age
3021 enddef
3022 endclass
3023 END
3024 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
3025
3026 lines =<< trim END
3027 vim9script
3028 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003029 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003030 def ToString(): string
3031 return super .ToString() .. ': ' .. this.age
3032 enddef
3033 endclass
3034 var o = Child.new(42)
3035 echo o.ToString()
3036 END
3037 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
3038
3039 lines =<< trim END
3040 vim9script
3041 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003042 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003043 def ToString(): string
3044 return this.name
3045 enddef
3046 endclass
3047
3048 var age = 42
3049 def ToString(): string
3050 return super.ToString() .. ': ' .. age
3051 enddef
3052 echo ToString()
3053 END
3054 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
3055
3056 lines =<< trim END
3057 vim9script
3058 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003059 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003060 def ToString(): string
3061 return super.ToString() .. ': ' .. this.age
3062 enddef
3063 endclass
3064 var o = Child.new(42)
3065 echo o.ToString()
3066 END
3067 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
3068
3069 lines =<< trim END
3070 vim9script
3071 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003072 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003073 static def ToString(): string
3074 return 'Base class'
3075 enddef
3076 endclass
3077
3078 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003079 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003080 def ToString(): string
3081 return Base.ToString() .. ': ' .. this.age
3082 enddef
3083 endclass
3084
3085 var o = Child.new('John', 42)
3086 assert_equal('Base class: 42', o.ToString())
3087 END
3088 v9.CheckSourceSuccess(lines)
3089
3090 lines =<< trim END
3091 vim9script
3092 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003093 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003094 def new(init: number)
3095 this.value = number + 1
3096 enddef
3097 endclass
3098 class Child extends Base
3099 def new()
3100 this.new(3)
3101 enddef
3102 endclass
3103 var c = Child.new()
3104 END
3105 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003106
3107 # base class with more than one object member
3108 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003109 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003110
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003111 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003112 var success: bool
3113 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003114 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003115
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003116 class Success extends Result
3117 def new(this.value = v:none)
3118 this.success = true
3119 enddef
3120 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003121
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003122 var v = Success.new('asdf')
3123 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003124 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003125 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003126
3127 # class name after "extends" doesn't end in a space or NUL character
3128 lines =<< trim END
3129 vim9script
3130 class A
3131 endclass
3132 class B extends A"
3133 endclass
3134 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003135 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003136enddef
3137
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003138def Test_using_base_class()
3139 var lines =<< trim END
3140 vim9script
3141
3142 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003143 def Enter(): any
3144 return null
3145 enddef
3146 def Exit(resource: any): void
3147 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003148 endclass
3149
3150 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003151 def Enter(): any
3152 return 42
3153 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003154
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003155 def Exit(resource: number): void
3156 g:result ..= '/exit'
3157 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003158 endclass
3159
3160 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003161 var r = ee.Enter()
3162 try
3163 g:result ..= r
3164 finally
3165 g:result ..= '/finally'
3166 ee.Exit(r)
3167 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003168 enddef
3169
3170 g:result = ''
3171 With(ChildEE.new())
3172 assert_equal('42/finally/exit', g:result)
3173 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003174 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003175 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003176
3177 # Using super, Child invokes Base method which has optional arg. #12471
3178 lines =<< trim END
3179 vim9script
3180
3181 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003182 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003183 def Method(arg = 0)
3184 this.success = true
3185 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003186 endclass
3187
3188 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003189 def new()
3190 super.Method()
3191 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003192 endclass
3193
3194 var obj = Child.new()
3195 assert_equal(true, obj.success)
3196 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003197 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003198enddef
3199
Bram Moolenaara86655a2023-01-12 17:06:27 +00003200def Test_class_import()
3201 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003202 vim9script
3203 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003204 var kind: string
3205 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003206 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003207 END
3208 writefile(lines, 'Xanimal.vim', 'D')
3209
3210 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003211 vim9script
3212 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003213
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003214 var a: animal.Animal
3215 a = animal.Animal.new('fish', 'Eric')
3216 assert_equal('fish', a.kind)
3217 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003218
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003219 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3220 assert_equal('cat', b.kind)
3221 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003222 END
3223 v9.CheckScriptSuccess(lines)
3224enddef
3225
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003226" Test for importing a class into a legacy script and calling the class method
3227def Test_class_method_from_legacy_script()
3228 var lines =<< trim END
3229 vim9script
3230 export class A
3231 static var name: string = 'a'
3232 static def SetName(n: string)
3233 name = n
3234 enddef
3235 endclass
3236 END
3237 writefile(lines, 'Xvim9export.vim', 'D')
3238
3239 lines =<< trim END
3240 import './Xvim9export.vim' as vim9
3241
3242 call s:vim9.A.SetName('b')
3243 call assert_equal('b', s:vim9.A.name)
3244 END
3245 v9.CheckScriptSuccess(lines)
3246enddef
3247
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003248" Test for implementing an imported interface
3249def Test_implement_imported_interface()
3250 var lines =<< trim END
3251 vim9script
3252 export interface Imp_Intf1
3253 def Fn1(): number
3254 endinterface
3255 export interface Imp_Intf2
3256 def Fn2(): number
3257 endinterface
3258 END
3259 writefile(lines, 'Ximportinterface.vim', 'D')
3260
3261 lines =<< trim END
3262 vim9script
3263 import './Ximportinterface.vim' as Xintf
3264
3265 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3266 def Fn1(): number
3267 return 10
3268 enddef
3269 def Fn2(): number
3270 return 20
3271 enddef
3272 endclass
3273 var a = A.new()
3274 assert_equal(10, a.Fn1())
3275 assert_equal(20, a.Fn2())
3276 END
3277 v9.CheckScriptSuccess(lines)
3278enddef
3279
3280" Test for extending an imported class
3281def Test_extend_imported_class()
3282 var lines =<< trim END
3283 vim9script
3284 export class Imp_C1
3285 def Fn1(): number
3286 return 5
3287 enddef
3288 endclass
3289 END
3290 writefile(lines, 'Xextendimportclass.vim', 'D')
3291
3292 lines =<< trim END
3293 vim9script
3294 import './Xextendimportclass.vim' as XClass
3295
3296 class A extends XClass.Imp_C1
3297 endclass
3298 var a = A.new()
3299 assert_equal(5, a.Fn1())
3300 END
3301 v9.CheckScriptSuccess(lines)
3302enddef
3303
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003304def Test_abstract_class()
3305 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003306 vim9script
3307 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003308 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003309 endclass
3310 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003311 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003312 endclass
3313 var p: Base = Person.new('Peter', 42)
3314 assert_equal('Peter', p.name)
3315 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003316 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003317 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003318
3319 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003320 vim9script
3321 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003322 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003323 endclass
3324 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003325 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003326 endclass
3327 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003328 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003329 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003330
3331 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003332 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003333 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003334 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003335 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003336 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003337
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003338 # Additional commands after "abstract class"
3339 lines =<< trim END
3340 vim9script
3341 abstract class Something | var x = []
3342 endclass
3343 END
3344 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3345
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003346 # Abstract class cannot have a "new" function
3347 lines =<< trim END
3348 vim9script
3349 abstract class Base
3350 def new()
3351 enddef
3352 endclass
3353 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003354 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003355
3356 # extending an abstract class with class methods and variables
3357 lines =<< trim END
3358 vim9script
3359 abstract class A
3360 static var s: string = 'vim'
3361 static def Fn(): list<number>
3362 return [10]
3363 enddef
3364 endclass
3365 class B extends A
3366 endclass
3367 var b = B.new()
3368 assert_equal('vim', A.s)
3369 assert_equal([10], A.Fn())
3370 END
3371 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003372enddef
3373
Bram Moolenaar486fc252023-01-18 14:51:07 +00003374def Test_closure_in_class()
3375 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003376 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003377
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003378 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003379 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003380
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003381 def new()
3382 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3383 enddef
3384 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003385
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003386 Foo.new()
3387 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003388 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003389 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003390enddef
3391
Ernie Rael9ed53752023-12-11 17:40:46 +01003392def Test_construct_object_from_legacy()
3393 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003394 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003395 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003396
Ernie Rael9ed53752023-12-11 17:40:46 +01003397 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003398
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003399 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003400 def new(arg: string)
3401 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003402 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003403 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003404
Ernie Rael9ed53752023-12-11 17:40:46 +01003405 export def CreateA(...args: list<any>): A
3406 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003407 enddef
3408
Ernie Rael9ed53752023-12-11 17:40:46 +01003409 g:P = CreateA
3410 legacy call g:P('some_arg')
3411 assert_equal(true, newCalled)
3412 unlet g:P
3413 END
3414 v9.CheckSourceSuccess(lines)
3415
3416 lines =<< trim END
3417 vim9script
3418
3419 var newCalled = false
3420
3421 class A
3422 static def CreateA(options = {}): any
3423 return A.new()
3424 enddef
3425 def new()
3426 newCalled = true
3427 enddef
3428 endclass
3429
3430 g:P = A.CreateA
3431 legacy call g:P()
3432 assert_equal(true, newCalled)
3433 unlet g:P
3434 END
3435 v9.CheckSourceSuccess(lines)
3436
3437 # This also tests invoking "new()" with "call"
3438 lines =<< trim END
3439 vim9script
3440
3441 var createdObject: any
3442
3443 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003444 var val1: number
3445 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003446 static def CreateA(...args: list<any>): any
3447 createdObject = call(A.new, args)
3448 return createdObject
3449 enddef
3450 endclass
3451
3452 g:P = A.CreateA
3453 legacy call g:P(3, 5)
3454 assert_equal(3, createdObject.val1)
3455 assert_equal(5, createdObject.val2)
3456 legacy call g:P()
3457 assert_equal(0, createdObject.val1)
3458 assert_equal(0, createdObject.val2)
3459 legacy call g:P(7)
3460 assert_equal(7, createdObject.val1)
3461 assert_equal(0, createdObject.val2)
3462 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003463 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003464 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003465enddef
3466
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003467def Test_defer_with_object()
3468 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003469 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003470
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003471 class CWithEE
3472 def Enter()
3473 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003474 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003475 def Exit()
3476 g:result ..= "exited"
3477 enddef
3478 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003479
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003480 def With(ee: CWithEE, F: func)
3481 ee.Enter()
3482 defer ee.Exit()
3483 F()
3484 enddef
3485
3486 g:result = ''
3487 var obj = CWithEE.new()
3488 obj->With(() => {
3489 g:result ..= "called/"
3490 })
3491 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003492 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003493 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003494 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003495
3496 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003497 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003498
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003499 class BaseWithEE
3500 def Enter()
3501 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003502 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003503 def Exit()
3504 g:result ..= "exited-base"
3505 enddef
3506 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003507
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003508 class CWithEE extends BaseWithEE
3509 def Enter()
3510 g:result ..= "entered-child/"
3511 enddef
3512 def Exit()
3513 g:result ..= "exited-child"
3514 enddef
3515 endclass
3516
3517 def With(ee: BaseWithEE, F: func)
3518 ee.Enter()
3519 defer ee.Exit()
3520 F()
3521 enddef
3522
3523 g:result = ''
3524 var obj = CWithEE.new()
3525 obj->With(() => {
3526 g:result ..= "called/"
3527 })
3528 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003529 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003530 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003531 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003532enddef
3533
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003534" The following test used to crash Vim (Github issue #12676)
3535def Test_extends_method_crashes_vim()
3536 var lines =<< trim END
3537 vim9script
3538
3539 class Observer
3540 endclass
3541
3542 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003543 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003544
3545 def Set(v: any)
3546 if v != this.value
3547 this.value = v
3548 endif
3549 enddef
3550
3551 def Register(observer: Observer)
3552 enddef
3553 endclass
3554
3555 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003556 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003557 endclass
3558
3559 def Observe(obj: Property, who: Observer)
3560 obj.Register(who)
3561 enddef
3562
3563 var p = Bool.new(false)
3564 var myObserver = Observer.new()
3565
3566 Observe(p, myObserver)
3567
3568 p.Set(true)
3569 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003570 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003571enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003572
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003573" Test for calling a method in a class that is extended
3574def Test_call_method_in_extended_class()
3575 var lines =<< trim END
3576 vim9script
3577
3578 var prop_init_called = false
3579 var prop_register_called = false
3580
3581 class Property
3582 def Init()
3583 prop_init_called = true
3584 enddef
3585
3586 def Register()
3587 prop_register_called = true
3588 enddef
3589 endclass
3590
3591 class Bool extends Property
3592 endclass
3593
3594 def Observe(obj: Property)
3595 obj.Register()
3596 enddef
3597
3598 var p = Property.new()
3599 Observe(p)
3600
3601 p.Init()
3602 assert_true(prop_init_called)
3603 assert_true(prop_register_called)
3604 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003605 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003606enddef
3607
LemonBoyafe04662023-08-23 21:08:11 +02003608def Test_instanceof()
3609 var lines =<< trim END
3610 vim9script
3611
3612 class Base1
3613 endclass
3614
3615 class Base2 extends Base1
3616 endclass
3617
3618 interface Intf1
3619 endinterface
3620
3621 class Mix1 implements Intf1
3622 endclass
3623
3624 class Base3 extends Mix1
3625 endclass
3626
Ernie Rael2025af12023-12-12 16:58:00 +01003627 type AliasBase1 = Base1
3628 type AliasBase2 = Base2
3629 type AliasIntf1 = Intf1
3630 type AliasMix1 = Mix1
3631
LemonBoyafe04662023-08-23 21:08:11 +02003632 var b1 = Base1.new()
3633 var b2 = Base2.new()
3634 var b3 = Base3.new()
3635
3636 assert_true(instanceof(b1, Base1))
3637 assert_true(instanceof(b2, Base1))
3638 assert_false(instanceof(b1, Base2))
3639 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003640 assert_true(instanceof(b3, Base1, Base2, Intf1))
3641
3642 assert_true(instanceof(b1, AliasBase1))
3643 assert_true(instanceof(b2, AliasBase1))
3644 assert_false(instanceof(b1, AliasBase2))
3645 assert_true(instanceof(b3, AliasMix1))
3646 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003647
3648 def Foo()
3649 var a1 = Base1.new()
3650 var a2 = Base2.new()
3651 var a3 = Base3.new()
3652
3653 assert_true(instanceof(a1, Base1))
3654 assert_true(instanceof(a2, Base1))
3655 assert_false(instanceof(a1, Base2))
3656 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003657 assert_true(instanceof(a3, Base1, Base2, Intf1))
3658
3659 assert_true(instanceof(a1, AliasBase1))
3660 assert_true(instanceof(a2, AliasBase1))
3661 assert_false(instanceof(a1, AliasBase2))
3662 assert_true(instanceof(a3, AliasMix1))
3663 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003664 enddef
3665 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003666
3667 var o_null: Base1
3668 assert_false(instanceof(o_null, Base1))
3669
LemonBoyafe04662023-08-23 21:08:11 +02003670 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003671 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003672
3673 lines =<< trim END
3674 vim9script
3675
3676 class Base1
3677 endclass
3678 instanceof(Base1.new())
3679 END
3680 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3681
3682 lines =<< trim END
3683 vim9script
3684
3685 class Base1
3686 endclass
3687 def F()
3688 instanceof(Base1.new())
3689 enddef
3690 F()
3691 END
3692 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3693
3694 lines =<< trim END
3695 vim9script
3696
3697 class Base1
3698 endclass
3699
3700 class Base2
3701 endclass
3702
3703 var o = Base2.new()
3704 instanceof(o, Base1, Base2, 3)
3705 END
3706 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3707
3708 lines =<< trim END
3709 vim9script
3710
3711 class Base1
3712 endclass
3713
3714 class Base2
3715 endclass
3716
3717 def F()
3718 var o = Base2.new()
3719 instanceof(o, Base1, Base2, 3)
3720 enddef
3721 F()
3722 END
3723 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003724enddef
3725
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003726" Test for calling a method in the parent class that is extended partially.
3727" This used to fail with the 'E118: Too many arguments for function: Text' error
3728" message (Github issue #12524).
3729def Test_call_method_in_parent_class()
3730 var lines =<< trim END
3731 vim9script
3732
3733 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003734 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003735
3736 def SetY(lnum: number)
3737 this._lnum = lnum
3738 enddef
3739
3740 def Text(): string
3741 return ''
3742 enddef
3743 endclass
3744
3745 class Foo extends Widget
3746 def Text(): string
3747 return '<Foo>'
3748 enddef
3749 endclass
3750
3751 def Stack(w1: Widget, w2: Widget): list<Widget>
3752 w1.SetY(1)
3753 w2.SetY(2)
3754 return [w1, w2]
3755 enddef
3756
3757 var foo1 = Foo.new()
3758 var foo2 = Foo.new()
3759 var l = Stack(foo1, foo2)
3760 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003761 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003762enddef
3763
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003764" Test for calling methods from three levels of classes
3765def Test_multi_level_method_call()
3766 var lines =<< trim END
3767 vim9script
3768
3769 var A_func1: number = 0
3770 var A_func2: number = 0
3771 var A_func3: number = 0
3772 var B_func2: number = 0
3773 var B_func3: number = 0
3774 var C_func3: number = 0
3775
3776 class A
3777 def Func1()
3778 A_func1 += 1
3779 enddef
3780
3781 def Func2()
3782 A_func2 += 1
3783 enddef
3784
3785 def Func3()
3786 A_func3 += 1
3787 enddef
3788 endclass
3789
3790 class B extends A
3791 def Func2()
3792 B_func2 += 1
3793 enddef
3794
3795 def Func3()
3796 B_func3 += 1
3797 enddef
3798 endclass
3799
3800 class C extends B
3801 def Func3()
3802 C_func3 += 1
3803 enddef
3804 endclass
3805
3806 def A_CallFuncs(a: A)
3807 a.Func1()
3808 a.Func2()
3809 a.Func3()
3810 enddef
3811
3812 def B_CallFuncs(b: B)
3813 b.Func1()
3814 b.Func2()
3815 b.Func3()
3816 enddef
3817
3818 def C_CallFuncs(c: C)
3819 c.Func1()
3820 c.Func2()
3821 c.Func3()
3822 enddef
3823
3824 var cobj = C.new()
3825 A_CallFuncs(cobj)
3826 B_CallFuncs(cobj)
3827 C_CallFuncs(cobj)
3828 assert_equal(3, A_func1)
3829 assert_equal(0, A_func2)
3830 assert_equal(0, A_func3)
3831 assert_equal(3, B_func2)
3832 assert_equal(0, B_func3)
3833 assert_equal(3, C_func3)
3834 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003835 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003836enddef
3837
3838" Test for using members from three levels of classes
3839def Test_multi_level_member_access()
3840 var lines =<< trim END
3841 vim9script
3842
3843 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003844 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003845 endclass
3846
3847 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003848 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003849 endclass
3850
3851 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003852 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003853 endclass
3854
3855 def A_members(a: A)
3856 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003857 enddef
3858
3859 def B_members(b: B)
3860 b.val1 += 1
3861 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003862 enddef
3863
3864 def C_members(c: C)
3865 c.val1 += 1
3866 c.val2 += 1
3867 c.val3 += 1
3868 enddef
3869
3870 var cobj = C.new()
3871 A_members(cobj)
3872 B_members(cobj)
3873 C_members(cobj)
3874 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003875 assert_equal(2, cobj.val2)
3876 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003877 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003878 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003879enddef
3880
LemonBoy0ffc17a2023-08-20 18:09:11 +02003881" Test expansion of <stack> with class methods.
3882def Test_stack_expansion_with_methods()
3883 var lines =<< trim END
3884 vim9script
3885
3886 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003887 def M1()
3888 F0()
3889 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003890 endclass
3891
3892 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02003893 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02003894 enddef
3895
3896 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003897 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003898 enddef
3899
3900 F()
3901 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003902 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003903enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003904
3905" Test the return type of the new() constructor
3906def Test_new_return_type()
3907 # new() uses the default return type and there is no return statement
3908 var lines =<< trim END
3909 vim9script
3910
3911 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003912 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003913
3914 def new(this._bufnr)
3915 if !bufexists(this._bufnr)
3916 this._bufnr = -1
3917 endif
3918 enddef
3919 endclass
3920
3921 var c = C.new(12345)
3922 assert_equal('object<C>', typename(c))
3923
3924 var v1: C
3925 v1 = C.new(12345)
3926 assert_equal('object<C>', typename(v1))
3927
3928 def F()
3929 var v2: C
3930 v2 = C.new(12345)
3931 assert_equal('object<C>', typename(v2))
3932 enddef
3933 F()
3934 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003935 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003936
3937 # new() uses the default return type and an empty 'return' statement
3938 lines =<< trim END
3939 vim9script
3940
3941 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003942 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003943
3944 def new(this._bufnr)
3945 if !bufexists(this._bufnr)
3946 this._bufnr = -1
3947 return
3948 endif
3949 enddef
3950 endclass
3951
3952 var c = C.new(12345)
3953 assert_equal('object<C>', typename(c))
3954
3955 var v1: C
3956 v1 = C.new(12345)
3957 assert_equal('object<C>', typename(v1))
3958
3959 def F()
3960 var v2: C
3961 v2 = C.new(12345)
3962 assert_equal('object<C>', typename(v2))
3963 enddef
3964 F()
3965 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003966 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003967
3968 # new() uses "any" return type and returns "this"
3969 lines =<< trim END
3970 vim9script
3971
3972 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003973 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003974
3975 def new(this._bufnr): any
3976 if !bufexists(this._bufnr)
3977 this._bufnr = -1
3978 return this
3979 endif
3980 enddef
3981 endclass
3982 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003983 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003984
3985 # new() uses 'Dict' return type and returns a Dict
3986 lines =<< trim END
3987 vim9script
3988
3989 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003990 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003991
3992 def new(): dict<any>
3993 this._state = {}
3994 return this._state
3995 enddef
3996 endclass
3997
3998 var c = C.new()
3999 assert_equal('object<C>', typename(c))
4000 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004001 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004002enddef
4003
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004004" Test for checking a member initialization type at run time.
4005def Test_runtime_type_check_for_member_init()
4006 var lines =<< trim END
4007 vim9script
4008
4009 var retnum: bool = false
4010
4011 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004012 retnum = !retnum
4013 if retnum
4014 return 1
4015 else
4016 return "hello"
4017 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004018 enddef
4019
4020 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004021 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004022 endclass
4023
4024 var c1 = C.new()
4025 var c2 = C.new()
4026 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004027 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004028enddef
4029
4030" Test for locking a variable referring to an object and reassigning to another
4031" object.
Ernie Raelee865f32023-09-29 19:53:55 +02004032def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004033 var lines =<< trim END
4034 vim9script
4035
4036 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004037 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004038 def new(this.val)
4039 enddef
4040 endclass
4041
4042 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
4043 lockvar 2 some_dict
4044
4045 var current: C
4046 current = some_dict['c']
4047 assert_equal(3, current.val)
4048 current = some_dict['b']
4049 assert_equal(2, current.val)
4050
4051 def F()
4052 current = some_dict['c']
4053 enddef
4054
4055 def G()
4056 current = some_dict['b']
4057 enddef
4058
4059 F()
4060 assert_equal(3, current.val)
4061 G()
4062 assert_equal(2, current.val)
4063 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004064 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004065enddef
4066
Ernie Raelee865f32023-09-29 19:53:55 +02004067" Test trying to lock an object variable from various places
4068def Test_lockvar_object_variable()
4069 # An object variable lockvar has several cases:
4070 # object method, scriptlevel, scriplevel from :def, :def arg
4071 # method arg, static method arg.
4072 # Also different depths
4073
Ernie Raelee865f32023-09-29 19:53:55 +02004074 #
4075 # lockvar of read-only object variable
4076 #
4077
4078 # read-only lockvar from object method
4079 var lines =<< trim END
4080 vim9script
4081
4082 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004083 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004084 def Lock()
4085 lockvar this.val1
4086 enddef
4087 endclass
4088 var o = C.new(3)
4089 o.Lock()
4090 END
Ernie Rael64885642023-10-04 20:16:22 +02004091 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004092
4093 # read-only lockvar from scriptlevel
4094 lines =<< trim END
4095 vim9script
4096
4097 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004098 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004099 endclass
4100 var o = C.new(3)
4101 lockvar o.val2
4102 END
4103 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4104
4105 # read-only lockvar of scriptlevel variable from def
4106 lines =<< trim END
4107 vim9script
4108
4109 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004110 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004111 endclass
4112 var o = C.new(3)
4113 def Lock()
4114 lockvar o.val3
4115 enddef
4116 Lock()
4117 END
4118 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4119
4120 # read-only lockvar of def argument variable
4121 lines =<< trim END
4122 vim9script
4123
4124 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004125 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004126 endclass
4127 def Lock(o: C)
4128 lockvar o.val4
4129 enddef
4130 Lock(C.new(3))
4131 END
4132 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4133
4134 # TODO: the following tests use type "any" for argument. Need a run time
4135 # check for access. Probably OK as is for now.
4136
4137 # read-only lockvar from object method arg
4138 lines =<< trim END
4139 vim9script
4140
4141 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004142 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004143 def Lock(o_any: any)
4144 lockvar o_any.val5
4145 enddef
4146 endclass
4147 var o = C.new(3)
4148 o.Lock(C.new(5))
4149 END
Ernie Rael64885642023-10-04 20:16:22 +02004150 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004151
4152 # read-only lockvar from class method arg
4153 lines =<< trim END
4154 vim9script
4155
4156 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004157 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004158 static def Lock(o_any: any)
4159 lockvar o_any.val6
4160 enddef
4161 endclass
4162 var o = C.new(3)
4163 C.Lock(o)
4164 END
Ernie Rael64885642023-10-04 20:16:22 +02004165 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004166
4167 #
4168 # lockvar of public object variable
4169 #
4170
4171 # lockvar from object method
4172 lines =<< trim END
4173 vim9script
4174
4175 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004176 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004177 def Lock()
4178 lockvar this.val1
4179 enddef
4180 endclass
4181 var o = C.new(3)
4182 o.Lock()
4183 END
4184 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4185
4186 # lockvar from scriptlevel
4187 lines =<< trim END
4188 vim9script
4189
4190 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004191 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004192 endclass
4193 var o = C.new(3)
4194 lockvar o.val2
4195 END
4196 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4197
4198 # lockvar of scriptlevel variable from def
4199 lines =<< trim END
4200 vim9script
4201
4202 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004203 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004204 endclass
4205 var o = C.new(3)
4206 def Lock()
4207 lockvar o.val3
4208 enddef
4209 Lock()
4210 END
4211 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4212
4213 # lockvar of def argument variable
4214 lines =<< trim END
4215 vim9script
4216
4217 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004218 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004219 endclass
4220 def Lock(o: C)
4221 lockvar o.val4
4222 enddef
4223 Lock(C.new(3))
4224 END
4225 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4226
4227 # lockvar from object method arg
4228 lines =<< trim END
4229 vim9script
4230
4231 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004232 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004233 def Lock(o_any: any)
4234 lockvar o_any.val5
4235 enddef
4236 endclass
4237 var o = C.new(3)
4238 o.Lock(C.new(5))
4239 END
4240 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4241
4242 # lockvar from class method arg
4243 lines =<< trim END
4244 vim9script
4245
4246 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004247 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004248 static def Lock(o_any: any)
4249 lockvar o_any.val6
4250 enddef
4251 endclass
4252 var o = C.new(3)
4253 C.Lock(o)
4254 END
4255 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4256enddef
4257
4258" Test trying to lock a class variable from various places
4259def Test_lockvar_class_variable()
4260
4261 # lockvar bare static from object method
4262 var lines =<< trim END
4263 vim9script
4264
4265 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004266 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004267 def Lock()
4268 lockvar sval1
4269 enddef
4270 endclass
4271 var o = C.new()
4272 o.Lock()
4273 END
4274 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4275
4276 # lockvar C.static from object method
4277 lines =<< trim END
4278 vim9script
4279
4280 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004281 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004282 def Lock()
4283 lockvar C.sval2
4284 enddef
4285 endclass
4286 var o = C.new()
4287 o.Lock()
4288 END
4289 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4290
4291 # lockvar bare static from class method
4292 lines =<< trim END
4293 vim9script
4294
4295 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004296 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004297 static def Lock()
4298 lockvar sval3
4299 enddef
4300 endclass
4301 C.Lock()
4302 END
4303 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4304
4305 # lockvar C.static from class method
4306 lines =<< trim END
4307 vim9script
4308
4309 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004310 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004311 static def Lock()
4312 lockvar C.sval4
4313 enddef
4314 endclass
4315 C.Lock()
4316 END
4317 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4318
4319 # lockvar C.static from script level
4320 lines =<< trim END
4321 vim9script
4322
4323 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004324 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004325 endclass
4326 lockvar C.sval5
4327 END
4328 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4329
4330 # lockvar o.static from script level
4331 lines =<< trim END
4332 vim9script
4333
4334 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004335 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004336 endclass
4337 var o = C.new()
4338 lockvar o.sval6
4339 END
4340 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4341enddef
4342
4343" Test locking an argument to :def
4344def Test_lockvar_argument()
4345 # Lockvar a function arg
4346 var lines =<< trim END
4347 vim9script
4348
4349 def Lock(val: any)
4350 lockvar val
4351 enddef
4352
4353 var d = {a: 1, b: 2}
4354 Lock(d)
4355
4356 d->extend({c: 3})
4357 END
4358 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4359
4360 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4361 # class member in "C". This tests lval_root_is_arg.
4362 lines =<< trim END
4363 vim9script
4364
4365 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004366 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004367 endclass
4368
4369 def Lock2(sval: any)
4370 lockvar sval
4371 enddef
4372
4373 var o = C.new()
4374 Lock2(o)
4375 END
4376 v9.CheckSourceSuccess(lines)
4377
4378 # Lock a class.
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 Lock2(C)
4391 END
Ernie Raelb077b582023-12-14 20:11:44 +01004392 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004393
4394 # Lock an object.
4395 lines =<< trim END
4396 vim9script
4397
4398 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004399 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004400 endclass
4401
4402 def Lock2(sval: any)
4403 lockvar sval
4404 enddef
4405
4406 Lock2(C.new())
4407 END
4408 v9.CheckSourceSuccess(lines)
4409
4410 # In this case (unlike previous) "lockvar sval" is a class member.
4411 lines =<< trim END
4412 vim9script
4413
4414 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004415 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004416 def Lock2()
4417 lockvar sval
4418 enddef
4419 endclass
4420
4421
4422 var o = C.new()
4423 o.Lock2()
4424 END
4425 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4426enddef
4427
4428" Test that this can be locked without error
4429def Test_lockvar_this()
4430 # lockvar this
4431 var lines =<< trim END
4432 vim9script
4433 class C
4434 def TLock()
4435 lockvar this
4436 enddef
4437 endclass
4438 var o = C.new()
4439 o.TLock()
4440 END
4441 v9.CheckSourceSuccess(lines)
4442
4443 # lockvar four (four letter word, but not this)
4444 lines =<< trim END
4445 vim9script
4446 class C
4447 def TLock4()
4448 var four: number
4449 lockvar four
4450 enddef
4451 endclass
4452 var o = C.new()
4453 o.TLock4()
4454 END
4455 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4456
4457 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4458 lines =<< trim END
4459 vim9script
4460 class C
4461 def TLock5()
4462 var this5: number
4463 lockvar this5
4464 enddef
4465 endclass
4466 var o = C.new()
4467 o.TLock5()
4468 END
4469 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4470enddef
4471
4472" Test some general lockvar cases
4473def Test_lockvar_general()
4474 # lockvar an object and a class. It does nothing
4475 var lines =<< trim END
4476 vim9script
4477 class C
4478 endclass
4479 var o = C.new()
4480 lockvar o
4481 lockvar C
4482 END
4483 v9.CheckSourceSuccess(lines)
4484
4485 # Lock a list element that's nested in an object variable from a :def
4486 lines =<< trim END
4487 vim9script
4488
4489 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004490 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004491 endclass
4492 def Lock2(obj: any)
4493 lockvar obj.val[1]
4494 enddef
4495
4496 var o = C.new()
4497 Lock2(o)
4498 o.val[0] = [9]
4499 assert_equal([ [9], [2], [3] ], o.val)
4500 try
4501 o.val[1] = [999]
4502 call assert_false(true, 'assign should have failed')
4503 catch
4504 assert_exception('E741:')
4505 endtry
4506 o.val[2] = [8]
4507 assert_equal([ [9], [2], [8] ], o.val)
4508 END
4509 v9.CheckSourceSuccess(lines)
4510
4511 # Lock a list element that's nested in an object variable from scriptlevel
4512 lines =<< trim END
4513 vim9script
4514
4515 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004516 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004517 endclass
4518
4519 var o = C.new()
4520 lockvar o.val[1]
4521 o.val[0] = [9]
4522 assert_equal([ [9], [2], [3] ], o.val)
4523 try
4524 o.val[1] = [999]
4525 call assert_false(true, 'assign should have failed')
4526 catch
4527 assert_exception('E741:')
4528 endtry
4529 o.val[2] = [8]
4530 assert_equal([ [9], [2], [8] ], o.val)
4531 END
4532 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004533
4534 # lock a script level variable from an object method
4535 lines =<< trim END
4536 vim9script
4537
4538 class C
4539 def Lock()
4540 lockvar l
4541 enddef
4542 endclass
4543
4544 var l = [1]
4545 C.new().Lock()
4546 l[0] = 11
4547 END
4548 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4549
Ernie Rael03042a22023-11-11 08:53:32 +01004550 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004551 # in an object fetched via a script level list
4552 lines =<< trim END
4553 vim9script
4554
4555 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004556 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004557 def Lock()
4558 lockvar lc[0]._v1[1]
4559 enddef
4560 endclass
4561
4562 var l = [[1], [2], [3]]
4563 var o = C.new(l)
4564 var lc: list<C> = [ o ]
4565
4566 o.Lock()
4567 l[0] = [22]
4568 l[1] = [33]
4569 END
4570 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4571
4572 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004573 # in a class that does not own the protected variable.
4574 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004575 # the same name.
4576 lines =<< trim END
4577 vim9script
4578
4579 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004580 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004581 def Lock(obj: any)
4582 lockvar lc[0]._v1[1]
4583 enddef
4584 endclass
4585
4586 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004587 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004588 endclass
4589
4590 var l = [[1], [2], [3]]
4591 var o = C.new(l)
4592 var lc: list<C> = [ o ]
4593
4594 var o2 = C2.new()
4595 o2.Lock(o)
4596 END
Ernie Rael03042a22023-11-11 08:53:32 +01004597 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004598enddef
4599
Ernie Rael9771b2a2023-10-07 22:05:40 +02004600" Test builtin islocked()
4601def Test_lockvar_islocked()
4602 # Can't lock class/object variable
4603 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004604 # Lock item of variable's value (a list item)
4605 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004606 var lines =<< trim END
4607 vim9script
4608
4609 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004610 var o0: list<list<number>> = [ [0], [1], [2]]
4611 var o1: list<list<number>> = [[10], [11], [12]]
4612 static var c0: list<list<number>> = [[20], [21], [22]]
4613 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004614 endclass
4615
4616 def LockIt(arg: any)
4617 lockvar arg
4618 enddef
4619
4620 def UnlockIt(arg: any)
4621 unlockvar arg
4622 enddef
4623
4624 var obj = C.new()
4625 #lockvar obj.o1 # can't lock something you can't write to
4626
4627 try
4628 lockvar obj.o1 # can't lock something you can't write to
4629 call assert_false(1, '"lockvar obj.o1" should have failed')
4630 catch
4631 call assert_exception('E1335:')
4632 endtry
4633
4634 LockIt(obj.o1) # but can lock it's value
4635 assert_equal(1, islocked("obj.o1"))
4636 assert_equal(1, islocked("obj.o1[0]"))
4637 assert_equal(1, islocked("obj.o1[1]"))
4638 UnlockIt(obj.o1)
4639 assert_equal(0, islocked("obj.o1"))
4640 assert_equal(0, islocked("obj.o1[0]"))
4641
4642 lockvar obj.o1[0]
4643 assert_equal(0, islocked("obj.o1"))
4644 assert_equal(1, islocked("obj.o1[0]"))
4645 assert_equal(0, islocked("obj.o1[1]"))
4646 unlockvar obj.o1[0]
4647 assert_equal(0, islocked("obj.o1"))
4648 assert_equal(0, islocked("obj.o1[0]"))
4649
4650 # Same thing, but with a static
4651
4652 try
4653 lockvar C.c1 # can't lock something you can't write to
4654 call assert_false(1, '"lockvar C.c1" should have failed')
4655 catch
4656 call assert_exception('E1335:')
4657 endtry
4658
4659 LockIt(C.c1) # but can lock it's value
4660 assert_equal(1, islocked("C.c1"))
4661 assert_equal(1, islocked("C.c1[0]"))
4662 assert_equal(1, islocked("C.c1[1]"))
4663 UnlockIt(C.c1)
4664 assert_equal(0, islocked("C.c1"))
4665 assert_equal(0, islocked("C.c1[0]"))
4666
4667 lockvar C.c1[0]
4668 assert_equal(0, islocked("C.c1"))
4669 assert_equal(1, islocked("C.c1[0]"))
4670 assert_equal(0, islocked("C.c1[1]"))
4671 unlockvar C.c1[0]
4672 assert_equal(0, islocked("C.c1"))
4673 assert_equal(0, islocked("C.c1[0]"))
4674 END
4675 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004676
4677 # Do islocked() from an object method
4678 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004679 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004680 vim9script
4681
4682 var l0o0 = [ [0], [1], [2]]
4683 var l0o1 = [ [10], [11], [12]]
4684 var l0c0 = [[120], [121], [122]]
4685 var l0c1 = [[130], [131], [132]]
4686
4687 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004688 var o0: list<list<number>> = l0o0
4689 var o1: list<list<number>> = l0o1
4690 static var c0: list<list<number>> = l0c0
4691 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004692 def Islocked(arg: string): number
4693 return islocked(arg)
4694 enddef
4695 static def SIslocked(arg: string): number
4696 return islocked(arg)
4697 enddef
4698 endclass
4699
4700 var l2o0 = [[20000], [20001], [20002]]
4701 var l2o1 = [[20010], [20011], [20012]]
4702 var l2c0 = [[20120], [20121], [20122]]
4703 var l2c1 = [[20130], [20131], [20132]]
4704
4705 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004706 var o0: list<list<number>> = l2o0
4707 var o1: list<list<number>> = l2o1
4708 static var c0: list<list<number>> = l2c0
4709 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004710 def Islocked(arg: string): number
4711 return islocked(arg)
4712 enddef
4713 static def SIslocked(arg: string): number
4714 return islocked(arg)
4715 enddef
4716 endclass
4717
4718 var obj0 = C0.new()
4719 var obj2 = C2.new()
4720
4721 var l = [ obj0, null_object, obj2 ]
4722
4723 # lock list, object func access through script var expr
4724 assert_equal(0, obj0.Islocked("l[0].o0"))
4725 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4726 lockvar l0o0
4727 assert_equal(1, obj0.Islocked("l[0].o0"))
4728 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4729
4730 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4731
4732 # lock list element, object func access through script var expr
4733 lockvar l0o1[1]
4734 assert_equal(0, obj0.Islocked("this.o1[0]"))
4735 assert_equal(1, obj0.Islocked("this.o1[1]"))
4736
4737 assert_equal(0, obj0.Islocked("this.o1"))
4738 lockvar l0o1
4739 assert_equal(1, obj0.Islocked("this.o1"))
4740 unlockvar l0o1
4741
4742 lockvar l0c1[1]
4743
4744 # static by class name member expr from same class
4745 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4746 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4747 # static by bare name member expr from same class
4748 assert_equal(0, obj0.Islocked("c1[0]"))
4749 assert_equal(1, obj0.Islocked("c1[1]"))
4750
4751 # static by class name member expr from other class
4752 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4753 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4754 # static by bare name member expr from other class
4755 assert_equal(0, obj2.Islocked("c1[0]"))
4756 assert_equal(0, obj2.Islocked("c1[1]"))
4757
4758
4759 # static by bare name in same class
4760 assert_equal(0, obj0.Islocked("c0"))
4761 lockvar l0c0
4762 assert_equal(1, obj0.Islocked("c0"))
4763
4764 #
4765 # similar stuff, but use static method
4766 #
4767
4768 unlockvar l0o0
4769
4770 # lock list, object func access through script var expr
4771 assert_equal(0, C0.SIslocked("l[0].o0"))
4772 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4773 lockvar l0o0
4774 assert_equal(1, C0.SIslocked("l[0].o0"))
4775 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4776
4777 unlockvar l0o1
4778
4779 # can't access "this" from class method
4780 try
4781 C0.SIslocked("this.o1[0]")
4782 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4783 catch
4784 call assert_exception('E121: Undefined variable: this')
4785 endtry
4786
4787 lockvar l0c1[1]
4788
4789 # static by class name member expr from same class
4790 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4791 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4792 # static by bare name member expr from same class
4793 assert_equal(0, C0.SIslocked("c1[0]"))
4794 assert_equal(1, C0.SIslocked("c1[1]"))
4795
4796 # static by class name member expr from other class
4797 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4798 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4799 # static by bare name member expr from other class
4800 assert_equal(0, C2.SIslocked("c1[0]"))
4801 assert_equal(0, C2.SIslocked("c1[1]"))
4802
4803
4804 # static by bare name in same class
4805 unlockvar l0c0
4806 assert_equal(0, C0.SIslocked("c0"))
4807 lockvar l0c0
4808 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004809 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004810 v9.CheckSourceSuccess(lines)
4811
4812 # Check islocked class/object from various places.
4813 lines =<< trim END
4814 vim9script
4815
4816 class C
4817 def Islocked(arg: string): number
4818 return islocked(arg)
4819 enddef
4820 static def SIslocked(arg: string): number
4821 return islocked(arg)
4822 enddef
4823 endclass
4824 var obj = C.new()
4825
4826 # object method
4827 assert_equal(0, obj.Islocked("this"))
4828 assert_equal(0, obj.Islocked("C"))
4829
4830 # class method
4831 ### assert_equal(0, C.SIslocked("this"))
4832 assert_equal(0, C.SIslocked("C"))
4833
4834 #script level
4835 var v: number
4836 v = islocked("C")
4837 assert_equal(0, v)
4838 v = islocked("obj")
4839 assert_equal(0, v)
4840 END
4841 v9.CheckSourceSuccess(lines)
4842enddef
4843
4844def Test_lockvar_islocked_notfound()
4845 # Try non-existent things
4846 var lines =<< trim END
4847 vim9script
4848
4849 class C
4850 def Islocked(arg: string): number
4851 return islocked(arg)
4852 enddef
4853 static def SIslocked(arg: string): number
4854 return islocked(arg)
4855 enddef
4856 endclass
4857 var obj = C.new()
4858 assert_equal(-1, obj.Islocked("anywhere"))
4859 assert_equal(-1, C.SIslocked("notanywhere"))
4860 END
4861 v9.CheckSourceSuccess(lines)
4862
4863 # Something not found of the form "name1.name2" is an error
4864 lines =<< trim END
4865 vim9script
4866
4867 islocked("one.two")
4868 END
4869 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4870
4871 lines =<< trim END
4872 vim9script
4873
4874 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004875 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004876 def Islocked(arg: string): number
4877 return islocked(arg)
4878 enddef
4879 endclass
4880 var obj = C.new()
4881 obj.Islocked("this.val.not_there"))
4882 END
4883 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4884
4885 lines =<< trim END
4886 vim9script
4887
4888 class C
4889 def Islocked(arg: string): number
4890 return islocked(arg)
4891 enddef
4892 endclass
4893 var obj = C.new()
4894 obj.Islocked("this.notobjmember")
4895 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004896 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004897
4898 # access a script variable through methods
4899 lines =<< trim END
4900 vim9script
4901
4902 var l = [1]
4903 class C
4904 def Islocked(arg: string): number
4905 return islocked(arg)
4906 enddef
4907 static def SIslocked(arg: string): number
4908 return islocked(arg)
4909 enddef
4910 endclass
4911 var obj = C.new()
4912 assert_equal(0, obj.Islocked("l"))
4913 assert_equal(0, C.SIslocked("l"))
4914 lockvar l
4915 assert_equal(1, obj.Islocked("l"))
4916 assert_equal(1, C.SIslocked("l"))
4917 END
4918 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004919enddef
4920
Ernie Rael03042a22023-11-11 08:53:32 +01004921" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004922def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004923 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004924 var lines =<< trim END
4925 vim9script
4926
4927 class A
4928 def _Foo(): number
4929 return 1234
4930 enddef
4931 endclass
4932 var a = A.new()
4933 a._Foo()
4934 END
Ernie Rael03042a22023-11-11 08:53:32 +01004935 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004936
Ernie Rael03042a22023-11-11 08:53:32 +01004937 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004938 lines =<< trim END
4939 vim9script
4940
4941 class A
4942 def _Foo(): number
4943 return 1234
4944 enddef
4945 endclass
4946 def T()
4947 var a = A.new()
4948 a._Foo()
4949 enddef
4950 T()
4951 END
Ernie Rael03042a22023-11-11 08:53:32 +01004952 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004953
Ernie Rael03042a22023-11-11 08:53:32 +01004954 # Use a protected method from another object method (in script context)
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 def Bar(): number
4963 return this._Foo()
4964 enddef
4965 endclass
4966 var a = A.new()
4967 assert_equal(1234, a.Bar())
4968 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004969 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004970
Ernie Rael03042a22023-11-11 08:53:32 +01004971 # Use a protected method from another object method (def function 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 def T()
4984 var a = A.new()
4985 assert_equal(1234, a.Bar())
4986 enddef
4987 T()
4988 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004989 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004990
Ernie Rael03042a22023-11-11 08:53:32 +01004991 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004992 lines =<< trim END
4993 vim9script
4994
4995 class A
4996 def _Foo(): number
4997 return 1234
4998 enddef
4999 def Bar(): number
5000 return _Foo()
5001 enddef
5002 endclass
5003 var a = A.new()
5004 a.Bar()
5005 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005006 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005007
Ernie Rael03042a22023-11-11 08:53:32 +01005008 # Try calling a protected method using the class name
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 endclass
5017 A._Foo()
5018 END
Ernie Rael03042a22023-11-11 08:53:32 +01005019 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005020
Ernie Rael03042a22023-11-11 08:53:32 +01005021 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005022 lines =<< trim END
5023 vim9script
5024
5025 class A
5026 def _Foo()
5027 enddef
5028 def _Foo()
5029 enddef
5030 endclass
5031 var a = A.new()
5032 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005033 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005034
Ernie Rael03042a22023-11-11 08:53:32 +01005035 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005036 lines =<< trim END
5037 vim9script
5038
5039 class A
5040 def _Foo()
5041 enddef
5042 def Foo()
5043 enddef
5044 endclass
5045 var a = A.new()
5046 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005047 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005048
Ernie Rael03042a22023-11-11 08:53:32 +01005049 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005050 lines =<< trim END
5051 vim9script
5052
5053 class A
5054 def Foo()
5055 enddef
5056 def _Foo()
5057 enddef
5058 endclass
5059 var a = A.new()
5060 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005061 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005062
Ernie Rael03042a22023-11-11 08:53:32 +01005063 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005064 lines =<< trim END
5065 vim9script
5066
5067 class A
5068 def Foo(): number
5069 return 100
5070 enddef
5071 def _Bar(): number
5072 return 200
5073 enddef
5074 def _Baz()
5075 assert_equal(100, this.Foo())
5076 assert_equal(200, this._Bar())
5077 enddef
5078 def T()
5079 this._Baz()
5080 enddef
5081 endclass
5082 var a = A.new()
5083 a.T()
5084 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005085 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005086
Ernie Rael03042a22023-11-11 08:53:32 +01005087 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005088 lines =<< trim END
5089 vim9script
5090
5091 class A
5092 def _Foo(): number
5093 return 100
5094 enddef
5095 endclass
5096 class B
5097 def Foo(): number
5098 var a = A.new()
5099 a._Foo()
5100 enddef
5101 endclass
5102 var b = B.new()
5103 b.Foo()
5104 END
Ernie Rael03042a22023-11-11 08:53:32 +01005105 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005106
Ernie Rael03042a22023-11-11 08:53:32 +01005107 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005108 lines =<< trim END
5109 vim9script
5110 class A
5111 def _Foo(): number
5112 return 1234
5113 enddef
5114 endclass
5115 class B extends A
5116 def Bar()
5117 enddef
5118 endclass
5119 class C extends B
5120 def Baz(): number
5121 return this._Foo()
5122 enddef
5123 endclass
5124 var c = C.new()
5125 assert_equal(1234, c.Baz())
5126 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005127 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005128
Ernie Rael03042a22023-11-11 08:53:32 +01005129 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005130 lines =<< trim END
5131 vim9script
5132 class A
5133 def _Foo(): number
5134 return 1234
5135 enddef
5136 endclass
5137 class B extends A
5138 def Bar()
5139 enddef
5140 endclass
5141 class C extends B
5142 def Baz(): number
5143 enddef
5144 endclass
5145 var c = C.new()
5146 assert_equal(1234, c._Foo())
5147 END
Ernie Rael03042a22023-11-11 08:53:32 +01005148 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005149
5150 # Using "_" prefix in a method name should fail outside of a class
5151 lines =<< trim END
5152 vim9script
5153 def _Foo(): number
5154 return 1234
5155 enddef
5156 var a = _Foo()
5157 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005158 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005159enddef
5160
Ernie Rael03042a22023-11-11 08:53:32 +01005161" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005162def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005163 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005164 var lines =<< trim END
5165 vim9script
5166
5167 class A
5168 static def _Foo(): number
5169 return 1234
5170 enddef
5171 endclass
5172 A._Foo()
5173 END
Ernie Rael03042a22023-11-11 08:53:32 +01005174 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005175
Ernie Rael03042a22023-11-11 08:53:32 +01005176 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005177 lines =<< trim END
5178 vim9script
5179
5180 class A
5181 static def _Foo(): number
5182 return 1234
5183 enddef
5184 endclass
5185 def T()
5186 A._Foo()
5187 enddef
5188 T()
5189 END
Ernie Rael03042a22023-11-11 08:53:32 +01005190 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005191
Ernie Rael03042a22023-11-11 08:53:32 +01005192 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005193 lines =<< trim END
5194 vim9script
5195
5196 class A
5197 static def _Foo(): number
5198 return 1234
5199 enddef
5200 endclass
5201 var a = A.new()
5202 a._Foo()
5203 END
Ernie Rael03042a22023-11-11 08:53:32 +01005204 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005205
Ernie Rael03042a22023-11-11 08:53:32 +01005206 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005207 lines =<< trim END
5208 vim9script
5209
5210 class A
5211 static def _Foo(): number
5212 return 1234
5213 enddef
5214 endclass
5215 def T()
5216 var a = A.new()
5217 a._Foo()
5218 enddef
5219 T()
5220 END
Ernie Rael03042a22023-11-11 08:53:32 +01005221 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005222
Ernie Rael03042a22023-11-11 08:53:32 +01005223 # Use a class protected method from an object method
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 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005232 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005233 enddef
5234 endclass
5235 var a = A.new()
5236 a.Bar()
5237 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005238 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005239
Ernie Rael03042a22023-11-11 08:53:32 +01005240 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005241 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005242 lines =<< trim END
5243 vim9script
5244
5245 class A
5246 static def _Foo1(): number
5247 return 1234
5248 enddef
5249 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005250 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005251 enddef
5252 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005253 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005254 enddef
5255 endclass
5256 var a = A.new()
5257 a.Bar()
5258 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005259 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005260
Ernie Rael03042a22023-11-11 08:53:32 +01005261 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005262 lines =<< trim END
5263 vim9script
5264
5265 class A
5266 static def _Foo()
5267 enddef
5268 static def Foo()
5269 enddef
5270 endclass
5271 var a = A.new()
5272 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005273 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005274
Ernie Rael03042a22023-11-11 08:53:32 +01005275 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005276 lines =<< trim END
5277 vim9script
5278
5279 class A
5280 static def _Foo(): number
5281 return 1234
5282 enddef
5283 endclass
5284 class B
5285 def Foo(): number
5286 return A._Foo()
5287 enddef
5288 endclass
5289 var b = B.new()
5290 assert_equal(1234, b.Foo())
5291 END
Ernie Rael03042a22023-11-11 08:53:32 +01005292 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005293
Ernie Rael03042a22023-11-11 08:53:32 +01005294 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005295 lines =<< trim END
5296 vim9script
5297 class A
5298 static def _Foo(): number
5299 return 1234
5300 enddef
5301 endclass
5302 class B extends A
5303 def Bar()
5304 enddef
5305 endclass
5306 class C extends B
5307 def Baz(): number
5308 return A._Foo()
5309 enddef
5310 endclass
5311 var c = C.new()
5312 assert_equal(1234, c.Baz())
5313 END
Ernie Rael03042a22023-11-11 08:53:32 +01005314 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005315
Ernie Rael03042a22023-11-11 08:53:32 +01005316 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005317 lines =<< trim END
5318 vim9script
5319 class A
5320 static def _Foo(): number
5321 return 1234
5322 enddef
5323 endclass
5324 class B extends A
5325 def Bar()
5326 enddef
5327 endclass
5328 class C extends B
5329 static def Baz(): number
5330 return A._Foo()
5331 enddef
5332 endclass
5333 assert_equal(1234, C.Baz())
5334 END
Ernie Rael03042a22023-11-11 08:53:32 +01005335 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005336
Ernie Rael03042a22023-11-11 08:53:32 +01005337 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005338 lines =<< trim END
5339 vim9script
5340 class A
5341 static def _Foo(): number
5342 return 1234
5343 enddef
5344 endclass
5345 class B extends A
5346 def Bar()
5347 enddef
5348 endclass
5349 class C extends B
5350 def Baz(): number
5351 enddef
5352 endclass
5353 var c = C.new()
5354 assert_equal(1234, C._Foo())
5355 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005356 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005357enddef
5358
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005359" Test for using the return value of a class/object method as a function
5360" argument.
5361def Test_objmethod_funcarg()
5362 var lines =<< trim END
5363 vim9script
5364
5365 class C
5366 def Foo(): string
5367 return 'foo'
5368 enddef
5369 endclass
5370
5371 def Bar(a: number, s: string): string
5372 return s
5373 enddef
5374
5375 def Baz(c: C)
5376 assert_equal('foo', Bar(10, c.Foo()))
5377 enddef
5378
5379 var t = C.new()
5380 Baz(t)
5381 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005382 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005383
5384 lines =<< trim END
5385 vim9script
5386
5387 class C
5388 static def Foo(): string
5389 return 'foo'
5390 enddef
5391 endclass
5392
5393 def Bar(a: number, s: string): string
5394 return s
5395 enddef
5396
5397 def Baz()
5398 assert_equal('foo', Bar(10, C.Foo()))
5399 enddef
5400
5401 Baz()
5402 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005403 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005404enddef
5405
Ernie Raelcf138d42023-09-06 20:45:03 +02005406def Test_static_inheritence()
5407 # subclasses get their own static copy
5408 var lines =<< trim END
5409 vim9script
5410
5411 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005412 static var _svar: number
5413 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005414 def new()
5415 _svar = 1
5416 this._mvar = 101
5417 enddef
5418 def AccessObject(): number
5419 return this._mvar
5420 enddef
5421 def AccessStaticThroughObject(): number
5422 return _svar
5423 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005424 endclass
5425
5426 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005427 def new()
5428 this._mvar = 102
5429 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005430 endclass
5431
5432 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005433 def new()
5434 this._mvar = 103
5435 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005436
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005437 def AccessPrivateStaticThroughClassName(): number
5438 assert_equal(1, A._svar)
5439 return 444
5440 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005441 endclass
5442
5443 var oa = A.new()
5444 var ob = B.new()
5445 var oc = C.new()
5446 assert_equal(101, oa.AccessObject())
5447 assert_equal(102, ob.AccessObject())
5448 assert_equal(103, oc.AccessObject())
5449
Ernie Rael03042a22023-11-11 08:53:32 +01005450 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005451
5452 # verify object properly resolves to correct static
5453 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005454 assert_equal(1, ob.AccessStaticThroughObject())
5455 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005456 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005457 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005458enddef
5459
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005460" Test for declaring duplicate object and class members
5461def Test_dup_member_variable()
5462 # Duplicate member variable
5463 var lines =<< trim END
5464 vim9script
5465 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005466 var val = 10
5467 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005468 endclass
5469 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005470 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005471
Ernie Rael03042a22023-11-11 08:53:32 +01005472 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005473 lines =<< trim END
5474 vim9script
5475 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005476 var _val = 10
5477 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005478 endclass
5479 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005480 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005481
5482 # Duplicate public member variable
5483 lines =<< trim END
5484 vim9script
5485 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005486 public var val = 10
5487 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005488 endclass
5489 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005490 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005491
Ernie Rael03042a22023-11-11 08:53:32 +01005492 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005493 lines =<< trim END
5494 vim9script
5495 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005496 var val = 10
5497 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005498 endclass
5499 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005500 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005501
Ernie Rael03042a22023-11-11 08:53:32 +01005502 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005503 lines =<< trim END
5504 vim9script
5505 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005506 var _val = 20
5507 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005508 endclass
5509 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005510 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005511
5512 # Duplicate class member variable
5513 lines =<< trim END
5514 vim9script
5515 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005516 static var s: string = "abc"
5517 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005518 endclass
5519 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005520 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005521
Ernie Rael03042a22023-11-11 08:53:32 +01005522 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005523 lines =<< trim END
5524 vim9script
5525 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005526 public static var s: string = "abc"
5527 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005528 endclass
5529 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005530 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005531
5532 # Duplicate class and object member variable
5533 lines =<< trim END
5534 vim9script
5535 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005536 static var val = 10
5537 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005538 def new()
5539 enddef
5540 endclass
5541 var c = C.new()
5542 assert_equal(10, C.val)
5543 assert_equal(20, c.val)
5544 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005545 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005546
5547 # Duplicate object member variable in a derived class
5548 lines =<< trim END
5549 vim9script
5550 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005551 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005552 endclass
5553 class B extends A
5554 endclass
5555 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005556 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005557 endclass
5558 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005559 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005560
Ernie Rael03042a22023-11-11 08:53:32 +01005561 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005562 lines =<< trim END
5563 vim9script
5564 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005565 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005566 endclass
5567 class B extends A
5568 endclass
5569 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005570 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005571 endclass
5572 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005573 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005574
Ernie Rael03042a22023-11-11 08:53:32 +01005575 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005576 lines =<< trim END
5577 vim9script
5578 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005579 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005580 endclass
5581 class B extends A
5582 endclass
5583 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005584 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005585 endclass
5586 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005587 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005588
5589 # Duplicate object member variable in a derived class
5590 lines =<< trim END
5591 vim9script
5592 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005593 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005594 endclass
5595 class B extends A
5596 endclass
5597 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005598 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005599 endclass
5600 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005601 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005602
5603 # Two member variables with a common prefix
5604 lines =<< trim END
5605 vim9script
5606 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005607 public static var svar2: number
5608 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005609 endclass
5610 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005611 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005612enddef
5613
Ernie Rael03042a22023-11-11 08:53:32 +01005614" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005615def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005616 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005617 var lines =<< trim END
5618 vim9script
5619 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005620 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005621 def GetVal(): number
5622 return this._val
5623 enddef
5624 endclass
5625 def T()
5626 var a = A.new()
5627 a._val = 20
5628 enddef
5629 T()
5630 END
Ernie Rael03042a22023-11-11 08:53:32 +01005631 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005632
Ernie Rael03042a22023-11-11 08:53:32 +01005633 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005634 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 endclass
5639 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005640 var a = A.new()
5641 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005642 enddef
5643 T()
5644 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005645 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005646
Ernie Rael03042a22023-11-11 08:53:32 +01005647 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005648 lines =<< trim END
5649 vim9script
5650 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005651 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005652 endclass
5653 def T()
5654 var a = A.new()
5655 var x = a._val
5656 enddef
5657 T()
5658 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005659 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005660
Ernie Rael03042a22023-11-11 08:53:32 +01005661 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005662 lines =<< trim END
5663 vim9script
5664 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005665 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005666 endclass
5667 def T()
5668 var a = A.new()
5669 a._val = 3
5670 enddef
5671 T()
5672 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005673 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005674
Ernie Rael03042a22023-11-11 08:53:32 +01005675 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005676 lines =<< trim END
5677 vim9script
5678 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005679 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005680 endclass
5681 def T()
5682 var x = A._val
5683 enddef
5684 T()
5685 END
Ernie Rael03042a22023-11-11 08:53:32 +01005686 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005687
Ernie Rael03042a22023-11-11 08:53:32 +01005688 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005689 lines =<< trim END
5690 vim9script
5691 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005692 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005693 endclass
5694 def T()
5695 A._val = 3
5696 enddef
5697 T()
5698 END
Ernie Rael03042a22023-11-11 08:53:32 +01005699 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005700enddef
5701
5702" Test for changing the member access of an interface in a implementation class
5703def Test_change_interface_member_access()
5704 var lines =<< trim END
5705 vim9script
5706 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005707 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005708 endinterface
5709 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005710 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005711 endclass
5712 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005713 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005714
5715 lines =<< trim END
5716 vim9script
5717 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005718 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005719 endinterface
5720 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005721 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005722 endclass
5723 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005724 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005725enddef
5726
5727" Test for trying to change a readonly member from a def function
5728def Test_readonly_member_change_in_def_func()
5729 var lines =<< trim END
5730 vim9script
5731 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005732 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005733 endclass
5734 def T()
5735 var a = A.new()
5736 a.val = 20
5737 enddef
5738 T()
5739 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005740 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005741enddef
5742
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005743" Test for reading and writing a class member from a def function
5744def Test_modify_class_member_from_def_function()
5745 var lines =<< trim END
5746 vim9script
5747 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005748 var var1: number = 10
5749 public static var var2: list<number> = [1, 2]
5750 public static var var3: dict<number> = {a: 1, b: 2}
5751 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005752 endclass
5753 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005754 assert_equal([1, 2], A.var2)
5755 assert_equal({a: 1, b: 2}, A.var3)
5756 A.var2 = [3, 4]
5757 A.var3 = {c: 3, d: 4}
5758 assert_equal([3, 4], A.var2)
5759 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005760 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005761 enddef
5762 T()
5763 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005764 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005765enddef
5766
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005767" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005768def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005769 var lines =<< trim END
5770 vim9script
5771 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005772 public static var svar1: list<number> = [1]
5773 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005774 endclass
5775
5776 A.svar1->add(3)
5777 A.svar2->add(4)
5778 assert_equal([1, 3], A.svar1)
5779 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005780
5781 def Foo()
5782 A.svar1->add(7)
5783 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005784 assert_equal([1, 3, 7], A.svar1)
5785 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005786 enddef
5787 Foo()
5788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005789 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005790
5791 # Cannot read from a class variable using an object in script context
5792 lines =<< trim END
5793 vim9script
5794 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005795 public var var1: number
5796 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005797 endclass
5798
5799 var a = A.new()
5800 echo a.svar2
5801 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005802 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005803
5804 # Cannot write to a class variable using an object in script context
5805 lines =<< trim END
5806 vim9script
5807 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005808 public var var1: number
5809 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005810 endclass
5811
5812 var a = A.new()
5813 a.svar2 = [2]
5814 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005815 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005816
5817 # Cannot read from a class variable using an object in def method context
5818 lines =<< trim END
5819 vim9script
5820 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005821 public var var1: number
5822 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005823 endclass
5824
5825 def T()
5826 var a = A.new()
5827 echo a.svar2
5828 enddef
5829 T()
5830 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005831 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005832
5833 # Cannot write to a class variable using an object in def method context
5834 lines =<< trim END
5835 vim9script
5836 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005837 public var var1: number
5838 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005839 endclass
5840
5841 def T()
5842 var a = A.new()
5843 a.svar2 = [2]
5844 enddef
5845 T()
5846 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005847 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005848enddef
5849
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005850" Test for using a interface method using a child object
5851def Test_interface_method_from_child()
5852 var lines =<< trim END
5853 vim9script
5854
5855 interface A
5856 def Foo(): string
5857 endinterface
5858
5859 class B implements A
5860 def Foo(): string
5861 return 'foo'
5862 enddef
5863 endclass
5864
5865 class C extends B
5866 def Bar(): string
5867 return 'bar'
5868 enddef
5869 endclass
5870
5871 def T1(a: A)
5872 assert_equal('foo', a.Foo())
5873 enddef
5874
5875 def T2(b: B)
5876 assert_equal('foo', b.Foo())
5877 enddef
5878
5879 var c = C.new()
5880 T1(c)
5881 T2(c)
5882 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005883 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005884enddef
5885
5886" Test for using an interface method using a child object when it is overridden
5887" by the child class.
5888" FIXME: This test fails.
5889" def Test_interface_overridden_method_from_child()
5890" var lines =<< trim END
5891" vim9script
5892"
5893" interface A
5894" def Foo(): string
5895" endinterface
5896"
5897" class B implements A
5898" def Foo(): string
5899" return 'b-foo'
5900" enddef
5901" endclass
5902"
5903" class C extends B
5904" def Bar(): string
5905" return 'bar'
5906" enddef
5907" def Foo(): string
5908" return 'c-foo'
5909" enddef
5910" endclass
5911"
5912" def T1(a: A)
5913" assert_equal('c-foo', a.Foo())
5914" enddef
5915"
5916" def T2(b: B)
5917" assert_equal('c-foo', b.Foo())
5918" enddef
5919"
5920" var c = C.new()
5921" T1(c)
5922" T2(c)
5923" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005924" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005925" enddef
5926
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005927" Test for abstract methods
5928def Test_abstract_method()
5929 # Use two abstract methods
5930 var lines =<< trim END
5931 vim9script
5932 abstract class A
5933 def M1(): number
5934 return 10
5935 enddef
5936 abstract def M2(): number
5937 abstract def M3(): number
5938 endclass
5939 class B extends A
5940 def M2(): number
5941 return 20
5942 enddef
5943 def M3(): number
5944 return 30
5945 enddef
5946 endclass
5947 var b = B.new()
5948 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5949 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005950 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005951
5952 # Don't define an abstract method
5953 lines =<< trim END
5954 vim9script
5955 abstract class A
5956 abstract def Foo()
5957 endclass
5958 class B extends A
5959 endclass
5960 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005961 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005962
5963 # Use abstract method in a concrete class
5964 lines =<< trim END
5965 vim9script
5966 class A
5967 abstract def Foo()
5968 endclass
5969 class B extends A
5970 endclass
5971 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005972 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005973
5974 # Use abstract method in an interface
5975 lines =<< trim END
5976 vim9script
5977 interface A
5978 abstract def Foo()
5979 endinterface
5980 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005981 def Foo()
5982 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005983 endclass
5984 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005985 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5986
5987 # Use abstract static method in an interface
5988 lines =<< trim END
5989 vim9script
5990 interface A
5991 abstract static def Foo()
5992 enddef
5993 endinterface
5994 END
5995 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5996
5997 # Use abstract static variable in an interface
5998 lines =<< trim END
5999 vim9script
6000 interface A
6001 abstract static foo: number = 10
6002 endinterface
6003 END
6004 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006005
6006 # Abbreviate the "abstract" keyword
6007 lines =<< trim END
6008 vim9script
6009 class A
6010 abs def Foo()
6011 endclass
6012 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006013 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006014
6015 # Use "abstract" with a member variable
6016 lines =<< trim END
6017 vim9script
6018 abstract class A
6019 abstract this.val = 10
6020 endclass
6021 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006022 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006023
6024 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01006025 lines =<< trim END
6026 vim9script
6027 abstract class A
6028 abstract static def Foo(): number
6029 endclass
6030 END
6031 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006032
6033 # Type mismatch between abstract method and concrete method
6034 lines =<< trim END
6035 vim9script
6036 abstract class A
6037 abstract def Foo(a: string, b: number): list<number>
6038 endclass
6039 class B extends A
6040 def Foo(a: number, b: string): list<string>
6041 return []
6042 enddef
6043 endclass
6044 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006045 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 +02006046
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006047 # Invoke an abstract method from a def function
6048 lines =<< trim END
6049 vim9script
6050 abstract class A
6051 abstract def Foo(): list<number>
6052 endclass
6053 class B extends A
6054 def Foo(): list<number>
6055 return [3, 5]
6056 enddef
6057 endclass
6058 def Bar(c: B)
6059 assert_equal([3, 5], c.Foo())
6060 enddef
6061 var b = B.new()
6062 Bar(b)
6063 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006064 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006065
6066 # Use a static method in an abstract class
6067 lines =<< trim END
6068 vim9script
6069 abstract class A
6070 static def Foo(): string
6071 return 'foo'
6072 enddef
6073 endclass
6074 assert_equal('foo', A.Foo())
6075 END
6076 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006077enddef
6078
6079" Test for calling a class method from a subclass
6080def Test_class_method_call_from_subclass()
6081 # class method call from a subclass
6082 var lines =<< trim END
6083 vim9script
6084
6085 class A
6086 static def Foo()
6087 echo "foo"
6088 enddef
6089 endclass
6090
6091 class B extends A
6092 def Bar()
6093 Foo()
6094 enddef
6095 endclass
6096
6097 var b = B.new()
6098 b.Bar()
6099 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006100 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006101enddef
6102
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006103" Test for calling a class method using an object in a def function context and
6104" script context.
6105def Test_class_method_call_using_object()
6106 # script context
6107 var lines =<< trim END
6108 vim9script
6109 class A
6110 static def Foo(): list<string>
6111 return ['a', 'b']
6112 enddef
6113 def Bar()
6114 assert_equal(['a', 'b'], A.Foo())
6115 assert_equal(['a', 'b'], Foo())
6116 enddef
6117 endclass
6118
6119 def T()
6120 assert_equal(['a', 'b'], A.Foo())
6121 var t_a = A.new()
6122 t_a.Bar()
6123 enddef
6124
6125 assert_equal(['a', 'b'], A.Foo())
6126 var a = A.new()
6127 a.Bar()
6128 T()
6129 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006130 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006131
6132 # script context
6133 lines =<< trim END
6134 vim9script
6135 class A
6136 static def Foo(): string
6137 return 'foo'
6138 enddef
6139 endclass
6140
6141 var a = A.new()
6142 assert_equal('foo', a.Foo())
6143 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006144 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006145
6146 # def function context
6147 lines =<< trim END
6148 vim9script
6149 class A
6150 static def Foo(): string
6151 return 'foo'
6152 enddef
6153 endclass
6154
6155 def T()
6156 var a = A.new()
6157 assert_equal('foo', a.Foo())
6158 enddef
6159 T()
6160 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006161 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006162enddef
6163
6164def Test_class_variable()
6165 var lines =<< trim END
6166 vim9script
6167
6168 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006169 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006170 static def ClassFunc()
6171 assert_equal(10, val)
6172 enddef
6173 def ObjFunc()
6174 assert_equal(10, val)
6175 enddef
6176 endclass
6177
6178 class B extends A
6179 endclass
6180
6181 assert_equal(10, A.val)
6182 A.ClassFunc()
6183 var a = A.new()
6184 a.ObjFunc()
6185 var b = B.new()
6186 b.ObjFunc()
6187
6188 def T1(a1: A)
6189 a1.ObjFunc()
6190 A.ClassFunc()
6191 enddef
6192 T1(b)
6193
6194 A.val = 20
6195 assert_equal(20, A.val)
6196 END
6197 v9.CheckSourceSuccess(lines)
6198
6199 # Modifying a parent class variable from a child class method
6200 lines =<< trim END
6201 vim9script
6202
6203 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006204 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006205 endclass
6206
6207 class B extends A
6208 static def ClassFunc()
6209 val = 20
6210 enddef
6211 endclass
6212 B.ClassFunc()
6213 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006214 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006215
6216 # Reading 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 var i = val
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 # Modifying a parent class variable from a child object 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 def ObjFunc()
6243 val = 20
6244 enddef
6245 endclass
6246 var b = B.new()
6247 b.ObjFunc()
6248 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006249 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006250
6251 # Reading a parent class variable from a child object method
6252 lines =<< trim END
6253 vim9script
6254
6255 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006256 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006257 endclass
6258
6259 class B extends A
6260 def ObjFunc()
6261 var i = val
6262 enddef
6263 endclass
6264 var b = B.new()
6265 b.ObjFunc()
6266 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006267 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006268
6269 # Modifying a class variable using an object at script level
6270 lines =<< trim END
6271 vim9script
6272
6273 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006274 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006275 endclass
6276 var a = A.new()
6277 a.val = 20
6278 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006279 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006280
6281 # Reading a class variable using an object at script level
6282 lines =<< trim END
6283 vim9script
6284
6285 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006286 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006287 endclass
6288 var a = A.new()
6289 var i = a.val
6290 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006291 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006292
6293 # Modifying a class variable using an object at function level
6294 lines =<< trim END
6295 vim9script
6296
6297 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006298 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006299 endclass
6300
6301 def T()
6302 var a = A.new()
6303 a.val = 20
6304 enddef
6305 T()
6306 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006307 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006308
6309 # Reading a class variable using an object at function level
6310 lines =<< trim END
6311 vim9script
6312
6313 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006314 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006315 endclass
6316 def T()
6317 var a = A.new()
6318 var i = a.val
6319 enddef
6320 T()
6321 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006322 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006323
6324 # Use old implicit var declaration syntax (without initialization)
6325 lines =<< trim END
6326 vim9script
6327
6328 class A
6329 static val: number
6330 endclass
6331 END
6332 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6333
6334 # Use old implicit var declaration syntax (with initialization)
6335 lines =<< trim END
6336 vim9script
6337
6338 class A
6339 static val: number = 10
6340 endclass
6341 END
6342 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6343
6344 # Use old implicit var declaration syntax (type inferred)
6345 lines =<< trim END
6346 vim9script
6347
6348 class A
6349 static val = 10
6350 endclass
6351 END
6352 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6353
6354 # Missing ":var" in "var" class variable declaration (without initialization)
6355 lines =<< trim END
6356 vim9script
6357
6358 class A
6359 static var: number
6360 endclass
6361 END
6362 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6363
6364 # Missing ":var" in "var" class variable declaration (with initialization)
6365 lines =<< trim END
6366 vim9script
6367
6368 class A
6369 static var: number = 10
6370 endclass
6371 END
6372 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6373
6374 # Missing ":var" in "var" class variable declaration (type inferred)
6375 lines =<< trim END
6376 vim9script
6377
6378 class A
6379 static var = 10
6380 endclass
6381 END
6382 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6383
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006384enddef
6385
6386" Test for using a duplicate class method and class variable in a child class
6387def Test_dup_class_member()
6388 # duplicate class variable, class method and overridden object method
6389 var lines =<< trim END
6390 vim9script
6391 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006392 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006393 static def Check()
6394 assert_equal(100, sval)
6395 enddef
6396 def GetVal(): number
6397 return sval
6398 enddef
6399 endclass
6400
6401 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006402 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006403 static def Check()
6404 assert_equal(200, sval)
6405 enddef
6406 def GetVal(): number
6407 return sval
6408 enddef
6409 endclass
6410
6411 def T1(aa: A): number
6412 return aa.GetVal()
6413 enddef
6414
6415 def T2(bb: B): number
6416 return bb.GetVal()
6417 enddef
6418
6419 assert_equal(100, A.sval)
6420 assert_equal(200, B.sval)
6421 var a = A.new()
6422 assert_equal(100, a.GetVal())
6423 var b = B.new()
6424 assert_equal(200, b.GetVal())
6425 assert_equal(200, T1(b))
6426 assert_equal(200, T2(b))
6427 END
6428 v9.CheckSourceSuccess(lines)
6429
6430 # duplicate class variable and class method
6431 lines =<< trim END
6432 vim9script
6433 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006434 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006435 static def Check()
6436 assert_equal(100, sval)
6437 enddef
6438 def GetVal(): number
6439 return sval
6440 enddef
6441 endclass
6442
6443 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006444 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006445 static def Check()
6446 assert_equal(200, sval)
6447 enddef
6448 endclass
6449
6450 def T1(aa: A): number
6451 return aa.GetVal()
6452 enddef
6453
6454 def T2(bb: B): number
6455 return bb.GetVal()
6456 enddef
6457
6458 assert_equal(100, A.sval)
6459 assert_equal(200, B.sval)
6460 var a = A.new()
6461 assert_equal(100, a.GetVal())
6462 var b = B.new()
6463 assert_equal(100, b.GetVal())
6464 assert_equal(100, T1(b))
6465 assert_equal(100, T2(b))
6466 END
6467 v9.CheckSourceSuccess(lines)
6468enddef
6469
6470" Test for calling an instance method using the class
6471def Test_instance_method_call_using_class()
6472 # Invoke an object method using a class in script context
6473 var lines =<< trim END
6474 vim9script
6475 class A
6476 def Foo()
6477 echo "foo"
6478 enddef
6479 endclass
6480 A.Foo()
6481 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006482 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006483
6484 # Invoke an object method using a class in def function context
6485 lines =<< trim END
6486 vim9script
6487 class A
6488 def Foo()
6489 echo "foo"
6490 enddef
6491 endclass
6492 def T()
6493 A.Foo()
6494 enddef
6495 T()
6496 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006497 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006498enddef
6499
6500" Test for duplicate class method and instance method
6501def Test_dup_classmethod_objmethod()
6502 # Duplicate instance method
6503 var lines =<< trim END
6504 vim9script
6505 class A
6506 static def Foo()
6507 enddef
6508 def Foo()
6509 enddef
6510 endclass
6511 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006512 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006513
Ernie Rael03042a22023-11-11 08:53:32 +01006514 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006515 lines =<< trim END
6516 vim9script
6517 class A
6518 static def Foo()
6519 enddef
6520 def _Foo()
6521 enddef
6522 endclass
6523 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006524 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006525
6526 # Duplicate class method
6527 lines =<< trim END
6528 vim9script
6529 class A
6530 def Foo()
6531 enddef
6532 static def Foo()
6533 enddef
6534 endclass
6535 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006536 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006537
Ernie Rael03042a22023-11-11 08:53:32 +01006538 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006539 lines =<< trim END
6540 vim9script
6541 class A
6542 def Foo()
6543 enddef
6544 static def _Foo()
6545 enddef
6546 endclass
6547 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006548 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006549
Ernie Rael03042a22023-11-11 08:53:32 +01006550 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006551 lines =<< trim END
6552 vim9script
6553 class A
6554 def _Foo()
6555 enddef
6556 static def _Foo()
6557 enddef
6558 endclass
6559 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006560 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006561enddef
6562
6563" Test for an instance method access level comparison with parent instance
6564" methods.
6565def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006566 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006567 var lines =<< trim END
6568 vim9script
6569 class A
6570 def Foo()
6571 enddef
6572 endclass
6573 class B extends A
6574 endclass
6575 class C extends B
6576 def _Foo()
6577 enddef
6578 endclass
6579 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006580 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006581
6582 # Public method in subclass
6583 lines =<< trim END
6584 vim9script
6585 class A
6586 def _Foo()
6587 enddef
6588 endclass
6589 class B extends A
6590 endclass
6591 class C extends B
6592 def Foo()
6593 enddef
6594 endclass
6595 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006596 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006597enddef
6598
6599def Test_extend_empty_class()
6600 var lines =<< trim END
6601 vim9script
6602 class A
6603 endclass
6604 class B extends A
6605 endclass
6606 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006607 public static var rw_class_var = 1
6608 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006609 static def ClassMethod(): number
6610 return 3
6611 enddef
6612 def ObjMethod(): number
6613 return 4
6614 enddef
6615 endclass
6616 assert_equal(1, C.rw_class_var)
6617 assert_equal(3, C.ClassMethod())
6618 var c = C.new()
6619 assert_equal(2, c.rw_obj_var)
6620 assert_equal(4, c.ObjMethod())
6621 END
6622 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006623enddef
6624
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006625" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006626" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006627def Test_interface_with_unsupported_members()
6628 var lines =<< trim END
6629 vim9script
6630 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006631 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006632 endinterface
6633 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006634 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006635
6636 lines =<< trim END
6637 vim9script
6638 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006639 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006640 endinterface
6641 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006642 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006643
6644 lines =<< trim END
6645 vim9script
6646 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006647 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006648 endinterface
6649 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006650 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006651
6652 lines =<< trim END
6653 vim9script
6654 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006655 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006656 endinterface
6657 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006658 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006659
6660 lines =<< trim END
6661 vim9script
6662 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006663 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006664 endinterface
6665 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006666 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006667
6668 lines =<< trim END
6669 vim9script
6670 interface A
6671 static def Foo(d: dict<any>): list<string>
6672 endinterface
6673 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006674 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006675
6676 lines =<< trim END
6677 vim9script
6678 interface A
6679 static def _Foo(d: dict<any>): list<string>
6680 endinterface
6681 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006682 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006683
6684 lines =<< trim END
6685 vim9script
6686 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006687 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006688 endinterface
6689 END
Ernie Rael03042a22023-11-11 08:53:32 +01006690 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006691
6692 lines =<< trim END
6693 vim9script
6694 interface A
6695 def _Foo(d: dict<any>): list<string>
6696 endinterface
6697 END
Ernie Rael03042a22023-11-11 08:53:32 +01006698 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006699enddef
6700
6701" Test for extending an interface
6702def Test_extend_interface()
6703 var lines =<< trim END
6704 vim9script
6705 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006706 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006707 def Foo()
6708 endinterface
6709 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006710 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006711 def Bar()
6712 endinterface
6713 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006714 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006715 def Foo()
6716 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006717 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006718 def Bar()
6719 enddef
6720 endclass
6721 END
6722 v9.CheckSourceSuccess(lines)
6723
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006724 # extending empty interface
6725 lines =<< trim END
6726 vim9script
6727 interface A
6728 endinterface
6729 interface B extends A
6730 endinterface
6731 class C implements B
6732 endclass
6733 END
6734 v9.CheckSourceSuccess(lines)
6735
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006736 lines =<< trim END
6737 vim9script
6738 interface A
6739 def Foo()
6740 endinterface
6741 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006742 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006743 endinterface
6744 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006745 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006746 endclass
6747 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006748 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006749
6750 lines =<< trim END
6751 vim9script
6752 interface A
6753 def Foo()
6754 endinterface
6755 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006756 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006757 endinterface
6758 class C implements A, B
6759 def Foo()
6760 enddef
6761 endclass
6762 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006763 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006764
6765 # interface cannot extend a class
6766 lines =<< trim END
6767 vim9script
6768 class A
6769 endclass
6770 interface B extends A
6771 endinterface
6772 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006773 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006774
6775 # class cannot extend an interface
6776 lines =<< trim END
6777 vim9script
6778 interface A
6779 endinterface
6780 class B extends A
6781 endclass
6782 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006783 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006784
6785 # interface cannot implement another interface
6786 lines =<< trim END
6787 vim9script
6788 interface A
6789 endinterface
6790 interface B implements A
6791 endinterface
6792 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006793 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006794
6795 # interface cannot extend multiple interfaces
6796 lines =<< trim END
6797 vim9script
6798 interface A
6799 endinterface
6800 interface B
6801 endinterface
6802 interface C extends A, B
6803 endinterface
6804 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006805 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006806
6807 # Variable type in an extended interface is of different type
6808 lines =<< trim END
6809 vim9script
6810 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006811 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006812 endinterface
6813 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006814 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006815 endinterface
6816 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006817 var val1: string
6818 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006819 endinterface
6820 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006821 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006822enddef
6823
6824" Test for a child class implementing an interface when some of the methods are
6825" defined in the parent class.
6826def Test_child_class_implements_interface()
6827 var lines =<< trim END
6828 vim9script
6829
6830 interface Intf
6831 def F1(): list<list<number>>
6832 def F2(): list<list<number>>
6833 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006834 var var1: list<dict<number>>
6835 var var2: list<dict<number>>
6836 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006837 endinterface
6838
6839 class A
6840 def A1()
6841 enddef
6842 def F3(): list<list<number>>
6843 return [[3]]
6844 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006845 var v1: list<list<number>> = [[0]]
6846 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006847 endclass
6848
6849 class B extends A
6850 def B1()
6851 enddef
6852 def F2(): list<list<number>>
6853 return [[2]]
6854 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006855 var v2: list<list<number>> = [[0]]
6856 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006857 endclass
6858
6859 class C extends B implements Intf
6860 def C1()
6861 enddef
6862 def F1(): list<list<number>>
6863 return [[1]]
6864 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006865 var v3: list<list<number>> = [[0]]
6866 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006867 endclass
6868
6869 def T(if: Intf)
6870 assert_equal([[1]], if.F1())
6871 assert_equal([[2]], if.F2())
6872 assert_equal([[3]], if.F3())
6873 assert_equal([{a: 10}], if.var1)
6874 assert_equal([{b: 20}], if.var2)
6875 assert_equal([{c: 30}], if.var3)
6876 enddef
6877
6878 var c = C.new()
6879 T(c)
6880 assert_equal([[1]], c.F1())
6881 assert_equal([[2]], c.F2())
6882 assert_equal([[3]], c.F3())
6883 assert_equal([{a: 10}], c.var1)
6884 assert_equal([{b: 20}], c.var2)
6885 assert_equal([{c: 30}], c.var3)
6886 END
6887 v9.CheckSourceSuccess(lines)
6888
6889 # One of the interface methods is not found
6890 lines =<< trim END
6891 vim9script
6892
6893 interface Intf
6894 def F1()
6895 def F2()
6896 def F3()
6897 endinterface
6898
6899 class A
6900 def A1()
6901 enddef
6902 endclass
6903
6904 class B extends A
6905 def B1()
6906 enddef
6907 def F2()
6908 enddef
6909 endclass
6910
6911 class C extends B implements Intf
6912 def C1()
6913 enddef
6914 def F1()
6915 enddef
6916 endclass
6917 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006918 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006919
6920 # One of the interface methods is of different type
6921 lines =<< trim END
6922 vim9script
6923
6924 interface Intf
6925 def F1()
6926 def F2()
6927 def F3()
6928 endinterface
6929
6930 class A
6931 def F3(): number
6932 return 0
6933 enddef
6934 def A1()
6935 enddef
6936 endclass
6937
6938 class B extends A
6939 def B1()
6940 enddef
6941 def F2()
6942 enddef
6943 endclass
6944
6945 class C extends B implements Intf
6946 def C1()
6947 enddef
6948 def F1()
6949 enddef
6950 endclass
6951 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006952 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006953
6954 # One of the interface variables is not present
6955 lines =<< trim END
6956 vim9script
6957
6958 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006959 var var1: list<dict<number>>
6960 var var2: list<dict<number>>
6961 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006962 endinterface
6963
6964 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006965 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006966 endclass
6967
6968 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006969 var v2: list<list<number>> = [[0]]
6970 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006971 endclass
6972
6973 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006974 var v3: list<list<number>> = [[0]]
6975 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006976 endclass
6977 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006978 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006979
6980 # One of the interface variables is of different type
6981 lines =<< trim END
6982 vim9script
6983
6984 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006985 var var1: list<dict<number>>
6986 var var2: list<dict<number>>
6987 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006988 endinterface
6989
6990 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006991 var v1: list<list<number>> = [[0]]
6992 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006993 endclass
6994
6995 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006996 var v2: list<list<number>> = [[0]]
6997 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006998 endclass
6999
7000 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007001 var v3: list<list<number>> = [[0]]
7002 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007003 endclass
7004 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007005 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 +02007006enddef
7007
7008" Test for extending an interface with duplicate variables and methods
7009def Test_interface_extends_with_dup_members()
7010 var lines =<< trim END
7011 vim9script
7012 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007013 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007014 def Foo1(): number
7015 endinterface
7016 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007017 var n2: number
7018 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007019 def Foo2(): number
7020 def Foo1(): number
7021 endinterface
7022 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007023 var n1 = 10
7024 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007025 def Foo1(): number
7026 return 30
7027 enddef
7028 def Foo2(): number
7029 return 40
7030 enddef
7031 endclass
7032 def T1(a: A)
7033 assert_equal(10, a.n1)
7034 assert_equal(30, a.Foo1())
7035 enddef
7036 def T2(b: B)
7037 assert_equal(10, b.n1)
7038 assert_equal(20, b.n2)
7039 assert_equal(30, b.Foo1())
7040 assert_equal(40, b.Foo2())
7041 enddef
7042 var c = C.new()
7043 T1(c)
7044 T2(c)
7045 END
7046 v9.CheckSourceSuccess(lines)
7047enddef
7048
7049" Test for using "any" type for a variable in a sub-class while it has a
7050" concrete type in the interface
7051def Test_implements_using_var_type_any()
7052 var lines =<< trim END
7053 vim9script
7054 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007055 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007056 endinterface
7057 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007058 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007059 endclass
7060 var b = B.new()
7061 assert_equal([{a: '1'}, {b: '2'}], b.val)
7062 END
7063 v9.CheckSourceSuccess(lines)
7064
7065 # initialize instance variable using a different type
7066 lines =<< trim END
7067 vim9script
7068 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007069 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007070 endinterface
7071 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007072 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007073 endclass
7074 var b = B.new()
7075 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007076 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007077enddef
7078
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007079" Test for assigning to a member variable in a nested class
7080def Test_nested_object_assignment()
7081 var lines =<< trim END
7082 vim9script
7083
7084 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007085 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007086 endclass
7087
7088 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007089 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007090 endclass
7091
7092 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007093 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007094 endclass
7095
7096 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007097 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007098 endclass
7099
7100 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007101 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007102 enddef
7103
7104 var d = D.new()
7105 T(d)
7106 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007107 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007108enddef
7109
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007110" Test for calling methods using a null object
7111def Test_null_object_method_call()
7112 # Calling a object method using a null object in script context
7113 var lines =<< trim END
7114 vim9script
7115
7116 class C
7117 def Foo()
7118 assert_report('This method should not be executed')
7119 enddef
7120 endclass
7121
7122 var o: C
7123 o.Foo()
7124 END
7125 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7126
7127 # Calling a object method using a null object in def function context
7128 lines =<< trim END
7129 vim9script
7130
7131 class C
7132 def Foo()
7133 assert_report('This method should not be executed')
7134 enddef
7135 endclass
7136
7137 def T()
7138 var o: C
7139 o.Foo()
7140 enddef
7141 T()
7142 END
7143 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7144
7145 # Calling a object method through another class method using a null object in
7146 # script context
7147 lines =<< trim END
7148 vim9script
7149
7150 class C
7151 def Foo()
7152 assert_report('This method should not be executed')
7153 enddef
7154
7155 static def Bar(o_any: any)
7156 var o_typed: C = o_any
7157 o_typed.Foo()
7158 enddef
7159 endclass
7160
7161 var o: C
7162 C.Bar(o)
7163 END
7164 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7165
7166 # Calling a object method through another class method using a null object in
7167 # def function context
7168 lines =<< trim END
7169 vim9script
7170
7171 class C
7172 def Foo()
7173 assert_report('This method should not be executed')
7174 enddef
7175
7176 static def Bar(o_any: any)
7177 var o_typed: C = o_any
7178 o_typed.Foo()
7179 enddef
7180 endclass
7181
7182 def T()
7183 var o: C
7184 C.Bar(o)
7185 enddef
7186 T()
7187 END
7188 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7189enddef
7190
7191" Test for using a dict as an object member
7192def Test_dict_object_member()
7193 var lines =<< trim END
7194 vim9script
7195
7196 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007197 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007198 def GetState(): dict<number>
7199 return this.state
7200 enddef
7201 endclass
7202
7203 var ctx = Context.new()
7204 ctx.state->extend({a: 1})
7205 ctx.state['b'] = 2
7206 assert_equal({a: 1, b: 2}, ctx.GetState())
7207
7208 def F()
7209 ctx.state['c'] = 3
7210 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7211 enddef
7212 F()
7213 assert_equal(3, ctx.state.c)
7214 ctx.state.c = 4
7215 assert_equal(4, ctx.state.c)
7216 END
7217 v9.CheckSourceSuccess(lines)
7218enddef
7219
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007220" The following test was failing after 9.0.1914. This was caused by using a
7221" freed object from a previous method call.
7222def Test_freed_object_from_previous_method_call()
7223 var lines =<< trim END
7224 vim9script
7225
7226 class Context
7227 endclass
7228
7229 class Result
7230 endclass
7231
7232 def Failure(): Result
7233 return Result.new()
7234 enddef
7235
7236 def GetResult(ctx: Context): Result
7237 return Failure()
7238 enddef
7239
7240 def Test_GetResult()
7241 var ctx = Context.new()
7242 var result = GetResult(ctx)
7243 enddef
7244
7245 Test_GetResult()
7246 END
7247 v9.CheckSourceSuccess(lines)
7248enddef
7249
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007250" Test for duplicate object and class variable
7251def Test_duplicate_variable()
7252 # Object variable name is same as the class variable name
7253 var lines =<< trim END
7254 vim9script
7255 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007256 public static var sval: number
7257 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007258 endclass
7259 var a = A.new()
7260 END
7261 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7262
7263 # Duplicate variable name and calling a class method
7264 lines =<< trim END
7265 vim9script
7266 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007267 public static var sval: number
7268 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007269 def F1()
7270 echo this.sval
7271 enddef
7272 static def F2()
7273 echo sval
7274 enddef
7275 endclass
7276 A.F2()
7277 END
7278 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7279
7280 # Duplicate variable with an empty constructor
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 new()
7287 enddef
7288 endclass
7289 var a = A.new()
7290 END
7291 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7292enddef
7293
7294" Test for using a reserved keyword as a variable name
7295def Test_reserved_varname()
7296 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7297 'null_function', 'null_list', 'null_partial', 'null_string',
7298 'null_channel', 'null_job', 'super', 'this']
7299
7300 var lines =<< trim eval END
7301 vim9script
7302 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007303 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007304 endclass
7305 var o = C.new()
7306 END
7307 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7308
7309 lines =<< trim eval END
7310 vim9script
7311 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007312 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007313 def new()
7314 enddef
7315 endclass
7316 var o = C.new()
7317 END
7318 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7319
7320 lines =<< trim eval END
7321 vim9script
7322 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007323 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007324 def new()
7325 enddef
7326 def F()
7327 echo this.{kword}
7328 enddef
7329 endclass
7330 var o = C.new()
7331 o.F()
7332 END
7333 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007334
7335 # class variable name
7336 if kword != 'this'
7337 lines =<< trim eval END
7338 vim9script
7339 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007340 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007341 endclass
7342 END
7343 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7344 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007345 endfor
7346enddef
7347
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007348" Test for checking the type of the arguments and the return value of a object
7349" method in an extended class.
7350def Test_extended_obj_method_type_check()
7351 var lines =<< trim END
7352 vim9script
7353
7354 class A
7355 endclass
7356 class B extends A
7357 endclass
7358 class C extends B
7359 endclass
7360
7361 class Foo
7362 def Doit(p: B): B
7363 return B.new()
7364 enddef
7365 endclass
7366
7367 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007368 def Doit(p: C): B
7369 return B.new()
7370 enddef
7371 endclass
7372 END
7373 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7374
7375 lines =<< trim END
7376 vim9script
7377
7378 class A
7379 endclass
7380 class B extends A
7381 endclass
7382 class C extends B
7383 endclass
7384
7385 class Foo
7386 def Doit(p: B): B
7387 return B.new()
7388 enddef
7389 endclass
7390
7391 class Bar extends Foo
7392 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007393 return C.new()
7394 enddef
7395 endclass
7396 END
7397 v9.CheckSourceSuccess(lines)
7398
7399 lines =<< trim END
7400 vim9script
7401
7402 class A
7403 endclass
7404 class B extends A
7405 endclass
7406 class C extends B
7407 endclass
7408
7409 class Foo
7410 def Doit(p: B): B
7411 return B.new()
7412 enddef
7413 endclass
7414
7415 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007416 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007417 return B.new()
7418 enddef
7419 endclass
7420 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007421 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 +02007422
7423 lines =<< trim END
7424 vim9script
7425
7426 class A
7427 endclass
7428 class B extends A
7429 endclass
7430 class C extends B
7431 endclass
7432
7433 class Foo
7434 def Doit(p: B): B
7435 return B.new()
7436 enddef
7437 endclass
7438
7439 class Bar extends Foo
7440 def Doit(p: B): A
7441 return A.new()
7442 enddef
7443 endclass
7444 END
7445 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 +02007446
7447 # check varargs type mismatch
7448 lines =<< trim END
7449 vim9script
7450
7451 class B
7452 def F(...xxx: list<any>)
7453 enddef
7454 endclass
7455 class C extends B
7456 def F(xxx: list<any>)
7457 enddef
7458 endclass
7459 END
7460 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 +02007461enddef
7462
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007463" Test type checking for class variable in assignments
7464func Test_class_variable_complex_type_check()
7465 " class variable with a specific type. Try assigning a different type at
7466 " script level.
7467 let lines =<< trim END
7468 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007469 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007470 return {}
7471 enddef
7472 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007473 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007474 endclass
7475 test_garbagecollect_now()
7476 A.Fn = "abc"
7477 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007478 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 +02007479
7480 " class variable with a specific type. Try assigning a different type at
7481 " class def method level.
7482 let lines =<< trim END
7483 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007484 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007485 return {}
7486 enddef
7487 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007488 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007489 def Bar()
7490 Fn = "abc"
7491 enddef
7492 endclass
7493 var a = A.new()
7494 test_garbagecollect_now()
7495 a.Bar()
7496 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007497 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 +02007498
7499 " class variable with a specific type. Try assigning a different type at
7500 " script def method level.
7501 let lines =<< trim END
7502 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007503 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007504 return {}
7505 enddef
7506 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007507 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007508 endclass
7509 def Bar()
7510 A.Fn = "abc"
7511 enddef
7512 test_garbagecollect_now()
7513 Bar()
7514 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007515 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 +02007516
7517 " class variable without any type. Should be set to the initialization
7518 " expression type. Try assigning a different type from script level.
7519 let lines =<< trim END
7520 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007521 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007522 return {}
7523 enddef
7524 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007525 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007526 endclass
7527 test_garbagecollect_now()
7528 A.Fn = "abc"
7529 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007530 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 +02007531
7532 " class variable without any type. Should be set to the initialization
7533 " expression type. Try assigning a different type at class def level.
7534 let lines =<< trim END
7535 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007536 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007537 return {}
7538 enddef
7539 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007540 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007541 def Bar()
7542 Fn = "abc"
7543 enddef
7544 endclass
7545 var a = A.new()
7546 test_garbagecollect_now()
7547 a.Bar()
7548 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007549 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 +02007550
7551 " class variable without any type. Should be set to the initialization
7552 " expression type. Try assigning a different type at script def level.
7553 let lines =<< trim END
7554 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007555 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007556 return {}
7557 enddef
7558 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007559 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007560 endclass
7561 def Bar()
7562 A.Fn = "abc"
7563 enddef
7564 test_garbagecollect_now()
7565 Bar()
7566 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007567 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 +02007568
7569 " class variable with 'any" type. Can be assigned different types.
7570 let lines =<< trim END
7571 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007572 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007573 return {}
7574 enddef
7575 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007576 public static var Fn: any = Foo
7577 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007578 endclass
7579 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007580 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007581 A.Fn = "abc"
7582 test_garbagecollect_now()
7583 assert_equal('string', typename(A.Fn))
7584 A.Fn2 = Foo
7585 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007586 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007587 A.Fn2 = "xyz"
7588 test_garbagecollect_now()
7589 assert_equal('string', typename(A.Fn2))
7590 END
7591 call v9.CheckSourceSuccess(lines)
7592
7593 " class variable with 'any" type. Can be assigned different types.
7594 let lines =<< trim END
7595 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007596 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007597 return {}
7598 enddef
7599 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007600 public static var Fn: any = Foo
7601 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007602
7603 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007604 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007605 Fn = "abc"
7606 assert_equal('string', typename(Fn))
7607 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007608 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007609 Fn2 = "xyz"
7610 assert_equal('string', typename(Fn2))
7611 enddef
7612 endclass
7613 var a = A.new()
7614 test_garbagecollect_now()
7615 a.Bar()
7616 test_garbagecollect_now()
7617 A.Fn = Foo
7618 a.Bar()
7619 END
7620 call v9.CheckSourceSuccess(lines)
7621
7622 " class variable with 'any" type. Can be assigned different types.
7623 let lines =<< trim END
7624 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007625 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007626 return {}
7627 enddef
7628 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007629 public static var Fn: any = Foo
7630 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007631 endclass
7632
7633 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007634 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007635 A.Fn = "abc"
7636 assert_equal('string', typename(A.Fn))
7637 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007638 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007639 A.Fn2 = "xyz"
7640 assert_equal('string', typename(A.Fn2))
7641 enddef
7642 Bar()
7643 test_garbagecollect_now()
7644 A.Fn = Foo
7645 Bar()
7646 END
7647 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007648
7649 let lines =<< trim END
7650 vim9script
7651 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007652 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007653 endclass
7654 assert_equal([0z10, 0z20], A.foo)
7655 A.foo = [0z30]
7656 assert_equal([0z30], A.foo)
7657 var a = A.foo
7658 assert_equal([0z30], a)
7659 END
7660 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007661endfunc
7662
7663" Test type checking for object variable in assignments
7664func Test_object_variable_complex_type_check()
7665 " object variable with a specific type. Try assigning a different type at
7666 " script level.
7667 let lines =<< trim END
7668 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007669 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007670 return {}
7671 enddef
7672 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007673 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007674 endclass
7675 var a = A.new()
7676 test_garbagecollect_now()
7677 a.Fn = "abc"
7678 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007679 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 +02007680
7681 " object variable with a specific type. Try assigning a different type at
7682 " object def method level.
7683 let lines =<< trim END
7684 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007685 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007686 return {}
7687 enddef
7688 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007689 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007690 def Bar()
7691 this.Fn = "abc"
7692 this.Fn = Foo
7693 enddef
7694 endclass
7695 var a = A.new()
7696 test_garbagecollect_now()
7697 a.Bar()
7698 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007699 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 +02007700
7701 " object variable with a specific type. Try assigning a different type at
7702 " script def method level.
7703 let lines =<< trim END
7704 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007705 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007706 return {}
7707 enddef
7708 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007709 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007710 endclass
7711 def Bar()
7712 var a = A.new()
7713 a.Fn = "abc"
7714 a.Fn = Foo
7715 enddef
7716 test_garbagecollect_now()
7717 Bar()
7718 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007719 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 +02007720
7721 " object variable without any type. Should be set to the initialization
7722 " expression type. Try assigning a different type from script level.
7723 let lines =<< trim END
7724 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007725 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007726 return {}
7727 enddef
7728 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007729 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007730 endclass
7731 var a = A.new()
7732 test_garbagecollect_now()
7733 a.Fn = "abc"
7734 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007735 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 +02007736
7737 " object variable without any type. Should be set to the initialization
7738 " expression type. Try assigning a different type at object def level.
7739 let lines =<< trim END
7740 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007741 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007742 return {}
7743 enddef
7744 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007745 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007746 def Bar()
7747 this.Fn = "abc"
7748 this.Fn = Foo
7749 enddef
7750 endclass
7751 var a = A.new()
7752 test_garbagecollect_now()
7753 a.Bar()
7754 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007755 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 +02007756
7757 " object variable without any type. Should be set to the initialization
7758 " expression type. Try assigning a different type at script def level.
7759 let lines =<< trim END
7760 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007761 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007762 return {}
7763 enddef
7764 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007765 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007766 endclass
7767 def Bar()
7768 var a = A.new()
7769 a.Fn = "abc"
7770 a.Fn = Foo
7771 enddef
7772 test_garbagecollect_now()
7773 Bar()
7774 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007775 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 2)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007776
7777 " object variable with 'any" type. Can be assigned different types.
7778 let lines =<< trim END
7779 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007780 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007781 return {}
7782 enddef
7783 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007784 public var Fn: any = Foo
7785 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007786 endclass
7787
7788 var a = A.new()
7789 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007790 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007791 a.Fn = "abc"
7792 test_garbagecollect_now()
7793 assert_equal('string', typename(a.Fn))
7794 a.Fn2 = Foo
7795 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007796 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007797 a.Fn2 = "xyz"
7798 test_garbagecollect_now()
7799 assert_equal('string', typename(a.Fn2))
7800 END
7801 call v9.CheckSourceSuccess(lines)
7802
7803 " object variable with 'any" type. Can be assigned different types.
7804 let lines =<< trim END
7805 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007806 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007807 return {}
7808 enddef
7809 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007810 public var Fn: any = Foo
7811 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007812
7813 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007814 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007815 this.Fn = "abc"
7816 assert_equal('string', typename(this.Fn))
7817 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007818 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007819 this.Fn2 = "xyz"
7820 assert_equal('string', typename(this.Fn2))
7821 enddef
7822 endclass
7823
7824 var a = A.new()
7825 test_garbagecollect_now()
7826 a.Bar()
7827 test_garbagecollect_now()
7828 a.Fn = Foo
7829 a.Bar()
7830 END
7831 call v9.CheckSourceSuccess(lines)
7832
7833 " object variable with 'any" type. Can be assigned different types.
7834 let lines =<< trim END
7835 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007836 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007837 return {}
7838 enddef
7839 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007840 public var Fn: any = Foo
7841 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007842 endclass
7843
7844 def Bar()
7845 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007846 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007847 a.Fn = "abc"
7848 assert_equal('string', typename(a.Fn))
7849 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007850 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007851 a.Fn2 = "xyz"
7852 assert_equal('string', typename(a.Fn2))
7853 enddef
7854 test_garbagecollect_now()
7855 Bar()
7856 test_garbagecollect_now()
7857 Bar()
7858 END
7859 call v9.CheckSourceSuccess(lines)
7860endfunc
7861
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007862" Test for recursively calling an object method. This used to cause an
7863" use-after-free error.
7864def Test_recursive_object_method_call()
7865 var lines =<< trim END
7866 vim9script
7867 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007868 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007869 def Foo(): number
7870 if this.val >= 90
7871 return this.val
7872 endif
7873 this.val += 1
7874 return this.Foo()
7875 enddef
7876 endclass
7877 var a = A.new()
7878 assert_equal(90, a.Foo())
7879 END
7880 v9.CheckSourceSuccess(lines)
7881enddef
7882
7883" Test for recursively calling a class method.
7884def Test_recursive_class_method_call()
7885 var lines =<< trim END
7886 vim9script
7887 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007888 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007889 static def Foo(): number
7890 if val >= 90
7891 return val
7892 endif
7893 val += 1
7894 return Foo()
7895 enddef
7896 endclass
7897 assert_equal(90, A.Foo())
7898 END
7899 v9.CheckSourceSuccess(lines)
7900enddef
7901
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007902" Test for checking the argument types and the return type when assigning a
7903" funcref to make sure the invariant class type is used.
7904def Test_funcref_argtype_returntype_check()
7905 var lines =<< trim END
7906 vim9script
7907 class A
7908 endclass
7909 class B extends A
7910 endclass
7911
7912 def Foo(p: B): B
7913 return B.new()
7914 enddef
7915
7916 var Bar: func(A): A = Foo
7917 END
7918 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7919
7920 lines =<< trim END
7921 vim9script
7922 class A
7923 endclass
7924 class B extends A
7925 endclass
7926
7927 def Foo(p: B): B
7928 return B.new()
7929 enddef
7930
7931 def Baz()
7932 var Bar: func(A): A = Foo
7933 enddef
7934 Baz()
7935 END
7936 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7937enddef
7938
Ernie Rael96952b22023-10-17 18:15:01 +02007939def Test_funcref_argtype_invariance_check()
7940 var lines =<< trim END
7941 vim9script
7942
7943 class A
7944 endclass
7945 class B extends A
7946 endclass
7947 class C extends B
7948 endclass
7949
7950 var Func: func(B): number
7951 Func = (o: B): number => 3
7952 assert_equal(3, Func(B.new()))
7953 END
7954 v9.CheckSourceSuccess(lines)
7955
7956 lines =<< trim END
7957 vim9script
7958
7959 class A
7960 endclass
7961 class B extends A
7962 endclass
7963 class C extends B
7964 endclass
7965
7966 var Func: func(B): number
7967 Func = (o: A): number => 3
7968 END
7969 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7970
7971 lines =<< trim END
7972 vim9script
7973
7974 class A
7975 endclass
7976 class B extends A
7977 endclass
7978 class C extends B
7979 endclass
7980
7981 var Func: func(B): number
7982 Func = (o: C): number => 3
7983 END
7984 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7985enddef
7986
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007987" Test for using an operator (e.g. +) with an assignment
7988def Test_op_and_assignment()
7989 # Using += with a class variable
7990 var lines =<< trim END
7991 vim9script
7992 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007993 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007994 static def Foo(): list<number>
7995 val += [1]
7996 return val
7997 enddef
7998 endclass
7999 def Bar(): list<number>
8000 A.val += [2]
8001 return A.val
8002 enddef
8003 assert_equal([1], A.Foo())
8004 assert_equal([1, 2], Bar())
8005 A.val += [3]
8006 assert_equal([1, 2, 3], A.val)
8007 END
8008 v9.CheckSourceSuccess(lines)
8009
8010 # Using += with an object variable
8011 lines =<< trim END
8012 vim9script
8013 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008014 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008015 def Foo(): list<number>
8016 this.val += [1]
8017 return this.val
8018 enddef
8019 endclass
8020 def Bar(bar_a: A): list<number>
8021 bar_a.val += [2]
8022 return bar_a.val
8023 enddef
8024 var a = A.new()
8025 assert_equal([1], a.Foo())
8026 assert_equal([1, 2], Bar(a))
8027 a.val += [3]
8028 assert_equal([1, 2, 3], a.val)
8029 END
8030 v9.CheckSourceSuccess(lines)
8031enddef
8032
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008033" Test for using an object method as a funcref
8034def Test_object_funcref()
8035 # Using object method funcref from a def function
8036 var lines =<< trim END
8037 vim9script
8038 class A
8039 def Foo(): list<number>
8040 return [3, 2, 1]
8041 enddef
8042 endclass
8043 def Bar()
8044 var a = A.new()
8045 var Fn = a.Foo
8046 assert_equal([3, 2, 1], Fn())
8047 enddef
8048 Bar()
8049 END
8050 v9.CheckSourceSuccess(lines)
8051
8052 # Using object method funcref at the script level
8053 lines =<< trim END
8054 vim9script
8055 class A
8056 def Foo(): dict<number>
8057 return {a: 1, b: 2}
8058 enddef
8059 endclass
8060 var a = A.new()
8061 var Fn = a.Foo
8062 assert_equal({a: 1, b: 2}, Fn())
8063 END
8064 v9.CheckSourceSuccess(lines)
8065
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008066 # Using object method funcref at the script level
8067 lines =<< trim END
8068 vim9script
8069 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008070 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008071 def Foo(): number
8072 return this.val
8073 enddef
8074 endclass
8075 var a = A.new(345)
8076 var Fn = a.Foo
8077 assert_equal(345, Fn())
8078 END
8079 v9.CheckSourceSuccess(lines)
8080
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008081 # Using object method funcref from another object method
8082 lines =<< trim END
8083 vim9script
8084 class A
8085 def Foo(): list<number>
8086 return [3, 2, 1]
8087 enddef
8088 def Bar()
8089 var Fn = this.Foo
8090 assert_equal([3, 2, 1], Fn())
8091 enddef
8092 endclass
8093 var a = A.new()
8094 a.Bar()
8095 END
8096 v9.CheckSourceSuccess(lines)
8097
8098 # Using function() to get a object method funcref
8099 lines =<< trim END
8100 vim9script
8101 class A
8102 def Foo(l: list<any>): list<any>
8103 return l
8104 enddef
8105 endclass
8106 var a = A.new()
8107 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8108 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8109 END
8110 v9.CheckSourceSuccess(lines)
8111
8112 # Use an object method with a function returning a funcref and then call the
8113 # funcref.
8114 lines =<< trim END
8115 vim9script
8116
8117 def Map(F: func(number): number): func(number): number
8118 return (n: number) => F(n)
8119 enddef
8120
8121 class Math
8122 def Double(n: number): number
8123 return 2 * n
8124 enddef
8125 endclass
8126
8127 const math = Math.new()
8128 assert_equal(48, Map(math.Double)(24))
8129 END
8130 v9.CheckSourceSuccess(lines)
8131
Ernie Rael03042a22023-11-11 08:53:32 +01008132 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008133 lines =<< trim END
8134 vim9script
8135 class A
8136 def _Foo()
8137 enddef
8138 endclass
8139 def Bar()
8140 var a = A.new()
8141 var Fn = a._Foo
8142 enddef
8143 Bar()
8144 END
Ernie Rael03042a22023-11-11 08:53:32 +01008145 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008146
Ernie Rael03042a22023-11-11 08:53:32 +01008147 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008148 lines =<< trim END
8149 vim9script
8150 class A
8151 def _Foo()
8152 enddef
8153 endclass
8154 var a = A.new()
8155 var Fn = a._Foo
8156 END
Ernie Rael03042a22023-11-11 08:53:32 +01008157 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008158
Ernie Rael03042a22023-11-11 08:53:32 +01008159 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008160 lines =<< trim END
8161 vim9script
8162 class A
8163 def _Foo(): list<number>
8164 return [3, 2, 1]
8165 enddef
8166 def Bar()
8167 var Fn = this._Foo
8168 assert_equal([3, 2, 1], Fn())
8169 enddef
8170 endclass
8171 var a = A.new()
8172 a.Bar()
8173 END
8174 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008175
8176 # Using object method funcref using call()
8177 lines =<< trim END
8178 vim9script
8179 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008180 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008181 def Foo(): number
8182 return this.val
8183 enddef
8184 endclass
8185
8186 def Bar(obj: A)
8187 assert_equal(123, call(obj.Foo, []))
8188 enddef
8189
8190 var a = A.new(123)
8191 Bar(a)
8192 assert_equal(123, call(a.Foo, []))
8193 END
8194 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008195enddef
8196
8197" Test for using a class method as a funcref
8198def Test_class_funcref()
8199 # Using class method funcref in a def function
8200 var lines =<< trim END
8201 vim9script
8202 class A
8203 static def Foo(): list<number>
8204 return [3, 2, 1]
8205 enddef
8206 endclass
8207 def Bar()
8208 var Fn = A.Foo
8209 assert_equal([3, 2, 1], Fn())
8210 enddef
8211 Bar()
8212 END
8213 v9.CheckSourceSuccess(lines)
8214
8215 # Using class method funcref at script level
8216 lines =<< trim END
8217 vim9script
8218 class A
8219 static def Foo(): dict<number>
8220 return {a: 1, b: 2}
8221 enddef
8222 endclass
8223 var Fn = A.Foo
8224 assert_equal({a: 1, b: 2}, Fn())
8225 END
8226 v9.CheckSourceSuccess(lines)
8227
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008228 # Using class method funcref at the script level
8229 lines =<< trim END
8230 vim9script
8231 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008232 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008233 static def Foo(): number
8234 return val
8235 enddef
8236 endclass
8237 A.val = 567
8238 var Fn = A.Foo
8239 assert_equal(567, Fn())
8240 END
8241 v9.CheckSourceSuccess(lines)
8242
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008243 # Using function() to get a class method funcref
8244 lines =<< trim END
8245 vim9script
8246 class A
8247 static def Foo(l: list<any>): list<any>
8248 return l
8249 enddef
8250 endclass
8251 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8252 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8253 END
8254 v9.CheckSourceSuccess(lines)
8255
8256 # Using a class method funcref from another class method
8257 lines =<< trim END
8258 vim9script
8259 class A
8260 static def Foo(): list<number>
8261 return [3, 2, 1]
8262 enddef
8263 static def Bar()
8264 var Fn = Foo
8265 assert_equal([3, 2, 1], Fn())
8266 enddef
8267 endclass
8268 A.Bar()
8269 END
8270 v9.CheckSourceSuccess(lines)
8271
8272 # Use a class method with a function returning a funcref and then call the
8273 # funcref.
8274 lines =<< trim END
8275 vim9script
8276
8277 def Map(F: func(number): number): func(number): number
8278 return (n: number) => F(n)
8279 enddef
8280
8281 class Math
8282 static def StaticDouble(n: number): number
8283 return 2 * n
8284 enddef
8285 endclass
8286
8287 assert_equal(48, Map(Math.StaticDouble)(24))
8288 END
8289 v9.CheckSourceSuccess(lines)
8290
Ernie Rael03042a22023-11-11 08:53:32 +01008291 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008292 lines =<< trim END
8293 vim9script
8294 class A
8295 static def _Foo()
8296 enddef
8297 endclass
8298 def Bar()
8299 var Fn = A._Foo
8300 enddef
8301 Bar()
8302 END
Ernie Rael03042a22023-11-11 08:53:32 +01008303 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008304
Ernie Rael03042a22023-11-11 08:53:32 +01008305 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008306 lines =<< trim END
8307 vim9script
8308 class A
8309 static def _Foo()
8310 enddef
8311 endclass
8312 var Fn = A._Foo
8313 END
Ernie Rael03042a22023-11-11 08:53:32 +01008314 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008315
Ernie Rael03042a22023-11-11 08:53:32 +01008316 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008317 lines =<< trim END
8318 vim9script
8319 class A
8320 static def _Foo(): list<number>
8321 return [3, 2, 1]
8322 enddef
8323 static def Bar()
8324 var Fn = _Foo
8325 assert_equal([3, 2, 1], Fn())
8326 enddef
8327 endclass
8328 A.Bar()
8329 END
8330 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008331
8332 # Using class method funcref using call()
8333 lines =<< trim END
8334 vim9script
8335 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008336 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008337 static def Foo(): number
8338 return val
8339 enddef
8340 endclass
8341
8342 def Bar()
8343 A.val = 468
8344 assert_equal(468, call(A.Foo, []))
8345 enddef
8346 Bar()
8347 assert_equal(468, call(A.Foo, []))
8348 END
8349 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008350enddef
8351
8352" Test for using an object member as a funcref
8353def Test_object_member_funcref()
8354 # Using a funcref object variable in an object method
8355 var lines =<< trim END
8356 vim9script
8357 def Foo(n: number): number
8358 return n * 10
8359 enddef
8360
8361 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008362 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008363 def Bar()
8364 assert_equal(200, this.Cb(20))
8365 enddef
8366 endclass
8367
8368 var a = A.new()
8369 a.Bar()
8370 END
8371 v9.CheckSourceSuccess(lines)
8372
8373 # Using a funcref object variable in a def method
8374 lines =<< trim END
8375 vim9script
8376 def Foo(n: number): number
8377 return n * 10
8378 enddef
8379
8380 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008381 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008382 endclass
8383
8384 def Bar()
8385 var a = A.new()
8386 assert_equal(200, a.Cb(20))
8387 enddef
8388 Bar()
8389 END
8390 v9.CheckSourceSuccess(lines)
8391
8392 # Using a funcref object variable at script level
8393 lines =<< trim END
8394 vim9script
8395 def Foo(n: number): number
8396 return n * 10
8397 enddef
8398
8399 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008400 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008401 endclass
8402
8403 var a = A.new()
8404 assert_equal(200, a.Cb(20))
8405 END
8406 v9.CheckSourceSuccess(lines)
8407
8408 # Using a funcref object variable pointing to an object method in an object
8409 # method.
8410 lines =<< trim END
8411 vim9script
8412 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008413 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008414 def Foo(n: number): number
8415 return n * 10
8416 enddef
8417 def Bar()
8418 assert_equal(200, this.Cb(20))
8419 enddef
8420 endclass
8421
8422 var a = A.new()
8423 a.Bar()
8424 END
8425 v9.CheckSourceSuccess(lines)
8426
8427 # Using a funcref object variable pointing to an object method in a def
8428 # method.
8429 lines =<< trim END
8430 vim9script
8431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008432 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008433 def Foo(n: number): number
8434 return n * 10
8435 enddef
8436 endclass
8437
8438 def Bar()
8439 var a = A.new()
8440 assert_equal(200, a.Cb(20))
8441 enddef
8442 Bar()
8443 END
8444 v9.CheckSourceSuccess(lines)
8445
8446 # Using a funcref object variable pointing to an object method at script
8447 # level.
8448 lines =<< trim END
8449 vim9script
8450 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008451 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008452 def Foo(n: number): number
8453 return n * 10
8454 enddef
8455 endclass
8456
8457 var a = A.new()
8458 assert_equal(200, a.Cb(20))
8459 END
8460 v9.CheckSourceSuccess(lines)
8461enddef
8462
8463" Test for using a class member as a funcref
8464def Test_class_member_funcref()
8465 # Using a funcref class variable in a class method
8466 var lines =<< trim END
8467 vim9script
8468 def Foo(n: number): number
8469 return n * 10
8470 enddef
8471
8472 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008473 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008474 static def Bar()
8475 assert_equal(200, Cb(20))
8476 enddef
8477 endclass
8478
8479 A.Bar()
8480 END
8481 v9.CheckSourceSuccess(lines)
8482
8483 # Using a funcref class variable in a def method
8484 lines =<< trim END
8485 vim9script
8486 def Foo(n: number): number
8487 return n * 10
8488 enddef
8489
8490 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008491 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008492 endclass
8493
8494 def Bar()
8495 assert_equal(200, A.Cb(20))
8496 enddef
8497 Bar()
8498 END
8499 v9.CheckSourceSuccess(lines)
8500
8501 # Using a funcref class variable at script level
8502 lines =<< trim END
8503 vim9script
8504 def Foo(n: number): number
8505 return n * 10
8506 enddef
8507
8508 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008509 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008510 endclass
8511
8512 assert_equal(200, A.Cb(20))
8513 END
8514 v9.CheckSourceSuccess(lines)
8515
8516 # Using a funcref class variable pointing to a class method in a class
8517 # method.
8518 lines =<< trim END
8519 vim9script
8520 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008521 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008522 static def Foo(n: number): number
8523 return n * 10
8524 enddef
8525 static def Init()
8526 Cb = Foo
8527 enddef
8528 static def Bar()
8529 assert_equal(200, Cb(20))
8530 enddef
8531 endclass
8532
8533 A.Init()
8534 A.Bar()
8535 END
8536 v9.CheckSourceSuccess(lines)
8537
8538 # Using a funcref class variable pointing to a class method in a def method.
8539 lines =<< trim END
8540 vim9script
8541 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008542 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008543 static def Foo(n: number): number
8544 return n * 10
8545 enddef
8546 static def Init()
8547 Cb = Foo
8548 enddef
8549 endclass
8550
8551 def Bar()
8552 A.Init()
8553 assert_equal(200, A.Cb(20))
8554 enddef
8555 Bar()
8556 END
8557 v9.CheckSourceSuccess(lines)
8558
8559 # Using a funcref class variable pointing to a class method at script level.
8560 lines =<< trim END
8561 vim9script
8562 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008563 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008564 static def Foo(n: number): number
8565 return n * 10
8566 enddef
8567 static def Init()
8568 Cb = Foo
8569 enddef
8570 endclass
8571
8572 A.Init()
8573 assert_equal(200, A.Cb(20))
8574 END
8575 v9.CheckSourceSuccess(lines)
8576enddef
8577
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008578" Test for using object methods as popup callback functions
8579def Test_objmethod_popup_callback()
8580 # Use the popup from the script level
8581 var lines =<< trim END
8582 vim9script
8583
8584 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008585 var selection: number = -1
8586 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008587
8588 def PopupFilter(id: number, key: string): bool
8589 add(this.filterkeys, key)
8590 return popup_filter_yesno(id, key)
8591 enddef
8592
8593 def PopupCb(id: number, result: number)
8594 this.selection = result ? 100 : 200
8595 enddef
8596 endclass
8597
8598 var a = A.new()
8599 feedkeys('', 'xt')
8600 var winid = popup_create('Y/N?',
8601 {filter: a.PopupFilter, callback: a.PopupCb})
8602 feedkeys('y', 'xt')
8603 popup_close(winid)
8604 assert_equal(100, a.selection)
8605 assert_equal(['y'], a.filterkeys)
8606 feedkeys('', 'xt')
8607 winid = popup_create('Y/N?',
8608 {filter: a.PopupFilter, callback: a.PopupCb})
8609 feedkeys('n', 'xt')
8610 popup_close(winid)
8611 assert_equal(200, a.selection)
8612 assert_equal(['y', 'n'], a.filterkeys)
8613 END
8614 v9.CheckSourceSuccess(lines)
8615
8616 # Use the popup from a def function
8617 lines =<< trim END
8618 vim9script
8619
8620 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008621 var selection: number = -1
8622 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008623
8624 def PopupFilter(id: number, key: string): bool
8625 add(this.filterkeys, key)
8626 return popup_filter_yesno(id, key)
8627 enddef
8628
8629 def PopupCb(id: number, result: number)
8630 this.selection = result ? 100 : 200
8631 enddef
8632 endclass
8633
8634 def Foo()
8635 var a = A.new()
8636 feedkeys('', 'xt')
8637 var winid = popup_create('Y/N?',
8638 {filter: a.PopupFilter, callback: a.PopupCb})
8639 feedkeys('y', 'xt')
8640 popup_close(winid)
8641 assert_equal(100, a.selection)
8642 assert_equal(['y'], a.filterkeys)
8643 feedkeys('', 'xt')
8644 winid = popup_create('Y/N?',
8645 {filter: a.PopupFilter, callback: a.PopupCb})
8646 feedkeys('n', 'xt')
8647 popup_close(winid)
8648 assert_equal(200, a.selection)
8649 assert_equal(['y', 'n'], a.filterkeys)
8650 enddef
8651 Foo()
8652 END
8653 v9.CheckSourceSuccess(lines)
8654enddef
8655
8656" Test for using class methods as popup callback functions
8657def Test_classmethod_popup_callback()
8658 # Use the popup from the script level
8659 var lines =<< trim END
8660 vim9script
8661
8662 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008663 static var selection: number = -1
8664 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008665
8666 static def PopupFilter(id: number, key: string): bool
8667 add(filterkeys, key)
8668 return popup_filter_yesno(id, key)
8669 enddef
8670
8671 static def PopupCb(id: number, result: number)
8672 selection = result ? 100 : 200
8673 enddef
8674 endclass
8675
8676 feedkeys('', 'xt')
8677 var winid = popup_create('Y/N?',
8678 {filter: A.PopupFilter, callback: A.PopupCb})
8679 feedkeys('y', 'xt')
8680 popup_close(winid)
8681 assert_equal(100, A.selection)
8682 assert_equal(['y'], A.filterkeys)
8683 feedkeys('', 'xt')
8684 winid = popup_create('Y/N?',
8685 {filter: A.PopupFilter, callback: A.PopupCb})
8686 feedkeys('n', 'xt')
8687 popup_close(winid)
8688 assert_equal(200, A.selection)
8689 assert_equal(['y', 'n'], A.filterkeys)
8690 END
8691 v9.CheckSourceSuccess(lines)
8692
8693 # Use the popup from a def function
8694 lines =<< trim END
8695 vim9script
8696
8697 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008698 static var selection: number = -1
8699 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008700
8701 static def PopupFilter(id: number, key: string): bool
8702 add(filterkeys, key)
8703 return popup_filter_yesno(id, key)
8704 enddef
8705
8706 static def PopupCb(id: number, result: number)
8707 selection = result ? 100 : 200
8708 enddef
8709 endclass
8710
8711 def Foo()
8712 feedkeys('', 'xt')
8713 var winid = popup_create('Y/N?',
8714 {filter: A.PopupFilter, callback: A.PopupCb})
8715 feedkeys('y', 'xt')
8716 popup_close(winid)
8717 assert_equal(100, A.selection)
8718 assert_equal(['y'], A.filterkeys)
8719 feedkeys('', 'xt')
8720 winid = popup_create('Y/N?',
8721 {filter: A.PopupFilter, callback: A.PopupCb})
8722 feedkeys('n', 'xt')
8723 popup_close(winid)
8724 assert_equal(200, A.selection)
8725 assert_equal(['y', 'n'], A.filterkeys)
8726 enddef
8727 Foo()
8728 END
8729 v9.CheckSourceSuccess(lines)
8730enddef
8731
8732" Test for using an object method as a timer callback function
8733def Test_objmethod_timer_callback()
8734 # Use the timer callback from script level
8735 var lines =<< trim END
8736 vim9script
8737
8738 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008739 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008740 def TimerCb(timerID: number)
8741 this.timerTick = 6
8742 enddef
8743 endclass
8744
8745 var a = A.new()
8746 timer_start(0, a.TimerCb)
8747 var maxWait = 5
8748 while maxWait > 0 && a.timerTick == -1
8749 :sleep 10m
8750 maxWait -= 1
8751 endwhile
8752 assert_equal(6, a.timerTick)
8753 END
8754 v9.CheckSourceSuccess(lines)
8755
8756 # Use the timer callback from a def function
8757 lines =<< trim END
8758 vim9script
8759
8760 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008761 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008762 def TimerCb(timerID: number)
8763 this.timerTick = 6
8764 enddef
8765 endclass
8766
8767 def Foo()
8768 var a = A.new()
8769 timer_start(0, a.TimerCb)
8770 var maxWait = 5
8771 while maxWait > 0 && a.timerTick == -1
8772 :sleep 10m
8773 maxWait -= 1
8774 endwhile
8775 assert_equal(6, a.timerTick)
8776 enddef
8777 Foo()
8778 END
8779 v9.CheckSourceSuccess(lines)
8780enddef
8781
8782" Test for using a class method as a timer callback function
8783def Test_classmethod_timer_callback()
8784 # Use the timer callback from script level
8785 var lines =<< trim END
8786 vim9script
8787
8788 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008789 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008790 static def TimerCb(timerID: number)
8791 timerTick = 6
8792 enddef
8793 endclass
8794
8795 timer_start(0, A.TimerCb)
8796 var maxWait = 5
8797 while maxWait > 0 && A.timerTick == -1
8798 :sleep 10m
8799 maxWait -= 1
8800 endwhile
8801 assert_equal(6, A.timerTick)
8802 END
8803 v9.CheckSourceSuccess(lines)
8804
8805 # Use the timer callback from a def function
8806 lines =<< trim END
8807 vim9script
8808
8809 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008810 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008811 static def TimerCb(timerID: number)
8812 timerTick = 6
8813 enddef
8814 endclass
8815
8816 def Foo()
8817 timer_start(0, A.TimerCb)
8818 var maxWait = 5
8819 while maxWait > 0 && A.timerTick == -1
8820 :sleep 10m
8821 maxWait -= 1
8822 endwhile
8823 assert_equal(6, A.timerTick)
8824 enddef
8825 Foo()
8826 END
8827 v9.CheckSourceSuccess(lines)
8828enddef
8829
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008830" Test for using a class variable as the first and/or second operand of a binary
8831" operator.
8832def Test_class_variable_as_operands()
8833 var lines =<< trim END
8834 vim9script
8835 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008836 static var truthy: bool = true
8837 public static var TruthyFn: func
8838 static var list: list<any> = []
8839 static var four: number = 4
8840 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008841
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008842 static def Str(): string
8843 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008844 enddef
8845
8846 static def Four(): number
8847 return four
8848 enddef
8849
8850 static def List(): list<any>
8851 return list
8852 enddef
8853
8854 static def Truthy(): bool
8855 return truthy
8856 enddef
8857
8858 def TestOps()
8859 assert_true(Tests.truthy == truthy)
8860 assert_true(truthy == Tests.truthy)
8861 assert_true(Tests.list isnot [])
8862 assert_true([] isnot Tests.list)
8863 assert_equal(2, Tests.four >> 1)
8864 assert_equal(16, 1 << Tests.four)
8865 assert_equal(8, Tests.four + four)
8866 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008867 assert_equal('hellohello', Tests.str .. str)
8868 assert_equal('hellohello', str .. Tests.str)
8869
8870 # Using class variable for list indexing
8871 var l = range(10)
8872 assert_equal(4, l[Tests.four])
8873 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8874
8875 # Using class variable for Dict key
8876 var d = {hello: 'abc'}
8877 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008878 enddef
8879 endclass
8880
8881 def TestOps2()
8882 assert_true(Tests.truthy == Tests.Truthy())
8883 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008884 assert_true(Tests.truthy == Tests.TruthyFn())
8885 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008886 assert_true(Tests.list is Tests.List())
8887 assert_true(Tests.List() is Tests.list)
8888 assert_equal(2, Tests.four >> 1)
8889 assert_equal(16, 1 << Tests.four)
8890 assert_equal(8, Tests.four + Tests.Four())
8891 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008892 assert_equal('hellohello', Tests.str .. Tests.Str())
8893 assert_equal('hellohello', Tests.Str() .. Tests.str)
8894
8895 # Using class variable for list indexing
8896 var l = range(10)
8897 assert_equal(4, l[Tests.four])
8898 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8899
8900 # Using class variable for Dict key
8901 var d = {hello: 'abc'}
8902 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008903 enddef
8904
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008905 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008906 var t = Tests.new()
8907 t.TestOps()
8908 TestOps2()
8909
8910 assert_true(Tests.truthy == Tests.Truthy())
8911 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008912 assert_true(Tests.truthy == Tests.TruthyFn())
8913 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008914 assert_true(Tests.list is Tests.List())
8915 assert_true(Tests.List() is Tests.list)
8916 assert_equal(2, Tests.four >> 1)
8917 assert_equal(16, 1 << Tests.four)
8918 assert_equal(8, Tests.four + Tests.Four())
8919 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008920 assert_equal('hellohello', Tests.str .. Tests.Str())
8921 assert_equal('hellohello', Tests.Str() .. Tests.str)
8922
8923 # Using class variable for list indexing
8924 var l = range(10)
8925 assert_equal(4, l[Tests.four])
8926 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8927
8928 # Using class variable for Dict key
8929 var d = {hello: 'abc'}
8930 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008931 END
8932 v9.CheckSourceSuccess(lines)
8933enddef
8934
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008935" Test for checking the type of the key used to access an object dict member.
8936def Test_dict_member_key_type_check()
8937 var lines =<< trim END
8938 vim9script
8939
8940 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01008941 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008942 endclass
8943
8944 class Test extends State
8945 def ObjMethodTests()
8946 var cursor: number = 0
8947 var z: number = 0
8948 [this.numbers[cursor]] = ['zero.1']
8949 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8950 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8951 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8952 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8953 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8954 [this.numbers[cursor], z] = ['zero.4', 1]
8955 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8956 [z, this.numbers[cursor]] = [1, 'zero.5']
8957 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8958 enddef
8959
8960 static def ClassMethodTests(that: State)
8961 var cursor: number = 0
8962 var z: number = 0
8963 [that.numbers[cursor]] = ['zero.1']
8964 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8965 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8966 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8967 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8968 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8969 [that.numbers[cursor], z] = ['zero.4', 1]
8970 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8971 [z, that.numbers[cursor]] = [1, 'zero.5']
8972 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8973 enddef
8974
8975 def new()
8976 enddef
8977
8978 def newMethodTests()
8979 var cursor: number = 0
8980 var z: number
8981 [this.numbers[cursor]] = ['zero.1']
8982 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8983 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8984 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8985 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8986 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8987 [this.numbers[cursor], z] = ['zero.4', 1]
8988 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8989 [z, this.numbers[cursor]] = [1, 'zero.5']
8990 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8991 enddef
8992 endclass
8993
8994 def DefFuncTests(that: Test)
8995 var cursor: number = 0
8996 var z: number
8997 [that.numbers[cursor]] = ['zero.1']
8998 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8999 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9000 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9001 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9002 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9003 [that.numbers[cursor], z] = ['zero.4', 1]
9004 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9005 [z, that.numbers[cursor]] = [1, 'zero.5']
9006 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9007 enddef
9008
9009 Test.newMethodTests()
9010 Test.new().ObjMethodTests()
9011 Test.ClassMethodTests(Test.new())
9012 DefFuncTests(Test.new())
9013
9014 const test: Test = Test.new()
9015 var cursor: number = 0
9016 [test.numbers[cursor], cursor] = ['zero', 1]
9017 [cursor, test.numbers[cursor]] = [1, 'one']
9018 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
9019 END
9020 v9.CheckSourceSuccess(lines)
9021
9022 lines =<< trim END
9023 vim9script
9024
9025 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009026 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009027
9028 def new()
9029 enddef
9030
9031 def Foo()
9032 var z: number
9033 [this.numbers.a, z] = [{}, 10]
9034 enddef
9035 endclass
9036
9037 var a = A.new()
9038 a.Foo()
9039 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009040 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009041
9042 lines =<< trim END
9043 vim9script
9044
9045 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009046 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009047
9048 def new()
9049 enddef
9050
9051 def Foo()
9052 var x: string = 'a'
9053 var y: number
9054 [this.numbers[x], y] = [{}, 10]
9055 enddef
9056 endclass
9057
9058 var a = A.new()
9059 a.Foo()
9060 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009061 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009062enddef
9063
mityua5550692023-11-25 15:41:20 +01009064def Test_compile_many_def_functions_in_funcref_instr()
9065 # This used to crash Vim. This is reproducible only when run on new instance
9066 # of Vim.
9067 var lines =<< trim END
9068 vim9script
9069
9070 class A
9071 def new()
9072 this.TakeFunc(this.F00)
9073 enddef
9074
9075 def TakeFunc(F: func)
9076 enddef
9077
9078 def F00()
9079 this.F01()
9080 this.F02()
9081 this.F03()
9082 this.F04()
9083 this.F05()
9084 this.F06()
9085 this.F07()
9086 this.F08()
9087 this.F09()
9088 this.F10()
9089 this.F11()
9090 this.F12()
9091 this.F13()
9092 this.F14()
9093 this.F15()
9094 this.F16()
9095 this.F17()
9096 this.F18()
9097 this.F19()
9098 this.F20()
9099 this.F21()
9100 this.F22()
9101 this.F23()
9102 this.F24()
9103 this.F25()
9104 this.F26()
9105 this.F27()
9106 this.F28()
9107 this.F29()
9108 this.F30()
9109 this.F31()
9110 this.F32()
9111 this.F33()
9112 this.F34()
9113 this.F35()
9114 this.F36()
9115 this.F37()
9116 this.F38()
9117 this.F39()
9118 this.F40()
9119 this.F41()
9120 this.F42()
9121 this.F43()
9122 this.F44()
9123 this.F45()
9124 this.F46()
9125 this.F47()
9126 enddef
9127
9128 def F01()
9129 enddef
9130 def F02()
9131 enddef
9132 def F03()
9133 enddef
9134 def F04()
9135 enddef
9136 def F05()
9137 enddef
9138 def F06()
9139 enddef
9140 def F07()
9141 enddef
9142 def F08()
9143 enddef
9144 def F09()
9145 enddef
9146 def F10()
9147 enddef
9148 def F11()
9149 enddef
9150 def F12()
9151 enddef
9152 def F13()
9153 enddef
9154 def F14()
9155 enddef
9156 def F15()
9157 enddef
9158 def F16()
9159 enddef
9160 def F17()
9161 enddef
9162 def F18()
9163 enddef
9164 def F19()
9165 enddef
9166 def F20()
9167 enddef
9168 def F21()
9169 enddef
9170 def F22()
9171 enddef
9172 def F23()
9173 enddef
9174 def F24()
9175 enddef
9176 def F25()
9177 enddef
9178 def F26()
9179 enddef
9180 def F27()
9181 enddef
9182 def F28()
9183 enddef
9184 def F29()
9185 enddef
9186 def F30()
9187 enddef
9188 def F31()
9189 enddef
9190 def F32()
9191 enddef
9192 def F33()
9193 enddef
9194 def F34()
9195 enddef
9196 def F35()
9197 enddef
9198 def F36()
9199 enddef
9200 def F37()
9201 enddef
9202 def F38()
9203 enddef
9204 def F39()
9205 enddef
9206 def F40()
9207 enddef
9208 def F41()
9209 enddef
9210 def F42()
9211 enddef
9212 def F43()
9213 enddef
9214 def F44()
9215 enddef
9216 def F45()
9217 enddef
9218 def F46()
9219 enddef
9220 def F47()
9221 enddef
9222 endclass
9223
9224 A.new()
9225 END
9226 writefile(lines, 'Xscript', 'D')
9227 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9228 assert_equal(0, v:shell_error)
9229enddef
9230
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009231" Test for 'final' class and object variables
9232def Test_final_class_object_variable()
9233 # Test for changing a final object variable from an object function
9234 var lines =<< trim END
9235 vim9script
9236 class A
9237 final foo: string = "abc"
9238 def Foo()
9239 this.foo = "def"
9240 enddef
9241 endclass
9242 defcompile A.Foo
9243 END
9244 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9245
9246 # Test for changing a final object variable from the 'new' function
9247 lines =<< trim END
9248 vim9script
9249 class A
9250 final s1: string
9251 final s2: string
9252 def new(this.s1)
9253 this.s2 = 'def'
9254 enddef
9255 endclass
9256 var a = A.new('abc')
9257 assert_equal('abc', a.s1)
9258 assert_equal('def', a.s2)
9259 END
9260 v9.CheckSourceSuccess(lines)
9261
9262 # Test for a final class variable
9263 lines =<< trim END
9264 vim9script
9265 class A
9266 static final s1: string = "abc"
9267 endclass
9268 assert_equal('abc', A.s1)
9269 END
9270 v9.CheckSourceSuccess(lines)
9271
9272 # Test for changing a final class variable from a class function
9273 lines =<< trim END
9274 vim9script
9275 class A
9276 static final s1: string = "abc"
9277 static def Foo()
9278 s1 = "def"
9279 enddef
9280 endclass
9281 A.Foo()
9282 END
9283 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9284
9285 # Test for changing a public final class variable at script level
9286 lines =<< trim END
9287 vim9script
9288 class A
9289 public static final s1: string = "abc"
9290 endclass
9291 assert_equal('abc', A.s1)
9292 A.s1 = 'def'
9293 END
9294 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9295
9296 # Test for changing a public final class variable from a class function
9297 lines =<< trim END
9298 vim9script
9299 class A
9300 public static final s1: string = "abc"
9301 static def Foo()
9302 s1 = "def"
9303 enddef
9304 endclass
9305 A.Foo()
9306 END
9307 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9308
9309 # Test for changing a public final class variable from a function
9310 lines =<< trim END
9311 vim9script
9312 class A
9313 public static final s1: string = "abc"
9314 endclass
9315 def Foo()
9316 A.s1 = 'def'
9317 enddef
9318 defcompile
9319 END
9320 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9321
9322 # Test for using a final variable of composite type
9323 lines =<< trim END
9324 vim9script
9325 class A
9326 public final l: list<number>
9327 def new()
9328 this.l = [1, 2]
9329 enddef
9330 def Foo()
9331 this.l[0] = 3
9332 this.l->add(4)
9333 enddef
9334 endclass
9335 var a = A.new()
9336 assert_equal([1, 2], a.l)
9337 a.Foo()
9338 assert_equal([3, 2, 4], a.l)
9339 END
9340 v9.CheckSourceSuccess(lines)
9341
9342 # Test for changing a final variable of composite type from another object
9343 # function
9344 lines =<< trim END
9345 vim9script
9346 class A
9347 public final l: list<number> = [1, 2]
9348 def Foo()
9349 this.l = [3, 4]
9350 enddef
9351 endclass
9352 var a = A.new()
9353 a.Foo()
9354 END
9355 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9356
9357 # Test for modifying a final variable of composite type at script level
9358 lines =<< trim END
9359 vim9script
9360 class A
9361 public final l: list<number> = [1, 2]
9362 endclass
9363 var a = A.new()
9364 a.l[0] = 3
9365 a.l->add(4)
9366 assert_equal([3, 2, 4], a.l)
9367 END
9368 v9.CheckSourceSuccess(lines)
9369
9370 # Test for modifying a final variable of composite type from a function
9371 lines =<< trim END
9372 vim9script
9373 class A
9374 public final l: list<number> = [1, 2]
9375 endclass
9376 def Foo()
9377 var a = A.new()
9378 a.l[0] = 3
9379 a.l->add(4)
9380 assert_equal([3, 2, 4], a.l)
9381 enddef
9382 Foo()
9383 END
9384 v9.CheckSourceSuccess(lines)
9385
9386 # Test for modifying a final variable of composite type from another object
9387 # function
9388 lines =<< trim END
9389 vim9script
9390 class A
9391 public final l: list<number> = [1, 2]
9392 def Foo()
9393 this.l[0] = 3
9394 this.l->add(4)
9395 enddef
9396 endclass
9397 var a = A.new()
9398 a.Foo()
9399 assert_equal([3, 2, 4], a.l)
9400 END
9401 v9.CheckSourceSuccess(lines)
9402
9403 # Test for assigning a new value to a final variable of composite type at
9404 # script level
9405 lines =<< trim END
9406 vim9script
9407 class A
9408 public final l: list<number> = [1, 2]
9409 endclass
9410 var a = A.new()
9411 a.l = [3, 4]
9412 END
9413 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9414
9415 # Test for assigning a new value to a final variable of composite type from
9416 # another object function
9417 lines =<< trim END
9418 vim9script
9419 class A
9420 public final l: list<number> = [1, 2]
9421 def Foo()
9422 this.l = [3, 4]
9423 enddef
9424 endclass
9425 var a = A.new()
9426 a.Foo()
9427 END
9428 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9429
9430 # Test for assigning a new value to a final variable of composite type from
9431 # another function
9432 lines =<< trim END
9433 vim9script
9434 class A
9435 public final l: list<number> = [1, 2]
9436 endclass
9437 def Foo()
9438 var a = A.new()
9439 a.l = [3, 4]
9440 enddef
9441 Foo()
9442 END
9443 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9444
9445 # Error case: Use 'final' with just a variable name
9446 lines =<< trim END
9447 vim9script
9448 class A
9449 final foo
9450 endclass
9451 var a = A.new()
9452 END
9453 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9454
9455 # Error case: Use 'final' followed by 'public'
9456 lines =<< trim END
9457 vim9script
9458 class A
9459 final public foo: number
9460 endclass
9461 var a = A.new()
9462 END
9463 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9464
9465 # Error case: Use 'final' followed by 'static'
9466 lines =<< trim END
9467 vim9script
9468 class A
9469 final static foo: number
9470 endclass
9471 var a = A.new()
9472 END
9473 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9474
9475 # Error case: 'final' cannot be used in an interface
9476 lines =<< trim END
9477 vim9script
9478 interface A
9479 final foo: number = 10
9480 endinterface
9481 END
9482 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9483
9484 # Error case: 'final' not supported for an object method
9485 lines =<< trim END
9486 vim9script
9487 class A
9488 final def Foo()
9489 enddef
9490 endclass
9491 END
9492 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9493
9494 # Error case: 'final' not supported for a class method
9495 lines =<< trim END
9496 vim9script
9497 class A
9498 static final def Foo()
9499 enddef
9500 endclass
9501 END
9502 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9503enddef
9504
9505" Test for 'const' class and object variables
9506def Test_const_class_object_variable()
9507 # Test for changing a const object variable from an object function
9508 var lines =<< trim END
9509 vim9script
9510 class A
9511 const foo: string = "abc"
9512 def Foo()
9513 this.foo = "def"
9514 enddef
9515 endclass
9516 defcompile A.Foo
9517 END
9518 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9519
9520 # Test for changing a const object variable from the 'new' function
9521 lines =<< trim END
9522 vim9script
9523 class A
9524 const s1: string
9525 const s2: string
9526 def new(this.s1)
9527 this.s2 = 'def'
9528 enddef
9529 endclass
9530 var a = A.new('abc')
9531 assert_equal('abc', a.s1)
9532 assert_equal('def', a.s2)
9533 END
9534 v9.CheckSourceSuccess(lines)
9535
9536 # Test for changing a const object variable from an object method called from
9537 # the 'new' function
9538 lines =<< trim END
9539 vim9script
9540 class A
9541 const s1: string = 'abc'
9542 def new()
9543 this.ChangeStr()
9544 enddef
9545 def ChangeStr()
9546 this.s1 = 'def'
9547 enddef
9548 endclass
9549 var a = A.new()
9550 END
9551 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9552
9553 # Test for a const class variable
9554 lines =<< trim END
9555 vim9script
9556 class A
9557 static const s1: string = "abc"
9558 endclass
9559 assert_equal('abc', A.s1)
9560 END
9561 v9.CheckSourceSuccess(lines)
9562
9563 # Test for changing a const class variable from a class function
9564 lines =<< trim END
9565 vim9script
9566 class A
9567 static const s1: string = "abc"
9568 static def Foo()
9569 s1 = "def"
9570 enddef
9571 endclass
9572 A.Foo()
9573 END
9574 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9575
9576 # Test for changing a public const class variable at script level
9577 lines =<< trim END
9578 vim9script
9579 class A
9580 public static const s1: string = "abc"
9581 endclass
9582 assert_equal('abc', A.s1)
9583 A.s1 = 'def'
9584 END
9585 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9586
9587 # Test for changing a public const class variable from a class function
9588 lines =<< trim END
9589 vim9script
9590 class A
9591 public static const s1: string = "abc"
9592 static def Foo()
9593 s1 = "def"
9594 enddef
9595 endclass
9596 A.Foo()
9597 END
9598 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9599
9600 # Test for changing a public const class variable from a function
9601 lines =<< trim END
9602 vim9script
9603 class A
9604 public static const s1: string = "abc"
9605 endclass
9606 def Foo()
9607 A.s1 = 'def'
9608 enddef
9609 defcompile
9610 END
9611 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9612
9613 # Test for changing a const List item from an object function
9614 lines =<< trim END
9615 vim9script
9616 class A
9617 public const l: list<number>
9618 def new()
9619 this.l = [1, 2]
9620 enddef
9621 def Foo()
9622 this.l[0] = 3
9623 enddef
9624 endclass
9625 var a = A.new()
9626 assert_equal([1, 2], a.l)
9627 a.Foo()
9628 END
9629 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9630
9631 # Test for adding a value to a const List from an object function
9632 lines =<< trim END
9633 vim9script
9634 class A
9635 public const l: list<number>
9636 def new()
9637 this.l = [1, 2]
9638 enddef
9639 def Foo()
9640 this.l->add(3)
9641 enddef
9642 endclass
9643 var a = A.new()
9644 a.Foo()
9645 END
9646 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9647
9648 # Test for reassigning a const List from an object function
9649 lines =<< trim END
9650 vim9script
9651 class A
9652 public const l: list<number> = [1, 2]
9653 def Foo()
9654 this.l = [3, 4]
9655 enddef
9656 endclass
9657 var a = A.new()
9658 a.Foo()
9659 END
9660 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9661
9662 # Test for changing a const List item at script level
9663 lines =<< trim END
9664 vim9script
9665 class A
9666 public const l: list<number> = [1, 2]
9667 endclass
9668 var a = A.new()
9669 a.l[0] = 3
9670 END
9671 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9672
9673 # Test for adding a value to a const List item at script level
9674 lines =<< trim END
9675 vim9script
9676 class A
9677 public const l: list<number> = [1, 2]
9678 endclass
9679 var a = A.new()
9680 a.l->add(4)
9681 END
9682 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9683
9684 # Test for changing a const List item from a function
9685 lines =<< trim END
9686 vim9script
9687 class A
9688 public const l: list<number> = [1, 2]
9689 endclass
9690 def Foo()
9691 var a = A.new()
9692 a.l[0] = 3
9693 enddef
9694 Foo()
9695 END
9696 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9697
9698 # Test for adding a value to a const List item from a function
9699 lines =<< trim END
9700 vim9script
9701 class A
9702 public const l: list<number> = [1, 2]
9703 endclass
9704 def Foo()
9705 var a = A.new()
9706 a.l->add(4)
9707 enddef
9708 Foo()
9709 END
9710 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9711
9712 # Test for changing a const List item from an object method
9713 lines =<< trim END
9714 vim9script
9715 class A
9716 public const l: list<number> = [1, 2]
9717 def Foo()
9718 this.l[0] = 3
9719 enddef
9720 endclass
9721 var a = A.new()
9722 a.Foo()
9723 END
9724 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9725
9726 # Test for adding a value to a const List item from an object method
9727 lines =<< trim END
9728 vim9script
9729 class A
9730 public const l: list<number> = [1, 2]
9731 def Foo()
9732 this.l->add(4)
9733 enddef
9734 endclass
9735 var a = A.new()
9736 a.Foo()
9737 END
9738 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9739
9740 # Test for reassigning a const List object variable at script level
9741 lines =<< trim END
9742 vim9script
9743 class A
9744 public const l: list<number> = [1, 2]
9745 endclass
9746 var a = A.new()
9747 a.l = [3, 4]
9748 END
9749 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9750
9751 # Test for reassigning a const List object variable from an object method
9752 lines =<< trim END
9753 vim9script
9754 class A
9755 public const l: list<number> = [1, 2]
9756 def Foo()
9757 this.l = [3, 4]
9758 enddef
9759 endclass
9760 var a = A.new()
9761 a.Foo()
9762 END
9763 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9764
9765 # Test for reassigning a const List object variable from another function
9766 lines =<< trim END
9767 vim9script
9768 class A
9769 public const l: list<number> = [1, 2]
9770 endclass
9771 def Foo()
9772 var a = A.new()
9773 a.l = [3, 4]
9774 enddef
9775 Foo()
9776 END
9777 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9778
9779 # Error case: Use 'const' with just a variable name
9780 lines =<< trim END
9781 vim9script
9782 class A
9783 const foo
9784 endclass
9785 var a = A.new()
9786 END
9787 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9788
9789 # Error case: Use 'const' followed by 'public'
9790 lines =<< trim END
9791 vim9script
9792 class A
9793 const public foo: number
9794 endclass
9795 var a = A.new()
9796 END
9797 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9798
9799 # Error case: Use 'const' followed by 'static'
9800 lines =<< trim END
9801 vim9script
9802 class A
9803 const static foo: number
9804 endclass
9805 var a = A.new()
9806 END
9807 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9808
9809 # Error case: 'const' cannot be used in an interface
9810 lines =<< trim END
9811 vim9script
9812 interface A
9813 const foo: number = 10
9814 endinterface
9815 END
9816 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9817
9818 # Error case: 'const' not supported for an object method
9819 lines =<< trim END
9820 vim9script
9821 class A
9822 const def Foo()
9823 enddef
9824 endclass
9825 END
9826 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9827
9828 # Error case: 'const' not supported for a class method
9829 lines =<< trim END
9830 vim9script
9831 class A
9832 static const def Foo()
9833 enddef
9834 endclass
9835 END
9836 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9837enddef
9838
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009839" Test for compiling class/object methods using :defcompile
9840def Test_defcompile_class()
9841 # defcompile all the classes in the current script
9842 var lines =<< trim END
9843 vim9script
9844 class A
9845 def Foo()
9846 var i = 10
9847 enddef
9848 endclass
9849 class B
9850 def Bar()
9851 var i = 20
9852 xxx
9853 enddef
9854 endclass
9855 defcompile
9856 END
9857 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9858
9859 # defcompile a specific class
9860 lines =<< trim END
9861 vim9script
9862 class A
9863 def Foo()
9864 xxx
9865 enddef
9866 endclass
9867 class B
9868 def Bar()
9869 yyy
9870 enddef
9871 endclass
9872 defcompile B
9873 END
9874 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9875
9876 # defcompile a non-class
9877 lines =<< trim END
9878 vim9script
9879 class A
9880 def Foo()
9881 enddef
9882 endclass
9883 var X: list<number> = []
9884 defcompile X
9885 END
9886 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9887
9888 # defcompile a class twice
9889 lines =<< trim END
9890 vim9script
9891 class A
9892 def new()
9893 enddef
9894 endclass
9895 defcompile A
9896 defcompile A
9897 assert_equal('Function A.new does not need compiling', v:statusmsg)
9898 END
9899 v9.CheckSourceSuccess(lines)
9900
9901 # defcompile should not compile an imported class
9902 lines =<< trim END
9903 vim9script
9904 export class A
9905 def Foo()
9906 xxx
9907 enddef
9908 endclass
9909 END
9910 writefile(lines, 'Xdefcompileimport.vim', 'D')
9911 lines =<< trim END
9912 vim9script
9913
9914 import './Xdefcompileimport.vim'
9915 class B
9916 endclass
9917 defcompile
9918 END
9919 v9.CheckScriptSuccess(lines)
9920enddef
9921
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +01009922" Test for cases common to all the object builtin methods
9923def Test_object_builtin_method()
9924 var lines =<< trim END
9925 vim9script
9926 class A
9927 def abc()
9928 enddef
9929 endclass
9930 END
9931 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
9932
9933 for funcname in ["len", "string", "empty"]
9934 lines =<< trim eval END
9935 vim9script
9936 class A
9937 static def {funcname}(): number
9938 enddef
9939 endclass
9940 END
9941 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
9942 endfor
9943enddef
9944
9945" Test for using the empty() builtin method with an object
9946" This is a legacy function to use the test_garbagecollect_now() function.
9947func Test_object_empty()
9948 let lines =<< trim END
9949 vim9script
9950 class A
9951 def empty(): bool
9952 return true
9953 enddef
9954 endclass
9955
9956 def Foo()
9957 var afoo = A.new()
9958 assert_equal(true, empty(afoo))
9959 assert_equal(true, afoo->empty())
9960 enddef
9961
9962 var a = A.new()
9963 assert_equal(1, empty(a))
9964 assert_equal(1, a->empty())
9965 test_garbagecollect_now()
9966 assert_equal(1, empty(a))
9967 Foo()
9968 test_garbagecollect_now()
9969 Foo()
9970 END
9971 call v9.CheckSourceSuccess(lines)
9972
9973 " empty() should return 1 without a builtin method
9974 let lines =<< trim END
9975 vim9script
9976 class A
9977 endclass
9978
9979 def Foo()
9980 var afoo = A.new()
9981 assert_equal(1, empty(afoo))
9982 enddef
9983
9984 var a = A.new()
9985 assert_equal(1, empty(a))
9986 Foo()
9987 END
9988 call v9.CheckSourceSuccess(lines)
9989
9990 " Unsupported signature for the empty() method
9991 let lines =<< trim END
9992 vim9script
9993 class A
9994 def empty()
9995 enddef
9996 endclass
9997 END
9998 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
9999
10000 " Error when calling the empty() method
10001 let lines =<< trim END
10002 vim9script
10003 class A
10004 def empty(): bool
10005 throw "Failed to check emptiness"
10006 enddef
10007 endclass
10008
10009 def Foo()
10010 var afoo = A.new()
10011 var i = empty(afoo)
10012 enddef
10013
10014 var a = A.new()
10015 assert_fails('empty(a)', 'Failed to check emptiness')
10016 assert_fails('Foo()', 'Failed to check emptiness')
10017 END
10018 call v9.CheckSourceSuccess(lines)
10019
10020 " call empty() using an object from a script
10021 let lines =<< trim END
10022 vim9script
10023 class A
10024 def empty(): bool
10025 return true
10026 enddef
10027 endclass
10028 var afoo = A.new()
10029 assert_equal(true, afoo.empty())
10030 END
10031 call v9.CheckSourceSuccess(lines)
10032
10033 " call empty() using an object from a method
10034 let lines =<< trim END
10035 vim9script
10036 class A
10037 def empty(): bool
10038 return true
10039 enddef
10040 endclass
10041 def Foo()
10042 var afoo = A.new()
10043 assert_equal(true, afoo.empty())
10044 enddef
10045 Foo()
10046 END
10047 call v9.CheckSourceSuccess(lines)
10048
10049 " call empty() using "this" from an object method
10050 let lines =<< trim END
10051 vim9script
10052 class A
10053 def empty(): bool
10054 return true
10055 enddef
10056 def Foo(): bool
10057 return this.empty()
10058 enddef
10059 endclass
10060 def Bar()
10061 var abar = A.new()
10062 assert_equal(true, abar.Foo())
10063 enddef
10064 Bar()
10065 END
10066 call v9.CheckSourceSuccess(lines)
10067
10068 " Call empty() from a derived object
10069 let lines =<< trim END
10070 vim9script
10071 class A
10072 def empty(): bool
10073 return false
10074 enddef
10075 endclass
10076 class B extends A
10077 def empty(): bool
10078 return true
10079 enddef
10080 endclass
10081 def Foo(afoo: A)
10082 assert_equal(true, empty(afoo))
10083 var bfoo = B.new()
10084 assert_equal(true, empty(bfoo))
10085 enddef
10086 var b = B.new()
10087 assert_equal(1, empty(b))
10088 Foo(b)
10089 END
10090 call v9.CheckSourceSuccess(lines)
10091
10092 " Invoking empty method using an interface
10093 let lines =<< trim END
10094 vim9script
10095 interface A
10096 def empty(): bool
10097 endinterface
10098 class B implements A
10099 def empty(): bool
10100 return false
10101 enddef
10102 endclass
10103 def Foo(a: A)
10104 assert_equal(false, empty(a))
10105 enddef
10106 var b = B.new()
10107 Foo(b)
10108 END
10109 call v9.CheckSourceSuccess(lines)
10110endfunc
10111
10112" Test for using the len() builtin method with an object
10113" This is a legacy function to use the test_garbagecollect_now() function.
10114func Test_object_length()
10115 let lines =<< trim END
10116 vim9script
10117 class A
10118 var mylen: number = 0
10119 def new(n: number)
10120 this.mylen = n
10121 enddef
10122 def len(): number
10123 return this.mylen
10124 enddef
10125 endclass
10126
10127 def Foo()
10128 var afoo = A.new(12)
10129 assert_equal(12, len(afoo))
10130 assert_equal(12, afoo->len())
10131 enddef
10132
10133 var a = A.new(22)
10134 assert_equal(22, len(a))
10135 assert_equal(22, a->len())
10136 test_garbagecollect_now()
10137 assert_equal(22, len(a))
10138 Foo()
10139 test_garbagecollect_now()
10140 Foo()
10141 END
10142 call v9.CheckSourceSuccess(lines)
10143
10144 " len() should return 0 without a builtin method
10145 let lines =<< trim END
10146 vim9script
10147 class A
10148 endclass
10149
10150 def Foo()
10151 var afoo = A.new()
10152 assert_equal(0, len(afoo))
10153 enddef
10154
10155 var a = A.new()
10156 assert_equal(0, len(a))
10157 Foo()
10158 END
10159 call v9.CheckSourceSuccess(lines)
10160
10161 " Unsupported signature for the len() method
10162 let lines =<< trim END
10163 vim9script
10164 class A
10165 def len()
10166 enddef
10167 endclass
10168 END
10169 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10170
10171 " Error when calling the len() method
10172 let lines =<< trim END
10173 vim9script
10174 class A
10175 def len(): number
10176 throw "Failed to compute length"
10177 enddef
10178 endclass
10179
10180 def Foo()
10181 var afoo = A.new()
10182 var i = len(afoo)
10183 enddef
10184
10185 var a = A.new()
10186 assert_fails('len(a)', 'Failed to compute length')
10187 assert_fails('Foo()', 'Failed to compute length')
10188 END
10189 call v9.CheckSourceSuccess(lines)
10190
10191 " call len() using an object from a script
10192 let lines =<< trim END
10193 vim9script
10194 class A
10195 def len(): number
10196 return 5
10197 enddef
10198 endclass
10199 var afoo = A.new()
10200 assert_equal(5, afoo.len())
10201 END
10202 call v9.CheckSourceSuccess(lines)
10203
10204 " call len() using an object from a method
10205 let lines =<< trim END
10206 vim9script
10207 class A
10208 def len(): number
10209 return 5
10210 enddef
10211 endclass
10212 def Foo()
10213 var afoo = A.new()
10214 assert_equal(5, afoo.len())
10215 enddef
10216 Foo()
10217 END
10218 call v9.CheckSourceSuccess(lines)
10219
10220 " call len() using "this" from an object method
10221 let lines =<< trim END
10222 vim9script
10223 class A
10224 def len(): number
10225 return 8
10226 enddef
10227 def Foo(): number
10228 return this.len()
10229 enddef
10230 endclass
10231 def Bar()
10232 var abar = A.new()
10233 assert_equal(8, abar.Foo())
10234 enddef
10235 Bar()
10236 END
10237 call v9.CheckSourceSuccess(lines)
10238
10239 " Call len() from a derived object
10240 let lines =<< trim END
10241 vim9script
10242 class A
10243 def len(): number
10244 return 10
10245 enddef
10246 endclass
10247 class B extends A
10248 def len(): number
10249 return 20
10250 enddef
10251 endclass
10252 def Foo(afoo: A)
10253 assert_equal(20, len(afoo))
10254 var bfoo = B.new()
10255 assert_equal(20, len(bfoo))
10256 enddef
10257 var b = B.new()
10258 assert_equal(20, len(b))
10259 Foo(b)
10260 END
10261 call v9.CheckSourceSuccess(lines)
10262
10263 " Invoking len method using an interface
10264 let lines =<< trim END
10265 vim9script
10266 interface A
10267 def len(): number
10268 endinterface
10269 class B implements A
10270 def len(): number
10271 return 123
10272 enddef
10273 endclass
10274 def Foo(a: A)
10275 assert_equal(123, len(a))
10276 enddef
10277 var b = B.new()
10278 Foo(b)
10279 END
10280 call v9.CheckSourceSuccess(lines)
10281endfunc
10282
10283" Test for using the string() builtin method with an object
10284" This is a legacy function to use the test_garbagecollect_now() function.
10285func Test_object_string()
10286 let lines =<< trim END
10287 vim9script
10288 class A
10289 var name: string
10290 def string(): string
10291 return this.name
10292 enddef
10293 endclass
10294
10295 def Foo()
10296 var afoo = A.new("foo-A")
10297 assert_equal('foo-A', string(afoo))
10298 assert_equal('foo-A', afoo->string())
10299 enddef
10300
10301 var a = A.new("script-A")
10302 assert_equal('script-A', string(a))
10303 assert_equal('script-A', a->string())
10304 assert_equal(['script-A'], execute('echo a')->split("\n"))
10305 test_garbagecollect_now()
10306 assert_equal('script-A', string(a))
10307 Foo()
10308 test_garbagecollect_now()
10309 Foo()
10310 END
10311 call v9.CheckSourceSuccess(lines)
10312
10313 " string() should return "object of A {}" without a builtin method
10314 let lines =<< trim END
10315 vim9script
10316 class A
10317 endclass
10318
10319 def Foo()
10320 var afoo = A.new()
10321 assert_equal('object of A {}', string(afoo))
10322 enddef
10323
10324 var a = A.new()
10325 assert_equal('object of A {}', string(a))
10326 Foo()
10327 END
10328 call v9.CheckSourceSuccess(lines)
10329
10330 " Unsupported signature for the string() method
10331 let lines =<< trim END
10332 vim9script
10333 class A
10334 def string()
10335 enddef
10336 endclass
10337 END
10338 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10339
10340 " Error when calling the string() method
10341 let lines =<< trim END
10342 vim9script
10343 class A
10344 def string(): string
10345 throw "Failed to get text"
10346 enddef
10347 endclass
10348
10349 def Foo()
10350 var afoo = A.new()
10351 var i = string(afoo)
10352 enddef
10353
10354 var a = A.new()
10355 assert_fails('string(a)', 'Failed to get text')
10356 assert_fails('Foo()', 'Failed to get text')
10357 END
10358 call v9.CheckSourceSuccess(lines)
10359
10360 " call string() using an object from a script
10361 let lines =<< trim END
10362 vim9script
10363 class A
10364 def string(): string
10365 return 'A'
10366 enddef
10367 endclass
10368 var afoo = A.new()
10369 assert_equal('A', afoo.string())
10370 END
10371 call v9.CheckSourceSuccess(lines)
10372
10373 " call string() using an object from a method
10374 let lines =<< trim END
10375 vim9script
10376 class A
10377 def string(): string
10378 return 'A'
10379 enddef
10380 endclass
10381 def Foo()
10382 var afoo = A.new()
10383 assert_equal('A', afoo.string())
10384 enddef
10385 Foo()
10386 END
10387 call v9.CheckSourceSuccess(lines)
10388
10389 " call string() using "this" from an object method
10390 let lines =<< trim END
10391 vim9script
10392 class A
10393 def string(): string
10394 return 'A'
10395 enddef
10396 def Foo(): string
10397 return this.string()
10398 enddef
10399 endclass
10400 def Bar()
10401 var abar = A.new()
10402 assert_equal('A', abar.string())
10403 enddef
10404 Bar()
10405 END
10406 call v9.CheckSourceSuccess(lines)
10407
10408 " Call string() from a derived object
10409 let lines =<< trim END
10410 vim9script
10411 class A
10412 def string(): string
10413 return 'A'
10414 enddef
10415 endclass
10416 class B extends A
10417 def string(): string
10418 return 'B'
10419 enddef
10420 endclass
10421 def Foo(afoo: A)
10422 assert_equal('B', string(afoo))
10423 var bfoo = B.new()
10424 assert_equal('B', string(bfoo))
10425 enddef
10426 var b = B.new()
10427 assert_equal('B', string(b))
10428 Foo(b)
10429 END
10430 call v9.CheckSourceSuccess(lines)
10431
10432 " Invoking string method using an interface
10433 let lines =<< trim END
10434 vim9script
10435 interface A
10436 def string(): string
10437 endinterface
10438 class B implements A
10439 def string(): string
10440 return 'B'
10441 enddef
10442 endclass
10443 def Foo(a: A)
10444 assert_equal('B', string(a))
10445 enddef
10446 var b = B.new()
10447 Foo(b)
10448 END
10449 call v9.CheckSourceSuccess(lines)
10450endfunc
10451
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010452" Test for using a class in the class definition
10453def Test_Ref_Class_Within_Same_Class()
10454 var lines =<< trim END
10455 vim9script
10456 class A
10457 var n: number = 0
10458 def Equals(other: A): bool
10459 return this.n == other.n
10460 enddef
10461 endclass
10462
10463 var a1 = A.new(10)
10464 var a2 = A.new(10)
10465 var a3 = A.new(20)
10466 assert_equal(true, a1.Equals(a2))
10467 assert_equal(false, a2.Equals(a3))
10468 END
10469 v9.CheckScriptSuccess(lines)
10470
10471 lines =<< trim END
10472 vim9script
10473
10474 class Foo
10475 var num: number
10476 def Clone(): Foo
10477 return Foo.new(this.num)
10478 enddef
10479 endclass
10480
10481 var f1 = Foo.new(1)
10482
10483 def F()
10484 var f2: Foo = f1.Clone()
10485 assert_equal(false, f2 is f1)
10486 assert_equal(true, f2.num == f1.num)
10487 enddef
10488 F()
10489
10490 var f3: Foo = f1.Clone()
10491 assert_equal(false, f3 is f1)
10492 assert_equal(true, f3.num == f1.num)
10493 END
10494 v9.CheckScriptSuccess(lines)
10495
10496 # Test for trying to use a class to extend when defining the same class
10497 lines =<< trim END
10498 vim9script
10499 class A extends A
10500 endclass
10501 END
10502 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10503
10504 # Test for trying to use a class to implement when defining the same class
10505 lines =<< trim END
10506 vim9script
10507 class A implements A
10508 endclass
10509 END
10510 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10511enddef
10512
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010513" Test for using a compound operator from a lambda function in an object method
10514def Test_compound_op_in_objmethod_lambda()
10515 # Test using the "+=" operator
10516 var lines =<< trim END
10517 vim9script
10518 class A
10519 var n: number = 10
10520 def Foo()
10521 var Fn = () => {
10522 this.n += 1
10523 }
10524 Fn()
10525 enddef
10526 endclass
10527
10528 var a = A.new()
10529 a.Foo()
10530 assert_equal(11, a.n)
10531 END
10532 v9.CheckScriptSuccess(lines)
10533
10534 # Test using the "..=" operator
10535 lines =<< trim END
10536 vim9script
10537 class A
10538 var s: string = "a"
10539 def Foo()
10540 var Fn = () => {
10541 this.s ..= "a"
10542 }
10543 Fn()
10544 enddef
10545 endclass
10546
10547 var a = A.new()
10548 a.Foo()
10549 a.Foo()
10550 assert_equal("aaa", a.s)
10551 END
10552 v9.CheckScriptSuccess(lines)
10553enddef
10554
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010555" Test for using test_refcount() with a class and an object
10556def Test_class_object_refcount()
10557 var lines =<< trim END
10558 vim9script
10559 class A
10560 endclass
10561 var a: A = A.new()
10562 assert_equal(2, test_refcount(A))
10563 assert_equal(1, test_refcount(a))
10564 var b = a
10565 assert_equal(2, test_refcount(A))
10566 assert_equal(2, test_refcount(a))
10567 assert_equal(2, test_refcount(b))
10568 END
10569 v9.CheckScriptSuccess(lines)
10570enddef
10571
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010572" call a lambda function in one object from another object
10573def Test_lambda_invocation_across_classes()
10574 var lines =<< trim END
10575 vim9script
10576 class A
10577 var s: string = "foo"
10578 def GetFn(): func
10579 var Fn = (): string => {
10580 return this.s
10581 }
10582 return Fn
10583 enddef
10584 endclass
10585
10586 class B
10587 var s: string = "bar"
10588 def GetFn(): func
10589 var a = A.new()
10590 return a.GetFn()
10591 enddef
10592 endclass
10593
10594 var b = B.new()
10595 var Fn = b.GetFn()
10596 assert_equal("foo", Fn())
10597 END
10598 v9.CheckScriptSuccess(lines)
10599enddef
10600
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010601" Test for using a class member which is an object of the current class
10602def Test_current_class_object_class_member()
10603 var lines =<< trim END
10604 vim9script
10605 class A
10606 public static var obj1: A = A.new(10)
10607 var n: number
10608 endclass
10609 defcompile
10610 assert_equal(10, A.obj1.n)
10611 END
10612 v9.CheckScriptSuccess(lines)
10613enddef
10614
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020010615" Test for updating a base class variable from a base class method without the
10616" class name. This used to crash Vim (Github issue #14352).
10617def Test_use_base_class_variable_from_base_class_method()
10618 var lines =<< trim END
10619 vim9script
10620
10621 class DictKeyClass
10622 static var _obj_id_count = 1
10623 def _GenerateKey()
10624 _obj_id_count += 1
10625 enddef
10626 static def GetIdCount(): number
10627 return _obj_id_count
10628 enddef
10629 endclass
10630
10631 class C extends DictKeyClass
10632 def F()
10633 this._GenerateKey()
10634 enddef
10635 endclass
10636
10637 C.new().F()
10638 assert_equal(2, DictKeyClass.GetIdCount())
10639 END
10640 v9.CheckScriptSuccess(lines)
10641enddef
10642
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020010643" Test for accessing protected funcref object and class variables
10644def Test_protected_funcref()
10645 # protected funcref object variable
10646 var lines =<< trim END
10647 vim9script
10648 class Test1
10649 const _Id: func(any): any = (v) => v
10650 endclass
10651 var n = Test1.new()._Id(1)
10652 END
10653 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
10654
10655 # protected funcref class variable
10656 lines =<< trim END
10657 vim9script
10658 class Test2
10659 static const _Id: func(any): any = (v) => v
10660 endclass
10661 var n = Test2._Id(2)
10662 END
10663 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
10664enddef
10665
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020010666" Test for using lambda block in classes
10667def Test_lambda_block_in_class()
10668 # This used to crash Vim
10669 var lines =<< trim END
10670 vim9script
10671 class IdClass1
10672 const Id: func(number): number = (num: number): number => {
10673 # Return a ID
10674 return num * 10
10675 }
10676 endclass
10677 var id = IdClass1.new()
10678 assert_equal(20, id.Id(2))
10679 END
10680 v9.CheckScriptSuccess(lines)
10681
10682 # This used to crash Vim
10683 lines =<< trim END
10684 vim9script
10685 class IdClass2
10686 static const Id: func(number): number = (num: number): number => {
10687 # Return a ID
10688 return num * 2
10689 }
10690 endclass
10691 assert_equal(16, IdClass2.Id(8))
10692 END
10693 v9.CheckScriptSuccess(lines)
10694enddef
10695
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020010696" Test for defcompiling an abstract method
10697def Test_abstract_method_defcompile()
10698 # Compile an abstract class with abstract object methods
10699 var lines =<< trim END
10700 vim9script
10701 abstract class A
10702 abstract def Foo(): string
10703 abstract def Bar(): list<string>
10704 endclass
10705 defcompile
10706 END
10707 v9.CheckScriptSuccess(lines)
10708
10709 # Compile a concrete object method in an abstract class
10710 lines =<< trim END
10711 vim9script
10712 abstract class A
10713 abstract def Foo(): string
10714 abstract def Bar(): list<string>
10715 def Baz(): string
10716 pass
10717 enddef
10718 endclass
10719 defcompile
10720 END
10721 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10722
10723 # Compile a concrete class method in an abstract class
10724 lines =<< trim END
10725 vim9script
10726 abstract class A
10727 abstract def Foo(): string
10728 abstract def Bar(): list<string>
10729 static def Baz(): string
10730 pass
10731 enddef
10732 endclass
10733 defcompile
10734 END
10735 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10736enddef
10737
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020010738" Test for defining a class in a function
10739def Test_class_definition_in_a_function()
10740 var lines =<< trim END
10741 vim9script
10742 def Foo()
10743 class A
10744 endclass
10745 enddef
10746 defcompile
10747 END
10748 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
10749enddef
10750
Bram Moolenaar00b28d62022-12-08 15:32:33 +000010751" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker