blob: 0bc36393057dc186bc7d118a2bf61adff6e3f231 [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 Lakshmanan35b867b2024-03-09 15:44:19 +010070 # Try to define a class with the same name as an existing variable
71 lines =<< trim END
72 vim9script
73 var Something: list<number> = [1]
74 class Thing
75 endclass
76 interface Api
77 endinterface
78 class Something extends Thing implements Api
79 var v1: string = ''
80 def Foo()
81 enddef
82 endclass
83 END
84 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 7)
85
zeertzjqe7102202024-02-13 20:32:04 +010086 # Use old "this." prefixed member variable declaration syntax (without initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +010087 lines =<< trim END
88 vim9script
89 class Something
90 this.count: number
91 endclass
92 END
93 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
94
zeertzjqe7102202024-02-13 20:32:04 +010095 # Use old "this." prefixed member variable declaration syntax (with initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +010096 lines =<< trim END
97 vim9script
98 class Something
99 this.count: number = 42
100 endclass
101 END
102 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
103
104 # Use old "this." prefixed member variable declaration syntax (type inferred)
105 lines =<< trim END
106 vim9script
107 class Something
108 this.count = 42
109 endclass
110 END
111 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
112
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200113 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000114 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200115 vim9script
116 class Something
117 this
118 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000119 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100120 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000121
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200122 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000123 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200124 vim9script
125 class Something
126 this.
127 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000128 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100129 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000130
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200131 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000132 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200133 vim9script
134 class Something
135 this .count
136 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000137 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100138 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000139
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200140 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000141 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200142 vim9script
143 class Something
144 this. count
145 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000146 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100147 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000148
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200149 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000150 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200151 vim9script
152 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100153 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200154 that.count
155 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000156 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200157 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000158
Doug Kearns74da0ee2023-12-14 20:26:26 +0100159 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000160 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200161 vim9script
162 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100163 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200164 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000165 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100166 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
167
168 # Use "variable" instead of "var" for member variable declaration (with initialization)
169 lines =<< trim END
170 vim9script
171 class Something
172 variable count: number = 42
173 endclass
174 END
175 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
176
177 # Use "variable" instead of "var" for member variable declaration (type inferred)
178 lines =<< trim END
179 vim9script
180 class Something
181 variable count = 42
182 endclass
183 END
184 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000185
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200186 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000187 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200188 vim9script
189 class Something
190 def new()
191 this.state = 0
192 enddef
193 endclass
194 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000195 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200196 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000197
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200198 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000199 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200200 vim9script
201 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100202 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200203 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200205 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000206
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200207 # No space after ":" in a member variable declaration
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 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000213 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200214 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000215
Doug Kearns74da0ee2023-12-14 20:26:26 +0100216 # Missing ":var" in a "var" member variable declaration (without initialization)
217 lines =<< trim END
218 vim9script
219 class Something
220 var: number
221 endclass
222 END
223 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
224
225 # Missing ":var" in a "var" member variable declaration (with initialization)
226 lines =<< trim END
227 vim9script
228 class Something
229 var: number = 42
230 endclass
231 END
232 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
233
234 # Missing ":var" in a "var" member variable declaration (type inferred)
235 lines =<< trim END
236 vim9script
237 class Something
238 var = 42
239 endclass
240 END
241 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
242
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200243 # Test for unsupported comment specifier
244 lines =<< trim END
245 vim9script
246 class Something
247 # comment
248 #{
249 endclass
250 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200251 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200252
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200253 # Test for using class as a bool
254 lines =<< trim END
255 vim9script
256 class A
257 endclass
258 if A
259 endif
260 END
Ernie Raele75fde62023-12-21 17:18:54 +0100261 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200262
263 # Test for using object as a bool
264 lines =<< trim END
265 vim9script
266 class A
267 endclass
268 var a = A.new()
269 if a
270 endif
271 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200272 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200273
274 # Test for using class as a float
275 lines =<< trim END
276 vim9script
277 class A
278 endclass
279 sort([1.1, A], 'f')
280 END
Ernie Raelfa831102023-12-14 20:06:39 +0100281 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200282
283 # Test for using object as a float
284 lines =<< trim END
285 vim9script
286 class A
287 endclass
288 var a = A.new()
289 sort([1.1, a], 'f')
290 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200291 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200292
293 # Test for using class as a string
294 lines =<< trim END
295 vim9script
296 class A
297 endclass
298 :exe 'call ' .. A
299 END
Ernie Raele75fde62023-12-21 17:18:54 +0100300 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200301
302 # Test for using object as a string
303 lines =<< trim END
304 vim9script
305 class A
306 endclass
307 var a = A.new()
308 :exe 'call ' .. a
309 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200310 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200311
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200312 # Test creating a class with member variables and methods, calling a object
313 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000314 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200315 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000316
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200317 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100318 var lnum: number
319 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000320
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200321 # make a nicely formatted string
322 def ToString(): string
323 return $'({this.lnum}, {this.col})'
324 enddef
325 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000326
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200327 # use the automatically generated new() method
328 var pos = TextPosition.new(2, 12)
329 assert_equal(2, pos.lnum)
330 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000331
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200332 # call an object method
333 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000334
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200335 assert_equal(v:t_class, type(TextPosition))
336 assert_equal(v:t_object, type(pos))
337 assert_equal('class<TextPosition>', typename(TextPosition))
338 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000339 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200340 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200341
342 # When referencing object methods, space cannot be used after a "."
343 lines =<< trim END
344 vim9script
345 class A
346 def Foo(): number
347 return 10
348 enddef
349 endclass
350 var a = A.new()
351 var v = a. Foo()
352 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200353 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200354
355 # Using an object without specifying a method or a member variable
356 lines =<< trim END
357 vim9script
358 class A
359 def Foo(): number
360 return 10
361 enddef
362 endclass
363 var a = A.new()
364 var v = a.
365 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200366 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200367
368 # Error when parsing the arguments of an object method.
369 lines =<< trim END
370 vim9script
371 class A
372 def Foo()
373 enddef
374 endclass
375 var a = A.new()
376 var v = a.Foo(,)
377 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200378 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200379
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200380 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200381 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200382 vim9script
383 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100384 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200385 X: 1
386 }
387 endclass
388 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200389 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200390 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000391enddef
392
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200393" Tests for object/class methods in a class
394def Test_class_def_method()
395 # Using the "public" keyword when defining an object method
396 var lines =<< trim END
397 vim9script
398 class A
399 public def Foo()
400 enddef
401 endclass
402 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100403 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200404
405 # Using the "public" keyword when defining a class method
406 lines =<< trim END
407 vim9script
408 class A
409 public static def Foo()
410 enddef
411 endclass
412 END
413 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
414
Ernie Rael03042a22023-11-11 08:53:32 +0100415 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200416 lines =<< trim END
417 vim9script
418 class A
419 public def _Foo()
420 enddef
421 endclass
422 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100423 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200424
Ernie Rael03042a22023-11-11 08:53:32 +0100425 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200426 lines =<< trim END
427 vim9script
428 class A
429 public static def _Foo()
430 enddef
431 endclass
432 END
433 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
434
435 # Using a "def" keyword without an object method name
436 lines =<< trim END
437 vim9script
438 class A
439 def
440 enddef
441 endclass
442 END
443 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
444
445 # Using a "def" keyword without a class method name
446 lines =<< trim END
447 vim9script
448 class A
449 static def
450 enddef
451 endclass
452 END
453 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
454enddef
455
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000456def Test_class_defined_twice()
457 # class defined twice should fail
458 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200459 vim9script
460 class There
461 endclass
462 class There
463 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000464 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200465 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000466
467 # one class, reload same script twice is OK
468 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200469 vim9script
470 class There
471 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000472 END
473 writefile(lines, 'XclassTwice.vim', 'D')
474 source XclassTwice.vim
475 source XclassTwice.vim
476enddef
477
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000478def Test_returning_null_object()
479 # this was causing an internal error
480 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200481 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000482
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200483 class BufferList
484 def Current(): any
485 return null_object
486 enddef
487 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000488
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200489 var buffers = BufferList.new()
490 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000491 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200492 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000493enddef
494
Bram Moolenaard13dd302023-03-11 20:56:35 +0000495def Test_using_null_class()
496 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200497 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000498 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200499 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Bram Moolenaard13dd302023-03-11 20:56:35 +0000500enddef
501
Bram Moolenaar657aea72023-01-27 13:16:19 +0000502def Test_class_interface_wrong_end()
503 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200504 vim9script
505 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100506 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200507 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000508 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200509 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000510
511 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200512 vim9script
513 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100514 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200515 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000518enddef
519
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000520def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200521 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000522 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200523 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000524
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200525 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100526 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200527 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000528
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200529 var state: State
530 var db = {'xyz': 789}
531 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000532 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200533 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000534
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200535 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000536 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200537 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000538
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200539 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100540 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200541 def Method1()
542 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000543 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200544 endclass
545
546 var obj: Class
547 def Func()
548 obj.Method1()
549 enddef
550 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000551 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200552 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000553
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200554 # Pass an uninitialized object variable to a "new" function and try to call an
555 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000556 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200557 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000558
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200559 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100560 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200561 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000562
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200563 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100564 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000565
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200566 def GetBackground(): string
567 return this._bg.background
568 enddef
569 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000570
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200571 var bg: Background # UNINITIALIZED
572 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000573 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200574 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000575
576 # TODO: this should not give an error but be handled at runtime
577 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200578 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000579
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200580 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100581 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200582 def Method1()
583 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000584 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200585 endclass
586
587 var obj = null_object
588 def Func()
589 obj.Method1()
590 enddef
591 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000592 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200593 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000594enddef
595
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200596" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200597def Test_null_object_assign_compare()
598 var lines =<< trim END
599 vim9script
600
601 var nullo = null_object
602 def F(): any
603 return nullo
604 enddef
605 assert_equal('object<Unknown>', typename(F()))
606
607 var o0 = F()
608 assert_true(o0 == null_object)
609 assert_true(o0 == null)
610
611 var o1: any = nullo
612 assert_true(o1 == null_object)
613 assert_true(o1 == null)
614
615 def G()
616 var x = null_object
617 enddef
618
619 class C
620 endclass
621 var o2: C
622 assert_true(o2 == null_object)
623 assert_true(o2 == null)
624
625 o2 = null_object
626 assert_true(o2 == null)
627
628 o2 = C.new()
629 assert_true(o2 != null)
630
631 o2 = null_object
632 assert_true(o2 == null)
633 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200634 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200635enddef
636
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200637" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000638def Test_class_member_initializer()
639 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200640 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000641
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200642 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100643 var lnum: number = 1
644 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000645
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200646 # constructor with only the line number
647 def new(lnum: number)
648 this.lnum = lnum
649 enddef
650 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000651
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200652 var pos = TextPosition.new(3)
653 assert_equal(3, pos.lnum)
654 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000655
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200656 var instr = execute('disassemble TextPosition.new')
657 assert_match('new\_s*' ..
658 '0 NEW TextPosition size \d\+\_s*' ..
659 '\d PUSHNR 1\_s*' ..
660 '\d STORE_THIS 0\_s*' ..
661 '\d PUSHNR 1\_s*' ..
662 '\d STORE_THIS 1\_s*' ..
663 'this.lnum = lnum\_s*' ..
664 '\d LOAD arg\[-1]\_s*' ..
665 '\d PUSHNR 0\_s*' ..
666 '\d LOAD $0\_s*' ..
667 '\d\+ STOREINDEX object\_s*' ..
668 '\d\+ RETURN object.*',
669 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000670 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200671 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000672enddef
673
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000674def Test_member_any_used_as_object()
675 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200676 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000677
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200678 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100679 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200680 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000681
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200682 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100683 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200684 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000685
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200686 def F(outer: Outer)
687 outer.inner.value = 1
688 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000689
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200690 var inner_obj = Inner.new(0)
691 var outer_obj = Outer.new(inner_obj)
692 F(outer_obj)
693 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000694 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200695 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000696
Ernie Rael03042a22023-11-11 08:53:32 +0100697 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200698 lines =<< trim END
699 vim9script
700
701 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100702 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200703 endclass
704
705 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100706 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200707 endclass
708
709 def F(outer: Outer)
710 outer.inner._value = 'b'
711 enddef
712
713 var inner_obj = Inner.new('a')
714 var outer_obj = Outer.new(inner_obj)
715 F(outer_obj)
716 END
Ernie Rael03042a22023-11-11 08:53:32 +0100717 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200718
719 # Try modifying a non-existing variable using an "any" object
720 lines =<< trim END
721 vim9script
722
723 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100724 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200725 endclass
726
727 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100728 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200729 endclass
730
731 def F(outer: Outer)
732 outer.inner.someval = 'b'
733 enddef
734
735 var inner_obj = Inner.new('a')
736 var outer_obj = Outer.new(inner_obj)
737 F(outer_obj)
738 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200739 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000740enddef
741
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200742" Nested assignment to a object variable which is of another class type
743def Test_assignment_nested_type()
744 var lines =<< trim END
745 vim9script
746
747 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100748 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200749 endclass
750
751 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100752 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200753 endclass
754
755 def F(outer: Outer)
756 outer.inner.value = 1
757 enddef
758
759 def Test_assign_to_nested_typed_member()
760 var inner = Inner.new(0)
761 var outer = Outer.new(inner)
762 F(outer)
763 assert_equal(1, inner.value)
764 enddef
765
766 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200767
768 var script_inner = Inner.new(0)
769 var script_outer = Outer.new(script_inner)
770 script_outer.inner.value = 1
771 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200772 END
773 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200774
775 # Assignment where target item is read only in :def
776 lines =<< trim END
777 vim9script
778
779 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100780 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200781 endclass
782
783 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100784 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200785 endclass
786
787 def F(outer: Outer)
788 outer.inner.value = 1
789 enddef
790
791 def Test_assign_to_nested_typed_member()
792 var inner = Inner.new(0)
793 var outer = Outer.new(inner)
794 F(outer)
795 assert_equal(1, inner.value)
796 enddef
797
798 Test_assign_to_nested_typed_member()
799 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200800 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200801
802 # Assignment where target item is read only script level
803 lines =<< trim END
804 vim9script
805
806 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100807 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200808 endclass
809
810 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100811 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200812 endclass
813
814 def F(outer: Outer)
815 outer.inner.value = 1
816 enddef
817
818 var script_inner = Inner.new(0)
819 var script_outer = Outer.new(script_inner)
820 script_outer.inner.value = 1
821 assert_equal(1, script_inner.value)
822 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200823 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200824enddef
825
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000826def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200827 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000828 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200829 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000830
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200831 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100832 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000833
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200834 def Add(n: number)
835 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100836 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200837 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100838
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200839 var f = Foo.new(3)
840 f.Add(17)
841 assert_equal(20, f.x)
842
843 def AddToFoo(obj: Foo)
844 obj.x += 3
845 enddef
846
847 AddToFoo(f)
848 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000849 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200850 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000851enddef
852
Bram Moolenaarf4508042023-01-15 16:54:57 +0000853def Test_list_of_objects()
854 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200855 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000856
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200857 class Foo
858 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000859 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200860 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000861
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200862 def ProcessList(fooList: list<Foo>)
863 for foo in fooList
864 foo.Add()
865 endfor
866 enddef
867
868 var l: list<Foo> = [Foo.new()]
869 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000870 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200871 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000872enddef
873
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000874def Test_expr_after_using_object()
875 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200876 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000877
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200878 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100879 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200880 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000881
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200882 def Foo(): Something
883 var v = Something.new()
884 echo 'in Foo(): ' .. typename(v)
885 return v
886 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000887
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200888 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000889 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200890 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000891enddef
892
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000893def Test_class_default_new()
894 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200895 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000896
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200897 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100898 var lnum: number = 1
899 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200900 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000901
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200902 var pos = TextPosition.new()
903 assert_equal(1, pos.lnum)
904 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000905
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200906 pos = TextPosition.new(v:none, v:none)
907 assert_equal(1, pos.lnum)
908 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000909
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200910 pos = TextPosition.new(3, 22)
911 assert_equal(3, pos.lnum)
912 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000913
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200914 pos = TextPosition.new(v:none, 33)
915 assert_equal(1, pos.lnum)
916 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000917 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200918 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000919
920 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200921 vim9script
922 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100923 var name: string
924 var age: number = 42
925 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000926
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200927 def new(this.name, this.age = v:none, this.education = v:none)
928 enddef
929 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000930
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200931 var piet = Person.new("Piet")
932 assert_equal("Piet", piet.name)
933 assert_equal(42, piet.age)
934 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000935
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200936 var chris = Person.new("Chris", 4, "none")
937 assert_equal("Chris", chris.name)
938 assert_equal(4, chris.age)
939 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000940 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200941 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000942
943 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200944 vim9script
945 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100946 var name: string
947 var age: number = 42
948 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +0000949
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200950 def new(this.name, this.age = v:none, this.education = v:none)
951 enddef
952 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000953
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200954 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000955 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200956 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200957
958 # Using a specific value to initialize an instance variable in the new()
959 # method.
960 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200961 vim9script
962 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100963 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200964 def new(this.val = 'a')
965 enddef
966 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200967 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200968 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000969enddef
970
h-east2261c892023-08-16 21:49:54 +0900971def Test_class_new_with_object_member()
972 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200973 vim9script
h-east2261c892023-08-16 21:49:54 +0900974
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200975 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +0100976 var str: string
977 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200978 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +0900979 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200980 def newVals(this.str, this.num)
981 enddef
982 endclass
h-east2261c892023-08-16 21:49:54 +0900983
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200984 def Check()
985 try
986 var c = C.new('cats', 2)
987 assert_equal('cats', c.str)
988 assert_equal(2, c.num)
989
990 c = C.newVals('dogs', 4)
991 assert_equal('dogs', c.str)
992 assert_equal(4, c.num)
993 catch
994 assert_report($'Unexpected exception was caught: {v:exception}')
995 endtry
996 enddef
997
998 Check()
h-east2261c892023-08-16 21:49:54 +0900999 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001000 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001001
1002 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001003 vim9script
1004
1005 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001006 var str: string
1007 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001008 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001009 enddef
1010 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001011
1012 def Check()
1013 try
1014 var c = C.new(1, 2)
1015 catch
1016 assert_report($'Unexpected exception was caught: {v:exception}')
1017 endtry
1018 enddef
1019
1020 Check()
h-eastdb385522023-09-28 22:18:19 +02001021 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001022 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001023
1024 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001025 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001026
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001027 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001028 var str: string
1029 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001030 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001031 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001032 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001033
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001034 def Check()
1035 try
1036 var c = C.newVals('dogs', 'apes')
1037 catch
1038 assert_report($'Unexpected exception was caught: {v:exception}')
1039 endtry
1040 enddef
1041
1042 Check()
1043 END
1044 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1045
1046 lines =<< trim END
1047 vim9script
1048
1049 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001050 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001051 def new(str: any)
1052 enddef
1053 endclass
1054
1055 def Check()
1056 try
1057 var c = C.new(1)
1058 catch
1059 assert_report($'Unexpected exception was caught: {v:exception}')
1060 endtry
1061 enddef
1062
1063 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001064 END
1065 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001066
1067 # Try using "this." argument in a class method
1068 lines =<< trim END
1069 vim9script
1070 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001071 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001072 static def Foo(this.val: number)
1073 enddef
1074 endclass
1075 END
1076 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1077
1078 # Try using "this." argument in an object method
1079 lines =<< trim END
1080 vim9script
1081 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001082 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001083 def Foo(this.val: number)
1084 enddef
1085 endclass
1086 END
1087 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001088enddef
1089
Bram Moolenaar74e12742022-12-13 21:14:28 +00001090def Test_class_object_member_inits()
1091 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001092 vim9script
1093 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001094 var lnum: number
1095 var col = 1
1096 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001097 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001098
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001099 var pos = TextPosition.new()
1100 assert_equal(0, pos.lnum)
1101 assert_equal(1, pos.col)
1102 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001103 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001104 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001105
1106 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001107 vim9script
1108 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001109 var lnum
1110 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001111 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001112 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001113 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001114
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001115 # If the type is not specified for a member, then it should be set during
1116 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001117 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001118 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001119
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001120 var init_count = 0
1121 def Init(): string
1122 init_count += 1
1123 return 'foo'
1124 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001125
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001126 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001127 var str1 = Init()
1128 var str2: string = Init()
1129 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001130 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001131
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001132 assert_equal(init_count, 0)
1133 var a = A.new()
1134 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001135 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001136 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001137
1138 # Test for initializing an object member with an unknown variable/type
1139 lines =<< trim END
1140 vim9script
1141 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001142 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001143 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001144 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001145 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001146 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001147
1148 # Test for initializing an object member with an special type
1149 lines =<< trim END
1150 vim9script
1151 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001152 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001153 endclass
1154 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001155 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001156enddef
1157
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001158" Test for instance variable access
1159def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001160 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001161 vim9script
1162 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001163 var _one = 1
1164 var two = 2
1165 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001166
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001167 def GetOne(): number
1168 return this._one
1169 enddef
1170 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001171
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001172 var trip = Triple.new()
1173 assert_equal(1, trip.GetOne())
1174 assert_equal(2, trip.two)
1175 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001176 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001177
Ernie Rael03042a22023-11-11 08:53:32 +01001178 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001179 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1180 trip.three = 33
1181 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001182
Ernie Raeld4802ec2023-10-20 11:59:00 +02001183 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001184 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001185 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001186
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001187 # Test for a public member variable name beginning with an underscore
1188 lines =<< trim END
1189 vim9script
1190 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001191 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001192 endclass
1193 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001194 v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001195
Bram Moolenaar590162c2022-12-24 21:24:06 +00001196 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001197 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001198
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001199 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001200 var make: string
1201 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001203 def new(make_arg: string)
1204 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001205 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001206
1207 def GetMake(): string
1208 return $"make = {this.make}"
1209 enddef
1210 def GetAge(): number
1211 return this.age
1212 enddef
1213 endclass
1214
1215 var c = MyCar.new("abc")
1216 assert_equal('make = abc', c.GetMake())
1217
1218 c = MyCar.new("def")
1219 assert_equal('make = def', c.GetMake())
1220
1221 var c2 = MyCar.new("123")
1222 assert_equal('make = 123', c2.GetMake())
1223
1224 def CheckCar()
1225 assert_equal("make = def", c.GetMake())
1226 assert_equal(5, c.GetAge())
1227 enddef
1228 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001229 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001230 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001231
1232 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001233 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001234
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001235 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001236 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001237
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001238 def new(make_arg: string)
1239 this.make = make_arg
1240 enddef
1241 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001242
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001243 var c = MyCar.new("abc")
1244 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001245 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001246 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001247
1248 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001249 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001250
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001251 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001252 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001253
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001254 def Add(n: number): any
1255 this.x->add(n)
1256 return this
1257 enddef
1258 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001259
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001260 echo Foo.new().Add(1).Add(2).x
1261 echo Foo.new().Add(1).Add(2)
1262 .x
1263 echo Foo.new().Add(1)
1264 .Add(2).x
1265 echo Foo.new()
1266 .Add(1).Add(2).x
1267 echo Foo.new()
1268 .Add(1)
1269 .Add(2)
1270 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001271 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001272 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001273
1274 # Test for "public" cannot be abbreviated
1275 lines =<< trim END
1276 vim9script
1277 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001278 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001279 endclass
1280 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001281 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001282
Doug Kearns74da0ee2023-12-14 20:26:26 +01001283 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001284 lines =<< trim END
1285 vim9script
1286 class Something
1287 public val = 1
1288 endclass
1289 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001290 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001291
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001292 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001293 lines =<< trim END
1294 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001295 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001296 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001297 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001298 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001299 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001300 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001301
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001302 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001303 lines =<< trim END
1304 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001305 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001306 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001307 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001308 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001309 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001310 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001311
1312 # Modify a instance variable using the class name in a def function
1313 lines =<< trim END
1314 vim9script
1315 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001316 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001317 endclass
1318 def T()
1319 A.val = 1
1320 enddef
1321 T()
1322 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001323 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001324
1325 # Read a instance variable using the class name in a def function
1326 lines =<< trim END
1327 vim9script
1328 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001329 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001330 endclass
1331 def T()
1332 var i = A.val
1333 enddef
1334 T()
1335 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001336 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001337
1338 # Access from child class extending a class:
1339 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001340 vim9script
1341 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001342 var ro_obj_var = 10
1343 public var rw_obj_var = 20
1344 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001345 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001346
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001347 class B extends A
1348 def Foo()
1349 var x: number
1350 x = this.ro_obj_var
1351 this.ro_obj_var = 0
1352 x = this.rw_obj_var
1353 this.rw_obj_var = 0
1354 x = this._priv_obj_var
1355 this._priv_obj_var = 0
1356 enddef
1357 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001359 var b = B.new()
1360 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001361 END
1362 v9.CheckSourceSuccess(lines)
1363enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001364
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001365" Test for class variable access
1366def Test_class_variable_access()
1367 # Test for "static" cannot be abbreviated
1368 var lines =<< trim END
1369 vim9script
1370 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001371 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001372 endclass
1373 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001374 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001375
1376 # Test for "static" cannot be followed by "public".
1377 lines =<< trim END
1378 vim9script
1379 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001380 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001381 endclass
1382 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001383 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001384
1385 # A readonly class variable cannot be modified from a child class
1386 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001387 vim9script
1388 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001389 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001390 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001391
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001392 class B extends A
1393 def Foo()
1394 A.ro_class_var = 50
1395 enddef
1396 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001397
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001398 var b = B.new()
1399 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001400 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001401 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001402
Ernie Rael03042a22023-11-11 08:53:32 +01001403 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001404 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001405 vim9script
1406 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001407 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001408 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001409
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001410 class B extends A
1411 def Foo()
1412 var i = A._priv_class_var
1413 enddef
1414 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001415
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001416 var b = B.new()
1417 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001418 END
Ernie Rael03042a22023-11-11 08:53:32 +01001419 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001420
Ernie Rael03042a22023-11-11 08:53:32 +01001421 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001422 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001423 vim9script
1424 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001425 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001426 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001427
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001428 class B extends A
1429 def Foo()
1430 A._priv_class_var = 0
1431 enddef
1432 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001433
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001434 var b = B.new()
1435 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001436 END
Ernie Rael03042a22023-11-11 08:53:32 +01001437 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001438
1439 # Access from child class extending a class and from script context
1440 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001441 vim9script
1442 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001443 static var ro_class_var = 10
1444 public static var rw_class_var = 20
1445 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001446 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001447
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001448 class B extends A
1449 def Foo()
1450 var x: number
1451 x = A.ro_class_var
1452 assert_equal(10, x)
1453 x = A.rw_class_var
1454 assert_equal(25, x)
1455 A.rw_class_var = 20
1456 assert_equal(20, A.rw_class_var)
1457 enddef
1458 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001459
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001460 assert_equal(10, A.ro_class_var)
1461 assert_equal(20, A.rw_class_var)
1462 A.rw_class_var = 25
1463 assert_equal(25, A.rw_class_var)
1464 var b = B.new()
1465 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001466 END
1467 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001468enddef
1469
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001470def Test_class_object_compare()
1471 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001472 vim9script
1473 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001474 var nr = 0
1475 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001476 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001477 END
1478
1479 # used at the script level and in a compiled function
1480 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001481 var i1 = Item.new()
1482 assert_equal(i1, i1)
1483 assert_true(i1 is i1)
1484 var i2 = Item.new()
1485 assert_equal(i1, i2)
1486 assert_false(i1 is i2)
1487 var i3 = Item.new(0, 'xx')
1488 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001489
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001490 var io1 = Item.new(1, 'xx')
1491 assert_notequal(i1, io1)
1492 var io2 = Item.new(0, 'yy')
1493 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001494 END
1495
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001496 v9.CheckSourceSuccess(class_lines + test_lines)
1497 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001499
1500 for op in ['>', '>=', '<', '<=', '=~', '!~']
1501 var op_lines = [
1502 'var i1 = Item.new()',
1503 'var i2 = Item.new()',
1504 'echo i1 ' .. op .. ' i2',
1505 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001506 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001507 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001508 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001509 endfor
1510enddef
1511
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001512def Test_object_type()
1513 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001514 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001515
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001516 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001517 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001518 endclass
1519 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001520 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001521 endclass
1522 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001523 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001524 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001525
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001526 var o: One = One.new()
1527 var t: Two = Two.new()
1528 var m: TwoMore = TwoMore.new()
1529 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001530
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001531 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001532 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001533 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001534
1535 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001536 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001537
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001538 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001539 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001540 endclass
1541 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001542 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001543 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001544
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001545 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001547 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001548
1549 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001550 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001551
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001552 interface One
1553 def GetMember(): number
1554 endinterface
1555 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001556 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001557 def GetMember(): number
1558 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001559 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001560 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001561
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001562 var o: One = Two.new(5)
1563 assert_equal(5, o.GetMember())
1564 END
1565 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001566
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001567 lines =<< trim END
1568 vim9script
1569
1570 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001571 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001572 endclass
1573
1574 def Ref(name: string): func(Num): Num
1575 return (arg: Num): Num => {
1576 return eval(name)(arg)
1577 }
1578 enddef
1579
1580 const Fn = Ref('Double')
1581 var Double = (m: Num): Num => Num.new(m.n * 2)
1582
1583 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001584 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001585 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001586enddef
1587
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001588def Test_class_member()
1589 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001590 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001591 vim9script
1592 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001593 var lnum = 1
1594 var col = 1
1595 static var counter = 0
1596 static var _secret = 7
1597 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001599 static def AddToCounter(nr: number)
1600 counter += nr
1601 enddef
1602 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001603
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001604 assert_equal(0, TextPos.counter)
1605 TextPos.AddToCounter(3)
1606 assert_equal(3, TextPos.counter)
1607 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001608
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001609 def GetCounter(): number
1610 return TextPos.counter
1611 enddef
1612 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001613
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001614 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1615 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1616 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001617
Ernie Rael03042a22023-11-11 08:53:32 +01001618 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1619 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001620
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001621 assert_equal(42, TextPos.anybody)
1622 TextPos.anybody = 12
1623 assert_equal(12, TextPos.anybody)
1624 TextPos.anybody += 5
1625 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001626 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001627 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001628
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001629 # example in the help
1630 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001631 vim9script
1632 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001633 var size: number
1634 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001636 def new(this.size)
1637 totalSize += this.size
1638 enddef
1639 endclass
1640 assert_equal(0, OtherThing.totalSize)
1641 var to3 = OtherThing.new(3)
1642 assert_equal(3, OtherThing.totalSize)
1643 var to7 = OtherThing.new(7)
1644 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001645 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001646 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001647
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001648 # using static class member twice
1649 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001650 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001651
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001652 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001653 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001654
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001655 static def MacroSubstitute(s: string): string
1656 return substitute(s, '{{author}}', author, 'gi')
1657 enddef
1658 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001659
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001660 assert_equal('some text', HTML.MacroSubstitute('some text'))
1661 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001662 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001663 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001664
Ernie Rael03042a22023-11-11 08:53:32 +01001665 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001666 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001667 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001668
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001669 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001670 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001671
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001672 def Add(n: number): number
1673 const F = (): number => this._x + n
1674 return F()
1675 enddef
1676 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001677
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001678 var foo = Foo.new()
1679 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001680 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001681 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001682
Ernie Rael03042a22023-11-11 08:53:32 +01001683 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001684 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001685 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001686
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001687 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001688 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001689
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001690 def Add(n: number): number
1691 var Lam = () => {
1692 this._x = this._x + n
1693 }
1694 Lam()
1695 return this._x
1696 enddef
1697 endclass
h-east2bd6a092023-05-19 19:01:17 +01001698
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001699 var foo = Foo.new()
1700 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001701 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001702 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001703
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001704 # check shadowing
1705 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001706 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001707
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001708 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001709 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001710 def Method(count: number)
1711 echo count
1712 enddef
1713 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001714
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001715 var s = Some.new()
1716 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001717 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001718 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001719
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001720 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001721 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001722 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001723
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001724 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001725 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001726 def Method(arg: number)
1727 var count = 3
1728 echo arg count
1729 enddef
1730 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001731
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001732 var s = Some.new()
1733 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001734 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001735 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001736
1737 # Test for using an invalid type for a member variable
1738 lines =<< trim END
1739 vim9script
1740 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001741 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001742 endclass
1743 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001744 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001745
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001746 # Test for setting a member on a null object
1747 lines =<< trim END
1748 vim9script
1749 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001750 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001751 endclass
1752
1753 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001754 var obj: A
1755 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001756 enddef
1757 F()
1758 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001759 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001760
1761 # Test for accessing a member on a null object
1762 lines =<< trim END
1763 vim9script
1764 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001765 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001766 endclass
1767
1768 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001769 var obj: A
1770 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001771 enddef
1772 F()
1773 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001774 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001775
1776 # Test for setting a member on a null object, at script level
1777 lines =<< trim END
1778 vim9script
1779 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001780 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001781 endclass
1782
1783 var obj: A
1784 obj.val = ""
1785 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001786 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001787
1788 # Test for accessing a member on a null object, at script level
1789 lines =<< trim END
1790 vim9script
1791 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001792 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001793 endclass
1794
1795 var obj: A
1796 echo obj.val
1797 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001798 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001799
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001800 # Test for no space before or after the '=' when initializing a member
1801 # variable
1802 lines =<< trim END
1803 vim9script
1804 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001805 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001806 endclass
1807 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001808 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001809 lines =<< trim END
1810 vim9script
1811 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001812 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001813 endclass
1814 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001815 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001816
1817 # Access a non-existing member
1818 lines =<< trim END
1819 vim9script
1820 class A
1821 endclass
1822 var a = A.new()
1823 var v = a.bar
1824 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001825 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001826enddef
1827
Ernie Raele6c9aa52023-10-06 19:55:52 +02001828" These messages should show the defining class of the variable (base class),
1829" not the class that did the reference (super class)
1830def Test_defining_class_message()
1831 var lines =<< trim END
1832 vim9script
1833
1834 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001835 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001836 endclass
1837
1838 class Child extends Base
1839 endclass
1840
1841 var o = Child.new()
1842 var x = o._v1
1843 END
Ernie Rael03042a22023-11-11 08:53:32 +01001844 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001845 lines =<< trim END
1846 vim9script
1847
1848 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001849 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001850 endclass
1851
1852 class Child extends Base
1853 endclass
1854
1855 def F()
1856 var o = Child.new()
1857 var x = o._v1
1858 enddef
1859 F()
1860 END
Ernie Rael03042a22023-11-11 08:53:32 +01001861 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001862 lines =<< trim END
1863 vim9script
1864
1865 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001866 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001867 endclass
1868
1869 class Child extends Base
1870 endclass
1871
1872 var o = Child.new()
1873 o.v1 = []
1874 END
1875 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1876 lines =<< trim END
1877 vim9script
1878
1879 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001880 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001881 endclass
1882
1883 class Child extends Base
1884 endclass
1885
1886 def F()
1887 var o = Child.new()
1888 o.v1 = []
1889 enddef
1890 F()
1891 END
1892
Ernie Rael03042a22023-11-11 08:53:32 +01001893 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001894 # of the class hierarchy.
1895 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1896 lines =<< trim END
1897 vim9script
1898
1899 class Base0
1900 endclass
1901
1902 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01001903 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001904 endclass
1905
1906 class Child extends Base
1907 endclass
1908
1909 def F()
1910 var o = Child.new()
1911 var x = o._v1
1912 enddef
1913 F()
1914 END
Ernie Rael03042a22023-11-11 08:53:32 +01001915 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001916
Ernie Rael03042a22023-11-11 08:53:32 +01001917 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02001918 # of the class hierarchy.
1919 lines =<< trim END
1920 vim9script
1921
1922 class Base0
1923 endclass
1924
1925 class Base extends Base0
1926 endclass
1927
1928 class Child extends 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 def F()
1933 var o = Child.new()
1934 var x = o._v1
1935 enddef
1936 F()
1937 END
Ernie Rael03042a22023-11-11 08:53:32 +01001938 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001939enddef
1940
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001941func Test_class_garbagecollect()
1942 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001943 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001944
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001945 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01001946 var p = [2, 3]
1947 static var pl = ['a', 'b']
1948 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001949 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001950
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001951 echo Point.pl Point.pd
1952 call test_garbagecollect_now()
1953 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001954 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001955 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001956
1957 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001958 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001959
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001960 interface View
1961 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001962
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001963 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01001964 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001965 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001966
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001967 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01001968 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001969
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001970 def new()
1971 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01001972 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001973 enddef
1974 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001975
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001976 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001977
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001978 # overwrite "view", will be garbage-collected next
1979 view = MyView.new()
1980 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001981 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001982 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001983endfunc
1984
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001985" Test interface garbage collection
1986func Test_interface_garbagecollect()
1987 let lines =<< trim END
1988 vim9script
1989
1990 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01001991 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001992
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001993 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001994 endinterface
1995
1996 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01001997 static var ro_class_var: number = 10
1998 public static var rw_class_var: number = 20
1999 static var _priv_class_var: number = 30
2000 var ro_obj_var: number = 40
2001 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002002
2003 static def _ClassBar(): number
2004 return _priv_class_var
2005 enddef
2006
2007 static def ClassFoo(): number
2008 return ro_class_var + rw_class_var + A._ClassBar()
2009 enddef
2010
2011 def _ObjBar(): number
2012 return this._priv_obj_var
2013 enddef
2014
2015 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002016 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002017 enddef
2018 endclass
2019
2020 assert_equal(60, A.ClassFoo())
2021 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002022 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002023 test_garbagecollect_now()
2024 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002025 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002026 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002027 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002028endfunc
2029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002030def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002031 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002032 vim9script
2033 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002034 var value = 0
2035 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002036
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002037 def new(v: number)
2038 this.value = v
2039 ++objects
2040 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002041
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002042 static def GetCount(): number
2043 return objects
2044 enddef
2045 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002046
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002047 assert_equal(0, Value.GetCount())
2048 var v1 = Value.new(2)
2049 assert_equal(1, Value.GetCount())
2050 var v2 = Value.new(7)
2051 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002052 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002053 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002054
2055 # Test for cleaning up after a class definition failure when using class
2056 # functions.
2057 lines =<< trim END
2058 vim9script
2059 class A
2060 static def Foo()
2061 enddef
2062 aaa
2063 endclass
2064 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002065 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002066
2067 # Test for calling a class method from another class method without the class
2068 # name prefix.
2069 lines =<< trim END
2070 vim9script
2071 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002072 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002073 static def Foo(n: number)
2074 myList->add(n)
2075 enddef
2076 static def Bar()
2077 Foo(2)
2078 enddef
2079 def Baz()
2080 Foo(3)
2081 enddef
2082 endclass
2083 A.Bar()
2084 var a = A.new()
2085 a.Baz()
2086 assert_equal([1, 2, 3], A.myList)
2087 END
2088 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002089enddef
2090
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002091def Test_class_defcompile()
2092 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002093 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002094
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002095 class C
2096 def Fo(i: number): string
2097 return i
2098 enddef
2099 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002100
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002101 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002102 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002103 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002104
2105 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002106 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002107
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002108 class C
2109 static def Fc(): number
2110 return 'x'
2111 enddef
2112 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002113
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002114 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002115 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002116 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002117
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002118 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002119 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002120
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002121 class C
2122 static def new()
2123 enddef
2124 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002125
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002126 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002127 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002128 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002129
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002130 # Trying to compile a function using a non-existing class variable
2131 lines =<< trim END
2132 vim9script
2133 defcompile x.Foo()
2134 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002135 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002136
2137 # Trying to compile a function using a variable which is not a class
2138 lines =<< trim END
2139 vim9script
2140 var x: number
2141 defcompile x.Foo()
2142 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002143 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002144
2145 # Trying to compile a function without specifying the name
2146 lines =<< trim END
2147 vim9script
2148 class A
2149 endclass
2150 defcompile A.
2151 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002152 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002153
2154 # Trying to compile a non-existing class object member function
2155 lines =<< trim END
2156 vim9script
2157 class A
2158 endclass
2159 var a = A.new()
2160 defcompile a.Foo()
2161 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002162 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002163enddef
2164
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002165def Test_class_object_to_string()
2166 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002167 vim9script
2168 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002169 var lnum = 1
2170 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002171 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002172
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002173 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002174
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002175 var pos = TextPosition.new()
2176 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002177 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002178 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002179enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002180
Bram Moolenaar554d0312023-01-05 19:59:18 +00002181def Test_interface_basics()
2182 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002183 vim9script
2184 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002185 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002186 def GetCount(): number
2187 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002188 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002189 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002190
2191 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002192 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002193 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002194 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002195 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002196 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002197
2198 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002199 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002200
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002201 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002202 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 def Method(value: number)
2204 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002205 END
h-east61378a12023-04-18 19:07:29 +01002206 # The argument name and the object member name are the same, but this is not a
2207 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002208 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002209
2210 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002211 vim9script
2212 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002213 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002214 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002215 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002216 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002217
2218 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002219 vim9script
2220 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002221 var value: string
2222 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002223 def GetCount(): number
2224 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002225 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002226 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002227
2228 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002229 vim9script
2230 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002231 var value: string
2232 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002233 def GetCount(): number
2234 return 5
2235 enddef
2236 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002237 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002238 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002239
2240 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002241 vim9script
2242 export interface EnterExit
2243 def Enter(): void
2244 def Exit(): void
2245 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002246 END
2247 writefile(lines, 'XdefIntf.vim', 'D')
2248
2249 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002250 vim9script
2251 import './XdefIntf.vim' as defIntf
2252 export def With(ee: defIntf.EnterExit, F: func)
2253 ee.Enter()
2254 try
2255 F()
2256 finally
2257 ee.Exit()
2258 endtry
2259 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002260 END
2261 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002262
2263 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002264 vim9script
2265 export abstract class EnterExit
2266 def Enter(): void
2267 enddef
2268 def Exit(): void
2269 enddef
2270 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002271 END
2272 writefile(imported, 'XdefIntf2.vim', 'D')
2273
2274 lines[1] = " import './XdefIntf2.vim' as defIntf"
2275 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002276enddef
2277
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002278" Test for using string() with an interface
2279def Test_interface_to_string()
2280 var lines =<< trim END
2281 vim9script
2282 interface Intf
2283 def Method(nr: number)
2284 endinterface
2285 assert_equal("interface Intf", string(Intf))
2286 END
2287 v9.CheckSourceSuccess(lines)
2288enddef
2289
Bram Moolenaar94674f22023-01-06 18:42:20 +00002290def Test_class_implements_interface()
2291 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002292 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002293
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002294 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002295 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002296 def Method(nr: number)
2297 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002298
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002299 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002300 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002301 def Method(nr: number)
2302 echo nr
2303 enddef
2304 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002305
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002306 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002307 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002308 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002309
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002310 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002311 var member = 'abc'
2312 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002313 def Method(nr: number)
2314 echo nr
2315 enddef
2316 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002317 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002318 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002319
2320 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002321 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002322
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002323 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002324 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002325 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002326
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002327 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002328 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002329 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002330 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002331 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002332
2333 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002334 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002335
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002336 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002337 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002338 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002339
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002340 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002341 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002342 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002343 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002344 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002345
2346 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002347 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002348
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002349 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002350 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002351 def Method(nr: number)
2352 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002353
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002354 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002355 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002356 def Method(nr: number)
2357 echo nr
2358 enddef
2359 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002360 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002361 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002362
2363 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002364 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002365
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002366 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002367 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002368 def Methods(nr: number)
2369 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002370
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002371 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002372 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002373 def Method(nr: number)
2374 echo nr
2375 enddef
2376 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002377 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002378 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002379
2380 # Check different order of members in class and interface works.
2381 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002383
2384 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002385 var label: string
2386 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002387 endinterface
2388
2389 # order of members is opposite of interface
2390 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002391 public var lnum: number = 5
2392 var errpos: number = 42
2393 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002394 endclass
2395
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002396 def Test()
2397 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002398
2399 assert_equal('label', result.label)
2400 assert_equal(42, result.errpos)
2401 enddef
2402
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002403 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002404 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002405 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002406
2407 # Interface name after "extends" doesn't end in a space or NUL character
2408 lines =<< trim END
2409 vim9script
2410 interface A
2411 endinterface
2412 class B extends A"
2413 endclass
2414 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002415 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002416
2417 # Trailing characters after a class name
2418 lines =<< trim END
2419 vim9script
2420 class A bbb
2421 endclass
2422 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002423 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002424
2425 # using "implements" with a non-existing class
2426 lines =<< trim END
2427 vim9script
2428 class A implements B
2429 endclass
2430 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002431 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002432
2433 # using "implements" with a regular class
2434 lines =<< trim END
2435 vim9script
2436 class A
2437 endclass
2438 class B implements A
2439 endclass
2440 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002441 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002442
2443 # using "implements" with a variable
2444 lines =<< trim END
2445 vim9script
2446 var T: number = 10
2447 class A implements T
2448 endclass
2449 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002450 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002451
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002452 # implements should be followed by a white space
2453 lines =<< trim END
2454 vim9script
2455 interface A
2456 endinterface
2457 class B implements A;
2458 endclass
2459 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002460 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002461
LemonBoyc5d27442023-08-19 13:02:35 +02002462 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002463 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002464
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002465 interface One
2466 def IsEven(nr: number): bool
2467 endinterface
2468 class Two implements One
2469 def IsEven(nr: number): string
2470 enddef
2471 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002472 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002473 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002474
2475 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002476 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002477
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002478 interface One
2479 def IsEven(nr: number): bool
2480 endinterface
2481 class Two implements One
2482 def IsEven(nr: bool): bool
2483 enddef
2484 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002485 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002486 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002487
2488 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002489 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002490
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002491 interface One
2492 def IsEven(nr: number): bool
2493 endinterface
2494 class Two implements One
2495 def IsEven(nr: number, ...extra: list<number>): bool
2496 enddef
2497 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002498 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002499 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 +02002500
2501 # access superclass interface members from subclass, mix variable order
2502 lines =<< trim END
2503 vim9script
2504
2505 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002506 var mvar1: number
2507 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002508 endinterface
2509
2510 # NOTE: the order is swapped
2511 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002512 var mvar2: number
2513 var mvar1: number
2514 public static var svar2: number
2515 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002516 def new()
2517 svar1 = 11
2518 svar2 = 12
2519 this.mvar1 = 111
2520 this.mvar2 = 112
2521 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002522 endclass
2523
2524 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002525 def new()
2526 this.mvar1 = 121
2527 this.mvar2 = 122
2528 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002529 endclass
2530
2531 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002532 def new()
2533 this.mvar1 = 131
2534 this.mvar2 = 132
2535 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002536 endclass
2537
Ernie Raelcf138d42023-09-06 20:45:03 +02002538 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002539 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002540 enddef
2541
2542 var oa = A.new()
2543 var ob = B.new()
2544 var oc = C.new()
2545
Ernie Raelcf138d42023-09-06 20:45:03 +02002546 assert_equal([111, 112], F2(oa))
2547 assert_equal([121, 122], F2(ob))
2548 assert_equal([131, 132], F2(oc))
2549 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002550 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002551
2552 # Access superclass interface members from subclass, mix variable order.
2553 # Two interfaces, one on A, one on B; each has both kinds of variables
2554 lines =<< trim END
2555 vim9script
2556
2557 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002558 var mvar1: number
2559 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002560 endinterface
2561
2562 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002563 var mvar3: number
2564 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002565 endinterface
2566
2567 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002568 public static var svar1: number
2569 public static var svar2: number
2570 var mvar1: number
2571 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002572 def new()
2573 svar1 = 11
2574 svar2 = 12
2575 this.mvar1 = 111
2576 this.mvar2 = 112
2577 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002578 endclass
2579
2580 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002581 static var svar3: number
2582 static var svar4: number
2583 var mvar3: number
2584 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002585 def new()
2586 svar3 = 23
2587 svar4 = 24
2588 this.mvar1 = 121
2589 this.mvar2 = 122
2590 this.mvar3 = 123
2591 this.mvar4 = 124
2592 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002593 endclass
2594
2595 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002596 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002597 def new()
2598 svar5 = 1001
2599 this.mvar1 = 131
2600 this.mvar2 = 132
2601 this.mvar3 = 133
2602 this.mvar4 = 134
2603 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002604 endclass
2605
Ernie Raelcf138d42023-09-06 20:45:03 +02002606 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002607 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002608 enddef
2609
Ernie Raelcf138d42023-09-06 20:45:03 +02002610 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002611 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002612 enddef
2613
Ernie Raelcf138d42023-09-06 20:45:03 +02002614 var oa = A.new()
2615 var ob = B.new()
2616 var oc = C.new()
2617
Ernie Raelcf138d42023-09-06 20:45:03 +02002618 assert_equal([[111, 112]], [F2(oa)])
2619 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2620 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002621 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002622 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002623
2624 # Using two interface names without a space after the ","
2625 lines =<< trim END
2626 vim9script
2627 interface A
2628 endinterface
2629 interface B
2630 endinterface
2631 class C implements A,B
2632 endclass
2633 END
2634 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2635
2636 # No interface name after a comma
2637 lines =<< trim END
2638 vim9script
2639 interface A
2640 endinterface
2641 class B implements A,
2642 endclass
2643 END
2644 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2645
2646 # No interface name after implements
2647 lines =<< trim END
2648 vim9script
2649 class A implements
2650 endclass
2651 END
2652 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002653enddef
2654
Bram Moolenaard0200c82023-01-28 15:19:40 +00002655def Test_call_interface_method()
2656 var lines =<< trim END
2657 vim9script
2658 interface Base
2659 def Enter(): void
2660 endinterface
2661
2662 class Child implements Base
2663 def Enter(): void
2664 g:result ..= 'child'
2665 enddef
2666 endclass
2667
2668 def F(obj: Base)
2669 obj.Enter()
2670 enddef
2671
2672 g:result = ''
2673 F(Child.new())
2674 assert_equal('child', g:result)
2675 unlet g:result
2676 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002677 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002678
2679 lines =<< trim END
2680 vim9script
2681 class Base
2682 def Enter(): void
2683 g:result ..= 'base'
2684 enddef
2685 endclass
2686
2687 class Child extends Base
2688 def Enter(): void
2689 g:result ..= 'child'
2690 enddef
2691 endclass
2692
2693 def F(obj: Base)
2694 obj.Enter()
2695 enddef
2696
2697 g:result = ''
2698 F(Child.new())
2699 assert_equal('child', g:result)
2700 unlet g:result
2701 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002702 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002703
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002704 # method of interface returns a value
2705 lines =<< trim END
2706 vim9script
2707 interface Base
2708 def Enter(): string
2709 endinterface
2710
2711 class Child implements Base
2712 def Enter(): string
2713 g:result ..= 'child'
2714 return "/resource"
2715 enddef
2716 endclass
2717
2718 def F(obj: Base)
2719 var r = obj.Enter()
2720 g:result ..= r
2721 enddef
2722
2723 g:result = ''
2724 F(Child.new())
2725 assert_equal('child/resource', g:result)
2726 unlet g:result
2727 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002728 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002729
2730 lines =<< trim END
2731 vim9script
2732 class Base
2733 def Enter(): string
2734 return null_string
2735 enddef
2736 endclass
2737
2738 class Child extends Base
2739 def Enter(): string
2740 g:result ..= 'child'
2741 return "/resource"
2742 enddef
2743 endclass
2744
2745 def F(obj: Base)
2746 var r = obj.Enter()
2747 g:result ..= r
2748 enddef
2749
2750 g:result = ''
2751 F(Child.new())
2752 assert_equal('child/resource', g:result)
2753 unlet g:result
2754 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002755 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002756
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002757 # No class that implements the interface.
2758 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002759 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002760
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002761 interface IWithEE
2762 def Enter(): any
2763 def Exit(): void
2764 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002765
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002766 def With1(ee: IWithEE, F: func)
2767 var r = ee.Enter()
2768 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002769
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002770 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002771 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002772 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002773enddef
2774
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002775def Test_class_used_as_type()
2776 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002777 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002778
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002779 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002780 var x = 0
2781 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002782 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002783
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002784 var p: Point
2785 p = Point.new(2, 33)
2786 assert_equal(2, p.x)
2787 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002789 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002790
2791 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002792 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002794 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002795 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002796 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002797
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002798 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002799 var x = 0
2800 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002801 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002802
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002803 var p: Point
2804 p = Point.new(2, 33)
2805 var hx = p
2806 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002807 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002808 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002809
2810 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002811 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002812
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002813 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002814 var x = 0
2815 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002816 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002817
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002818 var p: Point
2819 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002820 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002821 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002822enddef
2823
Bram Moolenaar83677162023-01-08 19:54:10 +00002824def Test_class_extends()
2825 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002826 vim9script
2827 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002828 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002829 def GetOne(): number
2830 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002831 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002832 endclass
2833 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002834 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002835 def GetTotal(): number
2836 return this.one + this.two
2837 enddef
2838 endclass
2839 var o = Child.new()
2840 assert_equal(1, o.one)
2841 assert_equal(2, o.two)
2842 assert_equal(1, o.GetOne())
2843 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002844 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002845 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002846
2847 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002848 vim9script
2849 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002850 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002851 endclass
2852 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002853 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002854 endclass
2855 var o = Child.new(3, 44)
2856 assert_equal(3, o.one)
2857 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002858 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002859 v9.CheckSourceSuccess(lines)
2860
2861 lines =<< trim END
2862 vim9script
2863 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002864 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002865 endclass
2866 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002867 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002868 endclass
2869 END
2870 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2871
2872 lines =<< trim END
2873 vim9script
2874 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01002875 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002876 endclass
2877 END
2878 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2879
2880 lines =<< trim END
2881 vim9script
2882 var SomeVar = 99
2883 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01002884 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002885 endclass
2886 END
2887 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2888
2889 lines =<< trim END
2890 vim9script
2891 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002892 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002893 def ToString(): string
2894 return this.name
2895 enddef
2896 endclass
2897
2898 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002899 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002900 def ToString(): string
2901 return super.ToString() .. ': ' .. this.age
2902 enddef
2903 endclass
2904
2905 var o = Child.new('John', 42)
2906 assert_equal('John: 42', o.ToString())
2907 END
2908 v9.CheckSourceSuccess(lines)
2909
2910 lines =<< trim END
2911 vim9script
2912 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002913 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002914 def ToString(): number
2915 return this.age
2916 enddef
2917 def ToString(): string
2918 return this.age
2919 enddef
2920 endclass
2921 END
2922 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2923
2924 lines =<< trim END
2925 vim9script
2926 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002927 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002928 def ToString(): string
2929 return super .ToString() .. ': ' .. this.age
2930 enddef
2931 endclass
2932 var o = Child.new(42)
2933 echo o.ToString()
2934 END
2935 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2936
2937 lines =<< trim END
2938 vim9script
2939 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002940 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002941 def ToString(): string
2942 return this.name
2943 enddef
2944 endclass
2945
2946 var age = 42
2947 def ToString(): string
2948 return super.ToString() .. ': ' .. age
2949 enddef
2950 echo ToString()
2951 END
2952 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2953
2954 lines =<< trim END
2955 vim9script
2956 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002957 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002958 def ToString(): string
2959 return super.ToString() .. ': ' .. this.age
2960 enddef
2961 endclass
2962 var o = Child.new(42)
2963 echo o.ToString()
2964 END
2965 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
2966
2967 lines =<< trim END
2968 vim9script
2969 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002970 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002971 static def ToString(): string
2972 return 'Base class'
2973 enddef
2974 endclass
2975
2976 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002977 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002978 def ToString(): string
2979 return Base.ToString() .. ': ' .. this.age
2980 enddef
2981 endclass
2982
2983 var o = Child.new('John', 42)
2984 assert_equal('Base class: 42', o.ToString())
2985 END
2986 v9.CheckSourceSuccess(lines)
2987
2988 lines =<< trim END
2989 vim9script
2990 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002991 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002992 def new(init: number)
2993 this.value = number + 1
2994 enddef
2995 endclass
2996 class Child extends Base
2997 def new()
2998 this.new(3)
2999 enddef
3000 endclass
3001 var c = Child.new()
3002 END
3003 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003004
3005 # base class with more than one object member
3006 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003007 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003008
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003009 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003010 var success: bool
3011 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003012 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003013
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003014 class Success extends Result
3015 def new(this.value = v:none)
3016 this.success = true
3017 enddef
3018 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003019
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003020 var v = Success.new('asdf')
3021 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003022 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003023 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003024
3025 # class name after "extends" doesn't end in a space or NUL character
3026 lines =<< trim END
3027 vim9script
3028 class A
3029 endclass
3030 class B extends A"
3031 endclass
3032 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003033 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003034enddef
3035
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003036def Test_using_base_class()
3037 var lines =<< trim END
3038 vim9script
3039
3040 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003041 def Enter(): any
3042 return null
3043 enddef
3044 def Exit(resource: any): void
3045 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003046 endclass
3047
3048 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003049 def Enter(): any
3050 return 42
3051 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003052
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003053 def Exit(resource: number): void
3054 g:result ..= '/exit'
3055 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003056 endclass
3057
3058 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003059 var r = ee.Enter()
3060 try
3061 g:result ..= r
3062 finally
3063 g:result ..= '/finally'
3064 ee.Exit(r)
3065 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003066 enddef
3067
3068 g:result = ''
3069 With(ChildEE.new())
3070 assert_equal('42/finally/exit', g:result)
3071 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003072 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003073 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003074
3075 # Using super, Child invokes Base method which has optional arg. #12471
3076 lines =<< trim END
3077 vim9script
3078
3079 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003080 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003081 def Method(arg = 0)
3082 this.success = true
3083 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003084 endclass
3085
3086 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003087 def new()
3088 super.Method()
3089 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003090 endclass
3091
3092 var obj = Child.new()
3093 assert_equal(true, obj.success)
3094 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003095 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003096enddef
3097
Bram Moolenaara86655a2023-01-12 17:06:27 +00003098def Test_class_import()
3099 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003100 vim9script
3101 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003102 var kind: string
3103 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003104 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003105 END
3106 writefile(lines, 'Xanimal.vim', 'D')
3107
3108 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003109 vim9script
3110 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003111
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003112 var a: animal.Animal
3113 a = animal.Animal.new('fish', 'Eric')
3114 assert_equal('fish', a.kind)
3115 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003116
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003117 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3118 assert_equal('cat', b.kind)
3119 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003120 END
3121 v9.CheckScriptSuccess(lines)
3122enddef
3123
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003124" Test for implementing an imported interface
3125def Test_implement_imported_interface()
3126 var lines =<< trim END
3127 vim9script
3128 export interface Imp_Intf1
3129 def Fn1(): number
3130 endinterface
3131 export interface Imp_Intf2
3132 def Fn2(): number
3133 endinterface
3134 END
3135 writefile(lines, 'Ximportinterface.vim', 'D')
3136
3137 lines =<< trim END
3138 vim9script
3139 import './Ximportinterface.vim' as Xintf
3140
3141 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3142 def Fn1(): number
3143 return 10
3144 enddef
3145 def Fn2(): number
3146 return 20
3147 enddef
3148 endclass
3149 var a = A.new()
3150 assert_equal(10, a.Fn1())
3151 assert_equal(20, a.Fn2())
3152 END
3153 v9.CheckScriptSuccess(lines)
3154enddef
3155
3156" Test for extending an imported class
3157def Test_extend_imported_class()
3158 var lines =<< trim END
3159 vim9script
3160 export class Imp_C1
3161 def Fn1(): number
3162 return 5
3163 enddef
3164 endclass
3165 END
3166 writefile(lines, 'Xextendimportclass.vim', 'D')
3167
3168 lines =<< trim END
3169 vim9script
3170 import './Xextendimportclass.vim' as XClass
3171
3172 class A extends XClass.Imp_C1
3173 endclass
3174 var a = A.new()
3175 assert_equal(5, a.Fn1())
3176 END
3177 v9.CheckScriptSuccess(lines)
3178enddef
3179
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003180def Test_abstract_class()
3181 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003182 vim9script
3183 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003184 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003185 endclass
3186 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003187 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003188 endclass
3189 var p: Base = Person.new('Peter', 42)
3190 assert_equal('Peter', p.name)
3191 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003192 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003193 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003194
3195 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003196 vim9script
3197 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003198 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003199 endclass
3200 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003201 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003202 endclass
3203 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003204 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003205 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003206
3207 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003208 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003209 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003210 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003211 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003212 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003213
3214 # Abstract class cannot have a "new" function
3215 lines =<< trim END
3216 vim9script
3217 abstract class Base
3218 def new()
3219 enddef
3220 endclass
3221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003222 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003223enddef
3224
Bram Moolenaar486fc252023-01-18 14:51:07 +00003225def Test_closure_in_class()
3226 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003227 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003228
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003229 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003230 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003231
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003232 def new()
3233 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3234 enddef
3235 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003236
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003237 Foo.new()
3238 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003239 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003240 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003241enddef
3242
Ernie Rael9ed53752023-12-11 17:40:46 +01003243def Test_construct_object_from_legacy()
3244 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003245 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003246 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003247
Ernie Rael9ed53752023-12-11 17:40:46 +01003248 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003249
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003250 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003251 def new(arg: string)
3252 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003253 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003254 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003255
Ernie Rael9ed53752023-12-11 17:40:46 +01003256 export def CreateA(...args: list<any>): A
3257 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003258 enddef
3259
Ernie Rael9ed53752023-12-11 17:40:46 +01003260 g:P = CreateA
3261 legacy call g:P('some_arg')
3262 assert_equal(true, newCalled)
3263 unlet g:P
3264 END
3265 v9.CheckSourceSuccess(lines)
3266
3267 lines =<< trim END
3268 vim9script
3269
3270 var newCalled = false
3271
3272 class A
3273 static def CreateA(options = {}): any
3274 return A.new()
3275 enddef
3276 def new()
3277 newCalled = true
3278 enddef
3279 endclass
3280
3281 g:P = A.CreateA
3282 legacy call g:P()
3283 assert_equal(true, newCalled)
3284 unlet g:P
3285 END
3286 v9.CheckSourceSuccess(lines)
3287
3288 # This also tests invoking "new()" with "call"
3289 lines =<< trim END
3290 vim9script
3291
3292 var createdObject: any
3293
3294 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003295 var val1: number
3296 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003297 static def CreateA(...args: list<any>): any
3298 createdObject = call(A.new, args)
3299 return createdObject
3300 enddef
3301 endclass
3302
3303 g:P = A.CreateA
3304 legacy call g:P(3, 5)
3305 assert_equal(3, createdObject.val1)
3306 assert_equal(5, createdObject.val2)
3307 legacy call g:P()
3308 assert_equal(0, createdObject.val1)
3309 assert_equal(0, createdObject.val2)
3310 legacy call g:P(7)
3311 assert_equal(7, createdObject.val1)
3312 assert_equal(0, createdObject.val2)
3313 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003314 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003315 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003316enddef
3317
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003318def Test_defer_with_object()
3319 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003320 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003321
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003322 class CWithEE
3323 def Enter()
3324 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003325 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003326 def Exit()
3327 g:result ..= "exited"
3328 enddef
3329 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003330
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003331 def With(ee: CWithEE, F: func)
3332 ee.Enter()
3333 defer ee.Exit()
3334 F()
3335 enddef
3336
3337 g:result = ''
3338 var obj = CWithEE.new()
3339 obj->With(() => {
3340 g:result ..= "called/"
3341 })
3342 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003343 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003344 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003345 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003346
3347 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003348 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003349
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003350 class BaseWithEE
3351 def Enter()
3352 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003353 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003354 def Exit()
3355 g:result ..= "exited-base"
3356 enddef
3357 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003359 class CWithEE extends BaseWithEE
3360 def Enter()
3361 g:result ..= "entered-child/"
3362 enddef
3363 def Exit()
3364 g:result ..= "exited-child"
3365 enddef
3366 endclass
3367
3368 def With(ee: BaseWithEE, F: func)
3369 ee.Enter()
3370 defer ee.Exit()
3371 F()
3372 enddef
3373
3374 g:result = ''
3375 var obj = CWithEE.new()
3376 obj->With(() => {
3377 g:result ..= "called/"
3378 })
3379 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003380 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003381 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003382 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003383enddef
3384
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003385" The following test used to crash Vim (Github issue #12676)
3386def Test_extends_method_crashes_vim()
3387 var lines =<< trim END
3388 vim9script
3389
3390 class Observer
3391 endclass
3392
3393 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003394 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003395
3396 def Set(v: any)
3397 if v != this.value
3398 this.value = v
3399 endif
3400 enddef
3401
3402 def Register(observer: Observer)
3403 enddef
3404 endclass
3405
3406 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003407 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003408 endclass
3409
3410 def Observe(obj: Property, who: Observer)
3411 obj.Register(who)
3412 enddef
3413
3414 var p = Bool.new(false)
3415 var myObserver = Observer.new()
3416
3417 Observe(p, myObserver)
3418
3419 p.Set(true)
3420 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003421 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003422enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003423
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003424" Test for calling a method in a class that is extended
3425def Test_call_method_in_extended_class()
3426 var lines =<< trim END
3427 vim9script
3428
3429 var prop_init_called = false
3430 var prop_register_called = false
3431
3432 class Property
3433 def Init()
3434 prop_init_called = true
3435 enddef
3436
3437 def Register()
3438 prop_register_called = true
3439 enddef
3440 endclass
3441
3442 class Bool extends Property
3443 endclass
3444
3445 def Observe(obj: Property)
3446 obj.Register()
3447 enddef
3448
3449 var p = Property.new()
3450 Observe(p)
3451
3452 p.Init()
3453 assert_true(prop_init_called)
3454 assert_true(prop_register_called)
3455 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003456 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003457enddef
3458
LemonBoyafe04662023-08-23 21:08:11 +02003459def Test_instanceof()
3460 var lines =<< trim END
3461 vim9script
3462
3463 class Base1
3464 endclass
3465
3466 class Base2 extends Base1
3467 endclass
3468
3469 interface Intf1
3470 endinterface
3471
3472 class Mix1 implements Intf1
3473 endclass
3474
3475 class Base3 extends Mix1
3476 endclass
3477
Ernie Rael2025af12023-12-12 16:58:00 +01003478 type AliasBase1 = Base1
3479 type AliasBase2 = Base2
3480 type AliasIntf1 = Intf1
3481 type AliasMix1 = Mix1
3482
LemonBoyafe04662023-08-23 21:08:11 +02003483 var b1 = Base1.new()
3484 var b2 = Base2.new()
3485 var b3 = Base3.new()
3486
3487 assert_true(instanceof(b1, Base1))
3488 assert_true(instanceof(b2, Base1))
3489 assert_false(instanceof(b1, Base2))
3490 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003491 assert_true(instanceof(b3, Base1, Base2, Intf1))
3492
3493 assert_true(instanceof(b1, AliasBase1))
3494 assert_true(instanceof(b2, AliasBase1))
3495 assert_false(instanceof(b1, AliasBase2))
3496 assert_true(instanceof(b3, AliasMix1))
3497 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003498
3499 def Foo()
3500 var a1 = Base1.new()
3501 var a2 = Base2.new()
3502 var a3 = Base3.new()
3503
3504 assert_true(instanceof(a1, Base1))
3505 assert_true(instanceof(a2, Base1))
3506 assert_false(instanceof(a1, Base2))
3507 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003508 assert_true(instanceof(a3, Base1, Base2, Intf1))
3509
3510 assert_true(instanceof(a1, AliasBase1))
3511 assert_true(instanceof(a2, AliasBase1))
3512 assert_false(instanceof(a1, AliasBase2))
3513 assert_true(instanceof(a3, AliasMix1))
3514 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003515 enddef
3516 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003517
3518 var o_null: Base1
3519 assert_false(instanceof(o_null, Base1))
3520
LemonBoyafe04662023-08-23 21:08:11 +02003521 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003522 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003523
3524 lines =<< trim END
3525 vim9script
3526
3527 class Base1
3528 endclass
3529 instanceof(Base1.new())
3530 END
3531 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3532
3533 lines =<< trim END
3534 vim9script
3535
3536 class Base1
3537 endclass
3538 def F()
3539 instanceof(Base1.new())
3540 enddef
3541 F()
3542 END
3543 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3544
3545 lines =<< trim END
3546 vim9script
3547
3548 class Base1
3549 endclass
3550
3551 class Base2
3552 endclass
3553
3554 var o = Base2.new()
3555 instanceof(o, Base1, Base2, 3)
3556 END
3557 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3558
3559 lines =<< trim END
3560 vim9script
3561
3562 class Base1
3563 endclass
3564
3565 class Base2
3566 endclass
3567
3568 def F()
3569 var o = Base2.new()
3570 instanceof(o, Base1, Base2, 3)
3571 enddef
3572 F()
3573 END
3574 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003575enddef
3576
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003577" Test for calling a method in the parent class that is extended partially.
3578" This used to fail with the 'E118: Too many arguments for function: Text' error
3579" message (Github issue #12524).
3580def Test_call_method_in_parent_class()
3581 var lines =<< trim END
3582 vim9script
3583
3584 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003585 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003586
3587 def SetY(lnum: number)
3588 this._lnum = lnum
3589 enddef
3590
3591 def Text(): string
3592 return ''
3593 enddef
3594 endclass
3595
3596 class Foo extends Widget
3597 def Text(): string
3598 return '<Foo>'
3599 enddef
3600 endclass
3601
3602 def Stack(w1: Widget, w2: Widget): list<Widget>
3603 w1.SetY(1)
3604 w2.SetY(2)
3605 return [w1, w2]
3606 enddef
3607
3608 var foo1 = Foo.new()
3609 var foo2 = Foo.new()
3610 var l = Stack(foo1, foo2)
3611 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003612 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003613enddef
3614
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003615" Test for calling methods from three levels of classes
3616def Test_multi_level_method_call()
3617 var lines =<< trim END
3618 vim9script
3619
3620 var A_func1: number = 0
3621 var A_func2: number = 0
3622 var A_func3: number = 0
3623 var B_func2: number = 0
3624 var B_func3: number = 0
3625 var C_func3: number = 0
3626
3627 class A
3628 def Func1()
3629 A_func1 += 1
3630 enddef
3631
3632 def Func2()
3633 A_func2 += 1
3634 enddef
3635
3636 def Func3()
3637 A_func3 += 1
3638 enddef
3639 endclass
3640
3641 class B extends A
3642 def Func2()
3643 B_func2 += 1
3644 enddef
3645
3646 def Func3()
3647 B_func3 += 1
3648 enddef
3649 endclass
3650
3651 class C extends B
3652 def Func3()
3653 C_func3 += 1
3654 enddef
3655 endclass
3656
3657 def A_CallFuncs(a: A)
3658 a.Func1()
3659 a.Func2()
3660 a.Func3()
3661 enddef
3662
3663 def B_CallFuncs(b: B)
3664 b.Func1()
3665 b.Func2()
3666 b.Func3()
3667 enddef
3668
3669 def C_CallFuncs(c: C)
3670 c.Func1()
3671 c.Func2()
3672 c.Func3()
3673 enddef
3674
3675 var cobj = C.new()
3676 A_CallFuncs(cobj)
3677 B_CallFuncs(cobj)
3678 C_CallFuncs(cobj)
3679 assert_equal(3, A_func1)
3680 assert_equal(0, A_func2)
3681 assert_equal(0, A_func3)
3682 assert_equal(3, B_func2)
3683 assert_equal(0, B_func3)
3684 assert_equal(3, C_func3)
3685 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003686 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003687enddef
3688
3689" Test for using members from three levels of classes
3690def Test_multi_level_member_access()
3691 var lines =<< trim END
3692 vim9script
3693
3694 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003695 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003696 endclass
3697
3698 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003699 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003700 endclass
3701
3702 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003703 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003704 endclass
3705
3706 def A_members(a: A)
3707 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003708 enddef
3709
3710 def B_members(b: B)
3711 b.val1 += 1
3712 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003713 enddef
3714
3715 def C_members(c: C)
3716 c.val1 += 1
3717 c.val2 += 1
3718 c.val3 += 1
3719 enddef
3720
3721 var cobj = C.new()
3722 A_members(cobj)
3723 B_members(cobj)
3724 C_members(cobj)
3725 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003726 assert_equal(2, cobj.val2)
3727 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003728 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003729 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003730enddef
3731
LemonBoy0ffc17a2023-08-20 18:09:11 +02003732" Test expansion of <stack> with class methods.
3733def Test_stack_expansion_with_methods()
3734 var lines =<< trim END
3735 vim9script
3736
3737 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003738 def M1()
3739 F0()
3740 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003741 endclass
3742
3743 def F0()
3744 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3745 enddef
3746
3747 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003748 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003749 enddef
3750
3751 F()
3752 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003753 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003754enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003755
3756" Test the return type of the new() constructor
3757def Test_new_return_type()
3758 # new() uses the default return type and there is no return statement
3759 var lines =<< trim END
3760 vim9script
3761
3762 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003763 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003764
3765 def new(this._bufnr)
3766 if !bufexists(this._bufnr)
3767 this._bufnr = -1
3768 endif
3769 enddef
3770 endclass
3771
3772 var c = C.new(12345)
3773 assert_equal('object<C>', typename(c))
3774
3775 var v1: C
3776 v1 = C.new(12345)
3777 assert_equal('object<C>', typename(v1))
3778
3779 def F()
3780 var v2: C
3781 v2 = C.new(12345)
3782 assert_equal('object<C>', typename(v2))
3783 enddef
3784 F()
3785 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003786 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003787
3788 # new() uses the default return type and an empty 'return' statement
3789 lines =<< trim END
3790 vim9script
3791
3792 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003793 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003794
3795 def new(this._bufnr)
3796 if !bufexists(this._bufnr)
3797 this._bufnr = -1
3798 return
3799 endif
3800 enddef
3801 endclass
3802
3803 var c = C.new(12345)
3804 assert_equal('object<C>', typename(c))
3805
3806 var v1: C
3807 v1 = C.new(12345)
3808 assert_equal('object<C>', typename(v1))
3809
3810 def F()
3811 var v2: C
3812 v2 = C.new(12345)
3813 assert_equal('object<C>', typename(v2))
3814 enddef
3815 F()
3816 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003817 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003818
3819 # new() uses "any" return type and returns "this"
3820 lines =<< trim END
3821 vim9script
3822
3823 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003824 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003825
3826 def new(this._bufnr): any
3827 if !bufexists(this._bufnr)
3828 this._bufnr = -1
3829 return this
3830 endif
3831 enddef
3832 endclass
3833 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003834 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003835
3836 # new() uses 'Dict' return type and returns a Dict
3837 lines =<< trim END
3838 vim9script
3839
3840 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003841 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003842
3843 def new(): dict<any>
3844 this._state = {}
3845 return this._state
3846 enddef
3847 endclass
3848
3849 var c = C.new()
3850 assert_equal('object<C>', typename(c))
3851 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003852 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003853enddef
3854
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003855" Test for checking a member initialization type at run time.
3856def Test_runtime_type_check_for_member_init()
3857 var lines =<< trim END
3858 vim9script
3859
3860 var retnum: bool = false
3861
3862 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003863 retnum = !retnum
3864 if retnum
3865 return 1
3866 else
3867 return "hello"
3868 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003869 enddef
3870
3871 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003872 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003873 endclass
3874
3875 var c1 = C.new()
3876 var c2 = C.new()
3877 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003878 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003879enddef
3880
3881" Test for locking a variable referring to an object and reassigning to another
3882" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003883def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003884 var lines =<< trim END
3885 vim9script
3886
3887 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003888 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003889 def new(this.val)
3890 enddef
3891 endclass
3892
3893 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3894 lockvar 2 some_dict
3895
3896 var current: C
3897 current = some_dict['c']
3898 assert_equal(3, current.val)
3899 current = some_dict['b']
3900 assert_equal(2, current.val)
3901
3902 def F()
3903 current = some_dict['c']
3904 enddef
3905
3906 def G()
3907 current = some_dict['b']
3908 enddef
3909
3910 F()
3911 assert_equal(3, current.val)
3912 G()
3913 assert_equal(2, current.val)
3914 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003915 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003916enddef
3917
Ernie Raelee865f32023-09-29 19:53:55 +02003918" Test trying to lock an object variable from various places
3919def Test_lockvar_object_variable()
3920 # An object variable lockvar has several cases:
3921 # object method, scriptlevel, scriplevel from :def, :def arg
3922 # method arg, static method arg.
3923 # Also different depths
3924
Ernie Raelee865f32023-09-29 19:53:55 +02003925 #
3926 # lockvar of read-only object variable
3927 #
3928
3929 # read-only lockvar from object method
3930 var lines =<< trim END
3931 vim9script
3932
3933 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003934 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02003935 def Lock()
3936 lockvar this.val1
3937 enddef
3938 endclass
3939 var o = C.new(3)
3940 o.Lock()
3941 END
Ernie Rael64885642023-10-04 20:16:22 +02003942 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003943
3944 # read-only lockvar from scriptlevel
3945 lines =<< trim END
3946 vim9script
3947
3948 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003949 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02003950 endclass
3951 var o = C.new(3)
3952 lockvar o.val2
3953 END
3954 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3955
3956 # read-only lockvar of scriptlevel variable from def
3957 lines =<< trim END
3958 vim9script
3959
3960 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003961 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02003962 endclass
3963 var o = C.new(3)
3964 def Lock()
3965 lockvar o.val3
3966 enddef
3967 Lock()
3968 END
3969 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3970
3971 # read-only lockvar of def argument variable
3972 lines =<< trim END
3973 vim9script
3974
3975 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003976 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02003977 endclass
3978 def Lock(o: C)
3979 lockvar o.val4
3980 enddef
3981 Lock(C.new(3))
3982 END
3983 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3984
3985 # TODO: the following tests use type "any" for argument. Need a run time
3986 # check for access. Probably OK as is for now.
3987
3988 # read-only lockvar from object method arg
3989 lines =<< trim END
3990 vim9script
3991
3992 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003993 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02003994 def Lock(o_any: any)
3995 lockvar o_any.val5
3996 enddef
3997 endclass
3998 var o = C.new(3)
3999 o.Lock(C.new(5))
4000 END
Ernie Rael64885642023-10-04 20:16:22 +02004001 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004002
4003 # read-only lockvar from class method arg
4004 lines =<< trim END
4005 vim9script
4006
4007 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004008 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004009 static def Lock(o_any: any)
4010 lockvar o_any.val6
4011 enddef
4012 endclass
4013 var o = C.new(3)
4014 C.Lock(o)
4015 END
Ernie Rael64885642023-10-04 20:16:22 +02004016 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004017
4018 #
4019 # lockvar of public object variable
4020 #
4021
4022 # lockvar from object method
4023 lines =<< trim END
4024 vim9script
4025
4026 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004027 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004028 def Lock()
4029 lockvar this.val1
4030 enddef
4031 endclass
4032 var o = C.new(3)
4033 o.Lock()
4034 END
4035 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4036
4037 # lockvar from scriptlevel
4038 lines =<< trim END
4039 vim9script
4040
4041 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004042 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004043 endclass
4044 var o = C.new(3)
4045 lockvar o.val2
4046 END
4047 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4048
4049 # lockvar of scriptlevel variable from def
4050 lines =<< trim END
4051 vim9script
4052
4053 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004054 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004055 endclass
4056 var o = C.new(3)
4057 def Lock()
4058 lockvar o.val3
4059 enddef
4060 Lock()
4061 END
4062 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4063
4064 # lockvar of def argument variable
4065 lines =<< trim END
4066 vim9script
4067
4068 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004069 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004070 endclass
4071 def Lock(o: C)
4072 lockvar o.val4
4073 enddef
4074 Lock(C.new(3))
4075 END
4076 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4077
4078 # lockvar from object method arg
4079 lines =<< trim END
4080 vim9script
4081
4082 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004083 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004084 def Lock(o_any: any)
4085 lockvar o_any.val5
4086 enddef
4087 endclass
4088 var o = C.new(3)
4089 o.Lock(C.new(5))
4090 END
4091 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4092
4093 # lockvar from class method arg
4094 lines =<< trim END
4095 vim9script
4096
4097 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004098 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004099 static def Lock(o_any: any)
4100 lockvar o_any.val6
4101 enddef
4102 endclass
4103 var o = C.new(3)
4104 C.Lock(o)
4105 END
4106 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4107enddef
4108
4109" Test trying to lock a class variable from various places
4110def Test_lockvar_class_variable()
4111
4112 # lockvar bare static from object method
4113 var lines =<< trim END
4114 vim9script
4115
4116 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004117 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004118 def Lock()
4119 lockvar sval1
4120 enddef
4121 endclass
4122 var o = C.new()
4123 o.Lock()
4124 END
4125 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4126
4127 # lockvar C.static from object method
4128 lines =<< trim END
4129 vim9script
4130
4131 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004132 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004133 def Lock()
4134 lockvar C.sval2
4135 enddef
4136 endclass
4137 var o = C.new()
4138 o.Lock()
4139 END
4140 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4141
4142 # lockvar bare static from class method
4143 lines =<< trim END
4144 vim9script
4145
4146 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004147 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004148 static def Lock()
4149 lockvar sval3
4150 enddef
4151 endclass
4152 C.Lock()
4153 END
4154 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4155
4156 # lockvar C.static from class method
4157 lines =<< trim END
4158 vim9script
4159
4160 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004161 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004162 static def Lock()
4163 lockvar C.sval4
4164 enddef
4165 endclass
4166 C.Lock()
4167 END
4168 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4169
4170 # lockvar C.static from script level
4171 lines =<< trim END
4172 vim9script
4173
4174 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004175 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004176 endclass
4177 lockvar C.sval5
4178 END
4179 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4180
4181 # lockvar o.static from script level
4182 lines =<< trim END
4183 vim9script
4184
4185 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004186 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004187 endclass
4188 var o = C.new()
4189 lockvar o.sval6
4190 END
4191 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4192enddef
4193
4194" Test locking an argument to :def
4195def Test_lockvar_argument()
4196 # Lockvar a function arg
4197 var lines =<< trim END
4198 vim9script
4199
4200 def Lock(val: any)
4201 lockvar val
4202 enddef
4203
4204 var d = {a: 1, b: 2}
4205 Lock(d)
4206
4207 d->extend({c: 3})
4208 END
4209 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4210
4211 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4212 # class member in "C". This tests lval_root_is_arg.
4213 lines =<< trim END
4214 vim9script
4215
4216 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004217 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004218 endclass
4219
4220 def Lock2(sval: any)
4221 lockvar sval
4222 enddef
4223
4224 var o = C.new()
4225 Lock2(o)
4226 END
4227 v9.CheckSourceSuccess(lines)
4228
4229 # Lock a class.
4230 lines =<< trim END
4231 vim9script
4232
4233 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004234 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004235 endclass
4236
4237 def Lock2(sval: any)
4238 lockvar sval
4239 enddef
4240
4241 Lock2(C)
4242 END
Ernie Raelb077b582023-12-14 20:11:44 +01004243 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004244
4245 # Lock an object.
4246 lines =<< trim END
4247 vim9script
4248
4249 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004250 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004251 endclass
4252
4253 def Lock2(sval: any)
4254 lockvar sval
4255 enddef
4256
4257 Lock2(C.new())
4258 END
4259 v9.CheckSourceSuccess(lines)
4260
4261 # In this case (unlike previous) "lockvar sval" is a class member.
4262 lines =<< trim END
4263 vim9script
4264
4265 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004266 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004267 def Lock2()
4268 lockvar sval
4269 enddef
4270 endclass
4271
4272
4273 var o = C.new()
4274 o.Lock2()
4275 END
4276 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4277enddef
4278
4279" Test that this can be locked without error
4280def Test_lockvar_this()
4281 # lockvar this
4282 var lines =<< trim END
4283 vim9script
4284 class C
4285 def TLock()
4286 lockvar this
4287 enddef
4288 endclass
4289 var o = C.new()
4290 o.TLock()
4291 END
4292 v9.CheckSourceSuccess(lines)
4293
4294 # lockvar four (four letter word, but not this)
4295 lines =<< trim END
4296 vim9script
4297 class C
4298 def TLock4()
4299 var four: number
4300 lockvar four
4301 enddef
4302 endclass
4303 var o = C.new()
4304 o.TLock4()
4305 END
4306 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4307
4308 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4309 lines =<< trim END
4310 vim9script
4311 class C
4312 def TLock5()
4313 var this5: number
4314 lockvar this5
4315 enddef
4316 endclass
4317 var o = C.new()
4318 o.TLock5()
4319 END
4320 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4321enddef
4322
4323" Test some general lockvar cases
4324def Test_lockvar_general()
4325 # lockvar an object and a class. It does nothing
4326 var lines =<< trim END
4327 vim9script
4328 class C
4329 endclass
4330 var o = C.new()
4331 lockvar o
4332 lockvar C
4333 END
4334 v9.CheckSourceSuccess(lines)
4335
4336 # Lock a list element that's nested in an object variable from a :def
4337 lines =<< trim END
4338 vim9script
4339
4340 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004341 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004342 endclass
4343 def Lock2(obj: any)
4344 lockvar obj.val[1]
4345 enddef
4346
4347 var o = C.new()
4348 Lock2(o)
4349 o.val[0] = [9]
4350 assert_equal([ [9], [2], [3] ], o.val)
4351 try
4352 o.val[1] = [999]
4353 call assert_false(true, 'assign should have failed')
4354 catch
4355 assert_exception('E741:')
4356 endtry
4357 o.val[2] = [8]
4358 assert_equal([ [9], [2], [8] ], o.val)
4359 END
4360 v9.CheckSourceSuccess(lines)
4361
4362 # Lock a list element that's nested in an object variable from scriptlevel
4363 lines =<< trim END
4364 vim9script
4365
4366 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004367 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004368 endclass
4369
4370 var o = C.new()
4371 lockvar o.val[1]
4372 o.val[0] = [9]
4373 assert_equal([ [9], [2], [3] ], o.val)
4374 try
4375 o.val[1] = [999]
4376 call assert_false(true, 'assign should have failed')
4377 catch
4378 assert_exception('E741:')
4379 endtry
4380 o.val[2] = [8]
4381 assert_equal([ [9], [2], [8] ], o.val)
4382 END
4383 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004384
4385 # lock a script level variable from an object method
4386 lines =<< trim END
4387 vim9script
4388
4389 class C
4390 def Lock()
4391 lockvar l
4392 enddef
4393 endclass
4394
4395 var l = [1]
4396 C.new().Lock()
4397 l[0] = 11
4398 END
4399 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4400
Ernie Rael03042a22023-11-11 08:53:32 +01004401 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004402 # in an object fetched via a script level list
4403 lines =<< trim END
4404 vim9script
4405
4406 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004407 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004408 def Lock()
4409 lockvar lc[0]._v1[1]
4410 enddef
4411 endclass
4412
4413 var l = [[1], [2], [3]]
4414 var o = C.new(l)
4415 var lc: list<C> = [ o ]
4416
4417 o.Lock()
4418 l[0] = [22]
4419 l[1] = [33]
4420 END
4421 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4422
4423 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004424 # in a class that does not own the protected variable.
4425 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004426 # the same name.
4427 lines =<< trim END
4428 vim9script
4429
4430 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004431 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004432 def Lock(obj: any)
4433 lockvar lc[0]._v1[1]
4434 enddef
4435 endclass
4436
4437 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004438 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004439 endclass
4440
4441 var l = [[1], [2], [3]]
4442 var o = C.new(l)
4443 var lc: list<C> = [ o ]
4444
4445 var o2 = C2.new()
4446 o2.Lock(o)
4447 END
Ernie Rael03042a22023-11-11 08:53:32 +01004448 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004449enddef
4450
Ernie Rael9771b2a2023-10-07 22:05:40 +02004451" Test builtin islocked()
4452def Test_lockvar_islocked()
4453 # Can't lock class/object variable
4454 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004455 # Lock item of variable's value (a list item)
4456 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004457 var lines =<< trim END
4458 vim9script
4459
4460 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004461 var o0: list<list<number>> = [ [0], [1], [2]]
4462 var o1: list<list<number>> = [[10], [11], [12]]
4463 static var c0: list<list<number>> = [[20], [21], [22]]
4464 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004465 endclass
4466
4467 def LockIt(arg: any)
4468 lockvar arg
4469 enddef
4470
4471 def UnlockIt(arg: any)
4472 unlockvar arg
4473 enddef
4474
4475 var obj = C.new()
4476 #lockvar obj.o1 # can't lock something you can't write to
4477
4478 try
4479 lockvar obj.o1 # can't lock something you can't write to
4480 call assert_false(1, '"lockvar obj.o1" should have failed')
4481 catch
4482 call assert_exception('E1335:')
4483 endtry
4484
4485 LockIt(obj.o1) # but can lock it's value
4486 assert_equal(1, islocked("obj.o1"))
4487 assert_equal(1, islocked("obj.o1[0]"))
4488 assert_equal(1, islocked("obj.o1[1]"))
4489 UnlockIt(obj.o1)
4490 assert_equal(0, islocked("obj.o1"))
4491 assert_equal(0, islocked("obj.o1[0]"))
4492
4493 lockvar obj.o1[0]
4494 assert_equal(0, islocked("obj.o1"))
4495 assert_equal(1, islocked("obj.o1[0]"))
4496 assert_equal(0, islocked("obj.o1[1]"))
4497 unlockvar obj.o1[0]
4498 assert_equal(0, islocked("obj.o1"))
4499 assert_equal(0, islocked("obj.o1[0]"))
4500
4501 # Same thing, but with a static
4502
4503 try
4504 lockvar C.c1 # can't lock something you can't write to
4505 call assert_false(1, '"lockvar C.c1" should have failed')
4506 catch
4507 call assert_exception('E1335:')
4508 endtry
4509
4510 LockIt(C.c1) # but can lock it's value
4511 assert_equal(1, islocked("C.c1"))
4512 assert_equal(1, islocked("C.c1[0]"))
4513 assert_equal(1, islocked("C.c1[1]"))
4514 UnlockIt(C.c1)
4515 assert_equal(0, islocked("C.c1"))
4516 assert_equal(0, islocked("C.c1[0]"))
4517
4518 lockvar C.c1[0]
4519 assert_equal(0, islocked("C.c1"))
4520 assert_equal(1, islocked("C.c1[0]"))
4521 assert_equal(0, islocked("C.c1[1]"))
4522 unlockvar C.c1[0]
4523 assert_equal(0, islocked("C.c1"))
4524 assert_equal(0, islocked("C.c1[0]"))
4525 END
4526 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004527
4528 # Do islocked() from an object method
4529 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004530 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004531 vim9script
4532
4533 var l0o0 = [ [0], [1], [2]]
4534 var l0o1 = [ [10], [11], [12]]
4535 var l0c0 = [[120], [121], [122]]
4536 var l0c1 = [[130], [131], [132]]
4537
4538 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004539 var o0: list<list<number>> = l0o0
4540 var o1: list<list<number>> = l0o1
4541 static var c0: list<list<number>> = l0c0
4542 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004543 def Islocked(arg: string): number
4544 return islocked(arg)
4545 enddef
4546 static def SIslocked(arg: string): number
4547 return islocked(arg)
4548 enddef
4549 endclass
4550
4551 var l2o0 = [[20000], [20001], [20002]]
4552 var l2o1 = [[20010], [20011], [20012]]
4553 var l2c0 = [[20120], [20121], [20122]]
4554 var l2c1 = [[20130], [20131], [20132]]
4555
4556 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004557 var o0: list<list<number>> = l2o0
4558 var o1: list<list<number>> = l2o1
4559 static var c0: list<list<number>> = l2c0
4560 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004561 def Islocked(arg: string): number
4562 return islocked(arg)
4563 enddef
4564 static def SIslocked(arg: string): number
4565 return islocked(arg)
4566 enddef
4567 endclass
4568
4569 var obj0 = C0.new()
4570 var obj2 = C2.new()
4571
4572 var l = [ obj0, null_object, obj2 ]
4573
4574 # lock list, object func access through script var expr
4575 assert_equal(0, obj0.Islocked("l[0].o0"))
4576 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4577 lockvar l0o0
4578 assert_equal(1, obj0.Islocked("l[0].o0"))
4579 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4580
4581 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4582
4583 # lock list element, object func access through script var expr
4584 lockvar l0o1[1]
4585 assert_equal(0, obj0.Islocked("this.o1[0]"))
4586 assert_equal(1, obj0.Islocked("this.o1[1]"))
4587
4588 assert_equal(0, obj0.Islocked("this.o1"))
4589 lockvar l0o1
4590 assert_equal(1, obj0.Islocked("this.o1"))
4591 unlockvar l0o1
4592
4593 lockvar l0c1[1]
4594
4595 # static by class name member expr from same class
4596 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4597 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4598 # static by bare name member expr from same class
4599 assert_equal(0, obj0.Islocked("c1[0]"))
4600 assert_equal(1, obj0.Islocked("c1[1]"))
4601
4602 # static by class name member expr from other class
4603 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4604 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4605 # static by bare name member expr from other class
4606 assert_equal(0, obj2.Islocked("c1[0]"))
4607 assert_equal(0, obj2.Islocked("c1[1]"))
4608
4609
4610 # static by bare name in same class
4611 assert_equal(0, obj0.Islocked("c0"))
4612 lockvar l0c0
4613 assert_equal(1, obj0.Islocked("c0"))
4614
4615 #
4616 # similar stuff, but use static method
4617 #
4618
4619 unlockvar l0o0
4620
4621 # lock list, object func access through script var expr
4622 assert_equal(0, C0.SIslocked("l[0].o0"))
4623 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4624 lockvar l0o0
4625 assert_equal(1, C0.SIslocked("l[0].o0"))
4626 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4627
4628 unlockvar l0o1
4629
4630 # can't access "this" from class method
4631 try
4632 C0.SIslocked("this.o1[0]")
4633 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4634 catch
4635 call assert_exception('E121: Undefined variable: this')
4636 endtry
4637
4638 lockvar l0c1[1]
4639
4640 # static by class name member expr from same class
4641 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4642 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4643 # static by bare name member expr from same class
4644 assert_equal(0, C0.SIslocked("c1[0]"))
4645 assert_equal(1, C0.SIslocked("c1[1]"))
4646
4647 # static by class name member expr from other class
4648 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4649 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4650 # static by bare name member expr from other class
4651 assert_equal(0, C2.SIslocked("c1[0]"))
4652 assert_equal(0, C2.SIslocked("c1[1]"))
4653
4654
4655 # static by bare name in same class
4656 unlockvar l0c0
4657 assert_equal(0, C0.SIslocked("c0"))
4658 lockvar l0c0
4659 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004660 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004661 v9.CheckSourceSuccess(lines)
4662
4663 # Check islocked class/object from various places.
4664 lines =<< trim END
4665 vim9script
4666
4667 class C
4668 def Islocked(arg: string): number
4669 return islocked(arg)
4670 enddef
4671 static def SIslocked(arg: string): number
4672 return islocked(arg)
4673 enddef
4674 endclass
4675 var obj = C.new()
4676
4677 # object method
4678 assert_equal(0, obj.Islocked("this"))
4679 assert_equal(0, obj.Islocked("C"))
4680
4681 # class method
4682 ### assert_equal(0, C.SIslocked("this"))
4683 assert_equal(0, C.SIslocked("C"))
4684
4685 #script level
4686 var v: number
4687 v = islocked("C")
4688 assert_equal(0, v)
4689 v = islocked("obj")
4690 assert_equal(0, v)
4691 END
4692 v9.CheckSourceSuccess(lines)
4693enddef
4694
4695def Test_lockvar_islocked_notfound()
4696 # Try non-existent things
4697 var lines =<< trim END
4698 vim9script
4699
4700 class C
4701 def Islocked(arg: string): number
4702 return islocked(arg)
4703 enddef
4704 static def SIslocked(arg: string): number
4705 return islocked(arg)
4706 enddef
4707 endclass
4708 var obj = C.new()
4709 assert_equal(-1, obj.Islocked("anywhere"))
4710 assert_equal(-1, C.SIslocked("notanywhere"))
4711 END
4712 v9.CheckSourceSuccess(lines)
4713
4714 # Something not found of the form "name1.name2" is an error
4715 lines =<< trim END
4716 vim9script
4717
4718 islocked("one.two")
4719 END
4720 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4721
4722 lines =<< trim END
4723 vim9script
4724
4725 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004726 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004727 def Islocked(arg: string): number
4728 return islocked(arg)
4729 enddef
4730 endclass
4731 var obj = C.new()
4732 obj.Islocked("this.val.not_there"))
4733 END
4734 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4735
4736 lines =<< trim END
4737 vim9script
4738
4739 class C
4740 def Islocked(arg: string): number
4741 return islocked(arg)
4742 enddef
4743 endclass
4744 var obj = C.new()
4745 obj.Islocked("this.notobjmember")
4746 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004747 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004748
4749 # access a script variable through methods
4750 lines =<< trim END
4751 vim9script
4752
4753 var l = [1]
4754 class C
4755 def Islocked(arg: string): number
4756 return islocked(arg)
4757 enddef
4758 static def SIslocked(arg: string): number
4759 return islocked(arg)
4760 enddef
4761 endclass
4762 var obj = C.new()
4763 assert_equal(0, obj.Islocked("l"))
4764 assert_equal(0, C.SIslocked("l"))
4765 lockvar l
4766 assert_equal(1, obj.Islocked("l"))
4767 assert_equal(1, C.SIslocked("l"))
4768 END
4769 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004770enddef
4771
Ernie Rael03042a22023-11-11 08:53:32 +01004772" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004773def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004774 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004775 var lines =<< trim END
4776 vim9script
4777
4778 class A
4779 def _Foo(): number
4780 return 1234
4781 enddef
4782 endclass
4783 var a = A.new()
4784 a._Foo()
4785 END
Ernie Rael03042a22023-11-11 08:53:32 +01004786 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004787
Ernie Rael03042a22023-11-11 08:53:32 +01004788 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004789 lines =<< trim END
4790 vim9script
4791
4792 class A
4793 def _Foo(): number
4794 return 1234
4795 enddef
4796 endclass
4797 def T()
4798 var a = A.new()
4799 a._Foo()
4800 enddef
4801 T()
4802 END
Ernie Rael03042a22023-11-11 08:53:32 +01004803 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004804
Ernie Rael03042a22023-11-11 08:53:32 +01004805 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004806 lines =<< trim END
4807 vim9script
4808
4809 class A
4810 def _Foo(): number
4811 return 1234
4812 enddef
4813 def Bar(): number
4814 return this._Foo()
4815 enddef
4816 endclass
4817 var a = A.new()
4818 assert_equal(1234, a.Bar())
4819 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004820 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004821
Ernie Rael03042a22023-11-11 08:53:32 +01004822 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004823 lines =<< trim END
4824 vim9script
4825
4826 class A
4827 def _Foo(): number
4828 return 1234
4829 enddef
4830 def Bar(): number
4831 return this._Foo()
4832 enddef
4833 endclass
4834 def T()
4835 var a = A.new()
4836 assert_equal(1234, a.Bar())
4837 enddef
4838 T()
4839 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004840 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004841
Ernie Rael03042a22023-11-11 08:53:32 +01004842 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004843 lines =<< trim END
4844 vim9script
4845
4846 class A
4847 def _Foo(): number
4848 return 1234
4849 enddef
4850 def Bar(): number
4851 return _Foo()
4852 enddef
4853 endclass
4854 var a = A.new()
4855 a.Bar()
4856 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004857 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004858
Ernie Rael03042a22023-11-11 08:53:32 +01004859 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004860 lines =<< trim END
4861 vim9script
4862
4863 class A
4864 def _Foo(): number
4865 return 1234
4866 enddef
4867 endclass
4868 A._Foo()
4869 END
Ernie Rael03042a22023-11-11 08:53:32 +01004870 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004871
Ernie Rael03042a22023-11-11 08:53:32 +01004872 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004873 lines =<< trim END
4874 vim9script
4875
4876 class A
4877 def _Foo()
4878 enddef
4879 def _Foo()
4880 enddef
4881 endclass
4882 var a = A.new()
4883 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004884 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004885
Ernie Rael03042a22023-11-11 08:53:32 +01004886 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004887 lines =<< trim END
4888 vim9script
4889
4890 class A
4891 def _Foo()
4892 enddef
4893 def Foo()
4894 enddef
4895 endclass
4896 var a = A.new()
4897 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004898 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004899
Ernie Rael03042a22023-11-11 08:53:32 +01004900 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004901 lines =<< trim END
4902 vim9script
4903
4904 class A
4905 def Foo()
4906 enddef
4907 def _Foo()
4908 enddef
4909 endclass
4910 var a = A.new()
4911 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004912 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004913
Ernie Rael03042a22023-11-11 08:53:32 +01004914 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004915 lines =<< trim END
4916 vim9script
4917
4918 class A
4919 def Foo(): number
4920 return 100
4921 enddef
4922 def _Bar(): number
4923 return 200
4924 enddef
4925 def _Baz()
4926 assert_equal(100, this.Foo())
4927 assert_equal(200, this._Bar())
4928 enddef
4929 def T()
4930 this._Baz()
4931 enddef
4932 endclass
4933 var a = A.new()
4934 a.T()
4935 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004936 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004937
Ernie Rael03042a22023-11-11 08:53:32 +01004938 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004939 lines =<< trim END
4940 vim9script
4941
4942 class A
4943 def _Foo(): number
4944 return 100
4945 enddef
4946 endclass
4947 class B
4948 def Foo(): number
4949 var a = A.new()
4950 a._Foo()
4951 enddef
4952 endclass
4953 var b = B.new()
4954 b.Foo()
4955 END
Ernie Rael03042a22023-11-11 08:53:32 +01004956 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004957
Ernie Rael03042a22023-11-11 08:53:32 +01004958 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004959 lines =<< trim END
4960 vim9script
4961 class A
4962 def _Foo(): number
4963 return 1234
4964 enddef
4965 endclass
4966 class B extends A
4967 def Bar()
4968 enddef
4969 endclass
4970 class C extends B
4971 def Baz(): number
4972 return this._Foo()
4973 enddef
4974 endclass
4975 var c = C.new()
4976 assert_equal(1234, c.Baz())
4977 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004978 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004979
Ernie Rael03042a22023-11-11 08:53:32 +01004980 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004981 lines =<< trim END
4982 vim9script
4983 class A
4984 def _Foo(): number
4985 return 1234
4986 enddef
4987 endclass
4988 class B extends A
4989 def Bar()
4990 enddef
4991 endclass
4992 class C extends B
4993 def Baz(): number
4994 enddef
4995 endclass
4996 var c = C.new()
4997 assert_equal(1234, c._Foo())
4998 END
Ernie Rael03042a22023-11-11 08:53:32 +01004999 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005000
5001 # Using "_" prefix in a method name should fail outside of a class
5002 lines =<< trim END
5003 vim9script
5004 def _Foo(): number
5005 return 1234
5006 enddef
5007 var a = _Foo()
5008 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005009 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005010enddef
5011
Ernie Rael03042a22023-11-11 08:53:32 +01005012" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005013def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005014 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005015 var lines =<< trim END
5016 vim9script
5017
5018 class A
5019 static def _Foo(): number
5020 return 1234
5021 enddef
5022 endclass
5023 A._Foo()
5024 END
Ernie Rael03042a22023-11-11 08:53:32 +01005025 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005026
Ernie Rael03042a22023-11-11 08:53:32 +01005027 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005028 lines =<< trim END
5029 vim9script
5030
5031 class A
5032 static def _Foo(): number
5033 return 1234
5034 enddef
5035 endclass
5036 def T()
5037 A._Foo()
5038 enddef
5039 T()
5040 END
Ernie Rael03042a22023-11-11 08:53:32 +01005041 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005042
Ernie Rael03042a22023-11-11 08:53:32 +01005043 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005044 lines =<< trim END
5045 vim9script
5046
5047 class A
5048 static def _Foo(): number
5049 return 1234
5050 enddef
5051 endclass
5052 var a = A.new()
5053 a._Foo()
5054 END
Ernie Rael03042a22023-11-11 08:53:32 +01005055 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005056
Ernie Rael03042a22023-11-11 08:53:32 +01005057 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005058 lines =<< trim END
5059 vim9script
5060
5061 class A
5062 static def _Foo(): number
5063 return 1234
5064 enddef
5065 endclass
5066 def T()
5067 var a = A.new()
5068 a._Foo()
5069 enddef
5070 T()
5071 END
Ernie Rael03042a22023-11-11 08:53:32 +01005072 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005073
Ernie Rael03042a22023-11-11 08:53:32 +01005074 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005075 lines =<< trim END
5076 vim9script
5077
5078 class A
5079 static def _Foo(): number
5080 return 1234
5081 enddef
5082 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005083 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005084 enddef
5085 endclass
5086 var a = A.new()
5087 a.Bar()
5088 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005089 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005090
Ernie Rael03042a22023-11-11 08:53:32 +01005091 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005092 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005093 lines =<< trim END
5094 vim9script
5095
5096 class A
5097 static def _Foo1(): number
5098 return 1234
5099 enddef
5100 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005101 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005102 enddef
5103 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005104 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005105 enddef
5106 endclass
5107 var a = A.new()
5108 a.Bar()
5109 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005110 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005111
Ernie Rael03042a22023-11-11 08:53:32 +01005112 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005113 lines =<< trim END
5114 vim9script
5115
5116 class A
5117 static def _Foo()
5118 enddef
5119 static def Foo()
5120 enddef
5121 endclass
5122 var a = A.new()
5123 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005124 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005125
Ernie Rael03042a22023-11-11 08:53:32 +01005126 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005127 lines =<< trim END
5128 vim9script
5129
5130 class A
5131 static def _Foo(): number
5132 return 1234
5133 enddef
5134 endclass
5135 class B
5136 def Foo(): number
5137 return A._Foo()
5138 enddef
5139 endclass
5140 var b = B.new()
5141 assert_equal(1234, b.Foo())
5142 END
Ernie Rael03042a22023-11-11 08:53:32 +01005143 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005144
Ernie Rael03042a22023-11-11 08:53:32 +01005145 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005146 lines =<< trim END
5147 vim9script
5148 class A
5149 static def _Foo(): number
5150 return 1234
5151 enddef
5152 endclass
5153 class B extends A
5154 def Bar()
5155 enddef
5156 endclass
5157 class C extends B
5158 def Baz(): number
5159 return A._Foo()
5160 enddef
5161 endclass
5162 var c = C.new()
5163 assert_equal(1234, c.Baz())
5164 END
Ernie Rael03042a22023-11-11 08:53:32 +01005165 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005166
Ernie Rael03042a22023-11-11 08:53:32 +01005167 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005168 lines =<< trim END
5169 vim9script
5170 class A
5171 static def _Foo(): number
5172 return 1234
5173 enddef
5174 endclass
5175 class B extends A
5176 def Bar()
5177 enddef
5178 endclass
5179 class C extends B
5180 static def Baz(): number
5181 return A._Foo()
5182 enddef
5183 endclass
5184 assert_equal(1234, C.Baz())
5185 END
Ernie Rael03042a22023-11-11 08:53:32 +01005186 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005187
Ernie Rael03042a22023-11-11 08:53:32 +01005188 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005189 lines =<< trim END
5190 vim9script
5191 class A
5192 static def _Foo(): number
5193 return 1234
5194 enddef
5195 endclass
5196 class B extends A
5197 def Bar()
5198 enddef
5199 endclass
5200 class C extends B
5201 def Baz(): number
5202 enddef
5203 endclass
5204 var c = C.new()
5205 assert_equal(1234, C._Foo())
5206 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005207 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005208enddef
5209
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005210" Test for using the return value of a class/object method as a function
5211" argument.
5212def Test_objmethod_funcarg()
5213 var lines =<< trim END
5214 vim9script
5215
5216 class C
5217 def Foo(): string
5218 return 'foo'
5219 enddef
5220 endclass
5221
5222 def Bar(a: number, s: string): string
5223 return s
5224 enddef
5225
5226 def Baz(c: C)
5227 assert_equal('foo', Bar(10, c.Foo()))
5228 enddef
5229
5230 var t = C.new()
5231 Baz(t)
5232 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005233 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005234
5235 lines =<< trim END
5236 vim9script
5237
5238 class C
5239 static def Foo(): string
5240 return 'foo'
5241 enddef
5242 endclass
5243
5244 def Bar(a: number, s: string): string
5245 return s
5246 enddef
5247
5248 def Baz()
5249 assert_equal('foo', Bar(10, C.Foo()))
5250 enddef
5251
5252 Baz()
5253 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005254 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005255enddef
5256
Ernie Raelcf138d42023-09-06 20:45:03 +02005257def Test_static_inheritence()
5258 # subclasses get their own static copy
5259 var lines =<< trim END
5260 vim9script
5261
5262 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005263 static var _svar: number
5264 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005265 def new()
5266 _svar = 1
5267 this._mvar = 101
5268 enddef
5269 def AccessObject(): number
5270 return this._mvar
5271 enddef
5272 def AccessStaticThroughObject(): number
5273 return _svar
5274 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005275 endclass
5276
5277 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005278 def new()
5279 this._mvar = 102
5280 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005281 endclass
5282
5283 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005284 def new()
5285 this._mvar = 103
5286 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005287
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005288 def AccessPrivateStaticThroughClassName(): number
5289 assert_equal(1, A._svar)
5290 return 444
5291 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005292 endclass
5293
5294 var oa = A.new()
5295 var ob = B.new()
5296 var oc = C.new()
5297 assert_equal(101, oa.AccessObject())
5298 assert_equal(102, ob.AccessObject())
5299 assert_equal(103, oc.AccessObject())
5300
Ernie Rael03042a22023-11-11 08:53:32 +01005301 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005302
5303 # verify object properly resolves to correct static
5304 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005305 assert_equal(1, ob.AccessStaticThroughObject())
5306 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005307 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005308 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005309enddef
5310
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005311" Test for declaring duplicate object and class members
5312def Test_dup_member_variable()
5313 # Duplicate member variable
5314 var lines =<< trim END
5315 vim9script
5316 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005317 var val = 10
5318 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005319 endclass
5320 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005321 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005322
Ernie Rael03042a22023-11-11 08:53:32 +01005323 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005324 lines =<< trim END
5325 vim9script
5326 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005327 var _val = 10
5328 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005329 endclass
5330 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005331 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005332
5333 # Duplicate public member variable
5334 lines =<< trim END
5335 vim9script
5336 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005337 public var val = 10
5338 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005339 endclass
5340 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005341 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005342
Ernie Rael03042a22023-11-11 08:53:32 +01005343 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005344 lines =<< trim END
5345 vim9script
5346 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005347 var val = 10
5348 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005349 endclass
5350 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005351 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005352
Ernie Rael03042a22023-11-11 08:53:32 +01005353 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005354 lines =<< trim END
5355 vim9script
5356 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005357 var _val = 20
5358 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005359 endclass
5360 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005361 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005362
5363 # Duplicate class member variable
5364 lines =<< trim END
5365 vim9script
5366 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005367 static var s: string = "abc"
5368 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005369 endclass
5370 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005371 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005372
Ernie Rael03042a22023-11-11 08:53:32 +01005373 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005374 lines =<< trim END
5375 vim9script
5376 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005377 public static var s: string = "abc"
5378 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005379 endclass
5380 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005381 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005382
5383 # Duplicate class and object member variable
5384 lines =<< trim END
5385 vim9script
5386 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005387 static var val = 10
5388 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005389 def new()
5390 enddef
5391 endclass
5392 var c = C.new()
5393 assert_equal(10, C.val)
5394 assert_equal(20, c.val)
5395 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005396 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005397
5398 # Duplicate object member variable in a derived class
5399 lines =<< trim END
5400 vim9script
5401 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005402 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005403 endclass
5404 class B extends A
5405 endclass
5406 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005407 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005408 endclass
5409 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005410 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005411
Ernie Rael03042a22023-11-11 08:53:32 +01005412 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005413 lines =<< trim END
5414 vim9script
5415 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005416 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005417 endclass
5418 class B extends A
5419 endclass
5420 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005421 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005422 endclass
5423 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005424 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005425
Ernie Rael03042a22023-11-11 08:53:32 +01005426 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005427 lines =<< trim END
5428 vim9script
5429 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005430 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005431 endclass
5432 class B extends A
5433 endclass
5434 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005435 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005436 endclass
5437 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005438 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005439
5440 # Duplicate object member variable in a derived class
5441 lines =<< trim END
5442 vim9script
5443 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005444 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005445 endclass
5446 class B extends A
5447 endclass
5448 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005449 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005450 endclass
5451 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005452 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005453
5454 # Two member variables with a common prefix
5455 lines =<< trim END
5456 vim9script
5457 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005458 public static var svar2: number
5459 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005460 endclass
5461 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005462 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005463enddef
5464
Ernie Rael03042a22023-11-11 08:53:32 +01005465" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005466def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005467 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005468 var lines =<< trim END
5469 vim9script
5470 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005471 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005472 def GetVal(): number
5473 return this._val
5474 enddef
5475 endclass
5476 def T()
5477 var a = A.new()
5478 a._val = 20
5479 enddef
5480 T()
5481 END
Ernie Rael03042a22023-11-11 08:53:32 +01005482 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005483
Ernie Rael03042a22023-11-11 08:53:32 +01005484 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005485 lines =<< trim END
5486 vim9script
5487 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005488 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005489 endclass
5490 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005491 var a = A.new()
5492 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005493 enddef
5494 T()
5495 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005496 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005497
Ernie Rael03042a22023-11-11 08:53:32 +01005498 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005499 lines =<< trim END
5500 vim9script
5501 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005502 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005503 endclass
5504 def T()
5505 var a = A.new()
5506 var x = a._val
5507 enddef
5508 T()
5509 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005510 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005511
Ernie Rael03042a22023-11-11 08:53:32 +01005512 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005513 lines =<< trim END
5514 vim9script
5515 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005516 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005517 endclass
5518 def T()
5519 var a = A.new()
5520 a._val = 3
5521 enddef
5522 T()
5523 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005524 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005525
Ernie Rael03042a22023-11-11 08:53:32 +01005526 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005527 lines =<< trim END
5528 vim9script
5529 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005530 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005531 endclass
5532 def T()
5533 var x = A._val
5534 enddef
5535 T()
5536 END
Ernie Rael03042a22023-11-11 08:53:32 +01005537 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005538
Ernie Rael03042a22023-11-11 08:53:32 +01005539 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005540 lines =<< trim END
5541 vim9script
5542 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005543 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005544 endclass
5545 def T()
5546 A._val = 3
5547 enddef
5548 T()
5549 END
Ernie Rael03042a22023-11-11 08:53:32 +01005550 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005551enddef
5552
5553" Test for changing the member access of an interface in a implementation class
5554def Test_change_interface_member_access()
5555 var lines =<< trim END
5556 vim9script
5557 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005558 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005559 endinterface
5560 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005561 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005562 endclass
5563 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005564 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005565
5566 lines =<< trim END
5567 vim9script
5568 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005569 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005570 endinterface
5571 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005572 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005573 endclass
5574 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005575 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005576enddef
5577
5578" Test for trying to change a readonly member from a def function
5579def Test_readonly_member_change_in_def_func()
5580 var lines =<< trim END
5581 vim9script
5582 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005583 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005584 endclass
5585 def T()
5586 var a = A.new()
5587 a.val = 20
5588 enddef
5589 T()
5590 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005591 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005592enddef
5593
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005594" Test for reading and writing a class member from a def function
5595def Test_modify_class_member_from_def_function()
5596 var lines =<< trim END
5597 vim9script
5598 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005599 var var1: number = 10
5600 public static var var2: list<number> = [1, 2]
5601 public static var var3: dict<number> = {a: 1, b: 2}
5602 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005603 endclass
5604 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005605 assert_equal([1, 2], A.var2)
5606 assert_equal({a: 1, b: 2}, A.var3)
5607 A.var2 = [3, 4]
5608 A.var3 = {c: 3, d: 4}
5609 assert_equal([3, 4], A.var2)
5610 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005611 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005612 enddef
5613 T()
5614 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005615 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005616enddef
5617
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005618" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005619def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005620 var lines =<< trim END
5621 vim9script
5622 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005623 public static var svar1: list<number> = [1]
5624 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005625 endclass
5626
5627 A.svar1->add(3)
5628 A.svar2->add(4)
5629 assert_equal([1, 3], A.svar1)
5630 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005631
5632 def Foo()
5633 A.svar1->add(7)
5634 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005635 assert_equal([1, 3, 7], A.svar1)
5636 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005637 enddef
5638 Foo()
5639 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005640 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005641
5642 # Cannot read from a class variable using an object in script context
5643 lines =<< trim END
5644 vim9script
5645 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005646 public var var1: number
5647 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005648 endclass
5649
5650 var a = A.new()
5651 echo a.svar2
5652 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005653 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005654
5655 # Cannot write to a class variable using an object in script context
5656 lines =<< trim END
5657 vim9script
5658 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005659 public var var1: number
5660 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005661 endclass
5662
5663 var a = A.new()
5664 a.svar2 = [2]
5665 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005666 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005667
5668 # Cannot read from a class variable using an object in def method context
5669 lines =<< trim END
5670 vim9script
5671 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005672 public var var1: number
5673 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005674 endclass
5675
5676 def T()
5677 var a = A.new()
5678 echo a.svar2
5679 enddef
5680 T()
5681 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005682 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005683
5684 # Cannot write to a class variable using an object in def method context
5685 lines =<< trim END
5686 vim9script
5687 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005688 public var var1: number
5689 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005690 endclass
5691
5692 def T()
5693 var a = A.new()
5694 a.svar2 = [2]
5695 enddef
5696 T()
5697 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005698 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005699enddef
5700
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005701" Test for using a interface method using a child object
5702def Test_interface_method_from_child()
5703 var lines =<< trim END
5704 vim9script
5705
5706 interface A
5707 def Foo(): string
5708 endinterface
5709
5710 class B implements A
5711 def Foo(): string
5712 return 'foo'
5713 enddef
5714 endclass
5715
5716 class C extends B
5717 def Bar(): string
5718 return 'bar'
5719 enddef
5720 endclass
5721
5722 def T1(a: A)
5723 assert_equal('foo', a.Foo())
5724 enddef
5725
5726 def T2(b: B)
5727 assert_equal('foo', b.Foo())
5728 enddef
5729
5730 var c = C.new()
5731 T1(c)
5732 T2(c)
5733 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005734 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005735enddef
5736
5737" Test for using an interface method using a child object when it is overridden
5738" by the child class.
5739" FIXME: This test fails.
5740" def Test_interface_overridden_method_from_child()
5741" var lines =<< trim END
5742" vim9script
5743"
5744" interface A
5745" def Foo(): string
5746" endinterface
5747"
5748" class B implements A
5749" def Foo(): string
5750" return 'b-foo'
5751" enddef
5752" endclass
5753"
5754" class C extends B
5755" def Bar(): string
5756" return 'bar'
5757" enddef
5758" def Foo(): string
5759" return 'c-foo'
5760" enddef
5761" endclass
5762"
5763" def T1(a: A)
5764" assert_equal('c-foo', a.Foo())
5765" enddef
5766"
5767" def T2(b: B)
5768" assert_equal('c-foo', b.Foo())
5769" enddef
5770"
5771" var c = C.new()
5772" T1(c)
5773" T2(c)
5774" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005775" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005776" enddef
5777
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005778" Test for abstract methods
5779def Test_abstract_method()
5780 # Use two abstract methods
5781 var lines =<< trim END
5782 vim9script
5783 abstract class A
5784 def M1(): number
5785 return 10
5786 enddef
5787 abstract def M2(): number
5788 abstract def M3(): number
5789 endclass
5790 class B extends A
5791 def M2(): number
5792 return 20
5793 enddef
5794 def M3(): number
5795 return 30
5796 enddef
5797 endclass
5798 var b = B.new()
5799 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5800 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005801 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005802
5803 # Don't define an abstract method
5804 lines =<< trim END
5805 vim9script
5806 abstract class A
5807 abstract def Foo()
5808 endclass
5809 class B extends A
5810 endclass
5811 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005812 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005813
5814 # Use abstract method in a concrete class
5815 lines =<< trim END
5816 vim9script
5817 class A
5818 abstract def Foo()
5819 endclass
5820 class B extends A
5821 endclass
5822 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005823 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005824
5825 # Use abstract method in an interface
5826 lines =<< trim END
5827 vim9script
5828 interface A
5829 abstract def Foo()
5830 endinterface
5831 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005832 def Foo()
5833 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005834 endclass
5835 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005836 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5837
5838 # Use abstract static method in an interface
5839 lines =<< trim END
5840 vim9script
5841 interface A
5842 abstract static def Foo()
5843 enddef
5844 endinterface
5845 END
5846 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5847
5848 # Use abstract static variable in an interface
5849 lines =<< trim END
5850 vim9script
5851 interface A
5852 abstract static foo: number = 10
5853 endinterface
5854 END
5855 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005856
5857 # Abbreviate the "abstract" keyword
5858 lines =<< trim END
5859 vim9script
5860 class A
5861 abs def Foo()
5862 endclass
5863 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005864 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005865
5866 # Use "abstract" with a member variable
5867 lines =<< trim END
5868 vim9script
5869 abstract class A
5870 abstract this.val = 10
5871 endclass
5872 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005873 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005874
5875 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01005876 lines =<< trim END
5877 vim9script
5878 abstract class A
5879 abstract static def Foo(): number
5880 endclass
5881 END
5882 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005883
5884 # Type mismatch between abstract method and concrete method
5885 lines =<< trim END
5886 vim9script
5887 abstract class A
5888 abstract def Foo(a: string, b: number): list<number>
5889 endclass
5890 class B extends A
5891 def Foo(a: number, b: string): list<string>
5892 return []
5893 enddef
5894 endclass
5895 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005896 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 +02005897
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005898 # Invoke an abstract method from a def function
5899 lines =<< trim END
5900 vim9script
5901 abstract class A
5902 abstract def Foo(): list<number>
5903 endclass
5904 class B extends A
5905 def Foo(): list<number>
5906 return [3, 5]
5907 enddef
5908 endclass
5909 def Bar(c: B)
5910 assert_equal([3, 5], c.Foo())
5911 enddef
5912 var b = B.new()
5913 Bar(b)
5914 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005915 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005916
5917 # Use a static method in an abstract class
5918 lines =<< trim END
5919 vim9script
5920 abstract class A
5921 static def Foo(): string
5922 return 'foo'
5923 enddef
5924 endclass
5925 assert_equal('foo', A.Foo())
5926 END
5927 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005928enddef
5929
5930" Test for calling a class method from a subclass
5931def Test_class_method_call_from_subclass()
5932 # class method call from a subclass
5933 var lines =<< trim END
5934 vim9script
5935
5936 class A
5937 static def Foo()
5938 echo "foo"
5939 enddef
5940 endclass
5941
5942 class B extends A
5943 def Bar()
5944 Foo()
5945 enddef
5946 endclass
5947
5948 var b = B.new()
5949 b.Bar()
5950 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005951 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005952enddef
5953
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005954" Test for calling a class method using an object in a def function context and
5955" script context.
5956def Test_class_method_call_using_object()
5957 # script context
5958 var lines =<< trim END
5959 vim9script
5960 class A
5961 static def Foo(): list<string>
5962 return ['a', 'b']
5963 enddef
5964 def Bar()
5965 assert_equal(['a', 'b'], A.Foo())
5966 assert_equal(['a', 'b'], Foo())
5967 enddef
5968 endclass
5969
5970 def T()
5971 assert_equal(['a', 'b'], A.Foo())
5972 var t_a = A.new()
5973 t_a.Bar()
5974 enddef
5975
5976 assert_equal(['a', 'b'], A.Foo())
5977 var a = A.new()
5978 a.Bar()
5979 T()
5980 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005981 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005982
5983 # script context
5984 lines =<< trim END
5985 vim9script
5986 class A
5987 static def Foo(): string
5988 return 'foo'
5989 enddef
5990 endclass
5991
5992 var a = A.new()
5993 assert_equal('foo', a.Foo())
5994 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005995 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005996
5997 # def function context
5998 lines =<< trim END
5999 vim9script
6000 class A
6001 static def Foo(): string
6002 return 'foo'
6003 enddef
6004 endclass
6005
6006 def T()
6007 var a = A.new()
6008 assert_equal('foo', a.Foo())
6009 enddef
6010 T()
6011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006012 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006013enddef
6014
6015def Test_class_variable()
6016 var lines =<< trim END
6017 vim9script
6018
6019 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006020 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006021 static def ClassFunc()
6022 assert_equal(10, val)
6023 enddef
6024 def ObjFunc()
6025 assert_equal(10, val)
6026 enddef
6027 endclass
6028
6029 class B extends A
6030 endclass
6031
6032 assert_equal(10, A.val)
6033 A.ClassFunc()
6034 var a = A.new()
6035 a.ObjFunc()
6036 var b = B.new()
6037 b.ObjFunc()
6038
6039 def T1(a1: A)
6040 a1.ObjFunc()
6041 A.ClassFunc()
6042 enddef
6043 T1(b)
6044
6045 A.val = 20
6046 assert_equal(20, A.val)
6047 END
6048 v9.CheckSourceSuccess(lines)
6049
6050 # Modifying a parent class variable from a child class method
6051 lines =<< trim END
6052 vim9script
6053
6054 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006055 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006056 endclass
6057
6058 class B extends A
6059 static def ClassFunc()
6060 val = 20
6061 enddef
6062 endclass
6063 B.ClassFunc()
6064 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006065 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006066
6067 # Reading a parent class variable from a child class method
6068 lines =<< trim END
6069 vim9script
6070
6071 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006072 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006073 endclass
6074
6075 class B extends A
6076 static def ClassFunc()
6077 var i = val
6078 enddef
6079 endclass
6080 B.ClassFunc()
6081 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006082 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006083
6084 # Modifying a parent class variable from a child object method
6085 lines =<< trim END
6086 vim9script
6087
6088 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006089 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006090 endclass
6091
6092 class B extends A
6093 def ObjFunc()
6094 val = 20
6095 enddef
6096 endclass
6097 var b = B.new()
6098 b.ObjFunc()
6099 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006100 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006101
6102 # Reading a parent class variable from a child object method
6103 lines =<< trim END
6104 vim9script
6105
6106 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006107 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006108 endclass
6109
6110 class B extends A
6111 def ObjFunc()
6112 var i = val
6113 enddef
6114 endclass
6115 var b = B.new()
6116 b.ObjFunc()
6117 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006118 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006119
6120 # Modifying a class variable using an object at script level
6121 lines =<< trim END
6122 vim9script
6123
6124 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006125 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006126 endclass
6127 var a = A.new()
6128 a.val = 20
6129 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006130 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006131
6132 # Reading a class variable using an object at script level
6133 lines =<< trim END
6134 vim9script
6135
6136 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006137 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006138 endclass
6139 var a = A.new()
6140 var i = a.val
6141 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006142 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006143
6144 # Modifying a class variable using an object at function level
6145 lines =<< trim END
6146 vim9script
6147
6148 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006149 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006150 endclass
6151
6152 def T()
6153 var a = A.new()
6154 a.val = 20
6155 enddef
6156 T()
6157 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006158 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006159
6160 # Reading a class variable using an object at function level
6161 lines =<< trim END
6162 vim9script
6163
6164 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006165 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006166 endclass
6167 def T()
6168 var a = A.new()
6169 var i = a.val
6170 enddef
6171 T()
6172 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006173 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006174
6175 # Use old implicit var declaration syntax (without initialization)
6176 lines =<< trim END
6177 vim9script
6178
6179 class A
6180 static val: number
6181 endclass
6182 END
6183 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6184
6185 # Use old implicit var declaration syntax (with initialization)
6186 lines =<< trim END
6187 vim9script
6188
6189 class A
6190 static val: number = 10
6191 endclass
6192 END
6193 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6194
6195 # Use old implicit var declaration syntax (type inferred)
6196 lines =<< trim END
6197 vim9script
6198
6199 class A
6200 static val = 10
6201 endclass
6202 END
6203 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6204
6205 # Missing ":var" in "var" class variable declaration (without initialization)
6206 lines =<< trim END
6207 vim9script
6208
6209 class A
6210 static var: number
6211 endclass
6212 END
6213 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6214
6215 # Missing ":var" in "var" class variable declaration (with initialization)
6216 lines =<< trim END
6217 vim9script
6218
6219 class A
6220 static var: number = 10
6221 endclass
6222 END
6223 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6224
6225 # Missing ":var" in "var" class variable declaration (type inferred)
6226 lines =<< trim END
6227 vim9script
6228
6229 class A
6230 static var = 10
6231 endclass
6232 END
6233 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6234
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006235enddef
6236
6237" Test for using a duplicate class method and class variable in a child class
6238def Test_dup_class_member()
6239 # duplicate class variable, class method and overridden object method
6240 var lines =<< trim END
6241 vim9script
6242 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006243 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006244 static def Check()
6245 assert_equal(100, sval)
6246 enddef
6247 def GetVal(): number
6248 return sval
6249 enddef
6250 endclass
6251
6252 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006253 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006254 static def Check()
6255 assert_equal(200, sval)
6256 enddef
6257 def GetVal(): number
6258 return sval
6259 enddef
6260 endclass
6261
6262 def T1(aa: A): number
6263 return aa.GetVal()
6264 enddef
6265
6266 def T2(bb: B): number
6267 return bb.GetVal()
6268 enddef
6269
6270 assert_equal(100, A.sval)
6271 assert_equal(200, B.sval)
6272 var a = A.new()
6273 assert_equal(100, a.GetVal())
6274 var b = B.new()
6275 assert_equal(200, b.GetVal())
6276 assert_equal(200, T1(b))
6277 assert_equal(200, T2(b))
6278 END
6279 v9.CheckSourceSuccess(lines)
6280
6281 # duplicate class variable and class method
6282 lines =<< trim END
6283 vim9script
6284 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006285 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006286 static def Check()
6287 assert_equal(100, sval)
6288 enddef
6289 def GetVal(): number
6290 return sval
6291 enddef
6292 endclass
6293
6294 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006295 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006296 static def Check()
6297 assert_equal(200, sval)
6298 enddef
6299 endclass
6300
6301 def T1(aa: A): number
6302 return aa.GetVal()
6303 enddef
6304
6305 def T2(bb: B): number
6306 return bb.GetVal()
6307 enddef
6308
6309 assert_equal(100, A.sval)
6310 assert_equal(200, B.sval)
6311 var a = A.new()
6312 assert_equal(100, a.GetVal())
6313 var b = B.new()
6314 assert_equal(100, b.GetVal())
6315 assert_equal(100, T1(b))
6316 assert_equal(100, T2(b))
6317 END
6318 v9.CheckSourceSuccess(lines)
6319enddef
6320
6321" Test for calling an instance method using the class
6322def Test_instance_method_call_using_class()
6323 # Invoke an object method using a class in script context
6324 var lines =<< trim END
6325 vim9script
6326 class A
6327 def Foo()
6328 echo "foo"
6329 enddef
6330 endclass
6331 A.Foo()
6332 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006333 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006334
6335 # Invoke an object method using a class in def function context
6336 lines =<< trim END
6337 vim9script
6338 class A
6339 def Foo()
6340 echo "foo"
6341 enddef
6342 endclass
6343 def T()
6344 A.Foo()
6345 enddef
6346 T()
6347 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006348 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006349enddef
6350
6351" Test for duplicate class method and instance method
6352def Test_dup_classmethod_objmethod()
6353 # Duplicate instance method
6354 var lines =<< trim END
6355 vim9script
6356 class A
6357 static def Foo()
6358 enddef
6359 def Foo()
6360 enddef
6361 endclass
6362 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006363 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006364
Ernie Rael03042a22023-11-11 08:53:32 +01006365 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006366 lines =<< trim END
6367 vim9script
6368 class A
6369 static def Foo()
6370 enddef
6371 def _Foo()
6372 enddef
6373 endclass
6374 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006375 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006376
6377 # Duplicate class method
6378 lines =<< trim END
6379 vim9script
6380 class A
6381 def Foo()
6382 enddef
6383 static def Foo()
6384 enddef
6385 endclass
6386 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006387 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006388
Ernie Rael03042a22023-11-11 08:53:32 +01006389 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006390 lines =<< trim END
6391 vim9script
6392 class A
6393 def Foo()
6394 enddef
6395 static def _Foo()
6396 enddef
6397 endclass
6398 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006399 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006400
Ernie Rael03042a22023-11-11 08:53:32 +01006401 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006402 lines =<< trim END
6403 vim9script
6404 class A
6405 def _Foo()
6406 enddef
6407 static def _Foo()
6408 enddef
6409 endclass
6410 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006411 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006412enddef
6413
6414" Test for an instance method access level comparison with parent instance
6415" methods.
6416def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006417 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006418 var lines =<< trim END
6419 vim9script
6420 class A
6421 def Foo()
6422 enddef
6423 endclass
6424 class B extends A
6425 endclass
6426 class C extends B
6427 def _Foo()
6428 enddef
6429 endclass
6430 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006431 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006432
6433 # Public method in subclass
6434 lines =<< trim END
6435 vim9script
6436 class A
6437 def _Foo()
6438 enddef
6439 endclass
6440 class B extends A
6441 endclass
6442 class C extends B
6443 def Foo()
6444 enddef
6445 endclass
6446 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006447 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006448enddef
6449
6450def Test_extend_empty_class()
6451 var lines =<< trim END
6452 vim9script
6453 class A
6454 endclass
6455 class B extends A
6456 endclass
6457 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006458 public static var rw_class_var = 1
6459 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006460 static def ClassMethod(): number
6461 return 3
6462 enddef
6463 def ObjMethod(): number
6464 return 4
6465 enddef
6466 endclass
6467 assert_equal(1, C.rw_class_var)
6468 assert_equal(3, C.ClassMethod())
6469 var c = C.new()
6470 assert_equal(2, c.rw_obj_var)
6471 assert_equal(4, c.ObjMethod())
6472 END
6473 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006474enddef
6475
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006476" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006477" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006478def Test_interface_with_unsupported_members()
6479 var lines =<< trim END
6480 vim9script
6481 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006482 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006483 endinterface
6484 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006485 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006486
6487 lines =<< trim END
6488 vim9script
6489 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006490 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006491 endinterface
6492 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006493 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006494
6495 lines =<< trim END
6496 vim9script
6497 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006498 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006499 endinterface
6500 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006501 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006502
6503 lines =<< trim END
6504 vim9script
6505 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006506 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006507 endinterface
6508 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006509 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006510
6511 lines =<< trim END
6512 vim9script
6513 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006514 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006515 endinterface
6516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006517 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006518
6519 lines =<< trim END
6520 vim9script
6521 interface A
6522 static def Foo(d: dict<any>): list<string>
6523 endinterface
6524 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006525 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006526
6527 lines =<< trim END
6528 vim9script
6529 interface A
6530 static def _Foo(d: dict<any>): list<string>
6531 endinterface
6532 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006533 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006534
6535 lines =<< trim END
6536 vim9script
6537 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006538 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006539 endinterface
6540 END
Ernie Rael03042a22023-11-11 08:53:32 +01006541 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006542
6543 lines =<< trim END
6544 vim9script
6545 interface A
6546 def _Foo(d: dict<any>): list<string>
6547 endinterface
6548 END
Ernie Rael03042a22023-11-11 08:53:32 +01006549 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006550enddef
6551
6552" Test for extending an interface
6553def Test_extend_interface()
6554 var lines =<< trim END
6555 vim9script
6556 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006557 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006558 def Foo()
6559 endinterface
6560 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006561 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006562 def Bar()
6563 endinterface
6564 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006565 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006566 def Foo()
6567 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006568 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006569 def Bar()
6570 enddef
6571 endclass
6572 END
6573 v9.CheckSourceSuccess(lines)
6574
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006575 # extending empty interface
6576 lines =<< trim END
6577 vim9script
6578 interface A
6579 endinterface
6580 interface B extends A
6581 endinterface
6582 class C implements B
6583 endclass
6584 END
6585 v9.CheckSourceSuccess(lines)
6586
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006587 lines =<< trim END
6588 vim9script
6589 interface A
6590 def Foo()
6591 endinterface
6592 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006593 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006594 endinterface
6595 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006596 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006597 endclass
6598 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006599 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006600
6601 lines =<< trim END
6602 vim9script
6603 interface A
6604 def Foo()
6605 endinterface
6606 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006607 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006608 endinterface
6609 class C implements A, B
6610 def Foo()
6611 enddef
6612 endclass
6613 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006614 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006615
6616 # interface cannot extend a class
6617 lines =<< trim END
6618 vim9script
6619 class A
6620 endclass
6621 interface B extends A
6622 endinterface
6623 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006624 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006625
6626 # class cannot extend an interface
6627 lines =<< trim END
6628 vim9script
6629 interface A
6630 endinterface
6631 class B extends A
6632 endclass
6633 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006634 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006635
6636 # interface cannot implement another interface
6637 lines =<< trim END
6638 vim9script
6639 interface A
6640 endinterface
6641 interface B implements A
6642 endinterface
6643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006644 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006645
6646 # interface cannot extend multiple interfaces
6647 lines =<< trim END
6648 vim9script
6649 interface A
6650 endinterface
6651 interface B
6652 endinterface
6653 interface C extends A, B
6654 endinterface
6655 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006656 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006657
6658 # Variable type in an extended interface is of different type
6659 lines =<< trim END
6660 vim9script
6661 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006662 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006663 endinterface
6664 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006665 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006666 endinterface
6667 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006668 var val1: string
6669 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006670 endinterface
6671 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006672 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006673enddef
6674
6675" Test for a child class implementing an interface when some of the methods are
6676" defined in the parent class.
6677def Test_child_class_implements_interface()
6678 var lines =<< trim END
6679 vim9script
6680
6681 interface Intf
6682 def F1(): list<list<number>>
6683 def F2(): list<list<number>>
6684 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006685 var var1: list<dict<number>>
6686 var var2: list<dict<number>>
6687 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006688 endinterface
6689
6690 class A
6691 def A1()
6692 enddef
6693 def F3(): list<list<number>>
6694 return [[3]]
6695 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006696 var v1: list<list<number>> = [[0]]
6697 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006698 endclass
6699
6700 class B extends A
6701 def B1()
6702 enddef
6703 def F2(): list<list<number>>
6704 return [[2]]
6705 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006706 var v2: list<list<number>> = [[0]]
6707 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006708 endclass
6709
6710 class C extends B implements Intf
6711 def C1()
6712 enddef
6713 def F1(): list<list<number>>
6714 return [[1]]
6715 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006716 var v3: list<list<number>> = [[0]]
6717 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006718 endclass
6719
6720 def T(if: Intf)
6721 assert_equal([[1]], if.F1())
6722 assert_equal([[2]], if.F2())
6723 assert_equal([[3]], if.F3())
6724 assert_equal([{a: 10}], if.var1)
6725 assert_equal([{b: 20}], if.var2)
6726 assert_equal([{c: 30}], if.var3)
6727 enddef
6728
6729 var c = C.new()
6730 T(c)
6731 assert_equal([[1]], c.F1())
6732 assert_equal([[2]], c.F2())
6733 assert_equal([[3]], c.F3())
6734 assert_equal([{a: 10}], c.var1)
6735 assert_equal([{b: 20}], c.var2)
6736 assert_equal([{c: 30}], c.var3)
6737 END
6738 v9.CheckSourceSuccess(lines)
6739
6740 # One of the interface methods is not found
6741 lines =<< trim END
6742 vim9script
6743
6744 interface Intf
6745 def F1()
6746 def F2()
6747 def F3()
6748 endinterface
6749
6750 class A
6751 def A1()
6752 enddef
6753 endclass
6754
6755 class B extends A
6756 def B1()
6757 enddef
6758 def F2()
6759 enddef
6760 endclass
6761
6762 class C extends B implements Intf
6763 def C1()
6764 enddef
6765 def F1()
6766 enddef
6767 endclass
6768 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006769 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006770
6771 # One of the interface methods is of different type
6772 lines =<< trim END
6773 vim9script
6774
6775 interface Intf
6776 def F1()
6777 def F2()
6778 def F3()
6779 endinterface
6780
6781 class A
6782 def F3(): number
6783 return 0
6784 enddef
6785 def A1()
6786 enddef
6787 endclass
6788
6789 class B extends A
6790 def B1()
6791 enddef
6792 def F2()
6793 enddef
6794 endclass
6795
6796 class C extends B implements Intf
6797 def C1()
6798 enddef
6799 def F1()
6800 enddef
6801 endclass
6802 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006803 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006804
6805 # One of the interface variables is not present
6806 lines =<< trim END
6807 vim9script
6808
6809 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006810 var var1: list<dict<number>>
6811 var var2: list<dict<number>>
6812 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006813 endinterface
6814
6815 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006816 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006817 endclass
6818
6819 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006820 var v2: list<list<number>> = [[0]]
6821 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006822 endclass
6823
6824 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006825 var v3: list<list<number>> = [[0]]
6826 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006827 endclass
6828 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006829 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006830
6831 # One of the interface variables is of different type
6832 lines =<< trim END
6833 vim9script
6834
6835 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006836 var var1: list<dict<number>>
6837 var var2: list<dict<number>>
6838 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006839 endinterface
6840
6841 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006842 var v1: list<list<number>> = [[0]]
6843 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006844 endclass
6845
6846 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006847 var v2: list<list<number>> = [[0]]
6848 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006849 endclass
6850
6851 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006852 var v3: list<list<number>> = [[0]]
6853 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006854 endclass
6855 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006856 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 +02006857enddef
6858
6859" Test for extending an interface with duplicate variables and methods
6860def Test_interface_extends_with_dup_members()
6861 var lines =<< trim END
6862 vim9script
6863 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006864 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006865 def Foo1(): number
6866 endinterface
6867 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006868 var n2: number
6869 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006870 def Foo2(): number
6871 def Foo1(): number
6872 endinterface
6873 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006874 var n1 = 10
6875 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006876 def Foo1(): number
6877 return 30
6878 enddef
6879 def Foo2(): number
6880 return 40
6881 enddef
6882 endclass
6883 def T1(a: A)
6884 assert_equal(10, a.n1)
6885 assert_equal(30, a.Foo1())
6886 enddef
6887 def T2(b: B)
6888 assert_equal(10, b.n1)
6889 assert_equal(20, b.n2)
6890 assert_equal(30, b.Foo1())
6891 assert_equal(40, b.Foo2())
6892 enddef
6893 var c = C.new()
6894 T1(c)
6895 T2(c)
6896 END
6897 v9.CheckSourceSuccess(lines)
6898enddef
6899
6900" Test for using "any" type for a variable in a sub-class while it has a
6901" concrete type in the interface
6902def Test_implements_using_var_type_any()
6903 var lines =<< trim END
6904 vim9script
6905 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006906 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006907 endinterface
6908 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006909 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006910 endclass
6911 var b = B.new()
6912 assert_equal([{a: '1'}, {b: '2'}], b.val)
6913 END
6914 v9.CheckSourceSuccess(lines)
6915
6916 # initialize instance variable using a different type
6917 lines =<< trim END
6918 vim9script
6919 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006920 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006921 endinterface
6922 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006923 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006924 endclass
6925 var b = B.new()
6926 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006927 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006928enddef
6929
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006930" Test for assigning to a member variable in a nested class
6931def Test_nested_object_assignment()
6932 var lines =<< trim END
6933 vim9script
6934
6935 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006936 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006937 endclass
6938
6939 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006940 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006941 endclass
6942
6943 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01006944 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006945 endclass
6946
6947 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01006948 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006949 endclass
6950
6951 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006952 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006953 enddef
6954
6955 var d = D.new()
6956 T(d)
6957 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006958 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006959enddef
6960
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006961" Test for calling methods using a null object
6962def Test_null_object_method_call()
6963 # Calling a object method using a null object in script context
6964 var lines =<< trim END
6965 vim9script
6966
6967 class C
6968 def Foo()
6969 assert_report('This method should not be executed')
6970 enddef
6971 endclass
6972
6973 var o: C
6974 o.Foo()
6975 END
6976 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6977
6978 # Calling a object method using a null object in def function context
6979 lines =<< trim END
6980 vim9script
6981
6982 class C
6983 def Foo()
6984 assert_report('This method should not be executed')
6985 enddef
6986 endclass
6987
6988 def T()
6989 var o: C
6990 o.Foo()
6991 enddef
6992 T()
6993 END
6994 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6995
6996 # Calling a object method through another class method using a null object in
6997 # script context
6998 lines =<< trim END
6999 vim9script
7000
7001 class C
7002 def Foo()
7003 assert_report('This method should not be executed')
7004 enddef
7005
7006 static def Bar(o_any: any)
7007 var o_typed: C = o_any
7008 o_typed.Foo()
7009 enddef
7010 endclass
7011
7012 var o: C
7013 C.Bar(o)
7014 END
7015 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7016
7017 # Calling a object method through another class method using a null object in
7018 # def function context
7019 lines =<< trim END
7020 vim9script
7021
7022 class C
7023 def Foo()
7024 assert_report('This method should not be executed')
7025 enddef
7026
7027 static def Bar(o_any: any)
7028 var o_typed: C = o_any
7029 o_typed.Foo()
7030 enddef
7031 endclass
7032
7033 def T()
7034 var o: C
7035 C.Bar(o)
7036 enddef
7037 T()
7038 END
7039 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7040enddef
7041
7042" Test for using a dict as an object member
7043def Test_dict_object_member()
7044 var lines =<< trim END
7045 vim9script
7046
7047 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007048 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007049 def GetState(): dict<number>
7050 return this.state
7051 enddef
7052 endclass
7053
7054 var ctx = Context.new()
7055 ctx.state->extend({a: 1})
7056 ctx.state['b'] = 2
7057 assert_equal({a: 1, b: 2}, ctx.GetState())
7058
7059 def F()
7060 ctx.state['c'] = 3
7061 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7062 enddef
7063 F()
7064 assert_equal(3, ctx.state.c)
7065 ctx.state.c = 4
7066 assert_equal(4, ctx.state.c)
7067 END
7068 v9.CheckSourceSuccess(lines)
7069enddef
7070
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007071" The following test was failing after 9.0.1914. This was caused by using a
7072" freed object from a previous method call.
7073def Test_freed_object_from_previous_method_call()
7074 var lines =<< trim END
7075 vim9script
7076
7077 class Context
7078 endclass
7079
7080 class Result
7081 endclass
7082
7083 def Failure(): Result
7084 return Result.new()
7085 enddef
7086
7087 def GetResult(ctx: Context): Result
7088 return Failure()
7089 enddef
7090
7091 def Test_GetResult()
7092 var ctx = Context.new()
7093 var result = GetResult(ctx)
7094 enddef
7095
7096 Test_GetResult()
7097 END
7098 v9.CheckSourceSuccess(lines)
7099enddef
7100
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007101" Test for duplicate object and class variable
7102def Test_duplicate_variable()
7103 # Object variable name is same as the class variable name
7104 var lines =<< trim END
7105 vim9script
7106 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007107 public static var sval: number
7108 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007109 endclass
7110 var a = A.new()
7111 END
7112 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7113
7114 # Duplicate variable name and calling a class method
7115 lines =<< trim END
7116 vim9script
7117 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007118 public static var sval: number
7119 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007120 def F1()
7121 echo this.sval
7122 enddef
7123 static def F2()
7124 echo sval
7125 enddef
7126 endclass
7127 A.F2()
7128 END
7129 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7130
7131 # Duplicate variable with an empty constructor
7132 lines =<< trim END
7133 vim9script
7134 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007135 public static var sval: number
7136 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007137 def new()
7138 enddef
7139 endclass
7140 var a = A.new()
7141 END
7142 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7143enddef
7144
7145" Test for using a reserved keyword as a variable name
7146def Test_reserved_varname()
7147 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7148 'null_function', 'null_list', 'null_partial', 'null_string',
7149 'null_channel', 'null_job', 'super', 'this']
7150
7151 var lines =<< trim eval END
7152 vim9script
7153 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007154 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007155 endclass
7156 var o = C.new()
7157 END
7158 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7159
7160 lines =<< trim eval END
7161 vim9script
7162 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007163 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007164 def new()
7165 enddef
7166 endclass
7167 var o = C.new()
7168 END
7169 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7170
7171 lines =<< trim eval END
7172 vim9script
7173 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007174 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007175 def new()
7176 enddef
7177 def F()
7178 echo this.{kword}
7179 enddef
7180 endclass
7181 var o = C.new()
7182 o.F()
7183 END
7184 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007185
7186 # class variable name
7187 if kword != 'this'
7188 lines =<< trim eval END
7189 vim9script
7190 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007191 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007192 endclass
7193 END
7194 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7195 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007196 endfor
7197enddef
7198
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007199" Test for checking the type of the arguments and the return value of a object
7200" method in an extended class.
7201def Test_extended_obj_method_type_check()
7202 var lines =<< trim END
7203 vim9script
7204
7205 class A
7206 endclass
7207 class B extends A
7208 endclass
7209 class C extends B
7210 endclass
7211
7212 class Foo
7213 def Doit(p: B): B
7214 return B.new()
7215 enddef
7216 endclass
7217
7218 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007219 def Doit(p: C): B
7220 return B.new()
7221 enddef
7222 endclass
7223 END
7224 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7225
7226 lines =<< trim END
7227 vim9script
7228
7229 class A
7230 endclass
7231 class B extends A
7232 endclass
7233 class C extends B
7234 endclass
7235
7236 class Foo
7237 def Doit(p: B): B
7238 return B.new()
7239 enddef
7240 endclass
7241
7242 class Bar extends Foo
7243 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007244 return C.new()
7245 enddef
7246 endclass
7247 END
7248 v9.CheckSourceSuccess(lines)
7249
7250 lines =<< trim END
7251 vim9script
7252
7253 class A
7254 endclass
7255 class B extends A
7256 endclass
7257 class C extends B
7258 endclass
7259
7260 class Foo
7261 def Doit(p: B): B
7262 return B.new()
7263 enddef
7264 endclass
7265
7266 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007267 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007268 return B.new()
7269 enddef
7270 endclass
7271 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007272 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 +02007273
7274 lines =<< trim END
7275 vim9script
7276
7277 class A
7278 endclass
7279 class B extends A
7280 endclass
7281 class C extends B
7282 endclass
7283
7284 class Foo
7285 def Doit(p: B): B
7286 return B.new()
7287 enddef
7288 endclass
7289
7290 class Bar extends Foo
7291 def Doit(p: B): A
7292 return A.new()
7293 enddef
7294 endclass
7295 END
7296 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 +02007297
7298 # check varargs type mismatch
7299 lines =<< trim END
7300 vim9script
7301
7302 class B
7303 def F(...xxx: list<any>)
7304 enddef
7305 endclass
7306 class C extends B
7307 def F(xxx: list<any>)
7308 enddef
7309 endclass
7310 END
7311 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 +02007312enddef
7313
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007314" Test type checking for class variable in assignments
7315func Test_class_variable_complex_type_check()
7316 " class variable with a specific type. Try assigning a different type at
7317 " script level.
7318 let lines =<< trim END
7319 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007320 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007321 return {}
7322 enddef
7323 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007324 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007325 endclass
7326 test_garbagecollect_now()
7327 A.Fn = "abc"
7328 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007329 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 +02007330
7331 " class variable with a specific type. Try assigning a different type at
7332 " class def method level.
7333 let lines =<< trim END
7334 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007335 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007336 return {}
7337 enddef
7338 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007339 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007340 def Bar()
7341 Fn = "abc"
7342 enddef
7343 endclass
7344 var a = A.new()
7345 test_garbagecollect_now()
7346 a.Bar()
7347 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007348 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 +02007349
7350 " class variable with a specific type. Try assigning a different type at
7351 " script def method level.
7352 let lines =<< trim END
7353 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007354 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007355 return {}
7356 enddef
7357 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007358 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007359 endclass
7360 def Bar()
7361 A.Fn = "abc"
7362 enddef
7363 test_garbagecollect_now()
7364 Bar()
7365 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007366 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 +02007367
7368 " class variable without any type. Should be set to the initialization
7369 " expression type. Try assigning a different type from script level.
7370 let lines =<< trim END
7371 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007372 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007373 return {}
7374 enddef
7375 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007376 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007377 endclass
7378 test_garbagecollect_now()
7379 A.Fn = "abc"
7380 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007381 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 +02007382
7383 " class variable without any type. Should be set to the initialization
7384 " expression type. Try assigning a different type at class def level.
7385 let lines =<< trim END
7386 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007387 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007388 return {}
7389 enddef
7390 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007391 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007392 def Bar()
7393 Fn = "abc"
7394 enddef
7395 endclass
7396 var a = A.new()
7397 test_garbagecollect_now()
7398 a.Bar()
7399 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007400 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 +02007401
7402 " class variable without any type. Should be set to the initialization
7403 " expression type. Try assigning a different type at script def level.
7404 let lines =<< trim END
7405 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007406 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007407 return {}
7408 enddef
7409 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007410 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007411 endclass
7412 def Bar()
7413 A.Fn = "abc"
7414 enddef
7415 test_garbagecollect_now()
7416 Bar()
7417 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007418 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 +02007419
7420 " class variable with 'any" type. Can be assigned different types.
7421 let lines =<< trim END
7422 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007423 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007424 return {}
7425 enddef
7426 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007427 public static var Fn: any = Foo
7428 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007429 endclass
7430 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007431 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007432 A.Fn = "abc"
7433 test_garbagecollect_now()
7434 assert_equal('string', typename(A.Fn))
7435 A.Fn2 = Foo
7436 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007437 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007438 A.Fn2 = "xyz"
7439 test_garbagecollect_now()
7440 assert_equal('string', typename(A.Fn2))
7441 END
7442 call v9.CheckSourceSuccess(lines)
7443
7444 " class variable with 'any" type. Can be assigned different types.
7445 let lines =<< trim END
7446 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007447 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007448 return {}
7449 enddef
7450 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007451 public static var Fn: any = Foo
7452 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007453
7454 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007455 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007456 Fn = "abc"
7457 assert_equal('string', typename(Fn))
7458 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007459 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007460 Fn2 = "xyz"
7461 assert_equal('string', typename(Fn2))
7462 enddef
7463 endclass
7464 var a = A.new()
7465 test_garbagecollect_now()
7466 a.Bar()
7467 test_garbagecollect_now()
7468 A.Fn = Foo
7469 a.Bar()
7470 END
7471 call v9.CheckSourceSuccess(lines)
7472
7473 " class variable with 'any" type. Can be assigned different types.
7474 let lines =<< trim END
7475 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007476 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007477 return {}
7478 enddef
7479 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007480 public static var Fn: any = Foo
7481 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007482 endclass
7483
7484 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007485 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007486 A.Fn = "abc"
7487 assert_equal('string', typename(A.Fn))
7488 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007489 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007490 A.Fn2 = "xyz"
7491 assert_equal('string', typename(A.Fn2))
7492 enddef
7493 Bar()
7494 test_garbagecollect_now()
7495 A.Fn = Foo
7496 Bar()
7497 END
7498 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007499
7500 let lines =<< trim END
7501 vim9script
7502 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007503 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007504 endclass
7505 assert_equal([0z10, 0z20], A.foo)
7506 A.foo = [0z30]
7507 assert_equal([0z30], A.foo)
7508 var a = A.foo
7509 assert_equal([0z30], a)
7510 END
7511 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007512endfunc
7513
7514" Test type checking for object variable in assignments
7515func Test_object_variable_complex_type_check()
7516 " object variable with a specific type. Try assigning a different type at
7517 " script level.
7518 let lines =<< trim END
7519 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007520 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007521 return {}
7522 enddef
7523 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007524 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007525 endclass
7526 var a = A.new()
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', 10)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007531
7532 " object variable with a specific type. Try assigning a different type at
7533 " object def method 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 var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007541 def Bar()
7542 this.Fn = "abc"
7543 this.Fn = Foo
7544 enddef
7545 endclass
7546 var a = A.new()
7547 test_garbagecollect_now()
7548 a.Bar()
7549 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007550 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 +02007551
7552 " object variable with a specific type. Try assigning a different type at
7553 " script def method level.
7554 let lines =<< trim END
7555 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007556 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007557 return {}
7558 enddef
7559 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007560 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007561 endclass
7562 def Bar()
7563 var a = A.new()
7564 a.Fn = "abc"
7565 a.Fn = Foo
7566 enddef
7567 test_garbagecollect_now()
7568 Bar()
7569 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007570 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 +02007571
7572 " object variable without any type. Should be set to the initialization
7573 " expression type. Try assigning a different type from script level.
7574 let lines =<< trim END
7575 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007576 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007577 return {}
7578 enddef
7579 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007580 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007581 endclass
7582 var a = A.new()
7583 test_garbagecollect_now()
7584 a.Fn = "abc"
7585 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007586 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 +02007587
7588 " object variable without any type. Should be set to the initialization
7589 " expression type. Try assigning a different type at object def level.
7590 let lines =<< trim END
7591 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007592 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007593 return {}
7594 enddef
7595 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007596 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007597 def Bar()
7598 this.Fn = "abc"
7599 this.Fn = Foo
7600 enddef
7601 endclass
7602 var a = A.new()
7603 test_garbagecollect_now()
7604 a.Bar()
7605 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007606 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 +02007607
7608 " object variable without any type. Should be set to the initialization
7609 " expression type. Try assigning a different type at script def level.
7610 let lines =<< trim END
7611 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007612 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007613 return {}
7614 enddef
7615 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007616 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007617 endclass
7618 def Bar()
7619 var a = A.new()
7620 a.Fn = "abc"
7621 a.Fn = Foo
7622 enddef
7623 test_garbagecollect_now()
7624 Bar()
7625 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007626 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 2)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007627
7628 " object variable with 'any" type. Can be assigned different types.
7629 let lines =<< trim END
7630 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007631 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007632 return {}
7633 enddef
7634 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007635 public var Fn: any = Foo
7636 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007637 endclass
7638
7639 var a = A.new()
7640 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007641 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007642 a.Fn = "abc"
7643 test_garbagecollect_now()
7644 assert_equal('string', typename(a.Fn))
7645 a.Fn2 = Foo
7646 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007647 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007648 a.Fn2 = "xyz"
7649 test_garbagecollect_now()
7650 assert_equal('string', typename(a.Fn2))
7651 END
7652 call v9.CheckSourceSuccess(lines)
7653
7654 " object variable with 'any" type. Can be assigned different types.
7655 let lines =<< trim END
7656 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007657 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007658 return {}
7659 enddef
7660 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007661 public var Fn: any = Foo
7662 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007663
7664 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007665 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007666 this.Fn = "abc"
7667 assert_equal('string', typename(this.Fn))
7668 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007669 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007670 this.Fn2 = "xyz"
7671 assert_equal('string', typename(this.Fn2))
7672 enddef
7673 endclass
7674
7675 var a = A.new()
7676 test_garbagecollect_now()
7677 a.Bar()
7678 test_garbagecollect_now()
7679 a.Fn = Foo
7680 a.Bar()
7681 END
7682 call v9.CheckSourceSuccess(lines)
7683
7684 " object variable with 'any" type. Can be assigned different types.
7685 let lines =<< trim END
7686 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007687 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007688 return {}
7689 enddef
7690 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007691 public var Fn: any = Foo
7692 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007693 endclass
7694
7695 def Bar()
7696 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007697 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007698 a.Fn = "abc"
7699 assert_equal('string', typename(a.Fn))
7700 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007701 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007702 a.Fn2 = "xyz"
7703 assert_equal('string', typename(a.Fn2))
7704 enddef
7705 test_garbagecollect_now()
7706 Bar()
7707 test_garbagecollect_now()
7708 Bar()
7709 END
7710 call v9.CheckSourceSuccess(lines)
7711endfunc
7712
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007713" Test for recursively calling an object method. This used to cause an
7714" use-after-free error.
7715def Test_recursive_object_method_call()
7716 var lines =<< trim END
7717 vim9script
7718 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007719 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007720 def Foo(): number
7721 if this.val >= 90
7722 return this.val
7723 endif
7724 this.val += 1
7725 return this.Foo()
7726 enddef
7727 endclass
7728 var a = A.new()
7729 assert_equal(90, a.Foo())
7730 END
7731 v9.CheckSourceSuccess(lines)
7732enddef
7733
7734" Test for recursively calling a class method.
7735def Test_recursive_class_method_call()
7736 var lines =<< trim END
7737 vim9script
7738 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007739 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007740 static def Foo(): number
7741 if val >= 90
7742 return val
7743 endif
7744 val += 1
7745 return Foo()
7746 enddef
7747 endclass
7748 assert_equal(90, A.Foo())
7749 END
7750 v9.CheckSourceSuccess(lines)
7751enddef
7752
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007753" Test for checking the argument types and the return type when assigning a
7754" funcref to make sure the invariant class type is used.
7755def Test_funcref_argtype_returntype_check()
7756 var lines =<< trim END
7757 vim9script
7758 class A
7759 endclass
7760 class B extends A
7761 endclass
7762
7763 def Foo(p: B): B
7764 return B.new()
7765 enddef
7766
7767 var Bar: func(A): A = Foo
7768 END
7769 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7770
7771 lines =<< trim END
7772 vim9script
7773 class A
7774 endclass
7775 class B extends A
7776 endclass
7777
7778 def Foo(p: B): B
7779 return B.new()
7780 enddef
7781
7782 def Baz()
7783 var Bar: func(A): A = Foo
7784 enddef
7785 Baz()
7786 END
7787 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7788enddef
7789
Ernie Rael96952b22023-10-17 18:15:01 +02007790def Test_funcref_argtype_invariance_check()
7791 var lines =<< trim END
7792 vim9script
7793
7794 class A
7795 endclass
7796 class B extends A
7797 endclass
7798 class C extends B
7799 endclass
7800
7801 var Func: func(B): number
7802 Func = (o: B): number => 3
7803 assert_equal(3, Func(B.new()))
7804 END
7805 v9.CheckSourceSuccess(lines)
7806
7807 lines =<< trim END
7808 vim9script
7809
7810 class A
7811 endclass
7812 class B extends A
7813 endclass
7814 class C extends B
7815 endclass
7816
7817 var Func: func(B): number
7818 Func = (o: A): number => 3
7819 END
7820 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7821
7822 lines =<< trim END
7823 vim9script
7824
7825 class A
7826 endclass
7827 class B extends A
7828 endclass
7829 class C extends B
7830 endclass
7831
7832 var Func: func(B): number
7833 Func = (o: C): number => 3
7834 END
7835 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7836enddef
7837
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007838" Test for using an operator (e.g. +) with an assignment
7839def Test_op_and_assignment()
7840 # Using += with a class variable
7841 var lines =<< trim END
7842 vim9script
7843 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007844 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007845 static def Foo(): list<number>
7846 val += [1]
7847 return val
7848 enddef
7849 endclass
7850 def Bar(): list<number>
7851 A.val += [2]
7852 return A.val
7853 enddef
7854 assert_equal([1], A.Foo())
7855 assert_equal([1, 2], Bar())
7856 A.val += [3]
7857 assert_equal([1, 2, 3], A.val)
7858 END
7859 v9.CheckSourceSuccess(lines)
7860
7861 # Using += with an object variable
7862 lines =<< trim END
7863 vim9script
7864 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007865 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007866 def Foo(): list<number>
7867 this.val += [1]
7868 return this.val
7869 enddef
7870 endclass
7871 def Bar(bar_a: A): list<number>
7872 bar_a.val += [2]
7873 return bar_a.val
7874 enddef
7875 var a = A.new()
7876 assert_equal([1], a.Foo())
7877 assert_equal([1, 2], Bar(a))
7878 a.val += [3]
7879 assert_equal([1, 2, 3], a.val)
7880 END
7881 v9.CheckSourceSuccess(lines)
7882enddef
7883
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007884" Test for using an object method as a funcref
7885def Test_object_funcref()
7886 # Using object method funcref from a def function
7887 var lines =<< trim END
7888 vim9script
7889 class A
7890 def Foo(): list<number>
7891 return [3, 2, 1]
7892 enddef
7893 endclass
7894 def Bar()
7895 var a = A.new()
7896 var Fn = a.Foo
7897 assert_equal([3, 2, 1], Fn())
7898 enddef
7899 Bar()
7900 END
7901 v9.CheckSourceSuccess(lines)
7902
7903 # Using object method funcref at the script level
7904 lines =<< trim END
7905 vim9script
7906 class A
7907 def Foo(): dict<number>
7908 return {a: 1, b: 2}
7909 enddef
7910 endclass
7911 var a = A.new()
7912 var Fn = a.Foo
7913 assert_equal({a: 1, b: 2}, Fn())
7914 END
7915 v9.CheckSourceSuccess(lines)
7916
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007917 # Using object method funcref at the script level
7918 lines =<< trim END
7919 vim9script
7920 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007921 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007922 def Foo(): number
7923 return this.val
7924 enddef
7925 endclass
7926 var a = A.new(345)
7927 var Fn = a.Foo
7928 assert_equal(345, Fn())
7929 END
7930 v9.CheckSourceSuccess(lines)
7931
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007932 # Using object method funcref from another object method
7933 lines =<< trim END
7934 vim9script
7935 class A
7936 def Foo(): list<number>
7937 return [3, 2, 1]
7938 enddef
7939 def Bar()
7940 var Fn = this.Foo
7941 assert_equal([3, 2, 1], Fn())
7942 enddef
7943 endclass
7944 var a = A.new()
7945 a.Bar()
7946 END
7947 v9.CheckSourceSuccess(lines)
7948
7949 # Using function() to get a object method funcref
7950 lines =<< trim END
7951 vim9script
7952 class A
7953 def Foo(l: list<any>): list<any>
7954 return l
7955 enddef
7956 endclass
7957 var a = A.new()
7958 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
7959 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7960 END
7961 v9.CheckSourceSuccess(lines)
7962
7963 # Use an object method with a function returning a funcref and then call the
7964 # funcref.
7965 lines =<< trim END
7966 vim9script
7967
7968 def Map(F: func(number): number): func(number): number
7969 return (n: number) => F(n)
7970 enddef
7971
7972 class Math
7973 def Double(n: number): number
7974 return 2 * n
7975 enddef
7976 endclass
7977
7978 const math = Math.new()
7979 assert_equal(48, Map(math.Double)(24))
7980 END
7981 v9.CheckSourceSuccess(lines)
7982
Ernie Rael03042a22023-11-11 08:53:32 +01007983 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007984 lines =<< trim END
7985 vim9script
7986 class A
7987 def _Foo()
7988 enddef
7989 endclass
7990 def Bar()
7991 var a = A.new()
7992 var Fn = a._Foo
7993 enddef
7994 Bar()
7995 END
Ernie Rael03042a22023-11-11 08:53:32 +01007996 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007997
Ernie Rael03042a22023-11-11 08:53:32 +01007998 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007999 lines =<< trim END
8000 vim9script
8001 class A
8002 def _Foo()
8003 enddef
8004 endclass
8005 var a = A.new()
8006 var Fn = a._Foo
8007 END
Ernie Rael03042a22023-11-11 08:53:32 +01008008 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008009
Ernie Rael03042a22023-11-11 08:53:32 +01008010 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008011 lines =<< trim END
8012 vim9script
8013 class A
8014 def _Foo(): list<number>
8015 return [3, 2, 1]
8016 enddef
8017 def Bar()
8018 var Fn = this._Foo
8019 assert_equal([3, 2, 1], Fn())
8020 enddef
8021 endclass
8022 var a = A.new()
8023 a.Bar()
8024 END
8025 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008026
8027 # Using object method funcref using call()
8028 lines =<< trim END
8029 vim9script
8030 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008031 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008032 def Foo(): number
8033 return this.val
8034 enddef
8035 endclass
8036
8037 def Bar(obj: A)
8038 assert_equal(123, call(obj.Foo, []))
8039 enddef
8040
8041 var a = A.new(123)
8042 Bar(a)
8043 assert_equal(123, call(a.Foo, []))
8044 END
8045 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008046enddef
8047
8048" Test for using a class method as a funcref
8049def Test_class_funcref()
8050 # Using class method funcref in a def function
8051 var lines =<< trim END
8052 vim9script
8053 class A
8054 static def Foo(): list<number>
8055 return [3, 2, 1]
8056 enddef
8057 endclass
8058 def Bar()
8059 var Fn = A.Foo
8060 assert_equal([3, 2, 1], Fn())
8061 enddef
8062 Bar()
8063 END
8064 v9.CheckSourceSuccess(lines)
8065
8066 # Using class method funcref at script level
8067 lines =<< trim END
8068 vim9script
8069 class A
8070 static def Foo(): dict<number>
8071 return {a: 1, b: 2}
8072 enddef
8073 endclass
8074 var Fn = A.Foo
8075 assert_equal({a: 1, b: 2}, Fn())
8076 END
8077 v9.CheckSourceSuccess(lines)
8078
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008079 # Using class method funcref at the script level
8080 lines =<< trim END
8081 vim9script
8082 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008083 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008084 static def Foo(): number
8085 return val
8086 enddef
8087 endclass
8088 A.val = 567
8089 var Fn = A.Foo
8090 assert_equal(567, Fn())
8091 END
8092 v9.CheckSourceSuccess(lines)
8093
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008094 # Using function() to get a class method funcref
8095 lines =<< trim END
8096 vim9script
8097 class A
8098 static def Foo(l: list<any>): list<any>
8099 return l
8100 enddef
8101 endclass
8102 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8103 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8104 END
8105 v9.CheckSourceSuccess(lines)
8106
8107 # Using a class method funcref from another class method
8108 lines =<< trim END
8109 vim9script
8110 class A
8111 static def Foo(): list<number>
8112 return [3, 2, 1]
8113 enddef
8114 static def Bar()
8115 var Fn = Foo
8116 assert_equal([3, 2, 1], Fn())
8117 enddef
8118 endclass
8119 A.Bar()
8120 END
8121 v9.CheckSourceSuccess(lines)
8122
8123 # Use a class method with a function returning a funcref and then call the
8124 # funcref.
8125 lines =<< trim END
8126 vim9script
8127
8128 def Map(F: func(number): number): func(number): number
8129 return (n: number) => F(n)
8130 enddef
8131
8132 class Math
8133 static def StaticDouble(n: number): number
8134 return 2 * n
8135 enddef
8136 endclass
8137
8138 assert_equal(48, Map(Math.StaticDouble)(24))
8139 END
8140 v9.CheckSourceSuccess(lines)
8141
Ernie Rael03042a22023-11-11 08:53:32 +01008142 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008143 lines =<< trim END
8144 vim9script
8145 class A
8146 static def _Foo()
8147 enddef
8148 endclass
8149 def Bar()
8150 var Fn = A._Foo
8151 enddef
8152 Bar()
8153 END
Ernie Rael03042a22023-11-11 08:53:32 +01008154 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008155
Ernie Rael03042a22023-11-11 08:53:32 +01008156 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008157 lines =<< trim END
8158 vim9script
8159 class A
8160 static def _Foo()
8161 enddef
8162 endclass
8163 var Fn = A._Foo
8164 END
Ernie Rael03042a22023-11-11 08:53:32 +01008165 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008166
Ernie Rael03042a22023-11-11 08:53:32 +01008167 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008168 lines =<< trim END
8169 vim9script
8170 class A
8171 static def _Foo(): list<number>
8172 return [3, 2, 1]
8173 enddef
8174 static def Bar()
8175 var Fn = _Foo
8176 assert_equal([3, 2, 1], Fn())
8177 enddef
8178 endclass
8179 A.Bar()
8180 END
8181 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008182
8183 # Using class method funcref using call()
8184 lines =<< trim END
8185 vim9script
8186 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008187 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008188 static def Foo(): number
8189 return val
8190 enddef
8191 endclass
8192
8193 def Bar()
8194 A.val = 468
8195 assert_equal(468, call(A.Foo, []))
8196 enddef
8197 Bar()
8198 assert_equal(468, call(A.Foo, []))
8199 END
8200 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008201enddef
8202
8203" Test for using an object member as a funcref
8204def Test_object_member_funcref()
8205 # Using a funcref object variable in an object method
8206 var lines =<< trim END
8207 vim9script
8208 def Foo(n: number): number
8209 return n * 10
8210 enddef
8211
8212 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008213 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008214 def Bar()
8215 assert_equal(200, this.Cb(20))
8216 enddef
8217 endclass
8218
8219 var a = A.new()
8220 a.Bar()
8221 END
8222 v9.CheckSourceSuccess(lines)
8223
8224 # Using a funcref object variable in a def method
8225 lines =<< trim END
8226 vim9script
8227 def Foo(n: number): number
8228 return n * 10
8229 enddef
8230
8231 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008232 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008233 endclass
8234
8235 def Bar()
8236 var a = A.new()
8237 assert_equal(200, a.Cb(20))
8238 enddef
8239 Bar()
8240 END
8241 v9.CheckSourceSuccess(lines)
8242
8243 # Using a funcref object variable at script level
8244 lines =<< trim END
8245 vim9script
8246 def Foo(n: number): number
8247 return n * 10
8248 enddef
8249
8250 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008251 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008252 endclass
8253
8254 var a = A.new()
8255 assert_equal(200, a.Cb(20))
8256 END
8257 v9.CheckSourceSuccess(lines)
8258
8259 # Using a funcref object variable pointing to an object method in an object
8260 # method.
8261 lines =<< trim END
8262 vim9script
8263 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008264 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008265 def Foo(n: number): number
8266 return n * 10
8267 enddef
8268 def Bar()
8269 assert_equal(200, this.Cb(20))
8270 enddef
8271 endclass
8272
8273 var a = A.new()
8274 a.Bar()
8275 END
8276 v9.CheckSourceSuccess(lines)
8277
8278 # Using a funcref object variable pointing to an object method in a def
8279 # method.
8280 lines =<< trim END
8281 vim9script
8282 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008283 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008284 def Foo(n: number): number
8285 return n * 10
8286 enddef
8287 endclass
8288
8289 def Bar()
8290 var a = A.new()
8291 assert_equal(200, a.Cb(20))
8292 enddef
8293 Bar()
8294 END
8295 v9.CheckSourceSuccess(lines)
8296
8297 # Using a funcref object variable pointing to an object method at script
8298 # level.
8299 lines =<< trim END
8300 vim9script
8301 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008302 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008303 def Foo(n: number): number
8304 return n * 10
8305 enddef
8306 endclass
8307
8308 var a = A.new()
8309 assert_equal(200, a.Cb(20))
8310 END
8311 v9.CheckSourceSuccess(lines)
8312enddef
8313
8314" Test for using a class member as a funcref
8315def Test_class_member_funcref()
8316 # Using a funcref class variable in a class method
8317 var lines =<< trim END
8318 vim9script
8319 def Foo(n: number): number
8320 return n * 10
8321 enddef
8322
8323 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008324 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008325 static def Bar()
8326 assert_equal(200, Cb(20))
8327 enddef
8328 endclass
8329
8330 A.Bar()
8331 END
8332 v9.CheckSourceSuccess(lines)
8333
8334 # Using a funcref class variable in a def method
8335 lines =<< trim END
8336 vim9script
8337 def Foo(n: number): number
8338 return n * 10
8339 enddef
8340
8341 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008342 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008343 endclass
8344
8345 def Bar()
8346 assert_equal(200, A.Cb(20))
8347 enddef
8348 Bar()
8349 END
8350 v9.CheckSourceSuccess(lines)
8351
8352 # Using a funcref class variable at script level
8353 lines =<< trim END
8354 vim9script
8355 def Foo(n: number): number
8356 return n * 10
8357 enddef
8358
8359 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008360 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008361 endclass
8362
8363 assert_equal(200, A.Cb(20))
8364 END
8365 v9.CheckSourceSuccess(lines)
8366
8367 # Using a funcref class variable pointing to a class method in a class
8368 # method.
8369 lines =<< trim END
8370 vim9script
8371 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008372 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008373 static def Foo(n: number): number
8374 return n * 10
8375 enddef
8376 static def Init()
8377 Cb = Foo
8378 enddef
8379 static def Bar()
8380 assert_equal(200, Cb(20))
8381 enddef
8382 endclass
8383
8384 A.Init()
8385 A.Bar()
8386 END
8387 v9.CheckSourceSuccess(lines)
8388
8389 # Using a funcref class variable pointing to a class method in a def method.
8390 lines =<< trim END
8391 vim9script
8392 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008393 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008394 static def Foo(n: number): number
8395 return n * 10
8396 enddef
8397 static def Init()
8398 Cb = Foo
8399 enddef
8400 endclass
8401
8402 def Bar()
8403 A.Init()
8404 assert_equal(200, A.Cb(20))
8405 enddef
8406 Bar()
8407 END
8408 v9.CheckSourceSuccess(lines)
8409
8410 # Using a funcref class variable pointing to a class method at script level.
8411 lines =<< trim END
8412 vim9script
8413 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008414 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008415 static def Foo(n: number): number
8416 return n * 10
8417 enddef
8418 static def Init()
8419 Cb = Foo
8420 enddef
8421 endclass
8422
8423 A.Init()
8424 assert_equal(200, A.Cb(20))
8425 END
8426 v9.CheckSourceSuccess(lines)
8427enddef
8428
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008429" Test for using object methods as popup callback functions
8430def Test_objmethod_popup_callback()
8431 # Use the popup from the script level
8432 var lines =<< trim END
8433 vim9script
8434
8435 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008436 var selection: number = -1
8437 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008438
8439 def PopupFilter(id: number, key: string): bool
8440 add(this.filterkeys, key)
8441 return popup_filter_yesno(id, key)
8442 enddef
8443
8444 def PopupCb(id: number, result: number)
8445 this.selection = result ? 100 : 200
8446 enddef
8447 endclass
8448
8449 var a = A.new()
8450 feedkeys('', 'xt')
8451 var winid = popup_create('Y/N?',
8452 {filter: a.PopupFilter, callback: a.PopupCb})
8453 feedkeys('y', 'xt')
8454 popup_close(winid)
8455 assert_equal(100, a.selection)
8456 assert_equal(['y'], a.filterkeys)
8457 feedkeys('', 'xt')
8458 winid = popup_create('Y/N?',
8459 {filter: a.PopupFilter, callback: a.PopupCb})
8460 feedkeys('n', 'xt')
8461 popup_close(winid)
8462 assert_equal(200, a.selection)
8463 assert_equal(['y', 'n'], a.filterkeys)
8464 END
8465 v9.CheckSourceSuccess(lines)
8466
8467 # Use the popup from a def function
8468 lines =<< trim END
8469 vim9script
8470
8471 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008472 var selection: number = -1
8473 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008474
8475 def PopupFilter(id: number, key: string): bool
8476 add(this.filterkeys, key)
8477 return popup_filter_yesno(id, key)
8478 enddef
8479
8480 def PopupCb(id: number, result: number)
8481 this.selection = result ? 100 : 200
8482 enddef
8483 endclass
8484
8485 def Foo()
8486 var a = A.new()
8487 feedkeys('', 'xt')
8488 var winid = popup_create('Y/N?',
8489 {filter: a.PopupFilter, callback: a.PopupCb})
8490 feedkeys('y', 'xt')
8491 popup_close(winid)
8492 assert_equal(100, a.selection)
8493 assert_equal(['y'], a.filterkeys)
8494 feedkeys('', 'xt')
8495 winid = popup_create('Y/N?',
8496 {filter: a.PopupFilter, callback: a.PopupCb})
8497 feedkeys('n', 'xt')
8498 popup_close(winid)
8499 assert_equal(200, a.selection)
8500 assert_equal(['y', 'n'], a.filterkeys)
8501 enddef
8502 Foo()
8503 END
8504 v9.CheckSourceSuccess(lines)
8505enddef
8506
8507" Test for using class methods as popup callback functions
8508def Test_classmethod_popup_callback()
8509 # Use the popup from the script level
8510 var lines =<< trim END
8511 vim9script
8512
8513 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008514 static var selection: number = -1
8515 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008516
8517 static def PopupFilter(id: number, key: string): bool
8518 add(filterkeys, key)
8519 return popup_filter_yesno(id, key)
8520 enddef
8521
8522 static def PopupCb(id: number, result: number)
8523 selection = result ? 100 : 200
8524 enddef
8525 endclass
8526
8527 feedkeys('', 'xt')
8528 var winid = popup_create('Y/N?',
8529 {filter: A.PopupFilter, callback: A.PopupCb})
8530 feedkeys('y', 'xt')
8531 popup_close(winid)
8532 assert_equal(100, A.selection)
8533 assert_equal(['y'], A.filterkeys)
8534 feedkeys('', 'xt')
8535 winid = popup_create('Y/N?',
8536 {filter: A.PopupFilter, callback: A.PopupCb})
8537 feedkeys('n', 'xt')
8538 popup_close(winid)
8539 assert_equal(200, A.selection)
8540 assert_equal(['y', 'n'], A.filterkeys)
8541 END
8542 v9.CheckSourceSuccess(lines)
8543
8544 # Use the popup from a def function
8545 lines =<< trim END
8546 vim9script
8547
8548 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008549 static var selection: number = -1
8550 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008551
8552 static def PopupFilter(id: number, key: string): bool
8553 add(filterkeys, key)
8554 return popup_filter_yesno(id, key)
8555 enddef
8556
8557 static def PopupCb(id: number, result: number)
8558 selection = result ? 100 : 200
8559 enddef
8560 endclass
8561
8562 def Foo()
8563 feedkeys('', 'xt')
8564 var winid = popup_create('Y/N?',
8565 {filter: A.PopupFilter, callback: A.PopupCb})
8566 feedkeys('y', 'xt')
8567 popup_close(winid)
8568 assert_equal(100, A.selection)
8569 assert_equal(['y'], A.filterkeys)
8570 feedkeys('', 'xt')
8571 winid = popup_create('Y/N?',
8572 {filter: A.PopupFilter, callback: A.PopupCb})
8573 feedkeys('n', 'xt')
8574 popup_close(winid)
8575 assert_equal(200, A.selection)
8576 assert_equal(['y', 'n'], A.filterkeys)
8577 enddef
8578 Foo()
8579 END
8580 v9.CheckSourceSuccess(lines)
8581enddef
8582
8583" Test for using an object method as a timer callback function
8584def Test_objmethod_timer_callback()
8585 # Use the timer callback from script level
8586 var lines =<< trim END
8587 vim9script
8588
8589 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008590 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008591 def TimerCb(timerID: number)
8592 this.timerTick = 6
8593 enddef
8594 endclass
8595
8596 var a = A.new()
8597 timer_start(0, a.TimerCb)
8598 var maxWait = 5
8599 while maxWait > 0 && a.timerTick == -1
8600 :sleep 10m
8601 maxWait -= 1
8602 endwhile
8603 assert_equal(6, a.timerTick)
8604 END
8605 v9.CheckSourceSuccess(lines)
8606
8607 # Use the timer callback from a def function
8608 lines =<< trim END
8609 vim9script
8610
8611 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008612 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008613 def TimerCb(timerID: number)
8614 this.timerTick = 6
8615 enddef
8616 endclass
8617
8618 def Foo()
8619 var a = A.new()
8620 timer_start(0, a.TimerCb)
8621 var maxWait = 5
8622 while maxWait > 0 && a.timerTick == -1
8623 :sleep 10m
8624 maxWait -= 1
8625 endwhile
8626 assert_equal(6, a.timerTick)
8627 enddef
8628 Foo()
8629 END
8630 v9.CheckSourceSuccess(lines)
8631enddef
8632
8633" Test for using a class method as a timer callback function
8634def Test_classmethod_timer_callback()
8635 # Use the timer callback from script level
8636 var lines =<< trim END
8637 vim9script
8638
8639 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008640 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008641 static def TimerCb(timerID: number)
8642 timerTick = 6
8643 enddef
8644 endclass
8645
8646 timer_start(0, A.TimerCb)
8647 var maxWait = 5
8648 while maxWait > 0 && A.timerTick == -1
8649 :sleep 10m
8650 maxWait -= 1
8651 endwhile
8652 assert_equal(6, A.timerTick)
8653 END
8654 v9.CheckSourceSuccess(lines)
8655
8656 # Use the timer callback from a def function
8657 lines =<< trim END
8658 vim9script
8659
8660 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008661 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008662 static def TimerCb(timerID: number)
8663 timerTick = 6
8664 enddef
8665 endclass
8666
8667 def Foo()
8668 timer_start(0, A.TimerCb)
8669 var maxWait = 5
8670 while maxWait > 0 && A.timerTick == -1
8671 :sleep 10m
8672 maxWait -= 1
8673 endwhile
8674 assert_equal(6, A.timerTick)
8675 enddef
8676 Foo()
8677 END
8678 v9.CheckSourceSuccess(lines)
8679enddef
8680
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008681" Test for using a class variable as the first and/or second operand of a binary
8682" operator.
8683def Test_class_variable_as_operands()
8684 var lines =<< trim END
8685 vim9script
8686 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008687 static var truthy: bool = true
8688 public static var TruthyFn: func
8689 static var list: list<any> = []
8690 static var four: number = 4
8691 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008692
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008693 static def Str(): string
8694 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008695 enddef
8696
8697 static def Four(): number
8698 return four
8699 enddef
8700
8701 static def List(): list<any>
8702 return list
8703 enddef
8704
8705 static def Truthy(): bool
8706 return truthy
8707 enddef
8708
8709 def TestOps()
8710 assert_true(Tests.truthy == truthy)
8711 assert_true(truthy == Tests.truthy)
8712 assert_true(Tests.list isnot [])
8713 assert_true([] isnot Tests.list)
8714 assert_equal(2, Tests.four >> 1)
8715 assert_equal(16, 1 << Tests.four)
8716 assert_equal(8, Tests.four + four)
8717 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008718 assert_equal('hellohello', Tests.str .. str)
8719 assert_equal('hellohello', str .. Tests.str)
8720
8721 # Using class variable for list indexing
8722 var l = range(10)
8723 assert_equal(4, l[Tests.four])
8724 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8725
8726 # Using class variable for Dict key
8727 var d = {hello: 'abc'}
8728 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008729 enddef
8730 endclass
8731
8732 def TestOps2()
8733 assert_true(Tests.truthy == Tests.Truthy())
8734 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008735 assert_true(Tests.truthy == Tests.TruthyFn())
8736 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008737 assert_true(Tests.list is Tests.List())
8738 assert_true(Tests.List() is Tests.list)
8739 assert_equal(2, Tests.four >> 1)
8740 assert_equal(16, 1 << Tests.four)
8741 assert_equal(8, Tests.four + Tests.Four())
8742 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008743 assert_equal('hellohello', Tests.str .. Tests.Str())
8744 assert_equal('hellohello', Tests.Str() .. Tests.str)
8745
8746 # Using class variable for list indexing
8747 var l = range(10)
8748 assert_equal(4, l[Tests.four])
8749 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8750
8751 # Using class variable for Dict key
8752 var d = {hello: 'abc'}
8753 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008754 enddef
8755
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008756 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008757 var t = Tests.new()
8758 t.TestOps()
8759 TestOps2()
8760
8761 assert_true(Tests.truthy == Tests.Truthy())
8762 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008763 assert_true(Tests.truthy == Tests.TruthyFn())
8764 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008765 assert_true(Tests.list is Tests.List())
8766 assert_true(Tests.List() is Tests.list)
8767 assert_equal(2, Tests.four >> 1)
8768 assert_equal(16, 1 << Tests.four)
8769 assert_equal(8, Tests.four + Tests.Four())
8770 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008771 assert_equal('hellohello', Tests.str .. Tests.Str())
8772 assert_equal('hellohello', Tests.Str() .. Tests.str)
8773
8774 # Using class variable for list indexing
8775 var l = range(10)
8776 assert_equal(4, l[Tests.four])
8777 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8778
8779 # Using class variable for Dict key
8780 var d = {hello: 'abc'}
8781 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008782 END
8783 v9.CheckSourceSuccess(lines)
8784enddef
8785
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008786" Test for checking the type of the key used to access an object dict member.
8787def Test_dict_member_key_type_check()
8788 var lines =<< trim END
8789 vim9script
8790
8791 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01008792 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008793 endclass
8794
8795 class Test extends State
8796 def ObjMethodTests()
8797 var cursor: number = 0
8798 var z: number = 0
8799 [this.numbers[cursor]] = ['zero.1']
8800 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8801 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8802 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8803 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8804 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8805 [this.numbers[cursor], z] = ['zero.4', 1]
8806 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8807 [z, this.numbers[cursor]] = [1, 'zero.5']
8808 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8809 enddef
8810
8811 static def ClassMethodTests(that: State)
8812 var cursor: number = 0
8813 var z: number = 0
8814 [that.numbers[cursor]] = ['zero.1']
8815 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8816 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8817 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8818 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8819 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8820 [that.numbers[cursor], z] = ['zero.4', 1]
8821 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8822 [z, that.numbers[cursor]] = [1, 'zero.5']
8823 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8824 enddef
8825
8826 def new()
8827 enddef
8828
8829 def newMethodTests()
8830 var cursor: number = 0
8831 var z: number
8832 [this.numbers[cursor]] = ['zero.1']
8833 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8834 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8835 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8836 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8837 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8838 [this.numbers[cursor], z] = ['zero.4', 1]
8839 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8840 [z, this.numbers[cursor]] = [1, 'zero.5']
8841 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8842 enddef
8843 endclass
8844
8845 def DefFuncTests(that: Test)
8846 var cursor: number = 0
8847 var z: number
8848 [that.numbers[cursor]] = ['zero.1']
8849 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8850 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8851 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8852 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8853 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8854 [that.numbers[cursor], z] = ['zero.4', 1]
8855 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8856 [z, that.numbers[cursor]] = [1, 'zero.5']
8857 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8858 enddef
8859
8860 Test.newMethodTests()
8861 Test.new().ObjMethodTests()
8862 Test.ClassMethodTests(Test.new())
8863 DefFuncTests(Test.new())
8864
8865 const test: Test = Test.new()
8866 var cursor: number = 0
8867 [test.numbers[cursor], cursor] = ['zero', 1]
8868 [cursor, test.numbers[cursor]] = [1, 'one']
8869 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8870 END
8871 v9.CheckSourceSuccess(lines)
8872
8873 lines =<< trim END
8874 vim9script
8875
8876 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008877 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008878
8879 def new()
8880 enddef
8881
8882 def Foo()
8883 var z: number
8884 [this.numbers.a, z] = [{}, 10]
8885 enddef
8886 endclass
8887
8888 var a = A.new()
8889 a.Foo()
8890 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008891 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008892
8893 lines =<< trim END
8894 vim9script
8895
8896 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008897 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008898
8899 def new()
8900 enddef
8901
8902 def Foo()
8903 var x: string = 'a'
8904 var y: number
8905 [this.numbers[x], y] = [{}, 10]
8906 enddef
8907 endclass
8908
8909 var a = A.new()
8910 a.Foo()
8911 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008912 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008913enddef
8914
mityua5550692023-11-25 15:41:20 +01008915def Test_compile_many_def_functions_in_funcref_instr()
8916 # This used to crash Vim. This is reproducible only when run on new instance
8917 # of Vim.
8918 var lines =<< trim END
8919 vim9script
8920
8921 class A
8922 def new()
8923 this.TakeFunc(this.F00)
8924 enddef
8925
8926 def TakeFunc(F: func)
8927 enddef
8928
8929 def F00()
8930 this.F01()
8931 this.F02()
8932 this.F03()
8933 this.F04()
8934 this.F05()
8935 this.F06()
8936 this.F07()
8937 this.F08()
8938 this.F09()
8939 this.F10()
8940 this.F11()
8941 this.F12()
8942 this.F13()
8943 this.F14()
8944 this.F15()
8945 this.F16()
8946 this.F17()
8947 this.F18()
8948 this.F19()
8949 this.F20()
8950 this.F21()
8951 this.F22()
8952 this.F23()
8953 this.F24()
8954 this.F25()
8955 this.F26()
8956 this.F27()
8957 this.F28()
8958 this.F29()
8959 this.F30()
8960 this.F31()
8961 this.F32()
8962 this.F33()
8963 this.F34()
8964 this.F35()
8965 this.F36()
8966 this.F37()
8967 this.F38()
8968 this.F39()
8969 this.F40()
8970 this.F41()
8971 this.F42()
8972 this.F43()
8973 this.F44()
8974 this.F45()
8975 this.F46()
8976 this.F47()
8977 enddef
8978
8979 def F01()
8980 enddef
8981 def F02()
8982 enddef
8983 def F03()
8984 enddef
8985 def F04()
8986 enddef
8987 def F05()
8988 enddef
8989 def F06()
8990 enddef
8991 def F07()
8992 enddef
8993 def F08()
8994 enddef
8995 def F09()
8996 enddef
8997 def F10()
8998 enddef
8999 def F11()
9000 enddef
9001 def F12()
9002 enddef
9003 def F13()
9004 enddef
9005 def F14()
9006 enddef
9007 def F15()
9008 enddef
9009 def F16()
9010 enddef
9011 def F17()
9012 enddef
9013 def F18()
9014 enddef
9015 def F19()
9016 enddef
9017 def F20()
9018 enddef
9019 def F21()
9020 enddef
9021 def F22()
9022 enddef
9023 def F23()
9024 enddef
9025 def F24()
9026 enddef
9027 def F25()
9028 enddef
9029 def F26()
9030 enddef
9031 def F27()
9032 enddef
9033 def F28()
9034 enddef
9035 def F29()
9036 enddef
9037 def F30()
9038 enddef
9039 def F31()
9040 enddef
9041 def F32()
9042 enddef
9043 def F33()
9044 enddef
9045 def F34()
9046 enddef
9047 def F35()
9048 enddef
9049 def F36()
9050 enddef
9051 def F37()
9052 enddef
9053 def F38()
9054 enddef
9055 def F39()
9056 enddef
9057 def F40()
9058 enddef
9059 def F41()
9060 enddef
9061 def F42()
9062 enddef
9063 def F43()
9064 enddef
9065 def F44()
9066 enddef
9067 def F45()
9068 enddef
9069 def F46()
9070 enddef
9071 def F47()
9072 enddef
9073 endclass
9074
9075 A.new()
9076 END
9077 writefile(lines, 'Xscript', 'D')
9078 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9079 assert_equal(0, v:shell_error)
9080enddef
9081
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009082" Test for 'final' class and object variables
9083def Test_final_class_object_variable()
9084 # Test for changing a final object variable from an object function
9085 var lines =<< trim END
9086 vim9script
9087 class A
9088 final foo: string = "abc"
9089 def Foo()
9090 this.foo = "def"
9091 enddef
9092 endclass
9093 defcompile A.Foo
9094 END
9095 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9096
9097 # Test for changing a final object variable from the 'new' function
9098 lines =<< trim END
9099 vim9script
9100 class A
9101 final s1: string
9102 final s2: string
9103 def new(this.s1)
9104 this.s2 = 'def'
9105 enddef
9106 endclass
9107 var a = A.new('abc')
9108 assert_equal('abc', a.s1)
9109 assert_equal('def', a.s2)
9110 END
9111 v9.CheckSourceSuccess(lines)
9112
9113 # Test for a final class variable
9114 lines =<< trim END
9115 vim9script
9116 class A
9117 static final s1: string = "abc"
9118 endclass
9119 assert_equal('abc', A.s1)
9120 END
9121 v9.CheckSourceSuccess(lines)
9122
9123 # Test for changing a final class variable from a class function
9124 lines =<< trim END
9125 vim9script
9126 class A
9127 static final s1: string = "abc"
9128 static def Foo()
9129 s1 = "def"
9130 enddef
9131 endclass
9132 A.Foo()
9133 END
9134 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9135
9136 # Test for changing a public final class variable at script level
9137 lines =<< trim END
9138 vim9script
9139 class A
9140 public static final s1: string = "abc"
9141 endclass
9142 assert_equal('abc', A.s1)
9143 A.s1 = 'def'
9144 END
9145 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9146
9147 # Test for changing a public final class variable from a class function
9148 lines =<< trim END
9149 vim9script
9150 class A
9151 public static final s1: string = "abc"
9152 static def Foo()
9153 s1 = "def"
9154 enddef
9155 endclass
9156 A.Foo()
9157 END
9158 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9159
9160 # Test for changing a public final class variable from a function
9161 lines =<< trim END
9162 vim9script
9163 class A
9164 public static final s1: string = "abc"
9165 endclass
9166 def Foo()
9167 A.s1 = 'def'
9168 enddef
9169 defcompile
9170 END
9171 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9172
9173 # Test for using a final variable of composite type
9174 lines =<< trim END
9175 vim9script
9176 class A
9177 public final l: list<number>
9178 def new()
9179 this.l = [1, 2]
9180 enddef
9181 def Foo()
9182 this.l[0] = 3
9183 this.l->add(4)
9184 enddef
9185 endclass
9186 var a = A.new()
9187 assert_equal([1, 2], a.l)
9188 a.Foo()
9189 assert_equal([3, 2, 4], a.l)
9190 END
9191 v9.CheckSourceSuccess(lines)
9192
9193 # Test for changing a final variable of composite type from another object
9194 # function
9195 lines =<< trim END
9196 vim9script
9197 class A
9198 public final l: list<number> = [1, 2]
9199 def Foo()
9200 this.l = [3, 4]
9201 enddef
9202 endclass
9203 var a = A.new()
9204 a.Foo()
9205 END
9206 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9207
9208 # Test for modifying a final variable of composite type at script level
9209 lines =<< trim END
9210 vim9script
9211 class A
9212 public final l: list<number> = [1, 2]
9213 endclass
9214 var a = A.new()
9215 a.l[0] = 3
9216 a.l->add(4)
9217 assert_equal([3, 2, 4], a.l)
9218 END
9219 v9.CheckSourceSuccess(lines)
9220
9221 # Test for modifying a final variable of composite type from a function
9222 lines =<< trim END
9223 vim9script
9224 class A
9225 public final l: list<number> = [1, 2]
9226 endclass
9227 def Foo()
9228 var a = A.new()
9229 a.l[0] = 3
9230 a.l->add(4)
9231 assert_equal([3, 2, 4], a.l)
9232 enddef
9233 Foo()
9234 END
9235 v9.CheckSourceSuccess(lines)
9236
9237 # Test for modifying a final variable of composite type from another object
9238 # function
9239 lines =<< trim END
9240 vim9script
9241 class A
9242 public final l: list<number> = [1, 2]
9243 def Foo()
9244 this.l[0] = 3
9245 this.l->add(4)
9246 enddef
9247 endclass
9248 var a = A.new()
9249 a.Foo()
9250 assert_equal([3, 2, 4], a.l)
9251 END
9252 v9.CheckSourceSuccess(lines)
9253
9254 # Test for assigning a new value to a final variable of composite type at
9255 # script level
9256 lines =<< trim END
9257 vim9script
9258 class A
9259 public final l: list<number> = [1, 2]
9260 endclass
9261 var a = A.new()
9262 a.l = [3, 4]
9263 END
9264 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9265
9266 # Test for assigning a new value to a final variable of composite type from
9267 # another object function
9268 lines =<< trim END
9269 vim9script
9270 class A
9271 public final l: list<number> = [1, 2]
9272 def Foo()
9273 this.l = [3, 4]
9274 enddef
9275 endclass
9276 var a = A.new()
9277 a.Foo()
9278 END
9279 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9280
9281 # Test for assigning a new value to a final variable of composite type from
9282 # another function
9283 lines =<< trim END
9284 vim9script
9285 class A
9286 public final l: list<number> = [1, 2]
9287 endclass
9288 def Foo()
9289 var a = A.new()
9290 a.l = [3, 4]
9291 enddef
9292 Foo()
9293 END
9294 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9295
9296 # Error case: Use 'final' with just a variable name
9297 lines =<< trim END
9298 vim9script
9299 class A
9300 final foo
9301 endclass
9302 var a = A.new()
9303 END
9304 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9305
9306 # Error case: Use 'final' followed by 'public'
9307 lines =<< trim END
9308 vim9script
9309 class A
9310 final public foo: number
9311 endclass
9312 var a = A.new()
9313 END
9314 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9315
9316 # Error case: Use 'final' followed by 'static'
9317 lines =<< trim END
9318 vim9script
9319 class A
9320 final static foo: number
9321 endclass
9322 var a = A.new()
9323 END
9324 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9325
9326 # Error case: 'final' cannot be used in an interface
9327 lines =<< trim END
9328 vim9script
9329 interface A
9330 final foo: number = 10
9331 endinterface
9332 END
9333 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9334
9335 # Error case: 'final' not supported for an object method
9336 lines =<< trim END
9337 vim9script
9338 class A
9339 final def Foo()
9340 enddef
9341 endclass
9342 END
9343 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9344
9345 # Error case: 'final' not supported for a class method
9346 lines =<< trim END
9347 vim9script
9348 class A
9349 static final def Foo()
9350 enddef
9351 endclass
9352 END
9353 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9354enddef
9355
9356" Test for 'const' class and object variables
9357def Test_const_class_object_variable()
9358 # Test for changing a const object variable from an object function
9359 var lines =<< trim END
9360 vim9script
9361 class A
9362 const foo: string = "abc"
9363 def Foo()
9364 this.foo = "def"
9365 enddef
9366 endclass
9367 defcompile A.Foo
9368 END
9369 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9370
9371 # Test for changing a const object variable from the 'new' function
9372 lines =<< trim END
9373 vim9script
9374 class A
9375 const s1: string
9376 const s2: string
9377 def new(this.s1)
9378 this.s2 = 'def'
9379 enddef
9380 endclass
9381 var a = A.new('abc')
9382 assert_equal('abc', a.s1)
9383 assert_equal('def', a.s2)
9384 END
9385 v9.CheckSourceSuccess(lines)
9386
9387 # Test for changing a const object variable from an object method called from
9388 # the 'new' function
9389 lines =<< trim END
9390 vim9script
9391 class A
9392 const s1: string = 'abc'
9393 def new()
9394 this.ChangeStr()
9395 enddef
9396 def ChangeStr()
9397 this.s1 = 'def'
9398 enddef
9399 endclass
9400 var a = A.new()
9401 END
9402 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9403
9404 # Test for a const class variable
9405 lines =<< trim END
9406 vim9script
9407 class A
9408 static const s1: string = "abc"
9409 endclass
9410 assert_equal('abc', A.s1)
9411 END
9412 v9.CheckSourceSuccess(lines)
9413
9414 # Test for changing a const class variable from a class function
9415 lines =<< trim END
9416 vim9script
9417 class A
9418 static const s1: string = "abc"
9419 static def Foo()
9420 s1 = "def"
9421 enddef
9422 endclass
9423 A.Foo()
9424 END
9425 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9426
9427 # Test for changing a public const class variable at script level
9428 lines =<< trim END
9429 vim9script
9430 class A
9431 public static const s1: string = "abc"
9432 endclass
9433 assert_equal('abc', A.s1)
9434 A.s1 = 'def'
9435 END
9436 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9437
9438 # Test for changing a public const class variable from a class function
9439 lines =<< trim END
9440 vim9script
9441 class A
9442 public static const s1: string = "abc"
9443 static def Foo()
9444 s1 = "def"
9445 enddef
9446 endclass
9447 A.Foo()
9448 END
9449 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9450
9451 # Test for changing a public const class variable from a function
9452 lines =<< trim END
9453 vim9script
9454 class A
9455 public static const s1: string = "abc"
9456 endclass
9457 def Foo()
9458 A.s1 = 'def'
9459 enddef
9460 defcompile
9461 END
9462 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9463
9464 # Test for changing a const List item from an object function
9465 lines =<< trim END
9466 vim9script
9467 class A
9468 public const l: list<number>
9469 def new()
9470 this.l = [1, 2]
9471 enddef
9472 def Foo()
9473 this.l[0] = 3
9474 enddef
9475 endclass
9476 var a = A.new()
9477 assert_equal([1, 2], a.l)
9478 a.Foo()
9479 END
9480 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9481
9482 # Test for adding a value to a const List from an object function
9483 lines =<< trim END
9484 vim9script
9485 class A
9486 public const l: list<number>
9487 def new()
9488 this.l = [1, 2]
9489 enddef
9490 def Foo()
9491 this.l->add(3)
9492 enddef
9493 endclass
9494 var a = A.new()
9495 a.Foo()
9496 END
9497 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9498
9499 # Test for reassigning a const List from an object function
9500 lines =<< trim END
9501 vim9script
9502 class A
9503 public const l: list<number> = [1, 2]
9504 def Foo()
9505 this.l = [3, 4]
9506 enddef
9507 endclass
9508 var a = A.new()
9509 a.Foo()
9510 END
9511 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9512
9513 # Test for changing a const List item at script level
9514 lines =<< trim END
9515 vim9script
9516 class A
9517 public const l: list<number> = [1, 2]
9518 endclass
9519 var a = A.new()
9520 a.l[0] = 3
9521 END
9522 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9523
9524 # Test for adding a value to a const List item at script level
9525 lines =<< trim END
9526 vim9script
9527 class A
9528 public const l: list<number> = [1, 2]
9529 endclass
9530 var a = A.new()
9531 a.l->add(4)
9532 END
9533 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9534
9535 # Test for changing a const List item from a function
9536 lines =<< trim END
9537 vim9script
9538 class A
9539 public const l: list<number> = [1, 2]
9540 endclass
9541 def Foo()
9542 var a = A.new()
9543 a.l[0] = 3
9544 enddef
9545 Foo()
9546 END
9547 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9548
9549 # Test for adding a value to a const List item from a function
9550 lines =<< trim END
9551 vim9script
9552 class A
9553 public const l: list<number> = [1, 2]
9554 endclass
9555 def Foo()
9556 var a = A.new()
9557 a.l->add(4)
9558 enddef
9559 Foo()
9560 END
9561 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9562
9563 # Test for changing a const List item from an object method
9564 lines =<< trim END
9565 vim9script
9566 class A
9567 public const l: list<number> = [1, 2]
9568 def Foo()
9569 this.l[0] = 3
9570 enddef
9571 endclass
9572 var a = A.new()
9573 a.Foo()
9574 END
9575 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9576
9577 # Test for adding a value to a const List item from an object method
9578 lines =<< trim END
9579 vim9script
9580 class A
9581 public const l: list<number> = [1, 2]
9582 def Foo()
9583 this.l->add(4)
9584 enddef
9585 endclass
9586 var a = A.new()
9587 a.Foo()
9588 END
9589 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9590
9591 # Test for reassigning a const List object variable at script level
9592 lines =<< trim END
9593 vim9script
9594 class A
9595 public const l: list<number> = [1, 2]
9596 endclass
9597 var a = A.new()
9598 a.l = [3, 4]
9599 END
9600 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9601
9602 # Test for reassigning a const List object variable from an object method
9603 lines =<< trim END
9604 vim9script
9605 class A
9606 public const l: list<number> = [1, 2]
9607 def Foo()
9608 this.l = [3, 4]
9609 enddef
9610 endclass
9611 var a = A.new()
9612 a.Foo()
9613 END
9614 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9615
9616 # Test for reassigning a const List object variable from another function
9617 lines =<< trim END
9618 vim9script
9619 class A
9620 public const l: list<number> = [1, 2]
9621 endclass
9622 def Foo()
9623 var a = A.new()
9624 a.l = [3, 4]
9625 enddef
9626 Foo()
9627 END
9628 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9629
9630 # Error case: Use 'const' with just a variable name
9631 lines =<< trim END
9632 vim9script
9633 class A
9634 const foo
9635 endclass
9636 var a = A.new()
9637 END
9638 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9639
9640 # Error case: Use 'const' followed by 'public'
9641 lines =<< trim END
9642 vim9script
9643 class A
9644 const public foo: number
9645 endclass
9646 var a = A.new()
9647 END
9648 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9649
9650 # Error case: Use 'const' followed by 'static'
9651 lines =<< trim END
9652 vim9script
9653 class A
9654 const static foo: number
9655 endclass
9656 var a = A.new()
9657 END
9658 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9659
9660 # Error case: 'const' cannot be used in an interface
9661 lines =<< trim END
9662 vim9script
9663 interface A
9664 const foo: number = 10
9665 endinterface
9666 END
9667 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9668
9669 # Error case: 'const' not supported for an object method
9670 lines =<< trim END
9671 vim9script
9672 class A
9673 const def Foo()
9674 enddef
9675 endclass
9676 END
9677 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9678
9679 # Error case: 'const' not supported for a class method
9680 lines =<< trim END
9681 vim9script
9682 class A
9683 static const def Foo()
9684 enddef
9685 endclass
9686 END
9687 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9688enddef
9689
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009690" Test for compiling class/object methods using :defcompile
9691def Test_defcompile_class()
9692 # defcompile all the classes in the current script
9693 var lines =<< trim END
9694 vim9script
9695 class A
9696 def Foo()
9697 var i = 10
9698 enddef
9699 endclass
9700 class B
9701 def Bar()
9702 var i = 20
9703 xxx
9704 enddef
9705 endclass
9706 defcompile
9707 END
9708 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9709
9710 # defcompile a specific class
9711 lines =<< trim END
9712 vim9script
9713 class A
9714 def Foo()
9715 xxx
9716 enddef
9717 endclass
9718 class B
9719 def Bar()
9720 yyy
9721 enddef
9722 endclass
9723 defcompile B
9724 END
9725 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9726
9727 # defcompile a non-class
9728 lines =<< trim END
9729 vim9script
9730 class A
9731 def Foo()
9732 enddef
9733 endclass
9734 var X: list<number> = []
9735 defcompile X
9736 END
9737 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9738
9739 # defcompile a class twice
9740 lines =<< trim END
9741 vim9script
9742 class A
9743 def new()
9744 enddef
9745 endclass
9746 defcompile A
9747 defcompile A
9748 assert_equal('Function A.new does not need compiling', v:statusmsg)
9749 END
9750 v9.CheckSourceSuccess(lines)
9751
9752 # defcompile should not compile an imported class
9753 lines =<< trim END
9754 vim9script
9755 export class A
9756 def Foo()
9757 xxx
9758 enddef
9759 endclass
9760 END
9761 writefile(lines, 'Xdefcompileimport.vim', 'D')
9762 lines =<< trim END
9763 vim9script
9764
9765 import './Xdefcompileimport.vim'
9766 class B
9767 endclass
9768 defcompile
9769 END
9770 v9.CheckScriptSuccess(lines)
9771enddef
9772
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +01009773" Test for cases common to all the object builtin methods
9774def Test_object_builtin_method()
9775 var lines =<< trim END
9776 vim9script
9777 class A
9778 def abc()
9779 enddef
9780 endclass
9781 END
9782 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
9783
9784 for funcname in ["len", "string", "empty"]
9785 lines =<< trim eval END
9786 vim9script
9787 class A
9788 static def {funcname}(): number
9789 enddef
9790 endclass
9791 END
9792 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
9793 endfor
9794enddef
9795
9796" Test for using the empty() builtin method with an object
9797" This is a legacy function to use the test_garbagecollect_now() function.
9798func Test_object_empty()
9799 let lines =<< trim END
9800 vim9script
9801 class A
9802 def empty(): bool
9803 return true
9804 enddef
9805 endclass
9806
9807 def Foo()
9808 var afoo = A.new()
9809 assert_equal(true, empty(afoo))
9810 assert_equal(true, afoo->empty())
9811 enddef
9812
9813 var a = A.new()
9814 assert_equal(1, empty(a))
9815 assert_equal(1, a->empty())
9816 test_garbagecollect_now()
9817 assert_equal(1, empty(a))
9818 Foo()
9819 test_garbagecollect_now()
9820 Foo()
9821 END
9822 call v9.CheckSourceSuccess(lines)
9823
9824 " empty() should return 1 without a builtin method
9825 let lines =<< trim END
9826 vim9script
9827 class A
9828 endclass
9829
9830 def Foo()
9831 var afoo = A.new()
9832 assert_equal(1, empty(afoo))
9833 enddef
9834
9835 var a = A.new()
9836 assert_equal(1, empty(a))
9837 Foo()
9838 END
9839 call v9.CheckSourceSuccess(lines)
9840
9841 " Unsupported signature for the empty() method
9842 let lines =<< trim END
9843 vim9script
9844 class A
9845 def empty()
9846 enddef
9847 endclass
9848 END
9849 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
9850
9851 " Error when calling the empty() method
9852 let lines =<< trim END
9853 vim9script
9854 class A
9855 def empty(): bool
9856 throw "Failed to check emptiness"
9857 enddef
9858 endclass
9859
9860 def Foo()
9861 var afoo = A.new()
9862 var i = empty(afoo)
9863 enddef
9864
9865 var a = A.new()
9866 assert_fails('empty(a)', 'Failed to check emptiness')
9867 assert_fails('Foo()', 'Failed to check emptiness')
9868 END
9869 call v9.CheckSourceSuccess(lines)
9870
9871 " call empty() using an object from a script
9872 let lines =<< trim END
9873 vim9script
9874 class A
9875 def empty(): bool
9876 return true
9877 enddef
9878 endclass
9879 var afoo = A.new()
9880 assert_equal(true, afoo.empty())
9881 END
9882 call v9.CheckSourceSuccess(lines)
9883
9884 " call empty() using an object from a method
9885 let lines =<< trim END
9886 vim9script
9887 class A
9888 def empty(): bool
9889 return true
9890 enddef
9891 endclass
9892 def Foo()
9893 var afoo = A.new()
9894 assert_equal(true, afoo.empty())
9895 enddef
9896 Foo()
9897 END
9898 call v9.CheckSourceSuccess(lines)
9899
9900 " call empty() using "this" from an object method
9901 let lines =<< trim END
9902 vim9script
9903 class A
9904 def empty(): bool
9905 return true
9906 enddef
9907 def Foo(): bool
9908 return this.empty()
9909 enddef
9910 endclass
9911 def Bar()
9912 var abar = A.new()
9913 assert_equal(true, abar.Foo())
9914 enddef
9915 Bar()
9916 END
9917 call v9.CheckSourceSuccess(lines)
9918
9919 " Call empty() from a derived object
9920 let lines =<< trim END
9921 vim9script
9922 class A
9923 def empty(): bool
9924 return false
9925 enddef
9926 endclass
9927 class B extends A
9928 def empty(): bool
9929 return true
9930 enddef
9931 endclass
9932 def Foo(afoo: A)
9933 assert_equal(true, empty(afoo))
9934 var bfoo = B.new()
9935 assert_equal(true, empty(bfoo))
9936 enddef
9937 var b = B.new()
9938 assert_equal(1, empty(b))
9939 Foo(b)
9940 END
9941 call v9.CheckSourceSuccess(lines)
9942
9943 " Invoking empty method using an interface
9944 let lines =<< trim END
9945 vim9script
9946 interface A
9947 def empty(): bool
9948 endinterface
9949 class B implements A
9950 def empty(): bool
9951 return false
9952 enddef
9953 endclass
9954 def Foo(a: A)
9955 assert_equal(false, empty(a))
9956 enddef
9957 var b = B.new()
9958 Foo(b)
9959 END
9960 call v9.CheckSourceSuccess(lines)
9961endfunc
9962
9963" Test for using the len() builtin method with an object
9964" This is a legacy function to use the test_garbagecollect_now() function.
9965func Test_object_length()
9966 let lines =<< trim END
9967 vim9script
9968 class A
9969 var mylen: number = 0
9970 def new(n: number)
9971 this.mylen = n
9972 enddef
9973 def len(): number
9974 return this.mylen
9975 enddef
9976 endclass
9977
9978 def Foo()
9979 var afoo = A.new(12)
9980 assert_equal(12, len(afoo))
9981 assert_equal(12, afoo->len())
9982 enddef
9983
9984 var a = A.new(22)
9985 assert_equal(22, len(a))
9986 assert_equal(22, a->len())
9987 test_garbagecollect_now()
9988 assert_equal(22, len(a))
9989 Foo()
9990 test_garbagecollect_now()
9991 Foo()
9992 END
9993 call v9.CheckSourceSuccess(lines)
9994
9995 " len() should return 0 without a builtin method
9996 let lines =<< trim END
9997 vim9script
9998 class A
9999 endclass
10000
10001 def Foo()
10002 var afoo = A.new()
10003 assert_equal(0, len(afoo))
10004 enddef
10005
10006 var a = A.new()
10007 assert_equal(0, len(a))
10008 Foo()
10009 END
10010 call v9.CheckSourceSuccess(lines)
10011
10012 " Unsupported signature for the len() method
10013 let lines =<< trim END
10014 vim9script
10015 class A
10016 def len()
10017 enddef
10018 endclass
10019 END
10020 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10021
10022 " Error when calling the len() method
10023 let lines =<< trim END
10024 vim9script
10025 class A
10026 def len(): number
10027 throw "Failed to compute length"
10028 enddef
10029 endclass
10030
10031 def Foo()
10032 var afoo = A.new()
10033 var i = len(afoo)
10034 enddef
10035
10036 var a = A.new()
10037 assert_fails('len(a)', 'Failed to compute length')
10038 assert_fails('Foo()', 'Failed to compute length')
10039 END
10040 call v9.CheckSourceSuccess(lines)
10041
10042 " call len() using an object from a script
10043 let lines =<< trim END
10044 vim9script
10045 class A
10046 def len(): number
10047 return 5
10048 enddef
10049 endclass
10050 var afoo = A.new()
10051 assert_equal(5, afoo.len())
10052 END
10053 call v9.CheckSourceSuccess(lines)
10054
10055 " call len() using an object from a method
10056 let lines =<< trim END
10057 vim9script
10058 class A
10059 def len(): number
10060 return 5
10061 enddef
10062 endclass
10063 def Foo()
10064 var afoo = A.new()
10065 assert_equal(5, afoo.len())
10066 enddef
10067 Foo()
10068 END
10069 call v9.CheckSourceSuccess(lines)
10070
10071 " call len() using "this" from an object method
10072 let lines =<< trim END
10073 vim9script
10074 class A
10075 def len(): number
10076 return 8
10077 enddef
10078 def Foo(): number
10079 return this.len()
10080 enddef
10081 endclass
10082 def Bar()
10083 var abar = A.new()
10084 assert_equal(8, abar.Foo())
10085 enddef
10086 Bar()
10087 END
10088 call v9.CheckSourceSuccess(lines)
10089
10090 " Call len() from a derived object
10091 let lines =<< trim END
10092 vim9script
10093 class A
10094 def len(): number
10095 return 10
10096 enddef
10097 endclass
10098 class B extends A
10099 def len(): number
10100 return 20
10101 enddef
10102 endclass
10103 def Foo(afoo: A)
10104 assert_equal(20, len(afoo))
10105 var bfoo = B.new()
10106 assert_equal(20, len(bfoo))
10107 enddef
10108 var b = B.new()
10109 assert_equal(20, len(b))
10110 Foo(b)
10111 END
10112 call v9.CheckSourceSuccess(lines)
10113
10114 " Invoking len method using an interface
10115 let lines =<< trim END
10116 vim9script
10117 interface A
10118 def len(): number
10119 endinterface
10120 class B implements A
10121 def len(): number
10122 return 123
10123 enddef
10124 endclass
10125 def Foo(a: A)
10126 assert_equal(123, len(a))
10127 enddef
10128 var b = B.new()
10129 Foo(b)
10130 END
10131 call v9.CheckSourceSuccess(lines)
10132endfunc
10133
10134" Test for using the string() builtin method with an object
10135" This is a legacy function to use the test_garbagecollect_now() function.
10136func Test_object_string()
10137 let lines =<< trim END
10138 vim9script
10139 class A
10140 var name: string
10141 def string(): string
10142 return this.name
10143 enddef
10144 endclass
10145
10146 def Foo()
10147 var afoo = A.new("foo-A")
10148 assert_equal('foo-A', string(afoo))
10149 assert_equal('foo-A', afoo->string())
10150 enddef
10151
10152 var a = A.new("script-A")
10153 assert_equal('script-A', string(a))
10154 assert_equal('script-A', a->string())
10155 assert_equal(['script-A'], execute('echo a')->split("\n"))
10156 test_garbagecollect_now()
10157 assert_equal('script-A', string(a))
10158 Foo()
10159 test_garbagecollect_now()
10160 Foo()
10161 END
10162 call v9.CheckSourceSuccess(lines)
10163
10164 " string() should return "object of A {}" without a builtin method
10165 let lines =<< trim END
10166 vim9script
10167 class A
10168 endclass
10169
10170 def Foo()
10171 var afoo = A.new()
10172 assert_equal('object of A {}', string(afoo))
10173 enddef
10174
10175 var a = A.new()
10176 assert_equal('object of A {}', string(a))
10177 Foo()
10178 END
10179 call v9.CheckSourceSuccess(lines)
10180
10181 " Unsupported signature for the string() method
10182 let lines =<< trim END
10183 vim9script
10184 class A
10185 def string()
10186 enddef
10187 endclass
10188 END
10189 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10190
10191 " Error when calling the string() method
10192 let lines =<< trim END
10193 vim9script
10194 class A
10195 def string(): string
10196 throw "Failed to get text"
10197 enddef
10198 endclass
10199
10200 def Foo()
10201 var afoo = A.new()
10202 var i = string(afoo)
10203 enddef
10204
10205 var a = A.new()
10206 assert_fails('string(a)', 'Failed to get text')
10207 assert_fails('Foo()', 'Failed to get text')
10208 END
10209 call v9.CheckSourceSuccess(lines)
10210
10211 " call string() using an object from a script
10212 let lines =<< trim END
10213 vim9script
10214 class A
10215 def string(): string
10216 return 'A'
10217 enddef
10218 endclass
10219 var afoo = A.new()
10220 assert_equal('A', afoo.string())
10221 END
10222 call v9.CheckSourceSuccess(lines)
10223
10224 " call string() using an object from a method
10225 let lines =<< trim END
10226 vim9script
10227 class A
10228 def string(): string
10229 return 'A'
10230 enddef
10231 endclass
10232 def Foo()
10233 var afoo = A.new()
10234 assert_equal('A', afoo.string())
10235 enddef
10236 Foo()
10237 END
10238 call v9.CheckSourceSuccess(lines)
10239
10240 " call string() using "this" from an object method
10241 let lines =<< trim END
10242 vim9script
10243 class A
10244 def string(): string
10245 return 'A'
10246 enddef
10247 def Foo(): string
10248 return this.string()
10249 enddef
10250 endclass
10251 def Bar()
10252 var abar = A.new()
10253 assert_equal('A', abar.string())
10254 enddef
10255 Bar()
10256 END
10257 call v9.CheckSourceSuccess(lines)
10258
10259 " Call string() from a derived object
10260 let lines =<< trim END
10261 vim9script
10262 class A
10263 def string(): string
10264 return 'A'
10265 enddef
10266 endclass
10267 class B extends A
10268 def string(): string
10269 return 'B'
10270 enddef
10271 endclass
10272 def Foo(afoo: A)
10273 assert_equal('B', string(afoo))
10274 var bfoo = B.new()
10275 assert_equal('B', string(bfoo))
10276 enddef
10277 var b = B.new()
10278 assert_equal('B', string(b))
10279 Foo(b)
10280 END
10281 call v9.CheckSourceSuccess(lines)
10282
10283 " Invoking string method using an interface
10284 let lines =<< trim END
10285 vim9script
10286 interface A
10287 def string(): string
10288 endinterface
10289 class B implements A
10290 def string(): string
10291 return 'B'
10292 enddef
10293 endclass
10294 def Foo(a: A)
10295 assert_equal('B', string(a))
10296 enddef
10297 var b = B.new()
10298 Foo(b)
10299 END
10300 call v9.CheckSourceSuccess(lines)
10301endfunc
10302
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010303" Test for using a class in the class definition
10304def Test_Ref_Class_Within_Same_Class()
10305 var lines =<< trim END
10306 vim9script
10307 class A
10308 var n: number = 0
10309 def Equals(other: A): bool
10310 return this.n == other.n
10311 enddef
10312 endclass
10313
10314 var a1 = A.new(10)
10315 var a2 = A.new(10)
10316 var a3 = A.new(20)
10317 assert_equal(true, a1.Equals(a2))
10318 assert_equal(false, a2.Equals(a3))
10319 END
10320 v9.CheckScriptSuccess(lines)
10321
10322 lines =<< trim END
10323 vim9script
10324
10325 class Foo
10326 var num: number
10327 def Clone(): Foo
10328 return Foo.new(this.num)
10329 enddef
10330 endclass
10331
10332 var f1 = Foo.new(1)
10333
10334 def F()
10335 var f2: Foo = f1.Clone()
10336 assert_equal(false, f2 is f1)
10337 assert_equal(true, f2.num == f1.num)
10338 enddef
10339 F()
10340
10341 var f3: Foo = f1.Clone()
10342 assert_equal(false, f3 is f1)
10343 assert_equal(true, f3.num == f1.num)
10344 END
10345 v9.CheckScriptSuccess(lines)
10346
10347 # Test for trying to use a class to extend when defining the same class
10348 lines =<< trim END
10349 vim9script
10350 class A extends A
10351 endclass
10352 END
10353 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10354
10355 # Test for trying to use a class to implement when defining the same class
10356 lines =<< trim END
10357 vim9script
10358 class A implements A
10359 endclass
10360 END
10361 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10362enddef
10363
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010364" Test for using a compound operator from a lambda function in an object method
10365def Test_compound_op_in_objmethod_lambda()
10366 # Test using the "+=" operator
10367 var lines =<< trim END
10368 vim9script
10369 class A
10370 var n: number = 10
10371 def Foo()
10372 var Fn = () => {
10373 this.n += 1
10374 }
10375 Fn()
10376 enddef
10377 endclass
10378
10379 var a = A.new()
10380 a.Foo()
10381 assert_equal(11, a.n)
10382 END
10383 v9.CheckScriptSuccess(lines)
10384
10385 # Test using the "..=" operator
10386 lines =<< trim END
10387 vim9script
10388 class A
10389 var s: string = "a"
10390 def Foo()
10391 var Fn = () => {
10392 this.s ..= "a"
10393 }
10394 Fn()
10395 enddef
10396 endclass
10397
10398 var a = A.new()
10399 a.Foo()
10400 a.Foo()
10401 assert_equal("aaa", a.s)
10402 END
10403 v9.CheckScriptSuccess(lines)
10404enddef
10405
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010406" Test for using test_refcount() with a class and an object
10407def Test_class_object_refcount()
10408 var lines =<< trim END
10409 vim9script
10410 class A
10411 endclass
10412 var a: A = A.new()
10413 assert_equal(2, test_refcount(A))
10414 assert_equal(1, test_refcount(a))
10415 var b = a
10416 assert_equal(2, test_refcount(A))
10417 assert_equal(2, test_refcount(a))
10418 assert_equal(2, test_refcount(b))
10419 END
10420 v9.CheckScriptSuccess(lines)
10421enddef
10422
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010423" call a lambda function in one object from another object
10424def Test_lambda_invocation_across_classes()
10425 var lines =<< trim END
10426 vim9script
10427 class A
10428 var s: string = "foo"
10429 def GetFn(): func
10430 var Fn = (): string => {
10431 return this.s
10432 }
10433 return Fn
10434 enddef
10435 endclass
10436
10437 class B
10438 var s: string = "bar"
10439 def GetFn(): func
10440 var a = A.new()
10441 return a.GetFn()
10442 enddef
10443 endclass
10444
10445 var b = B.new()
10446 var Fn = b.GetFn()
10447 assert_equal("foo", Fn())
10448 END
10449 v9.CheckScriptSuccess(lines)
10450enddef
10451
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010452" Test for using a class member which is an object of the current class
10453def Test_current_class_object_class_member()
10454 var lines =<< trim END
10455 vim9script
10456 class A
10457 public static var obj1: A = A.new(10)
10458 var n: number
10459 endclass
10460 defcompile
10461 assert_equal(10, A.obj1.n)
10462 END
10463 v9.CheckScriptSuccess(lines)
10464enddef
10465
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020010466" Test for updating a base class variable from a base class method without the
10467" class name. This used to crash Vim (Github issue #14352).
10468def Test_use_base_class_variable_from_base_class_method()
10469 var lines =<< trim END
10470 vim9script
10471
10472 class DictKeyClass
10473 static var _obj_id_count = 1
10474 def _GenerateKey()
10475 _obj_id_count += 1
10476 enddef
10477 static def GetIdCount(): number
10478 return _obj_id_count
10479 enddef
10480 endclass
10481
10482 class C extends DictKeyClass
10483 def F()
10484 this._GenerateKey()
10485 enddef
10486 endclass
10487
10488 C.new().F()
10489 assert_equal(2, DictKeyClass.GetIdCount())
10490 END
10491 v9.CheckScriptSuccess(lines)
10492enddef
10493
Bram Moolenaar00b28d62022-12-08 15:32:33 +000010494" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker