blob: 17252605f7e03ce5ca98d6df7cb4ba2c135fe209 [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
Bram Moolenaar94674f22023-01-06 18:42:20 +00002278def Test_class_implements_interface()
2279 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002280 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002281
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002282 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002283 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002284 def Method(nr: number)
2285 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002286
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002287 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002288 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002289 def Method(nr: number)
2290 echo nr
2291 enddef
2292 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002293
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002294 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002295 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002296 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002297
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002298 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002299 var member = 'abc'
2300 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002301 def Method(nr: number)
2302 echo nr
2303 enddef
2304 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002305 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002306 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002307
2308 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002309 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002310
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002311 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002312 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002313 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002314
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002315 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002316 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002317 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002318 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002319 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002320
2321 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002322 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002323
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002324 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002325 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002326 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002327
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002328 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002329 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002330 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002331 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002332 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002333
2334 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002335 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002336
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002337 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002338 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002339 def Method(nr: number)
2340 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002341
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002342 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002343 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002344 def Method(nr: number)
2345 echo nr
2346 enddef
2347 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002348 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002349 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002350
2351 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002352 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002353
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002354 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002355 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002356 def Methods(nr: number)
2357 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002359 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002360 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002361 def Method(nr: number)
2362 echo nr
2363 enddef
2364 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002365 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002366 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002367
2368 # Check different order of members in class and interface works.
2369 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002370 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002371
2372 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002373 var label: string
2374 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002375 endinterface
2376
2377 # order of members is opposite of interface
2378 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002379 public var lnum: number = 5
2380 var errpos: number = 42
2381 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002382 endclass
2383
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002384 def Test()
2385 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002386
2387 assert_equal('label', result.label)
2388 assert_equal(42, result.errpos)
2389 enddef
2390
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002391 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002392 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002393 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002394
2395 # Interface name after "extends" doesn't end in a space or NUL character
2396 lines =<< trim END
2397 vim9script
2398 interface A
2399 endinterface
2400 class B extends A"
2401 endclass
2402 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002403 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002404
2405 # Trailing characters after a class name
2406 lines =<< trim END
2407 vim9script
2408 class A bbb
2409 endclass
2410 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002411 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002412
2413 # using "implements" with a non-existing class
2414 lines =<< trim END
2415 vim9script
2416 class A implements B
2417 endclass
2418 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002419 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002420
2421 # using "implements" with a regular class
2422 lines =<< trim END
2423 vim9script
2424 class A
2425 endclass
2426 class B implements A
2427 endclass
2428 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002429 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002430
2431 # using "implements" with a variable
2432 lines =<< trim END
2433 vim9script
2434 var T: number = 10
2435 class A implements T
2436 endclass
2437 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002438 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002439
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002440 # implements should be followed by a white space
2441 lines =<< trim END
2442 vim9script
2443 interface A
2444 endinterface
2445 class B implements A;
2446 endclass
2447 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002448 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002449
LemonBoyc5d27442023-08-19 13:02:35 +02002450 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002451 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002452
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002453 interface One
2454 def IsEven(nr: number): bool
2455 endinterface
2456 class Two implements One
2457 def IsEven(nr: number): string
2458 enddef
2459 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002460 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002461 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002462
2463 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002464 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002465
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002466 interface One
2467 def IsEven(nr: number): bool
2468 endinterface
2469 class Two implements One
2470 def IsEven(nr: bool): bool
2471 enddef
2472 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002473 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002474 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002475
2476 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002477 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002478
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002479 interface One
2480 def IsEven(nr: number): bool
2481 endinterface
2482 class Two implements One
2483 def IsEven(nr: number, ...extra: list<number>): bool
2484 enddef
2485 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002486 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002487 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 +02002488
2489 # access superclass interface members from subclass, mix variable order
2490 lines =<< trim END
2491 vim9script
2492
2493 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002494 var mvar1: number
2495 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002496 endinterface
2497
2498 # NOTE: the order is swapped
2499 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002500 var mvar2: number
2501 var mvar1: number
2502 public static var svar2: number
2503 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002504 def new()
2505 svar1 = 11
2506 svar2 = 12
2507 this.mvar1 = 111
2508 this.mvar2 = 112
2509 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002510 endclass
2511
2512 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002513 def new()
2514 this.mvar1 = 121
2515 this.mvar2 = 122
2516 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002517 endclass
2518
2519 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002520 def new()
2521 this.mvar1 = 131
2522 this.mvar2 = 132
2523 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002524 endclass
2525
Ernie Raelcf138d42023-09-06 20:45:03 +02002526 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002527 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002528 enddef
2529
2530 var oa = A.new()
2531 var ob = B.new()
2532 var oc = C.new()
2533
Ernie Raelcf138d42023-09-06 20:45:03 +02002534 assert_equal([111, 112], F2(oa))
2535 assert_equal([121, 122], F2(ob))
2536 assert_equal([131, 132], F2(oc))
2537 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002538 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002539
2540 # Access superclass interface members from subclass, mix variable order.
2541 # Two interfaces, one on A, one on B; each has both kinds of variables
2542 lines =<< trim END
2543 vim9script
2544
2545 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002546 var mvar1: number
2547 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002548 endinterface
2549
2550 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002551 var mvar3: number
2552 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002553 endinterface
2554
2555 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002556 public static var svar1: number
2557 public static var svar2: number
2558 var mvar1: number
2559 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002560 def new()
2561 svar1 = 11
2562 svar2 = 12
2563 this.mvar1 = 111
2564 this.mvar2 = 112
2565 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002566 endclass
2567
2568 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002569 static var svar3: number
2570 static var svar4: number
2571 var mvar3: number
2572 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002573 def new()
2574 svar3 = 23
2575 svar4 = 24
2576 this.mvar1 = 121
2577 this.mvar2 = 122
2578 this.mvar3 = 123
2579 this.mvar4 = 124
2580 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002581 endclass
2582
2583 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002584 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002585 def new()
2586 svar5 = 1001
2587 this.mvar1 = 131
2588 this.mvar2 = 132
2589 this.mvar3 = 133
2590 this.mvar4 = 134
2591 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002592 endclass
2593
Ernie Raelcf138d42023-09-06 20:45:03 +02002594 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002595 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002596 enddef
2597
Ernie Raelcf138d42023-09-06 20:45:03 +02002598 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002599 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002600 enddef
2601
Ernie Raelcf138d42023-09-06 20:45:03 +02002602 var oa = A.new()
2603 var ob = B.new()
2604 var oc = C.new()
2605
Ernie Raelcf138d42023-09-06 20:45:03 +02002606 assert_equal([[111, 112]], [F2(oa)])
2607 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2608 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002609 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002610 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002611
2612 # Using two interface names without a space after the ","
2613 lines =<< trim END
2614 vim9script
2615 interface A
2616 endinterface
2617 interface B
2618 endinterface
2619 class C implements A,B
2620 endclass
2621 END
2622 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2623
2624 # No interface name after a comma
2625 lines =<< trim END
2626 vim9script
2627 interface A
2628 endinterface
2629 class B implements A,
2630 endclass
2631 END
2632 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2633
2634 # No interface name after implements
2635 lines =<< trim END
2636 vim9script
2637 class A implements
2638 endclass
2639 END
2640 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002641enddef
2642
Bram Moolenaard0200c82023-01-28 15:19:40 +00002643def Test_call_interface_method()
2644 var lines =<< trim END
2645 vim9script
2646 interface Base
2647 def Enter(): void
2648 endinterface
2649
2650 class Child implements Base
2651 def Enter(): void
2652 g:result ..= 'child'
2653 enddef
2654 endclass
2655
2656 def F(obj: Base)
2657 obj.Enter()
2658 enddef
2659
2660 g:result = ''
2661 F(Child.new())
2662 assert_equal('child', g:result)
2663 unlet g:result
2664 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002665 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002666
2667 lines =<< trim END
2668 vim9script
2669 class Base
2670 def Enter(): void
2671 g:result ..= 'base'
2672 enddef
2673 endclass
2674
2675 class Child extends Base
2676 def Enter(): void
2677 g:result ..= 'child'
2678 enddef
2679 endclass
2680
2681 def F(obj: Base)
2682 obj.Enter()
2683 enddef
2684
2685 g:result = ''
2686 F(Child.new())
2687 assert_equal('child', g:result)
2688 unlet g:result
2689 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002690 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002691
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002692 # method of interface returns a value
2693 lines =<< trim END
2694 vim9script
2695 interface Base
2696 def Enter(): string
2697 endinterface
2698
2699 class Child implements Base
2700 def Enter(): string
2701 g:result ..= 'child'
2702 return "/resource"
2703 enddef
2704 endclass
2705
2706 def F(obj: Base)
2707 var r = obj.Enter()
2708 g:result ..= r
2709 enddef
2710
2711 g:result = ''
2712 F(Child.new())
2713 assert_equal('child/resource', g:result)
2714 unlet g:result
2715 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002716 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002717
2718 lines =<< trim END
2719 vim9script
2720 class Base
2721 def Enter(): string
2722 return null_string
2723 enddef
2724 endclass
2725
2726 class Child extends Base
2727 def Enter(): string
2728 g:result ..= 'child'
2729 return "/resource"
2730 enddef
2731 endclass
2732
2733 def F(obj: Base)
2734 var r = obj.Enter()
2735 g:result ..= r
2736 enddef
2737
2738 g:result = ''
2739 F(Child.new())
2740 assert_equal('child/resource', g:result)
2741 unlet g:result
2742 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002743 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002744
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002745 # No class that implements the interface.
2746 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002747 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002748
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002749 interface IWithEE
2750 def Enter(): any
2751 def Exit(): void
2752 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002753
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002754 def With1(ee: IWithEE, F: func)
2755 var r = ee.Enter()
2756 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002757
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002758 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002759 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002760 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002761enddef
2762
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002763def Test_class_used_as_type()
2764 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002765 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002766
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002767 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002768 var x = 0
2769 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002770 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002771
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002772 var p: Point
2773 p = Point.new(2, 33)
2774 assert_equal(2, p.x)
2775 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002776 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002777 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002778
2779 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002780 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002781
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002782 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002783 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002784 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002785
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002786 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002787 var x = 0
2788 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002789 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002790
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002791 var p: Point
2792 p = Point.new(2, 33)
2793 var hx = p
2794 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002795 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002796 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002797
2798 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002799 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002800
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002801 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002802 var x = 0
2803 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002804 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002805
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002806 var p: Point
2807 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002808 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002809 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002810enddef
2811
Bram Moolenaar83677162023-01-08 19:54:10 +00002812def Test_class_extends()
2813 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002814 vim9script
2815 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002816 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002817 def GetOne(): number
2818 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002819 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002820 endclass
2821 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002822 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002823 def GetTotal(): number
2824 return this.one + this.two
2825 enddef
2826 endclass
2827 var o = Child.new()
2828 assert_equal(1, o.one)
2829 assert_equal(2, o.two)
2830 assert_equal(1, o.GetOne())
2831 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002832 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002833 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002834
2835 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002836 vim9script
2837 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002838 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002839 endclass
2840 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002841 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002842 endclass
2843 var o = Child.new(3, 44)
2844 assert_equal(3, o.one)
2845 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002846 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002847 v9.CheckSourceSuccess(lines)
2848
2849 lines =<< trim END
2850 vim9script
2851 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002852 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002853 endclass
2854 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002855 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002856 endclass
2857 END
2858 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2859
2860 lines =<< trim END
2861 vim9script
2862 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01002863 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002864 endclass
2865 END
2866 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2867
2868 lines =<< trim END
2869 vim9script
2870 var SomeVar = 99
2871 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01002872 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002873 endclass
2874 END
2875 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2876
2877 lines =<< trim END
2878 vim9script
2879 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002880 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002881 def ToString(): string
2882 return this.name
2883 enddef
2884 endclass
2885
2886 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002887 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002888 def ToString(): string
2889 return super.ToString() .. ': ' .. this.age
2890 enddef
2891 endclass
2892
2893 var o = Child.new('John', 42)
2894 assert_equal('John: 42', o.ToString())
2895 END
2896 v9.CheckSourceSuccess(lines)
2897
2898 lines =<< trim END
2899 vim9script
2900 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002901 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002902 def ToString(): number
2903 return this.age
2904 enddef
2905 def ToString(): string
2906 return this.age
2907 enddef
2908 endclass
2909 END
2910 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2911
2912 lines =<< trim END
2913 vim9script
2914 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002915 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002916 def ToString(): string
2917 return super .ToString() .. ': ' .. this.age
2918 enddef
2919 endclass
2920 var o = Child.new(42)
2921 echo o.ToString()
2922 END
2923 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2924
2925 lines =<< trim END
2926 vim9script
2927 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002928 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002929 def ToString(): string
2930 return this.name
2931 enddef
2932 endclass
2933
2934 var age = 42
2935 def ToString(): string
2936 return super.ToString() .. ': ' .. age
2937 enddef
2938 echo ToString()
2939 END
2940 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2941
2942 lines =<< trim END
2943 vim9script
2944 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002945 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002946 def ToString(): string
2947 return super.ToString() .. ': ' .. this.age
2948 enddef
2949 endclass
2950 var o = Child.new(42)
2951 echo o.ToString()
2952 END
2953 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
2954
2955 lines =<< trim END
2956 vim9script
2957 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002958 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002959 static def ToString(): string
2960 return 'Base class'
2961 enddef
2962 endclass
2963
2964 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002965 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002966 def ToString(): string
2967 return Base.ToString() .. ': ' .. this.age
2968 enddef
2969 endclass
2970
2971 var o = Child.new('John', 42)
2972 assert_equal('Base class: 42', o.ToString())
2973 END
2974 v9.CheckSourceSuccess(lines)
2975
2976 lines =<< trim END
2977 vim9script
2978 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002979 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002980 def new(init: number)
2981 this.value = number + 1
2982 enddef
2983 endclass
2984 class Child extends Base
2985 def new()
2986 this.new(3)
2987 enddef
2988 endclass
2989 var c = Child.new()
2990 END
2991 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002992
2993 # base class with more than one object member
2994 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002995 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002996
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002997 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002998 var success: bool
2999 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003000 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003001
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003002 class Success extends Result
3003 def new(this.value = v:none)
3004 this.success = true
3005 enddef
3006 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003007
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003008 var v = Success.new('asdf')
3009 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003010 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003011 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003012
3013 # class name after "extends" doesn't end in a space or NUL character
3014 lines =<< trim END
3015 vim9script
3016 class A
3017 endclass
3018 class B extends A"
3019 endclass
3020 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003021 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003022enddef
3023
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003024def Test_using_base_class()
3025 var lines =<< trim END
3026 vim9script
3027
3028 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003029 def Enter(): any
3030 return null
3031 enddef
3032 def Exit(resource: any): void
3033 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003034 endclass
3035
3036 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003037 def Enter(): any
3038 return 42
3039 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003040
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003041 def Exit(resource: number): void
3042 g:result ..= '/exit'
3043 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003044 endclass
3045
3046 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003047 var r = ee.Enter()
3048 try
3049 g:result ..= r
3050 finally
3051 g:result ..= '/finally'
3052 ee.Exit(r)
3053 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003054 enddef
3055
3056 g:result = ''
3057 With(ChildEE.new())
3058 assert_equal('42/finally/exit', g:result)
3059 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003060 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003061 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003062
3063 # Using super, Child invokes Base method which has optional arg. #12471
3064 lines =<< trim END
3065 vim9script
3066
3067 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003068 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003069 def Method(arg = 0)
3070 this.success = true
3071 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003072 endclass
3073
3074 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003075 def new()
3076 super.Method()
3077 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003078 endclass
3079
3080 var obj = Child.new()
3081 assert_equal(true, obj.success)
3082 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003083 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003084enddef
3085
Bram Moolenaara86655a2023-01-12 17:06:27 +00003086def Test_class_import()
3087 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003088 vim9script
3089 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003090 var kind: string
3091 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003092 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003093 END
3094 writefile(lines, 'Xanimal.vim', 'D')
3095
3096 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003097 vim9script
3098 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003099
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003100 var a: animal.Animal
3101 a = animal.Animal.new('fish', 'Eric')
3102 assert_equal('fish', a.kind)
3103 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003104
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003105 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3106 assert_equal('cat', b.kind)
3107 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003108 END
3109 v9.CheckScriptSuccess(lines)
3110enddef
3111
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003112" Test for implementing an imported interface
3113def Test_implement_imported_interface()
3114 var lines =<< trim END
3115 vim9script
3116 export interface Imp_Intf1
3117 def Fn1(): number
3118 endinterface
3119 export interface Imp_Intf2
3120 def Fn2(): number
3121 endinterface
3122 END
3123 writefile(lines, 'Ximportinterface.vim', 'D')
3124
3125 lines =<< trim END
3126 vim9script
3127 import './Ximportinterface.vim' as Xintf
3128
3129 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3130 def Fn1(): number
3131 return 10
3132 enddef
3133 def Fn2(): number
3134 return 20
3135 enddef
3136 endclass
3137 var a = A.new()
3138 assert_equal(10, a.Fn1())
3139 assert_equal(20, a.Fn2())
3140 END
3141 v9.CheckScriptSuccess(lines)
3142enddef
3143
3144" Test for extending an imported class
3145def Test_extend_imported_class()
3146 var lines =<< trim END
3147 vim9script
3148 export class Imp_C1
3149 def Fn1(): number
3150 return 5
3151 enddef
3152 endclass
3153 END
3154 writefile(lines, 'Xextendimportclass.vim', 'D')
3155
3156 lines =<< trim END
3157 vim9script
3158 import './Xextendimportclass.vim' as XClass
3159
3160 class A extends XClass.Imp_C1
3161 endclass
3162 var a = A.new()
3163 assert_equal(5, a.Fn1())
3164 END
3165 v9.CheckScriptSuccess(lines)
3166enddef
3167
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003168def Test_abstract_class()
3169 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003170 vim9script
3171 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003172 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003173 endclass
3174 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003175 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003176 endclass
3177 var p: Base = Person.new('Peter', 42)
3178 assert_equal('Peter', p.name)
3179 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003180 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003181 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003182
3183 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003184 vim9script
3185 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003186 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003187 endclass
3188 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003189 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003190 endclass
3191 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003192 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003193 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003194
3195 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003196 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003197 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003198 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003199 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003200 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003201
3202 # Abstract class cannot have a "new" function
3203 lines =<< trim END
3204 vim9script
3205 abstract class Base
3206 def new()
3207 enddef
3208 endclass
3209 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003210 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003211enddef
3212
Bram Moolenaar486fc252023-01-18 14:51:07 +00003213def Test_closure_in_class()
3214 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003215 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003216
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003217 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003218 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003219
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003220 def new()
3221 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3222 enddef
3223 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003224
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003225 Foo.new()
3226 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003227 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003228 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003229enddef
3230
Ernie Rael9ed53752023-12-11 17:40:46 +01003231def Test_construct_object_from_legacy()
3232 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003233 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003234 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003235
Ernie Rael9ed53752023-12-11 17:40:46 +01003236 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003237
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003238 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003239 def new(arg: string)
3240 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003241 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003242 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003243
Ernie Rael9ed53752023-12-11 17:40:46 +01003244 export def CreateA(...args: list<any>): A
3245 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003246 enddef
3247
Ernie Rael9ed53752023-12-11 17:40:46 +01003248 g:P = CreateA
3249 legacy call g:P('some_arg')
3250 assert_equal(true, newCalled)
3251 unlet g:P
3252 END
3253 v9.CheckSourceSuccess(lines)
3254
3255 lines =<< trim END
3256 vim9script
3257
3258 var newCalled = false
3259
3260 class A
3261 static def CreateA(options = {}): any
3262 return A.new()
3263 enddef
3264 def new()
3265 newCalled = true
3266 enddef
3267 endclass
3268
3269 g:P = A.CreateA
3270 legacy call g:P()
3271 assert_equal(true, newCalled)
3272 unlet g:P
3273 END
3274 v9.CheckSourceSuccess(lines)
3275
3276 # This also tests invoking "new()" with "call"
3277 lines =<< trim END
3278 vim9script
3279
3280 var createdObject: any
3281
3282 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003283 var val1: number
3284 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003285 static def CreateA(...args: list<any>): any
3286 createdObject = call(A.new, args)
3287 return createdObject
3288 enddef
3289 endclass
3290
3291 g:P = A.CreateA
3292 legacy call g:P(3, 5)
3293 assert_equal(3, createdObject.val1)
3294 assert_equal(5, createdObject.val2)
3295 legacy call g:P()
3296 assert_equal(0, createdObject.val1)
3297 assert_equal(0, createdObject.val2)
3298 legacy call g:P(7)
3299 assert_equal(7, createdObject.val1)
3300 assert_equal(0, createdObject.val2)
3301 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003302 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003303 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003304enddef
3305
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003306def Test_defer_with_object()
3307 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003308 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003309
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003310 class CWithEE
3311 def Enter()
3312 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003313 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003314 def Exit()
3315 g:result ..= "exited"
3316 enddef
3317 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003318
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003319 def With(ee: CWithEE, F: func)
3320 ee.Enter()
3321 defer ee.Exit()
3322 F()
3323 enddef
3324
3325 g:result = ''
3326 var obj = CWithEE.new()
3327 obj->With(() => {
3328 g:result ..= "called/"
3329 })
3330 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003331 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003332 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003333 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003334
3335 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003336 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003337
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003338 class BaseWithEE
3339 def Enter()
3340 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003341 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003342 def Exit()
3343 g:result ..= "exited-base"
3344 enddef
3345 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003346
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003347 class CWithEE extends BaseWithEE
3348 def Enter()
3349 g:result ..= "entered-child/"
3350 enddef
3351 def Exit()
3352 g:result ..= "exited-child"
3353 enddef
3354 endclass
3355
3356 def With(ee: BaseWithEE, F: func)
3357 ee.Enter()
3358 defer ee.Exit()
3359 F()
3360 enddef
3361
3362 g:result = ''
3363 var obj = CWithEE.new()
3364 obj->With(() => {
3365 g:result ..= "called/"
3366 })
3367 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003368 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003369 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003370 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003371enddef
3372
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003373" The following test used to crash Vim (Github issue #12676)
3374def Test_extends_method_crashes_vim()
3375 var lines =<< trim END
3376 vim9script
3377
3378 class Observer
3379 endclass
3380
3381 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003382 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003383
3384 def Set(v: any)
3385 if v != this.value
3386 this.value = v
3387 endif
3388 enddef
3389
3390 def Register(observer: Observer)
3391 enddef
3392 endclass
3393
3394 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003395 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003396 endclass
3397
3398 def Observe(obj: Property, who: Observer)
3399 obj.Register(who)
3400 enddef
3401
3402 var p = Bool.new(false)
3403 var myObserver = Observer.new()
3404
3405 Observe(p, myObserver)
3406
3407 p.Set(true)
3408 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003409 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003410enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003411
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003412" Test for calling a method in a class that is extended
3413def Test_call_method_in_extended_class()
3414 var lines =<< trim END
3415 vim9script
3416
3417 var prop_init_called = false
3418 var prop_register_called = false
3419
3420 class Property
3421 def Init()
3422 prop_init_called = true
3423 enddef
3424
3425 def Register()
3426 prop_register_called = true
3427 enddef
3428 endclass
3429
3430 class Bool extends Property
3431 endclass
3432
3433 def Observe(obj: Property)
3434 obj.Register()
3435 enddef
3436
3437 var p = Property.new()
3438 Observe(p)
3439
3440 p.Init()
3441 assert_true(prop_init_called)
3442 assert_true(prop_register_called)
3443 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003444 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003445enddef
3446
LemonBoyafe04662023-08-23 21:08:11 +02003447def Test_instanceof()
3448 var lines =<< trim END
3449 vim9script
3450
3451 class Base1
3452 endclass
3453
3454 class Base2 extends Base1
3455 endclass
3456
3457 interface Intf1
3458 endinterface
3459
3460 class Mix1 implements Intf1
3461 endclass
3462
3463 class Base3 extends Mix1
3464 endclass
3465
Ernie Rael2025af12023-12-12 16:58:00 +01003466 type AliasBase1 = Base1
3467 type AliasBase2 = Base2
3468 type AliasIntf1 = Intf1
3469 type AliasMix1 = Mix1
3470
LemonBoyafe04662023-08-23 21:08:11 +02003471 var b1 = Base1.new()
3472 var b2 = Base2.new()
3473 var b3 = Base3.new()
3474
3475 assert_true(instanceof(b1, Base1))
3476 assert_true(instanceof(b2, Base1))
3477 assert_false(instanceof(b1, Base2))
3478 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003479 assert_true(instanceof(b3, Base1, Base2, Intf1))
3480
3481 assert_true(instanceof(b1, AliasBase1))
3482 assert_true(instanceof(b2, AliasBase1))
3483 assert_false(instanceof(b1, AliasBase2))
3484 assert_true(instanceof(b3, AliasMix1))
3485 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003486
3487 def Foo()
3488 var a1 = Base1.new()
3489 var a2 = Base2.new()
3490 var a3 = Base3.new()
3491
3492 assert_true(instanceof(a1, Base1))
3493 assert_true(instanceof(a2, Base1))
3494 assert_false(instanceof(a1, Base2))
3495 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003496 assert_true(instanceof(a3, Base1, Base2, Intf1))
3497
3498 assert_true(instanceof(a1, AliasBase1))
3499 assert_true(instanceof(a2, AliasBase1))
3500 assert_false(instanceof(a1, AliasBase2))
3501 assert_true(instanceof(a3, AliasMix1))
3502 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003503 enddef
3504 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003505
3506 var o_null: Base1
3507 assert_false(instanceof(o_null, Base1))
3508
LemonBoyafe04662023-08-23 21:08:11 +02003509 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003510 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003511
3512 lines =<< trim END
3513 vim9script
3514
3515 class Base1
3516 endclass
3517 instanceof(Base1.new())
3518 END
3519 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3520
3521 lines =<< trim END
3522 vim9script
3523
3524 class Base1
3525 endclass
3526 def F()
3527 instanceof(Base1.new())
3528 enddef
3529 F()
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
3539 class Base2
3540 endclass
3541
3542 var o = Base2.new()
3543 instanceof(o, Base1, Base2, 3)
3544 END
3545 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3546
3547 lines =<< trim END
3548 vim9script
3549
3550 class Base1
3551 endclass
3552
3553 class Base2
3554 endclass
3555
3556 def F()
3557 var o = Base2.new()
3558 instanceof(o, Base1, Base2, 3)
3559 enddef
3560 F()
3561 END
3562 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003563enddef
3564
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003565" Test for calling a method in the parent class that is extended partially.
3566" This used to fail with the 'E118: Too many arguments for function: Text' error
3567" message (Github issue #12524).
3568def Test_call_method_in_parent_class()
3569 var lines =<< trim END
3570 vim9script
3571
3572 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003573 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003574
3575 def SetY(lnum: number)
3576 this._lnum = lnum
3577 enddef
3578
3579 def Text(): string
3580 return ''
3581 enddef
3582 endclass
3583
3584 class Foo extends Widget
3585 def Text(): string
3586 return '<Foo>'
3587 enddef
3588 endclass
3589
3590 def Stack(w1: Widget, w2: Widget): list<Widget>
3591 w1.SetY(1)
3592 w2.SetY(2)
3593 return [w1, w2]
3594 enddef
3595
3596 var foo1 = Foo.new()
3597 var foo2 = Foo.new()
3598 var l = Stack(foo1, foo2)
3599 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003600 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003601enddef
3602
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003603" Test for calling methods from three levels of classes
3604def Test_multi_level_method_call()
3605 var lines =<< trim END
3606 vim9script
3607
3608 var A_func1: number = 0
3609 var A_func2: number = 0
3610 var A_func3: number = 0
3611 var B_func2: number = 0
3612 var B_func3: number = 0
3613 var C_func3: number = 0
3614
3615 class A
3616 def Func1()
3617 A_func1 += 1
3618 enddef
3619
3620 def Func2()
3621 A_func2 += 1
3622 enddef
3623
3624 def Func3()
3625 A_func3 += 1
3626 enddef
3627 endclass
3628
3629 class B extends A
3630 def Func2()
3631 B_func2 += 1
3632 enddef
3633
3634 def Func3()
3635 B_func3 += 1
3636 enddef
3637 endclass
3638
3639 class C extends B
3640 def Func3()
3641 C_func3 += 1
3642 enddef
3643 endclass
3644
3645 def A_CallFuncs(a: A)
3646 a.Func1()
3647 a.Func2()
3648 a.Func3()
3649 enddef
3650
3651 def B_CallFuncs(b: B)
3652 b.Func1()
3653 b.Func2()
3654 b.Func3()
3655 enddef
3656
3657 def C_CallFuncs(c: C)
3658 c.Func1()
3659 c.Func2()
3660 c.Func3()
3661 enddef
3662
3663 var cobj = C.new()
3664 A_CallFuncs(cobj)
3665 B_CallFuncs(cobj)
3666 C_CallFuncs(cobj)
3667 assert_equal(3, A_func1)
3668 assert_equal(0, A_func2)
3669 assert_equal(0, A_func3)
3670 assert_equal(3, B_func2)
3671 assert_equal(0, B_func3)
3672 assert_equal(3, C_func3)
3673 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003674 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003675enddef
3676
3677" Test for using members from three levels of classes
3678def Test_multi_level_member_access()
3679 var lines =<< trim END
3680 vim9script
3681
3682 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003683 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003684 endclass
3685
3686 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003687 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003688 endclass
3689
3690 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003691 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003692 endclass
3693
3694 def A_members(a: A)
3695 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003696 enddef
3697
3698 def B_members(b: B)
3699 b.val1 += 1
3700 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003701 enddef
3702
3703 def C_members(c: C)
3704 c.val1 += 1
3705 c.val2 += 1
3706 c.val3 += 1
3707 enddef
3708
3709 var cobj = C.new()
3710 A_members(cobj)
3711 B_members(cobj)
3712 C_members(cobj)
3713 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003714 assert_equal(2, cobj.val2)
3715 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003716 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003717 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003718enddef
3719
LemonBoy0ffc17a2023-08-20 18:09:11 +02003720" Test expansion of <stack> with class methods.
3721def Test_stack_expansion_with_methods()
3722 var lines =<< trim END
3723 vim9script
3724
3725 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003726 def M1()
3727 F0()
3728 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003729 endclass
3730
3731 def F0()
3732 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3733 enddef
3734
3735 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003736 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003737 enddef
3738
3739 F()
3740 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003741 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003742enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003743
3744" Test the return type of the new() constructor
3745def Test_new_return_type()
3746 # new() uses the default return type and there is no return statement
3747 var lines =<< trim END
3748 vim9script
3749
3750 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003751 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003752
3753 def new(this._bufnr)
3754 if !bufexists(this._bufnr)
3755 this._bufnr = -1
3756 endif
3757 enddef
3758 endclass
3759
3760 var c = C.new(12345)
3761 assert_equal('object<C>', typename(c))
3762
3763 var v1: C
3764 v1 = C.new(12345)
3765 assert_equal('object<C>', typename(v1))
3766
3767 def F()
3768 var v2: C
3769 v2 = C.new(12345)
3770 assert_equal('object<C>', typename(v2))
3771 enddef
3772 F()
3773 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003774 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003775
3776 # new() uses the default return type and an empty 'return' statement
3777 lines =<< trim END
3778 vim9script
3779
3780 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003781 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003782
3783 def new(this._bufnr)
3784 if !bufexists(this._bufnr)
3785 this._bufnr = -1
3786 return
3787 endif
3788 enddef
3789 endclass
3790
3791 var c = C.new(12345)
3792 assert_equal('object<C>', typename(c))
3793
3794 var v1: C
3795 v1 = C.new(12345)
3796 assert_equal('object<C>', typename(v1))
3797
3798 def F()
3799 var v2: C
3800 v2 = C.new(12345)
3801 assert_equal('object<C>', typename(v2))
3802 enddef
3803 F()
3804 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003805 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003806
3807 # new() uses "any" return type and returns "this"
3808 lines =<< trim END
3809 vim9script
3810
3811 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003812 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003813
3814 def new(this._bufnr): any
3815 if !bufexists(this._bufnr)
3816 this._bufnr = -1
3817 return this
3818 endif
3819 enddef
3820 endclass
3821 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003822 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003823
3824 # new() uses 'Dict' return type and returns a Dict
3825 lines =<< trim END
3826 vim9script
3827
3828 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003829 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003830
3831 def new(): dict<any>
3832 this._state = {}
3833 return this._state
3834 enddef
3835 endclass
3836
3837 var c = C.new()
3838 assert_equal('object<C>', typename(c))
3839 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003840 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003841enddef
3842
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003843" Test for checking a member initialization type at run time.
3844def Test_runtime_type_check_for_member_init()
3845 var lines =<< trim END
3846 vim9script
3847
3848 var retnum: bool = false
3849
3850 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003851 retnum = !retnum
3852 if retnum
3853 return 1
3854 else
3855 return "hello"
3856 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003857 enddef
3858
3859 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003860 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003861 endclass
3862
3863 var c1 = C.new()
3864 var c2 = C.new()
3865 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003866 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003867enddef
3868
3869" Test for locking a variable referring to an object and reassigning to another
3870" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003871def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003872 var lines =<< trim END
3873 vim9script
3874
3875 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003876 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003877 def new(this.val)
3878 enddef
3879 endclass
3880
3881 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3882 lockvar 2 some_dict
3883
3884 var current: C
3885 current = some_dict['c']
3886 assert_equal(3, current.val)
3887 current = some_dict['b']
3888 assert_equal(2, current.val)
3889
3890 def F()
3891 current = some_dict['c']
3892 enddef
3893
3894 def G()
3895 current = some_dict['b']
3896 enddef
3897
3898 F()
3899 assert_equal(3, current.val)
3900 G()
3901 assert_equal(2, current.val)
3902 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003903 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003904enddef
3905
Ernie Raelee865f32023-09-29 19:53:55 +02003906" Test trying to lock an object variable from various places
3907def Test_lockvar_object_variable()
3908 # An object variable lockvar has several cases:
3909 # object method, scriptlevel, scriplevel from :def, :def arg
3910 # method arg, static method arg.
3911 # Also different depths
3912
Ernie Raelee865f32023-09-29 19:53:55 +02003913 #
3914 # lockvar of read-only object variable
3915 #
3916
3917 # read-only lockvar from object method
3918 var lines =<< trim END
3919 vim9script
3920
3921 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003922 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02003923 def Lock()
3924 lockvar this.val1
3925 enddef
3926 endclass
3927 var o = C.new(3)
3928 o.Lock()
3929 END
Ernie Rael64885642023-10-04 20:16:22 +02003930 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003931
3932 # read-only lockvar from scriptlevel
3933 lines =<< trim END
3934 vim9script
3935
3936 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003937 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02003938 endclass
3939 var o = C.new(3)
3940 lockvar o.val2
3941 END
3942 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3943
3944 # read-only lockvar of scriptlevel variable from def
3945 lines =<< trim END
3946 vim9script
3947
3948 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003949 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02003950 endclass
3951 var o = C.new(3)
3952 def Lock()
3953 lockvar o.val3
3954 enddef
3955 Lock()
3956 END
3957 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3958
3959 # read-only lockvar of def argument variable
3960 lines =<< trim END
3961 vim9script
3962
3963 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003964 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02003965 endclass
3966 def Lock(o: C)
3967 lockvar o.val4
3968 enddef
3969 Lock(C.new(3))
3970 END
3971 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3972
3973 # TODO: the following tests use type "any" for argument. Need a run time
3974 # check for access. Probably OK as is for now.
3975
3976 # read-only lockvar from object method arg
3977 lines =<< trim END
3978 vim9script
3979
3980 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003981 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02003982 def Lock(o_any: any)
3983 lockvar o_any.val5
3984 enddef
3985 endclass
3986 var o = C.new(3)
3987 o.Lock(C.new(5))
3988 END
Ernie Rael64885642023-10-04 20:16:22 +02003989 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003990
3991 # read-only lockvar from class method arg
3992 lines =<< trim END
3993 vim9script
3994
3995 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003996 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02003997 static def Lock(o_any: any)
3998 lockvar o_any.val6
3999 enddef
4000 endclass
4001 var o = C.new(3)
4002 C.Lock(o)
4003 END
Ernie Rael64885642023-10-04 20:16:22 +02004004 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004005
4006 #
4007 # lockvar of public object variable
4008 #
4009
4010 # lockvar from object method
4011 lines =<< trim END
4012 vim9script
4013
4014 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004015 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004016 def Lock()
4017 lockvar this.val1
4018 enddef
4019 endclass
4020 var o = C.new(3)
4021 o.Lock()
4022 END
4023 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4024
4025 # lockvar from scriptlevel
4026 lines =<< trim END
4027 vim9script
4028
4029 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004030 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004031 endclass
4032 var o = C.new(3)
4033 lockvar o.val2
4034 END
4035 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4036
4037 # lockvar of scriptlevel variable from def
4038 lines =<< trim END
4039 vim9script
4040
4041 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004042 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004043 endclass
4044 var o = C.new(3)
4045 def Lock()
4046 lockvar o.val3
4047 enddef
4048 Lock()
4049 END
4050 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4051
4052 # lockvar of def argument variable
4053 lines =<< trim END
4054 vim9script
4055
4056 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004057 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004058 endclass
4059 def Lock(o: C)
4060 lockvar o.val4
4061 enddef
4062 Lock(C.new(3))
4063 END
4064 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4065
4066 # lockvar from object method arg
4067 lines =<< trim END
4068 vim9script
4069
4070 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004071 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004072 def Lock(o_any: any)
4073 lockvar o_any.val5
4074 enddef
4075 endclass
4076 var o = C.new(3)
4077 o.Lock(C.new(5))
4078 END
4079 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4080
4081 # lockvar from class method arg
4082 lines =<< trim END
4083 vim9script
4084
4085 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004086 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004087 static def Lock(o_any: any)
4088 lockvar o_any.val6
4089 enddef
4090 endclass
4091 var o = C.new(3)
4092 C.Lock(o)
4093 END
4094 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4095enddef
4096
4097" Test trying to lock a class variable from various places
4098def Test_lockvar_class_variable()
4099
4100 # lockvar bare static from object method
4101 var lines =<< trim END
4102 vim9script
4103
4104 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004105 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004106 def Lock()
4107 lockvar sval1
4108 enddef
4109 endclass
4110 var o = C.new()
4111 o.Lock()
4112 END
4113 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4114
4115 # lockvar C.static from object method
4116 lines =<< trim END
4117 vim9script
4118
4119 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004120 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004121 def Lock()
4122 lockvar C.sval2
4123 enddef
4124 endclass
4125 var o = C.new()
4126 o.Lock()
4127 END
4128 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4129
4130 # lockvar bare static from class method
4131 lines =<< trim END
4132 vim9script
4133
4134 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004135 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004136 static def Lock()
4137 lockvar sval3
4138 enddef
4139 endclass
4140 C.Lock()
4141 END
4142 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4143
4144 # lockvar C.static from class method
4145 lines =<< trim END
4146 vim9script
4147
4148 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004149 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004150 static def Lock()
4151 lockvar C.sval4
4152 enddef
4153 endclass
4154 C.Lock()
4155 END
4156 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4157
4158 # lockvar C.static from script level
4159 lines =<< trim END
4160 vim9script
4161
4162 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004163 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004164 endclass
4165 lockvar C.sval5
4166 END
4167 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4168
4169 # lockvar o.static from script level
4170 lines =<< trim END
4171 vim9script
4172
4173 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004174 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004175 endclass
4176 var o = C.new()
4177 lockvar o.sval6
4178 END
4179 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4180enddef
4181
4182" Test locking an argument to :def
4183def Test_lockvar_argument()
4184 # Lockvar a function arg
4185 var lines =<< trim END
4186 vim9script
4187
4188 def Lock(val: any)
4189 lockvar val
4190 enddef
4191
4192 var d = {a: 1, b: 2}
4193 Lock(d)
4194
4195 d->extend({c: 3})
4196 END
4197 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4198
4199 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4200 # class member in "C". This tests lval_root_is_arg.
4201 lines =<< trim END
4202 vim9script
4203
4204 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004205 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004206 endclass
4207
4208 def Lock2(sval: any)
4209 lockvar sval
4210 enddef
4211
4212 var o = C.new()
4213 Lock2(o)
4214 END
4215 v9.CheckSourceSuccess(lines)
4216
4217 # Lock a class.
4218 lines =<< trim END
4219 vim9script
4220
4221 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004222 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004223 endclass
4224
4225 def Lock2(sval: any)
4226 lockvar sval
4227 enddef
4228
4229 Lock2(C)
4230 END
Ernie Raelb077b582023-12-14 20:11:44 +01004231 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004232
4233 # Lock an object.
4234 lines =<< trim END
4235 vim9script
4236
4237 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004238 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004239 endclass
4240
4241 def Lock2(sval: any)
4242 lockvar sval
4243 enddef
4244
4245 Lock2(C.new())
4246 END
4247 v9.CheckSourceSuccess(lines)
4248
4249 # In this case (unlike previous) "lockvar sval" is a class member.
4250 lines =<< trim END
4251 vim9script
4252
4253 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004254 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004255 def Lock2()
4256 lockvar sval
4257 enddef
4258 endclass
4259
4260
4261 var o = C.new()
4262 o.Lock2()
4263 END
4264 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4265enddef
4266
4267" Test that this can be locked without error
4268def Test_lockvar_this()
4269 # lockvar this
4270 var lines =<< trim END
4271 vim9script
4272 class C
4273 def TLock()
4274 lockvar this
4275 enddef
4276 endclass
4277 var o = C.new()
4278 o.TLock()
4279 END
4280 v9.CheckSourceSuccess(lines)
4281
4282 # lockvar four (four letter word, but not this)
4283 lines =<< trim END
4284 vim9script
4285 class C
4286 def TLock4()
4287 var four: number
4288 lockvar four
4289 enddef
4290 endclass
4291 var o = C.new()
4292 o.TLock4()
4293 END
4294 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4295
4296 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4297 lines =<< trim END
4298 vim9script
4299 class C
4300 def TLock5()
4301 var this5: number
4302 lockvar this5
4303 enddef
4304 endclass
4305 var o = C.new()
4306 o.TLock5()
4307 END
4308 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4309enddef
4310
4311" Test some general lockvar cases
4312def Test_lockvar_general()
4313 # lockvar an object and a class. It does nothing
4314 var lines =<< trim END
4315 vim9script
4316 class C
4317 endclass
4318 var o = C.new()
4319 lockvar o
4320 lockvar C
4321 END
4322 v9.CheckSourceSuccess(lines)
4323
4324 # Lock a list element that's nested in an object variable from a :def
4325 lines =<< trim END
4326 vim9script
4327
4328 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004329 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004330 endclass
4331 def Lock2(obj: any)
4332 lockvar obj.val[1]
4333 enddef
4334
4335 var o = C.new()
4336 Lock2(o)
4337 o.val[0] = [9]
4338 assert_equal([ [9], [2], [3] ], o.val)
4339 try
4340 o.val[1] = [999]
4341 call assert_false(true, 'assign should have failed')
4342 catch
4343 assert_exception('E741:')
4344 endtry
4345 o.val[2] = [8]
4346 assert_equal([ [9], [2], [8] ], o.val)
4347 END
4348 v9.CheckSourceSuccess(lines)
4349
4350 # Lock a list element that's nested in an object variable from scriptlevel
4351 lines =<< trim END
4352 vim9script
4353
4354 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004355 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004356 endclass
4357
4358 var o = C.new()
4359 lockvar o.val[1]
4360 o.val[0] = [9]
4361 assert_equal([ [9], [2], [3] ], o.val)
4362 try
4363 o.val[1] = [999]
4364 call assert_false(true, 'assign should have failed')
4365 catch
4366 assert_exception('E741:')
4367 endtry
4368 o.val[2] = [8]
4369 assert_equal([ [9], [2], [8] ], o.val)
4370 END
4371 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004372
4373 # lock a script level variable from an object method
4374 lines =<< trim END
4375 vim9script
4376
4377 class C
4378 def Lock()
4379 lockvar l
4380 enddef
4381 endclass
4382
4383 var l = [1]
4384 C.new().Lock()
4385 l[0] = 11
4386 END
4387 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4388
Ernie Rael03042a22023-11-11 08:53:32 +01004389 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004390 # in an object fetched via a script level list
4391 lines =<< trim END
4392 vim9script
4393
4394 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004395 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004396 def Lock()
4397 lockvar lc[0]._v1[1]
4398 enddef
4399 endclass
4400
4401 var l = [[1], [2], [3]]
4402 var o = C.new(l)
4403 var lc: list<C> = [ o ]
4404
4405 o.Lock()
4406 l[0] = [22]
4407 l[1] = [33]
4408 END
4409 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4410
4411 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004412 # in a class that does not own the protected variable.
4413 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004414 # the same name.
4415 lines =<< trim END
4416 vim9script
4417
4418 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004419 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004420 def Lock(obj: any)
4421 lockvar lc[0]._v1[1]
4422 enddef
4423 endclass
4424
4425 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004426 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004427 endclass
4428
4429 var l = [[1], [2], [3]]
4430 var o = C.new(l)
4431 var lc: list<C> = [ o ]
4432
4433 var o2 = C2.new()
4434 o2.Lock(o)
4435 END
Ernie Rael03042a22023-11-11 08:53:32 +01004436 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004437enddef
4438
Ernie Rael9771b2a2023-10-07 22:05:40 +02004439" Test builtin islocked()
4440def Test_lockvar_islocked()
4441 # Can't lock class/object variable
4442 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004443 # Lock item of variable's value (a list item)
4444 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004445 var lines =<< trim END
4446 vim9script
4447
4448 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004449 var o0: list<list<number>> = [ [0], [1], [2]]
4450 var o1: list<list<number>> = [[10], [11], [12]]
4451 static var c0: list<list<number>> = [[20], [21], [22]]
4452 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004453 endclass
4454
4455 def LockIt(arg: any)
4456 lockvar arg
4457 enddef
4458
4459 def UnlockIt(arg: any)
4460 unlockvar arg
4461 enddef
4462
4463 var obj = C.new()
4464 #lockvar obj.o1 # can't lock something you can't write to
4465
4466 try
4467 lockvar obj.o1 # can't lock something you can't write to
4468 call assert_false(1, '"lockvar obj.o1" should have failed')
4469 catch
4470 call assert_exception('E1335:')
4471 endtry
4472
4473 LockIt(obj.o1) # but can lock it's value
4474 assert_equal(1, islocked("obj.o1"))
4475 assert_equal(1, islocked("obj.o1[0]"))
4476 assert_equal(1, islocked("obj.o1[1]"))
4477 UnlockIt(obj.o1)
4478 assert_equal(0, islocked("obj.o1"))
4479 assert_equal(0, islocked("obj.o1[0]"))
4480
4481 lockvar obj.o1[0]
4482 assert_equal(0, islocked("obj.o1"))
4483 assert_equal(1, islocked("obj.o1[0]"))
4484 assert_equal(0, islocked("obj.o1[1]"))
4485 unlockvar obj.o1[0]
4486 assert_equal(0, islocked("obj.o1"))
4487 assert_equal(0, islocked("obj.o1[0]"))
4488
4489 # Same thing, but with a static
4490
4491 try
4492 lockvar C.c1 # can't lock something you can't write to
4493 call assert_false(1, '"lockvar C.c1" should have failed')
4494 catch
4495 call assert_exception('E1335:')
4496 endtry
4497
4498 LockIt(C.c1) # but can lock it's value
4499 assert_equal(1, islocked("C.c1"))
4500 assert_equal(1, islocked("C.c1[0]"))
4501 assert_equal(1, islocked("C.c1[1]"))
4502 UnlockIt(C.c1)
4503 assert_equal(0, islocked("C.c1"))
4504 assert_equal(0, islocked("C.c1[0]"))
4505
4506 lockvar C.c1[0]
4507 assert_equal(0, islocked("C.c1"))
4508 assert_equal(1, islocked("C.c1[0]"))
4509 assert_equal(0, islocked("C.c1[1]"))
4510 unlockvar C.c1[0]
4511 assert_equal(0, islocked("C.c1"))
4512 assert_equal(0, islocked("C.c1[0]"))
4513 END
4514 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004515
4516 # Do islocked() from an object method
4517 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004518 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004519 vim9script
4520
4521 var l0o0 = [ [0], [1], [2]]
4522 var l0o1 = [ [10], [11], [12]]
4523 var l0c0 = [[120], [121], [122]]
4524 var l0c1 = [[130], [131], [132]]
4525
4526 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004527 var o0: list<list<number>> = l0o0
4528 var o1: list<list<number>> = l0o1
4529 static var c0: list<list<number>> = l0c0
4530 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004531 def Islocked(arg: string): number
4532 return islocked(arg)
4533 enddef
4534 static def SIslocked(arg: string): number
4535 return islocked(arg)
4536 enddef
4537 endclass
4538
4539 var l2o0 = [[20000], [20001], [20002]]
4540 var l2o1 = [[20010], [20011], [20012]]
4541 var l2c0 = [[20120], [20121], [20122]]
4542 var l2c1 = [[20130], [20131], [20132]]
4543
4544 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004545 var o0: list<list<number>> = l2o0
4546 var o1: list<list<number>> = l2o1
4547 static var c0: list<list<number>> = l2c0
4548 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004549 def Islocked(arg: string): number
4550 return islocked(arg)
4551 enddef
4552 static def SIslocked(arg: string): number
4553 return islocked(arg)
4554 enddef
4555 endclass
4556
4557 var obj0 = C0.new()
4558 var obj2 = C2.new()
4559
4560 var l = [ obj0, null_object, obj2 ]
4561
4562 # lock list, object func access through script var expr
4563 assert_equal(0, obj0.Islocked("l[0].o0"))
4564 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4565 lockvar l0o0
4566 assert_equal(1, obj0.Islocked("l[0].o0"))
4567 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4568
4569 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4570
4571 # lock list element, object func access through script var expr
4572 lockvar l0o1[1]
4573 assert_equal(0, obj0.Islocked("this.o1[0]"))
4574 assert_equal(1, obj0.Islocked("this.o1[1]"))
4575
4576 assert_equal(0, obj0.Islocked("this.o1"))
4577 lockvar l0o1
4578 assert_equal(1, obj0.Islocked("this.o1"))
4579 unlockvar l0o1
4580
4581 lockvar l0c1[1]
4582
4583 # static by class name member expr from same class
4584 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4585 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4586 # static by bare name member expr from same class
4587 assert_equal(0, obj0.Islocked("c1[0]"))
4588 assert_equal(1, obj0.Islocked("c1[1]"))
4589
4590 # static by class name member expr from other class
4591 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4592 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4593 # static by bare name member expr from other class
4594 assert_equal(0, obj2.Islocked("c1[0]"))
4595 assert_equal(0, obj2.Islocked("c1[1]"))
4596
4597
4598 # static by bare name in same class
4599 assert_equal(0, obj0.Islocked("c0"))
4600 lockvar l0c0
4601 assert_equal(1, obj0.Islocked("c0"))
4602
4603 #
4604 # similar stuff, but use static method
4605 #
4606
4607 unlockvar l0o0
4608
4609 # lock list, object func access through script var expr
4610 assert_equal(0, C0.SIslocked("l[0].o0"))
4611 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4612 lockvar l0o0
4613 assert_equal(1, C0.SIslocked("l[0].o0"))
4614 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4615
4616 unlockvar l0o1
4617
4618 # can't access "this" from class method
4619 try
4620 C0.SIslocked("this.o1[0]")
4621 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4622 catch
4623 call assert_exception('E121: Undefined variable: this')
4624 endtry
4625
4626 lockvar l0c1[1]
4627
4628 # static by class name member expr from same class
4629 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4630 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4631 # static by bare name member expr from same class
4632 assert_equal(0, C0.SIslocked("c1[0]"))
4633 assert_equal(1, C0.SIslocked("c1[1]"))
4634
4635 # static by class name member expr from other class
4636 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4637 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4638 # static by bare name member expr from other class
4639 assert_equal(0, C2.SIslocked("c1[0]"))
4640 assert_equal(0, C2.SIslocked("c1[1]"))
4641
4642
4643 # static by bare name in same class
4644 unlockvar l0c0
4645 assert_equal(0, C0.SIslocked("c0"))
4646 lockvar l0c0
4647 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004648 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004649 v9.CheckSourceSuccess(lines)
4650
4651 # Check islocked class/object from various places.
4652 lines =<< trim END
4653 vim9script
4654
4655 class C
4656 def Islocked(arg: string): number
4657 return islocked(arg)
4658 enddef
4659 static def SIslocked(arg: string): number
4660 return islocked(arg)
4661 enddef
4662 endclass
4663 var obj = C.new()
4664
4665 # object method
4666 assert_equal(0, obj.Islocked("this"))
4667 assert_equal(0, obj.Islocked("C"))
4668
4669 # class method
4670 ### assert_equal(0, C.SIslocked("this"))
4671 assert_equal(0, C.SIslocked("C"))
4672
4673 #script level
4674 var v: number
4675 v = islocked("C")
4676 assert_equal(0, v)
4677 v = islocked("obj")
4678 assert_equal(0, v)
4679 END
4680 v9.CheckSourceSuccess(lines)
4681enddef
4682
4683def Test_lockvar_islocked_notfound()
4684 # Try non-existent things
4685 var lines =<< trim END
4686 vim9script
4687
4688 class C
4689 def Islocked(arg: string): number
4690 return islocked(arg)
4691 enddef
4692 static def SIslocked(arg: string): number
4693 return islocked(arg)
4694 enddef
4695 endclass
4696 var obj = C.new()
4697 assert_equal(-1, obj.Islocked("anywhere"))
4698 assert_equal(-1, C.SIslocked("notanywhere"))
4699 END
4700 v9.CheckSourceSuccess(lines)
4701
4702 # Something not found of the form "name1.name2" is an error
4703 lines =<< trim END
4704 vim9script
4705
4706 islocked("one.two")
4707 END
4708 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4709
4710 lines =<< trim END
4711 vim9script
4712
4713 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004714 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004715 def Islocked(arg: string): number
4716 return islocked(arg)
4717 enddef
4718 endclass
4719 var obj = C.new()
4720 obj.Islocked("this.val.not_there"))
4721 END
4722 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4723
4724 lines =<< trim END
4725 vim9script
4726
4727 class C
4728 def Islocked(arg: string): number
4729 return islocked(arg)
4730 enddef
4731 endclass
4732 var obj = C.new()
4733 obj.Islocked("this.notobjmember")
4734 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004735 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004736
4737 # access a script variable through methods
4738 lines =<< trim END
4739 vim9script
4740
4741 var l = [1]
4742 class C
4743 def Islocked(arg: string): number
4744 return islocked(arg)
4745 enddef
4746 static def SIslocked(arg: string): number
4747 return islocked(arg)
4748 enddef
4749 endclass
4750 var obj = C.new()
4751 assert_equal(0, obj.Islocked("l"))
4752 assert_equal(0, C.SIslocked("l"))
4753 lockvar l
4754 assert_equal(1, obj.Islocked("l"))
4755 assert_equal(1, C.SIslocked("l"))
4756 END
4757 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004758enddef
4759
Ernie Rael03042a22023-11-11 08:53:32 +01004760" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004761def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004762 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004763 var lines =<< trim END
4764 vim9script
4765
4766 class A
4767 def _Foo(): number
4768 return 1234
4769 enddef
4770 endclass
4771 var a = A.new()
4772 a._Foo()
4773 END
Ernie Rael03042a22023-11-11 08:53:32 +01004774 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004775
Ernie Rael03042a22023-11-11 08:53:32 +01004776 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004777 lines =<< trim END
4778 vim9script
4779
4780 class A
4781 def _Foo(): number
4782 return 1234
4783 enddef
4784 endclass
4785 def T()
4786 var a = A.new()
4787 a._Foo()
4788 enddef
4789 T()
4790 END
Ernie Rael03042a22023-11-11 08:53:32 +01004791 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004792
Ernie Rael03042a22023-11-11 08:53:32 +01004793 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004794 lines =<< trim END
4795 vim9script
4796
4797 class A
4798 def _Foo(): number
4799 return 1234
4800 enddef
4801 def Bar(): number
4802 return this._Foo()
4803 enddef
4804 endclass
4805 var a = A.new()
4806 assert_equal(1234, a.Bar())
4807 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004808 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004809
Ernie Rael03042a22023-11-11 08:53:32 +01004810 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004811 lines =<< trim END
4812 vim9script
4813
4814 class A
4815 def _Foo(): number
4816 return 1234
4817 enddef
4818 def Bar(): number
4819 return this._Foo()
4820 enddef
4821 endclass
4822 def T()
4823 var a = A.new()
4824 assert_equal(1234, a.Bar())
4825 enddef
4826 T()
4827 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004828 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004829
Ernie Rael03042a22023-11-11 08:53:32 +01004830 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004831 lines =<< trim END
4832 vim9script
4833
4834 class A
4835 def _Foo(): number
4836 return 1234
4837 enddef
4838 def Bar(): number
4839 return _Foo()
4840 enddef
4841 endclass
4842 var a = A.new()
4843 a.Bar()
4844 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004845 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004846
Ernie Rael03042a22023-11-11 08:53:32 +01004847 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004848 lines =<< trim END
4849 vim9script
4850
4851 class A
4852 def _Foo(): number
4853 return 1234
4854 enddef
4855 endclass
4856 A._Foo()
4857 END
Ernie Rael03042a22023-11-11 08:53:32 +01004858 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004859
Ernie Rael03042a22023-11-11 08:53:32 +01004860 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004861 lines =<< trim END
4862 vim9script
4863
4864 class A
4865 def _Foo()
4866 enddef
4867 def _Foo()
4868 enddef
4869 endclass
4870 var a = A.new()
4871 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004872 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004873
Ernie Rael03042a22023-11-11 08:53:32 +01004874 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004875 lines =<< trim END
4876 vim9script
4877
4878 class A
4879 def _Foo()
4880 enddef
4881 def Foo()
4882 enddef
4883 endclass
4884 var a = A.new()
4885 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004886 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004887
Ernie Rael03042a22023-11-11 08:53:32 +01004888 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004889 lines =<< trim END
4890 vim9script
4891
4892 class A
4893 def Foo()
4894 enddef
4895 def _Foo()
4896 enddef
4897 endclass
4898 var a = A.new()
4899 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004900 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004901
Ernie Rael03042a22023-11-11 08:53:32 +01004902 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004903 lines =<< trim END
4904 vim9script
4905
4906 class A
4907 def Foo(): number
4908 return 100
4909 enddef
4910 def _Bar(): number
4911 return 200
4912 enddef
4913 def _Baz()
4914 assert_equal(100, this.Foo())
4915 assert_equal(200, this._Bar())
4916 enddef
4917 def T()
4918 this._Baz()
4919 enddef
4920 endclass
4921 var a = A.new()
4922 a.T()
4923 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004924 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004925
Ernie Rael03042a22023-11-11 08:53:32 +01004926 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004927 lines =<< trim END
4928 vim9script
4929
4930 class A
4931 def _Foo(): number
4932 return 100
4933 enddef
4934 endclass
4935 class B
4936 def Foo(): number
4937 var a = A.new()
4938 a._Foo()
4939 enddef
4940 endclass
4941 var b = B.new()
4942 b.Foo()
4943 END
Ernie Rael03042a22023-11-11 08:53:32 +01004944 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004945
Ernie Rael03042a22023-11-11 08:53:32 +01004946 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004947 lines =<< trim END
4948 vim9script
4949 class A
4950 def _Foo(): number
4951 return 1234
4952 enddef
4953 endclass
4954 class B extends A
4955 def Bar()
4956 enddef
4957 endclass
4958 class C extends B
4959 def Baz(): number
4960 return this._Foo()
4961 enddef
4962 endclass
4963 var c = C.new()
4964 assert_equal(1234, c.Baz())
4965 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004966 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004967
Ernie Rael03042a22023-11-11 08:53:32 +01004968 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004969 lines =<< trim END
4970 vim9script
4971 class A
4972 def _Foo(): number
4973 return 1234
4974 enddef
4975 endclass
4976 class B extends A
4977 def Bar()
4978 enddef
4979 endclass
4980 class C extends B
4981 def Baz(): number
4982 enddef
4983 endclass
4984 var c = C.new()
4985 assert_equal(1234, c._Foo())
4986 END
Ernie Rael03042a22023-11-11 08:53:32 +01004987 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004988
4989 # Using "_" prefix in a method name should fail outside of a class
4990 lines =<< trim END
4991 vim9script
4992 def _Foo(): number
4993 return 1234
4994 enddef
4995 var a = _Foo()
4996 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004997 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004998enddef
4999
Ernie Rael03042a22023-11-11 08:53:32 +01005000" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005001def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005002 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005003 var lines =<< trim END
5004 vim9script
5005
5006 class A
5007 static def _Foo(): number
5008 return 1234
5009 enddef
5010 endclass
5011 A._Foo()
5012 END
Ernie Rael03042a22023-11-11 08:53:32 +01005013 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005014
Ernie Rael03042a22023-11-11 08:53:32 +01005015 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005016 lines =<< trim END
5017 vim9script
5018
5019 class A
5020 static def _Foo(): number
5021 return 1234
5022 enddef
5023 endclass
5024 def T()
5025 A._Foo()
5026 enddef
5027 T()
5028 END
Ernie Rael03042a22023-11-11 08:53:32 +01005029 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005030
Ernie Rael03042a22023-11-11 08:53:32 +01005031 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005032 lines =<< trim END
5033 vim9script
5034
5035 class A
5036 static def _Foo(): number
5037 return 1234
5038 enddef
5039 endclass
5040 var a = A.new()
5041 a._Foo()
5042 END
Ernie Rael03042a22023-11-11 08:53:32 +01005043 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005044
Ernie Rael03042a22023-11-11 08:53:32 +01005045 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005046 lines =<< trim END
5047 vim9script
5048
5049 class A
5050 static def _Foo(): number
5051 return 1234
5052 enddef
5053 endclass
5054 def T()
5055 var a = A.new()
5056 a._Foo()
5057 enddef
5058 T()
5059 END
Ernie Rael03042a22023-11-11 08:53:32 +01005060 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005061
Ernie Rael03042a22023-11-11 08:53:32 +01005062 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005063 lines =<< trim END
5064 vim9script
5065
5066 class A
5067 static def _Foo(): number
5068 return 1234
5069 enddef
5070 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005071 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005072 enddef
5073 endclass
5074 var a = A.new()
5075 a.Bar()
5076 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005077 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005078
Ernie Rael03042a22023-11-11 08:53:32 +01005079 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005080 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005081 lines =<< trim END
5082 vim9script
5083
5084 class A
5085 static def _Foo1(): number
5086 return 1234
5087 enddef
5088 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005089 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005090 enddef
5091 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005092 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005093 enddef
5094 endclass
5095 var a = A.new()
5096 a.Bar()
5097 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005098 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005099
Ernie Rael03042a22023-11-11 08:53:32 +01005100 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005101 lines =<< trim END
5102 vim9script
5103
5104 class A
5105 static def _Foo()
5106 enddef
5107 static def Foo()
5108 enddef
5109 endclass
5110 var a = A.new()
5111 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005112 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005113
Ernie Rael03042a22023-11-11 08:53:32 +01005114 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005115 lines =<< trim END
5116 vim9script
5117
5118 class A
5119 static def _Foo(): number
5120 return 1234
5121 enddef
5122 endclass
5123 class B
5124 def Foo(): number
5125 return A._Foo()
5126 enddef
5127 endclass
5128 var b = B.new()
5129 assert_equal(1234, b.Foo())
5130 END
Ernie Rael03042a22023-11-11 08:53:32 +01005131 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005132
Ernie Rael03042a22023-11-11 08:53:32 +01005133 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005134 lines =<< trim END
5135 vim9script
5136 class A
5137 static def _Foo(): number
5138 return 1234
5139 enddef
5140 endclass
5141 class B extends A
5142 def Bar()
5143 enddef
5144 endclass
5145 class C extends B
5146 def Baz(): number
5147 return A._Foo()
5148 enddef
5149 endclass
5150 var c = C.new()
5151 assert_equal(1234, c.Baz())
5152 END
Ernie Rael03042a22023-11-11 08:53:32 +01005153 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005154
Ernie Rael03042a22023-11-11 08:53:32 +01005155 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005156 lines =<< trim END
5157 vim9script
5158 class A
5159 static def _Foo(): number
5160 return 1234
5161 enddef
5162 endclass
5163 class B extends A
5164 def Bar()
5165 enddef
5166 endclass
5167 class C extends B
5168 static def Baz(): number
5169 return A._Foo()
5170 enddef
5171 endclass
5172 assert_equal(1234, C.Baz())
5173 END
Ernie Rael03042a22023-11-11 08:53:32 +01005174 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005175
Ernie Rael03042a22023-11-11 08:53:32 +01005176 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005177 lines =<< trim END
5178 vim9script
5179 class A
5180 static def _Foo(): number
5181 return 1234
5182 enddef
5183 endclass
5184 class B extends A
5185 def Bar()
5186 enddef
5187 endclass
5188 class C extends B
5189 def Baz(): number
5190 enddef
5191 endclass
5192 var c = C.new()
5193 assert_equal(1234, C._Foo())
5194 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005195 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005196enddef
5197
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005198" Test for using the return value of a class/object method as a function
5199" argument.
5200def Test_objmethod_funcarg()
5201 var lines =<< trim END
5202 vim9script
5203
5204 class C
5205 def Foo(): string
5206 return 'foo'
5207 enddef
5208 endclass
5209
5210 def Bar(a: number, s: string): string
5211 return s
5212 enddef
5213
5214 def Baz(c: C)
5215 assert_equal('foo', Bar(10, c.Foo()))
5216 enddef
5217
5218 var t = C.new()
5219 Baz(t)
5220 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005221 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005222
5223 lines =<< trim END
5224 vim9script
5225
5226 class C
5227 static def Foo(): string
5228 return 'foo'
5229 enddef
5230 endclass
5231
5232 def Bar(a: number, s: string): string
5233 return s
5234 enddef
5235
5236 def Baz()
5237 assert_equal('foo', Bar(10, C.Foo()))
5238 enddef
5239
5240 Baz()
5241 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005242 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005243enddef
5244
Ernie Raelcf138d42023-09-06 20:45:03 +02005245def Test_static_inheritence()
5246 # subclasses get their own static copy
5247 var lines =<< trim END
5248 vim9script
5249
5250 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005251 static var _svar: number
5252 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005253 def new()
5254 _svar = 1
5255 this._mvar = 101
5256 enddef
5257 def AccessObject(): number
5258 return this._mvar
5259 enddef
5260 def AccessStaticThroughObject(): number
5261 return _svar
5262 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005263 endclass
5264
5265 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005266 def new()
5267 this._mvar = 102
5268 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005269 endclass
5270
5271 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005272 def new()
5273 this._mvar = 103
5274 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005275
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005276 def AccessPrivateStaticThroughClassName(): number
5277 assert_equal(1, A._svar)
5278 return 444
5279 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005280 endclass
5281
5282 var oa = A.new()
5283 var ob = B.new()
5284 var oc = C.new()
5285 assert_equal(101, oa.AccessObject())
5286 assert_equal(102, ob.AccessObject())
5287 assert_equal(103, oc.AccessObject())
5288
Ernie Rael03042a22023-11-11 08:53:32 +01005289 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005290
5291 # verify object properly resolves to correct static
5292 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005293 assert_equal(1, ob.AccessStaticThroughObject())
5294 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005295 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005296 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005297enddef
5298
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005299" Test for declaring duplicate object and class members
5300def Test_dup_member_variable()
5301 # Duplicate member variable
5302 var lines =<< trim END
5303 vim9script
5304 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005305 var val = 10
5306 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005307 endclass
5308 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005309 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005310
Ernie Rael03042a22023-11-11 08:53:32 +01005311 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005312 lines =<< trim END
5313 vim9script
5314 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005315 var _val = 10
5316 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005317 endclass
5318 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005319 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005320
5321 # Duplicate public member variable
5322 lines =<< trim END
5323 vim9script
5324 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005325 public var val = 10
5326 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005327 endclass
5328 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005329 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005330
Ernie Rael03042a22023-11-11 08:53:32 +01005331 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005332 lines =<< trim END
5333 vim9script
5334 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005335 var val = 10
5336 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005337 endclass
5338 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005339 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005340
Ernie Rael03042a22023-11-11 08:53:32 +01005341 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005342 lines =<< trim END
5343 vim9script
5344 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005345 var _val = 20
5346 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005347 endclass
5348 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005349 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005350
5351 # Duplicate class member variable
5352 lines =<< trim END
5353 vim9script
5354 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005355 static var s: string = "abc"
5356 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005357 endclass
5358 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005359 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005360
Ernie Rael03042a22023-11-11 08:53:32 +01005361 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005362 lines =<< trim END
5363 vim9script
5364 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005365 public static var s: string = "abc"
5366 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005367 endclass
5368 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005369 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005370
5371 # Duplicate class and object member variable
5372 lines =<< trim END
5373 vim9script
5374 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005375 static var val = 10
5376 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005377 def new()
5378 enddef
5379 endclass
5380 var c = C.new()
5381 assert_equal(10, C.val)
5382 assert_equal(20, c.val)
5383 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005384 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005385
5386 # Duplicate object member variable in a derived class
5387 lines =<< trim END
5388 vim9script
5389 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005390 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005391 endclass
5392 class B extends A
5393 endclass
5394 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005395 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005396 endclass
5397 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005398 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005399
Ernie Rael03042a22023-11-11 08:53:32 +01005400 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005401 lines =<< trim END
5402 vim9script
5403 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005404 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005405 endclass
5406 class B extends A
5407 endclass
5408 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005409 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005410 endclass
5411 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005412 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005413
Ernie Rael03042a22023-11-11 08:53:32 +01005414 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005415 lines =<< trim END
5416 vim9script
5417 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005418 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005419 endclass
5420 class B extends A
5421 endclass
5422 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005423 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005424 endclass
5425 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005426 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005427
5428 # Duplicate object member variable in a derived class
5429 lines =<< trim END
5430 vim9script
5431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005432 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005433 endclass
5434 class B extends A
5435 endclass
5436 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005437 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005438 endclass
5439 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005440 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005441
5442 # Two member variables with a common prefix
5443 lines =<< trim END
5444 vim9script
5445 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005446 public static var svar2: number
5447 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005448 endclass
5449 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005450 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005451enddef
5452
Ernie Rael03042a22023-11-11 08:53:32 +01005453" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005454def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005455 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005456 var lines =<< trim END
5457 vim9script
5458 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005459 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005460 def GetVal(): number
5461 return this._val
5462 enddef
5463 endclass
5464 def T()
5465 var a = A.new()
5466 a._val = 20
5467 enddef
5468 T()
5469 END
Ernie Rael03042a22023-11-11 08:53:32 +01005470 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005471
Ernie Rael03042a22023-11-11 08:53:32 +01005472 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005473 lines =<< trim END
5474 vim9script
5475 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005476 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005477 endclass
5478 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005479 var a = A.new()
5480 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005481 enddef
5482 T()
5483 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005484 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005485
Ernie Rael03042a22023-11-11 08:53:32 +01005486 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005487 lines =<< trim END
5488 vim9script
5489 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005490 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005491 endclass
5492 def T()
5493 var a = A.new()
5494 var x = a._val
5495 enddef
5496 T()
5497 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005498 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005499
Ernie Rael03042a22023-11-11 08:53:32 +01005500 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005501 lines =<< trim END
5502 vim9script
5503 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005504 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005505 endclass
5506 def T()
5507 var a = A.new()
5508 a._val = 3
5509 enddef
5510 T()
5511 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005512 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005513
Ernie Rael03042a22023-11-11 08:53:32 +01005514 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005515 lines =<< trim END
5516 vim9script
5517 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005518 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005519 endclass
5520 def T()
5521 var x = A._val
5522 enddef
5523 T()
5524 END
Ernie Rael03042a22023-11-11 08:53:32 +01005525 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005526
Ernie Rael03042a22023-11-11 08:53:32 +01005527 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005528 lines =<< trim END
5529 vim9script
5530 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005531 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005532 endclass
5533 def T()
5534 A._val = 3
5535 enddef
5536 T()
5537 END
Ernie Rael03042a22023-11-11 08:53:32 +01005538 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005539enddef
5540
5541" Test for changing the member access of an interface in a implementation class
5542def Test_change_interface_member_access()
5543 var lines =<< trim END
5544 vim9script
5545 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005546 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005547 endinterface
5548 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005549 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005550 endclass
5551 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005552 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005553
5554 lines =<< trim END
5555 vim9script
5556 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005557 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005558 endinterface
5559 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005560 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005561 endclass
5562 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005563 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005564enddef
5565
5566" Test for trying to change a readonly member from a def function
5567def Test_readonly_member_change_in_def_func()
5568 var lines =<< trim END
5569 vim9script
5570 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005571 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005572 endclass
5573 def T()
5574 var a = A.new()
5575 a.val = 20
5576 enddef
5577 T()
5578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005579 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005580enddef
5581
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005582" Test for reading and writing a class member from a def function
5583def Test_modify_class_member_from_def_function()
5584 var lines =<< trim END
5585 vim9script
5586 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005587 var var1: number = 10
5588 public static var var2: list<number> = [1, 2]
5589 public static var var3: dict<number> = {a: 1, b: 2}
5590 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005591 endclass
5592 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005593 assert_equal([1, 2], A.var2)
5594 assert_equal({a: 1, b: 2}, A.var3)
5595 A.var2 = [3, 4]
5596 A.var3 = {c: 3, d: 4}
5597 assert_equal([3, 4], A.var2)
5598 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005599 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005600 enddef
5601 T()
5602 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005603 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005604enddef
5605
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005606" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005607def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005608 var lines =<< trim END
5609 vim9script
5610 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005611 public static var svar1: list<number> = [1]
5612 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005613 endclass
5614
5615 A.svar1->add(3)
5616 A.svar2->add(4)
5617 assert_equal([1, 3], A.svar1)
5618 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005619
5620 def Foo()
5621 A.svar1->add(7)
5622 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005623 assert_equal([1, 3, 7], A.svar1)
5624 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005625 enddef
5626 Foo()
5627 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005628 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005629
5630 # Cannot read from a class variable using an object in script context
5631 lines =<< trim END
5632 vim9script
5633 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005634 public var var1: number
5635 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005636 endclass
5637
5638 var a = A.new()
5639 echo a.svar2
5640 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005641 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005642
5643 # Cannot write to a class variable using an object in script context
5644 lines =<< trim END
5645 vim9script
5646 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005647 public var var1: number
5648 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005649 endclass
5650
5651 var a = A.new()
5652 a.svar2 = [2]
5653 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005654 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005655
5656 # Cannot read from a class variable using an object in def method context
5657 lines =<< trim END
5658 vim9script
5659 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005660 public var var1: number
5661 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005662 endclass
5663
5664 def T()
5665 var a = A.new()
5666 echo a.svar2
5667 enddef
5668 T()
5669 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005670 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005671
5672 # Cannot write to a class variable using an object in def method context
5673 lines =<< trim END
5674 vim9script
5675 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005676 public var var1: number
5677 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005678 endclass
5679
5680 def T()
5681 var a = A.new()
5682 a.svar2 = [2]
5683 enddef
5684 T()
5685 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005686 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005687enddef
5688
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005689" Test for using a interface method using a child object
5690def Test_interface_method_from_child()
5691 var lines =<< trim END
5692 vim9script
5693
5694 interface A
5695 def Foo(): string
5696 endinterface
5697
5698 class B implements A
5699 def Foo(): string
5700 return 'foo'
5701 enddef
5702 endclass
5703
5704 class C extends B
5705 def Bar(): string
5706 return 'bar'
5707 enddef
5708 endclass
5709
5710 def T1(a: A)
5711 assert_equal('foo', a.Foo())
5712 enddef
5713
5714 def T2(b: B)
5715 assert_equal('foo', b.Foo())
5716 enddef
5717
5718 var c = C.new()
5719 T1(c)
5720 T2(c)
5721 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005722 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005723enddef
5724
5725" Test for using an interface method using a child object when it is overridden
5726" by the child class.
5727" FIXME: This test fails.
5728" def Test_interface_overridden_method_from_child()
5729" var lines =<< trim END
5730" vim9script
5731"
5732" interface A
5733" def Foo(): string
5734" endinterface
5735"
5736" class B implements A
5737" def Foo(): string
5738" return 'b-foo'
5739" enddef
5740" endclass
5741"
5742" class C extends B
5743" def Bar(): string
5744" return 'bar'
5745" enddef
5746" def Foo(): string
5747" return 'c-foo'
5748" enddef
5749" endclass
5750"
5751" def T1(a: A)
5752" assert_equal('c-foo', a.Foo())
5753" enddef
5754"
5755" def T2(b: B)
5756" assert_equal('c-foo', b.Foo())
5757" enddef
5758"
5759" var c = C.new()
5760" T1(c)
5761" T2(c)
5762" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005763" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005764" enddef
5765
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005766" Test for abstract methods
5767def Test_abstract_method()
5768 # Use two abstract methods
5769 var lines =<< trim END
5770 vim9script
5771 abstract class A
5772 def M1(): number
5773 return 10
5774 enddef
5775 abstract def M2(): number
5776 abstract def M3(): number
5777 endclass
5778 class B extends A
5779 def M2(): number
5780 return 20
5781 enddef
5782 def M3(): number
5783 return 30
5784 enddef
5785 endclass
5786 var b = B.new()
5787 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005789 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005790
5791 # Don't define an abstract method
5792 lines =<< trim END
5793 vim9script
5794 abstract class A
5795 abstract def Foo()
5796 endclass
5797 class B extends A
5798 endclass
5799 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005800 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005801
5802 # Use abstract method in a concrete class
5803 lines =<< trim END
5804 vim9script
5805 class A
5806 abstract def Foo()
5807 endclass
5808 class B extends A
5809 endclass
5810 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005811 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005812
5813 # Use abstract method in an interface
5814 lines =<< trim END
5815 vim9script
5816 interface A
5817 abstract def Foo()
5818 endinterface
5819 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005820 def Foo()
5821 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005822 endclass
5823 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005824 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5825
5826 # Use abstract static method in an interface
5827 lines =<< trim END
5828 vim9script
5829 interface A
5830 abstract static def Foo()
5831 enddef
5832 endinterface
5833 END
5834 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5835
5836 # Use abstract static variable in an interface
5837 lines =<< trim END
5838 vim9script
5839 interface A
5840 abstract static foo: number = 10
5841 endinterface
5842 END
5843 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005844
5845 # Abbreviate the "abstract" keyword
5846 lines =<< trim END
5847 vim9script
5848 class A
5849 abs def Foo()
5850 endclass
5851 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005852 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005853
5854 # Use "abstract" with a member variable
5855 lines =<< trim END
5856 vim9script
5857 abstract class A
5858 abstract this.val = 10
5859 endclass
5860 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005861 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005862
5863 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01005864 lines =<< trim END
5865 vim9script
5866 abstract class A
5867 abstract static def Foo(): number
5868 endclass
5869 END
5870 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005871
5872 # Type mismatch between abstract method and concrete method
5873 lines =<< trim END
5874 vim9script
5875 abstract class A
5876 abstract def Foo(a: string, b: number): list<number>
5877 endclass
5878 class B extends A
5879 def Foo(a: number, b: string): list<string>
5880 return []
5881 enddef
5882 endclass
5883 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005884 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 +02005885
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005886 # Invoke an abstract method from a def function
5887 lines =<< trim END
5888 vim9script
5889 abstract class A
5890 abstract def Foo(): list<number>
5891 endclass
5892 class B extends A
5893 def Foo(): list<number>
5894 return [3, 5]
5895 enddef
5896 endclass
5897 def Bar(c: B)
5898 assert_equal([3, 5], c.Foo())
5899 enddef
5900 var b = B.new()
5901 Bar(b)
5902 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005903 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005904
5905 # Use a static method in an abstract class
5906 lines =<< trim END
5907 vim9script
5908 abstract class A
5909 static def Foo(): string
5910 return 'foo'
5911 enddef
5912 endclass
5913 assert_equal('foo', A.Foo())
5914 END
5915 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005916enddef
5917
5918" Test for calling a class method from a subclass
5919def Test_class_method_call_from_subclass()
5920 # class method call from a subclass
5921 var lines =<< trim END
5922 vim9script
5923
5924 class A
5925 static def Foo()
5926 echo "foo"
5927 enddef
5928 endclass
5929
5930 class B extends A
5931 def Bar()
5932 Foo()
5933 enddef
5934 endclass
5935
5936 var b = B.new()
5937 b.Bar()
5938 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005939 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005940enddef
5941
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005942" Test for calling a class method using an object in a def function context and
5943" script context.
5944def Test_class_method_call_using_object()
5945 # script context
5946 var lines =<< trim END
5947 vim9script
5948 class A
5949 static def Foo(): list<string>
5950 return ['a', 'b']
5951 enddef
5952 def Bar()
5953 assert_equal(['a', 'b'], A.Foo())
5954 assert_equal(['a', 'b'], Foo())
5955 enddef
5956 endclass
5957
5958 def T()
5959 assert_equal(['a', 'b'], A.Foo())
5960 var t_a = A.new()
5961 t_a.Bar()
5962 enddef
5963
5964 assert_equal(['a', 'b'], A.Foo())
5965 var a = A.new()
5966 a.Bar()
5967 T()
5968 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005969 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005970
5971 # script context
5972 lines =<< trim END
5973 vim9script
5974 class A
5975 static def Foo(): string
5976 return 'foo'
5977 enddef
5978 endclass
5979
5980 var a = A.new()
5981 assert_equal('foo', a.Foo())
5982 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005983 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005984
5985 # def function context
5986 lines =<< trim END
5987 vim9script
5988 class A
5989 static def Foo(): string
5990 return 'foo'
5991 enddef
5992 endclass
5993
5994 def T()
5995 var a = A.new()
5996 assert_equal('foo', a.Foo())
5997 enddef
5998 T()
5999 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006000 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006001enddef
6002
6003def Test_class_variable()
6004 var lines =<< trim END
6005 vim9script
6006
6007 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006008 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006009 static def ClassFunc()
6010 assert_equal(10, val)
6011 enddef
6012 def ObjFunc()
6013 assert_equal(10, val)
6014 enddef
6015 endclass
6016
6017 class B extends A
6018 endclass
6019
6020 assert_equal(10, A.val)
6021 A.ClassFunc()
6022 var a = A.new()
6023 a.ObjFunc()
6024 var b = B.new()
6025 b.ObjFunc()
6026
6027 def T1(a1: A)
6028 a1.ObjFunc()
6029 A.ClassFunc()
6030 enddef
6031 T1(b)
6032
6033 A.val = 20
6034 assert_equal(20, A.val)
6035 END
6036 v9.CheckSourceSuccess(lines)
6037
6038 # Modifying a parent class variable from a child class method
6039 lines =<< trim END
6040 vim9script
6041
6042 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006043 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006044 endclass
6045
6046 class B extends A
6047 static def ClassFunc()
6048 val = 20
6049 enddef
6050 endclass
6051 B.ClassFunc()
6052 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006053 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006054
6055 # Reading a parent class variable from a child class method
6056 lines =<< trim END
6057 vim9script
6058
6059 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006060 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006061 endclass
6062
6063 class B extends A
6064 static def ClassFunc()
6065 var i = val
6066 enddef
6067 endclass
6068 B.ClassFunc()
6069 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006070 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006071
6072 # Modifying a parent class variable from a child object method
6073 lines =<< trim END
6074 vim9script
6075
6076 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006077 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006078 endclass
6079
6080 class B extends A
6081 def ObjFunc()
6082 val = 20
6083 enddef
6084 endclass
6085 var b = B.new()
6086 b.ObjFunc()
6087 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006088 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006089
6090 # Reading a parent class variable from a child object method
6091 lines =<< trim END
6092 vim9script
6093
6094 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006095 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006096 endclass
6097
6098 class B extends A
6099 def ObjFunc()
6100 var i = val
6101 enddef
6102 endclass
6103 var b = B.new()
6104 b.ObjFunc()
6105 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006106 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006107
6108 # Modifying a class variable using an object at script level
6109 lines =<< trim END
6110 vim9script
6111
6112 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006113 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006114 endclass
6115 var a = A.new()
6116 a.val = 20
6117 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006118 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006119
6120 # Reading 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 var i = a.val
6129 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006130 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006131
6132 # Modifying a class variable using an object at function 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
6140 def T()
6141 var a = A.new()
6142 a.val = 20
6143 enddef
6144 T()
6145 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006146 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006147
6148 # Reading a class variable using an object at function level
6149 lines =<< trim END
6150 vim9script
6151
6152 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006153 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006154 endclass
6155 def T()
6156 var a = A.new()
6157 var i = a.val
6158 enddef
6159 T()
6160 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006161 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006162
6163 # Use old implicit var declaration syntax (without initialization)
6164 lines =<< trim END
6165 vim9script
6166
6167 class A
6168 static val: number
6169 endclass
6170 END
6171 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6172
6173 # Use old implicit var declaration syntax (with initialization)
6174 lines =<< trim END
6175 vim9script
6176
6177 class A
6178 static val: number = 10
6179 endclass
6180 END
6181 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6182
6183 # Use old implicit var declaration syntax (type inferred)
6184 lines =<< trim END
6185 vim9script
6186
6187 class A
6188 static val = 10
6189 endclass
6190 END
6191 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6192
6193 # Missing ":var" in "var" class variable declaration (without initialization)
6194 lines =<< trim END
6195 vim9script
6196
6197 class A
6198 static var: number
6199 endclass
6200 END
6201 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6202
6203 # Missing ":var" in "var" class variable declaration (with initialization)
6204 lines =<< trim END
6205 vim9script
6206
6207 class A
6208 static var: number = 10
6209 endclass
6210 END
6211 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6212
6213 # Missing ":var" in "var" class variable declaration (type inferred)
6214 lines =<< trim END
6215 vim9script
6216
6217 class A
6218 static var = 10
6219 endclass
6220 END
6221 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6222
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006223enddef
6224
6225" Test for using a duplicate class method and class variable in a child class
6226def Test_dup_class_member()
6227 # duplicate class variable, class method and overridden object method
6228 var lines =<< trim END
6229 vim9script
6230 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006231 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006232 static def Check()
6233 assert_equal(100, sval)
6234 enddef
6235 def GetVal(): number
6236 return sval
6237 enddef
6238 endclass
6239
6240 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006241 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006242 static def Check()
6243 assert_equal(200, sval)
6244 enddef
6245 def GetVal(): number
6246 return sval
6247 enddef
6248 endclass
6249
6250 def T1(aa: A): number
6251 return aa.GetVal()
6252 enddef
6253
6254 def T2(bb: B): number
6255 return bb.GetVal()
6256 enddef
6257
6258 assert_equal(100, A.sval)
6259 assert_equal(200, B.sval)
6260 var a = A.new()
6261 assert_equal(100, a.GetVal())
6262 var b = B.new()
6263 assert_equal(200, b.GetVal())
6264 assert_equal(200, T1(b))
6265 assert_equal(200, T2(b))
6266 END
6267 v9.CheckSourceSuccess(lines)
6268
6269 # duplicate class variable and class method
6270 lines =<< trim END
6271 vim9script
6272 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006273 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006274 static def Check()
6275 assert_equal(100, sval)
6276 enddef
6277 def GetVal(): number
6278 return sval
6279 enddef
6280 endclass
6281
6282 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006283 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006284 static def Check()
6285 assert_equal(200, sval)
6286 enddef
6287 endclass
6288
6289 def T1(aa: A): number
6290 return aa.GetVal()
6291 enddef
6292
6293 def T2(bb: B): number
6294 return bb.GetVal()
6295 enddef
6296
6297 assert_equal(100, A.sval)
6298 assert_equal(200, B.sval)
6299 var a = A.new()
6300 assert_equal(100, a.GetVal())
6301 var b = B.new()
6302 assert_equal(100, b.GetVal())
6303 assert_equal(100, T1(b))
6304 assert_equal(100, T2(b))
6305 END
6306 v9.CheckSourceSuccess(lines)
6307enddef
6308
6309" Test for calling an instance method using the class
6310def Test_instance_method_call_using_class()
6311 # Invoke an object method using a class in script context
6312 var lines =<< trim END
6313 vim9script
6314 class A
6315 def Foo()
6316 echo "foo"
6317 enddef
6318 endclass
6319 A.Foo()
6320 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006321 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006322
6323 # Invoke an object method using a class in def function context
6324 lines =<< trim END
6325 vim9script
6326 class A
6327 def Foo()
6328 echo "foo"
6329 enddef
6330 endclass
6331 def T()
6332 A.Foo()
6333 enddef
6334 T()
6335 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006336 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006337enddef
6338
6339" Test for duplicate class method and instance method
6340def Test_dup_classmethod_objmethod()
6341 # Duplicate instance method
6342 var lines =<< trim END
6343 vim9script
6344 class A
6345 static def Foo()
6346 enddef
6347 def Foo()
6348 enddef
6349 endclass
6350 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006351 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006352
Ernie Rael03042a22023-11-11 08:53:32 +01006353 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006354 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
6365 # Duplicate class method
6366 lines =<< trim END
6367 vim9script
6368 class A
6369 def Foo()
6370 enddef
6371 static 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
Ernie Rael03042a22023-11-11 08:53:32 +01006377 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006378 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 and object 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 +02006400enddef
6401
6402" Test for an instance method access level comparison with parent instance
6403" methods.
6404def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006405 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006406 var lines =<< trim END
6407 vim9script
6408 class A
6409 def Foo()
6410 enddef
6411 endclass
6412 class B extends A
6413 endclass
6414 class C extends B
6415 def _Foo()
6416 enddef
6417 endclass
6418 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006419 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006420
6421 # Public method in subclass
6422 lines =<< trim END
6423 vim9script
6424 class A
6425 def _Foo()
6426 enddef
6427 endclass
6428 class B extends A
6429 endclass
6430 class C extends B
6431 def Foo()
6432 enddef
6433 endclass
6434 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006435 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006436enddef
6437
6438def Test_extend_empty_class()
6439 var lines =<< trim END
6440 vim9script
6441 class A
6442 endclass
6443 class B extends A
6444 endclass
6445 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006446 public static var rw_class_var = 1
6447 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006448 static def ClassMethod(): number
6449 return 3
6450 enddef
6451 def ObjMethod(): number
6452 return 4
6453 enddef
6454 endclass
6455 assert_equal(1, C.rw_class_var)
6456 assert_equal(3, C.ClassMethod())
6457 var c = C.new()
6458 assert_equal(2, c.rw_obj_var)
6459 assert_equal(4, c.ObjMethod())
6460 END
6461 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006462enddef
6463
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006464" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006465" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006466def Test_interface_with_unsupported_members()
6467 var lines =<< trim END
6468 vim9script
6469 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006470 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006471 endinterface
6472 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006473 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006474
6475 lines =<< trim END
6476 vim9script
6477 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006478 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006479 endinterface
6480 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006481 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006482
6483 lines =<< trim END
6484 vim9script
6485 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006486 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006487 endinterface
6488 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006489 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006490
6491 lines =<< trim END
6492 vim9script
6493 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006494 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006495 endinterface
6496 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006497 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006498
6499 lines =<< trim END
6500 vim9script
6501 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006502 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006503 endinterface
6504 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006505 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006506
6507 lines =<< trim END
6508 vim9script
6509 interface A
6510 static def Foo(d: dict<any>): list<string>
6511 endinterface
6512 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006513 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006514
6515 lines =<< trim END
6516 vim9script
6517 interface A
6518 static def _Foo(d: dict<any>): list<string>
6519 endinterface
6520 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006521 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006522
6523 lines =<< trim END
6524 vim9script
6525 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006526 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006527 endinterface
6528 END
Ernie Rael03042a22023-11-11 08:53:32 +01006529 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006530
6531 lines =<< trim END
6532 vim9script
6533 interface A
6534 def _Foo(d: dict<any>): list<string>
6535 endinterface
6536 END
Ernie Rael03042a22023-11-11 08:53:32 +01006537 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006538enddef
6539
6540" Test for extending an interface
6541def Test_extend_interface()
6542 var lines =<< trim END
6543 vim9script
6544 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006545 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006546 def Foo()
6547 endinterface
6548 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006549 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006550 def Bar()
6551 endinterface
6552 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006553 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006554 def Foo()
6555 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006556 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006557 def Bar()
6558 enddef
6559 endclass
6560 END
6561 v9.CheckSourceSuccess(lines)
6562
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006563 # extending empty interface
6564 lines =<< trim END
6565 vim9script
6566 interface A
6567 endinterface
6568 interface B extends A
6569 endinterface
6570 class C implements B
6571 endclass
6572 END
6573 v9.CheckSourceSuccess(lines)
6574
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006575 lines =<< trim END
6576 vim9script
6577 interface A
6578 def Foo()
6579 endinterface
6580 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006581 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006582 endinterface
6583 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006584 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006585 endclass
6586 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006587 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006588
6589 lines =<< trim END
6590 vim9script
6591 interface A
6592 def Foo()
6593 endinterface
6594 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006595 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006596 endinterface
6597 class C implements A, B
6598 def Foo()
6599 enddef
6600 endclass
6601 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006602 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006603
6604 # interface cannot extend a class
6605 lines =<< trim END
6606 vim9script
6607 class A
6608 endclass
6609 interface B extends A
6610 endinterface
6611 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006612 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006613
6614 # class cannot extend an interface
6615 lines =<< trim END
6616 vim9script
6617 interface A
6618 endinterface
6619 class B extends A
6620 endclass
6621 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006622 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006623
6624 # interface cannot implement another interface
6625 lines =<< trim END
6626 vim9script
6627 interface A
6628 endinterface
6629 interface B implements A
6630 endinterface
6631 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006632 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006633
6634 # interface cannot extend multiple interfaces
6635 lines =<< trim END
6636 vim9script
6637 interface A
6638 endinterface
6639 interface B
6640 endinterface
6641 interface C extends A, B
6642 endinterface
6643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006644 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006645
6646 # Variable type in an extended interface is of different type
6647 lines =<< trim END
6648 vim9script
6649 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006650 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006651 endinterface
6652 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006653 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006654 endinterface
6655 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006656 var val1: string
6657 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006658 endinterface
6659 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006660 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006661enddef
6662
6663" Test for a child class implementing an interface when some of the methods are
6664" defined in the parent class.
6665def Test_child_class_implements_interface()
6666 var lines =<< trim END
6667 vim9script
6668
6669 interface Intf
6670 def F1(): list<list<number>>
6671 def F2(): list<list<number>>
6672 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006673 var var1: list<dict<number>>
6674 var var2: list<dict<number>>
6675 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006676 endinterface
6677
6678 class A
6679 def A1()
6680 enddef
6681 def F3(): list<list<number>>
6682 return [[3]]
6683 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006684 var v1: list<list<number>> = [[0]]
6685 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006686 endclass
6687
6688 class B extends A
6689 def B1()
6690 enddef
6691 def F2(): list<list<number>>
6692 return [[2]]
6693 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006694 var v2: list<list<number>> = [[0]]
6695 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006696 endclass
6697
6698 class C extends B implements Intf
6699 def C1()
6700 enddef
6701 def F1(): list<list<number>>
6702 return [[1]]
6703 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006704 var v3: list<list<number>> = [[0]]
6705 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006706 endclass
6707
6708 def T(if: Intf)
6709 assert_equal([[1]], if.F1())
6710 assert_equal([[2]], if.F2())
6711 assert_equal([[3]], if.F3())
6712 assert_equal([{a: 10}], if.var1)
6713 assert_equal([{b: 20}], if.var2)
6714 assert_equal([{c: 30}], if.var3)
6715 enddef
6716
6717 var c = C.new()
6718 T(c)
6719 assert_equal([[1]], c.F1())
6720 assert_equal([[2]], c.F2())
6721 assert_equal([[3]], c.F3())
6722 assert_equal([{a: 10}], c.var1)
6723 assert_equal([{b: 20}], c.var2)
6724 assert_equal([{c: 30}], c.var3)
6725 END
6726 v9.CheckSourceSuccess(lines)
6727
6728 # One of the interface methods is not found
6729 lines =<< trim END
6730 vim9script
6731
6732 interface Intf
6733 def F1()
6734 def F2()
6735 def F3()
6736 endinterface
6737
6738 class A
6739 def A1()
6740 enddef
6741 endclass
6742
6743 class B extends A
6744 def B1()
6745 enddef
6746 def F2()
6747 enddef
6748 endclass
6749
6750 class C extends B implements Intf
6751 def C1()
6752 enddef
6753 def F1()
6754 enddef
6755 endclass
6756 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006757 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006758
6759 # One of the interface methods is of different type
6760 lines =<< trim END
6761 vim9script
6762
6763 interface Intf
6764 def F1()
6765 def F2()
6766 def F3()
6767 endinterface
6768
6769 class A
6770 def F3(): number
6771 return 0
6772 enddef
6773 def A1()
6774 enddef
6775 endclass
6776
6777 class B extends A
6778 def B1()
6779 enddef
6780 def F2()
6781 enddef
6782 endclass
6783
6784 class C extends B implements Intf
6785 def C1()
6786 enddef
6787 def F1()
6788 enddef
6789 endclass
6790 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006791 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006792
6793 # One of the interface variables is not present
6794 lines =<< trim END
6795 vim9script
6796
6797 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006798 var var1: list<dict<number>>
6799 var var2: list<dict<number>>
6800 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006801 endinterface
6802
6803 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006804 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006805 endclass
6806
6807 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006808 var v2: list<list<number>> = [[0]]
6809 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006810 endclass
6811
6812 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006813 var v3: list<list<number>> = [[0]]
6814 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006815 endclass
6816 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006817 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006818
6819 # One of the interface variables is of different type
6820 lines =<< trim END
6821 vim9script
6822
6823 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006824 var var1: list<dict<number>>
6825 var var2: list<dict<number>>
6826 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006827 endinterface
6828
6829 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006830 var v1: list<list<number>> = [[0]]
6831 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006832 endclass
6833
6834 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006835 var v2: list<list<number>> = [[0]]
6836 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006837 endclass
6838
6839 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006840 var v3: list<list<number>> = [[0]]
6841 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006842 endclass
6843 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006844 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 +02006845enddef
6846
6847" Test for extending an interface with duplicate variables and methods
6848def Test_interface_extends_with_dup_members()
6849 var lines =<< trim END
6850 vim9script
6851 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006852 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006853 def Foo1(): number
6854 endinterface
6855 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006856 var n2: number
6857 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006858 def Foo2(): number
6859 def Foo1(): number
6860 endinterface
6861 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006862 var n1 = 10
6863 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006864 def Foo1(): number
6865 return 30
6866 enddef
6867 def Foo2(): number
6868 return 40
6869 enddef
6870 endclass
6871 def T1(a: A)
6872 assert_equal(10, a.n1)
6873 assert_equal(30, a.Foo1())
6874 enddef
6875 def T2(b: B)
6876 assert_equal(10, b.n1)
6877 assert_equal(20, b.n2)
6878 assert_equal(30, b.Foo1())
6879 assert_equal(40, b.Foo2())
6880 enddef
6881 var c = C.new()
6882 T1(c)
6883 T2(c)
6884 END
6885 v9.CheckSourceSuccess(lines)
6886enddef
6887
6888" Test for using "any" type for a variable in a sub-class while it has a
6889" concrete type in the interface
6890def Test_implements_using_var_type_any()
6891 var lines =<< trim END
6892 vim9script
6893 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006894 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006895 endinterface
6896 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006897 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006898 endclass
6899 var b = B.new()
6900 assert_equal([{a: '1'}, {b: '2'}], b.val)
6901 END
6902 v9.CheckSourceSuccess(lines)
6903
6904 # initialize instance variable using a different type
6905 lines =<< trim END
6906 vim9script
6907 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006908 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006909 endinterface
6910 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006911 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006912 endclass
6913 var b = B.new()
6914 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006915 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006916enddef
6917
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006918" Test for assigning to a member variable in a nested class
6919def Test_nested_object_assignment()
6920 var lines =<< trim END
6921 vim9script
6922
6923 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006924 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006925 endclass
6926
6927 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006928 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006929 endclass
6930
6931 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01006932 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006933 endclass
6934
6935 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01006936 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006937 endclass
6938
6939 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006940 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006941 enddef
6942
6943 var d = D.new()
6944 T(d)
6945 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006946 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006947enddef
6948
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006949" Test for calling methods using a null object
6950def Test_null_object_method_call()
6951 # Calling a object method using a null object in script context
6952 var lines =<< trim END
6953 vim9script
6954
6955 class C
6956 def Foo()
6957 assert_report('This method should not be executed')
6958 enddef
6959 endclass
6960
6961 var o: C
6962 o.Foo()
6963 END
6964 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6965
6966 # Calling a object method using a null object in def function context
6967 lines =<< trim END
6968 vim9script
6969
6970 class C
6971 def Foo()
6972 assert_report('This method should not be executed')
6973 enddef
6974 endclass
6975
6976 def T()
6977 var o: C
6978 o.Foo()
6979 enddef
6980 T()
6981 END
6982 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6983
6984 # Calling a object method through another class method using a null object in
6985 # script context
6986 lines =<< trim END
6987 vim9script
6988
6989 class C
6990 def Foo()
6991 assert_report('This method should not be executed')
6992 enddef
6993
6994 static def Bar(o_any: any)
6995 var o_typed: C = o_any
6996 o_typed.Foo()
6997 enddef
6998 endclass
6999
7000 var o: C
7001 C.Bar(o)
7002 END
7003 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7004
7005 # Calling a object method through another class method using a null object in
7006 # def function context
7007 lines =<< trim END
7008 vim9script
7009
7010 class C
7011 def Foo()
7012 assert_report('This method should not be executed')
7013 enddef
7014
7015 static def Bar(o_any: any)
7016 var o_typed: C = o_any
7017 o_typed.Foo()
7018 enddef
7019 endclass
7020
7021 def T()
7022 var o: C
7023 C.Bar(o)
7024 enddef
7025 T()
7026 END
7027 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7028enddef
7029
7030" Test for using a dict as an object member
7031def Test_dict_object_member()
7032 var lines =<< trim END
7033 vim9script
7034
7035 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007036 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007037 def GetState(): dict<number>
7038 return this.state
7039 enddef
7040 endclass
7041
7042 var ctx = Context.new()
7043 ctx.state->extend({a: 1})
7044 ctx.state['b'] = 2
7045 assert_equal({a: 1, b: 2}, ctx.GetState())
7046
7047 def F()
7048 ctx.state['c'] = 3
7049 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7050 enddef
7051 F()
7052 assert_equal(3, ctx.state.c)
7053 ctx.state.c = 4
7054 assert_equal(4, ctx.state.c)
7055 END
7056 v9.CheckSourceSuccess(lines)
7057enddef
7058
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007059" The following test was failing after 9.0.1914. This was caused by using a
7060" freed object from a previous method call.
7061def Test_freed_object_from_previous_method_call()
7062 var lines =<< trim END
7063 vim9script
7064
7065 class Context
7066 endclass
7067
7068 class Result
7069 endclass
7070
7071 def Failure(): Result
7072 return Result.new()
7073 enddef
7074
7075 def GetResult(ctx: Context): Result
7076 return Failure()
7077 enddef
7078
7079 def Test_GetResult()
7080 var ctx = Context.new()
7081 var result = GetResult(ctx)
7082 enddef
7083
7084 Test_GetResult()
7085 END
7086 v9.CheckSourceSuccess(lines)
7087enddef
7088
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007089" Test for duplicate object and class variable
7090def Test_duplicate_variable()
7091 # Object variable name is same as the class variable name
7092 var lines =<< trim END
7093 vim9script
7094 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007095 public static var sval: number
7096 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007097 endclass
7098 var a = A.new()
7099 END
7100 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7101
7102 # Duplicate variable name and calling a class method
7103 lines =<< trim END
7104 vim9script
7105 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007106 public static var sval: number
7107 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007108 def F1()
7109 echo this.sval
7110 enddef
7111 static def F2()
7112 echo sval
7113 enddef
7114 endclass
7115 A.F2()
7116 END
7117 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7118
7119 # Duplicate variable with an empty constructor
7120 lines =<< trim END
7121 vim9script
7122 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007123 public static var sval: number
7124 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007125 def new()
7126 enddef
7127 endclass
7128 var a = A.new()
7129 END
7130 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7131enddef
7132
7133" Test for using a reserved keyword as a variable name
7134def Test_reserved_varname()
7135 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7136 'null_function', 'null_list', 'null_partial', 'null_string',
7137 'null_channel', 'null_job', 'super', 'this']
7138
7139 var lines =<< trim eval END
7140 vim9script
7141 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007142 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007143 endclass
7144 var o = C.new()
7145 END
7146 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7147
7148 lines =<< trim eval END
7149 vim9script
7150 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007151 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007152 def new()
7153 enddef
7154 endclass
7155 var o = C.new()
7156 END
7157 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7158
7159 lines =<< trim eval END
7160 vim9script
7161 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007162 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007163 def new()
7164 enddef
7165 def F()
7166 echo this.{kword}
7167 enddef
7168 endclass
7169 var o = C.new()
7170 o.F()
7171 END
7172 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007173
7174 # class variable name
7175 if kword != 'this'
7176 lines =<< trim eval END
7177 vim9script
7178 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007179 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007180 endclass
7181 END
7182 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7183 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007184 endfor
7185enddef
7186
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007187" Test for checking the type of the arguments and the return value of a object
7188" method in an extended class.
7189def Test_extended_obj_method_type_check()
7190 var lines =<< trim END
7191 vim9script
7192
7193 class A
7194 endclass
7195 class B extends A
7196 endclass
7197 class C extends B
7198 endclass
7199
7200 class Foo
7201 def Doit(p: B): B
7202 return B.new()
7203 enddef
7204 endclass
7205
7206 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007207 def Doit(p: C): B
7208 return B.new()
7209 enddef
7210 endclass
7211 END
7212 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7213
7214 lines =<< trim END
7215 vim9script
7216
7217 class A
7218 endclass
7219 class B extends A
7220 endclass
7221 class C extends B
7222 endclass
7223
7224 class Foo
7225 def Doit(p: B): B
7226 return B.new()
7227 enddef
7228 endclass
7229
7230 class Bar extends Foo
7231 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007232 return C.new()
7233 enddef
7234 endclass
7235 END
7236 v9.CheckSourceSuccess(lines)
7237
7238 lines =<< trim END
7239 vim9script
7240
7241 class A
7242 endclass
7243 class B extends A
7244 endclass
7245 class C extends B
7246 endclass
7247
7248 class Foo
7249 def Doit(p: B): B
7250 return B.new()
7251 enddef
7252 endclass
7253
7254 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007255 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007256 return B.new()
7257 enddef
7258 endclass
7259 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007260 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 +02007261
7262 lines =<< trim END
7263 vim9script
7264
7265 class A
7266 endclass
7267 class B extends A
7268 endclass
7269 class C extends B
7270 endclass
7271
7272 class Foo
7273 def Doit(p: B): B
7274 return B.new()
7275 enddef
7276 endclass
7277
7278 class Bar extends Foo
7279 def Doit(p: B): A
7280 return A.new()
7281 enddef
7282 endclass
7283 END
7284 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 +02007285
7286 # check varargs type mismatch
7287 lines =<< trim END
7288 vim9script
7289
7290 class B
7291 def F(...xxx: list<any>)
7292 enddef
7293 endclass
7294 class C extends B
7295 def F(xxx: list<any>)
7296 enddef
7297 endclass
7298 END
7299 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 +02007300enddef
7301
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007302" Test type checking for class variable in assignments
7303func Test_class_variable_complex_type_check()
7304 " class variable with a specific type. Try assigning a different type at
7305 " script level.
7306 let lines =<< trim END
7307 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007308 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007309 return {}
7310 enddef
7311 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007312 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007313 endclass
7314 test_garbagecollect_now()
7315 A.Fn = "abc"
7316 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007317 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 +02007318
7319 " class variable with a specific type. Try assigning a different type at
7320 " class def method level.
7321 let lines =<< trim END
7322 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007323 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007324 return {}
7325 enddef
7326 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007327 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007328 def Bar()
7329 Fn = "abc"
7330 enddef
7331 endclass
7332 var a = A.new()
7333 test_garbagecollect_now()
7334 a.Bar()
7335 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007336 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 +02007337
7338 " class variable with a specific type. Try assigning a different type at
7339 " script def method level.
7340 let lines =<< trim END
7341 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007342 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007343 return {}
7344 enddef
7345 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007346 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007347 endclass
7348 def Bar()
7349 A.Fn = "abc"
7350 enddef
7351 test_garbagecollect_now()
7352 Bar()
7353 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007354 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 +02007355
7356 " class variable without any type. Should be set to the initialization
7357 " expression type. Try assigning a different type from script level.
7358 let lines =<< trim END
7359 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007360 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007361 return {}
7362 enddef
7363 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007364 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007365 endclass
7366 test_garbagecollect_now()
7367 A.Fn = "abc"
7368 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007369 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 +02007370
7371 " class variable without any type. Should be set to the initialization
7372 " expression type. Try assigning a different type at class def level.
7373 let lines =<< trim END
7374 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007375 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007376 return {}
7377 enddef
7378 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007379 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007380 def Bar()
7381 Fn = "abc"
7382 enddef
7383 endclass
7384 var a = A.new()
7385 test_garbagecollect_now()
7386 a.Bar()
7387 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007388 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 +02007389
7390 " class variable without any type. Should be set to the initialization
7391 " expression type. Try assigning a different type at script def level.
7392 let lines =<< trim END
7393 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007394 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007395 return {}
7396 enddef
7397 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007398 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007399 endclass
7400 def Bar()
7401 A.Fn = "abc"
7402 enddef
7403 test_garbagecollect_now()
7404 Bar()
7405 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007406 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 +02007407
7408 " class variable with 'any" type. Can be assigned different types.
7409 let lines =<< trim END
7410 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007411 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007412 return {}
7413 enddef
7414 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007415 public static var Fn: any = Foo
7416 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007417 endclass
7418 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007419 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007420 A.Fn = "abc"
7421 test_garbagecollect_now()
7422 assert_equal('string', typename(A.Fn))
7423 A.Fn2 = Foo
7424 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007425 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007426 A.Fn2 = "xyz"
7427 test_garbagecollect_now()
7428 assert_equal('string', typename(A.Fn2))
7429 END
7430 call v9.CheckSourceSuccess(lines)
7431
7432 " class variable with 'any" type. Can be assigned different types.
7433 let lines =<< trim END
7434 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007435 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007436 return {}
7437 enddef
7438 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007439 public static var Fn: any = Foo
7440 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007441
7442 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007443 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007444 Fn = "abc"
7445 assert_equal('string', typename(Fn))
7446 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007447 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007448 Fn2 = "xyz"
7449 assert_equal('string', typename(Fn2))
7450 enddef
7451 endclass
7452 var a = A.new()
7453 test_garbagecollect_now()
7454 a.Bar()
7455 test_garbagecollect_now()
7456 A.Fn = Foo
7457 a.Bar()
7458 END
7459 call v9.CheckSourceSuccess(lines)
7460
7461 " class variable with 'any" type. Can be assigned different types.
7462 let lines =<< trim END
7463 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007464 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007465 return {}
7466 enddef
7467 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007468 public static var Fn: any = Foo
7469 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007470 endclass
7471
7472 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007473 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007474 A.Fn = "abc"
7475 assert_equal('string', typename(A.Fn))
7476 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007477 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007478 A.Fn2 = "xyz"
7479 assert_equal('string', typename(A.Fn2))
7480 enddef
7481 Bar()
7482 test_garbagecollect_now()
7483 A.Fn = Foo
7484 Bar()
7485 END
7486 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007487
7488 let lines =<< trim END
7489 vim9script
7490 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007491 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007492 endclass
7493 assert_equal([0z10, 0z20], A.foo)
7494 A.foo = [0z30]
7495 assert_equal([0z30], A.foo)
7496 var a = A.foo
7497 assert_equal([0z30], a)
7498 END
7499 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007500endfunc
7501
7502" Test type checking for object variable in assignments
7503func Test_object_variable_complex_type_check()
7504 " object variable with a specific type. Try assigning a different type at
7505 " script level.
7506 let lines =<< trim END
7507 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007508 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007509 return {}
7510 enddef
7511 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007512 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007513 endclass
7514 var a = A.new()
7515 test_garbagecollect_now()
7516 a.Fn = "abc"
7517 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007518 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 +02007519
7520 " object variable with a specific type. Try assigning a different type at
7521 " object def method level.
7522 let lines =<< trim END
7523 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007524 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007525 return {}
7526 enddef
7527 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007528 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007529 def Bar()
7530 this.Fn = "abc"
7531 this.Fn = Foo
7532 enddef
7533 endclass
7534 var a = A.new()
7535 test_garbagecollect_now()
7536 a.Bar()
7537 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007538 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 +02007539
7540 " object variable with a specific type. Try assigning a different type at
7541 " script def method level.
7542 let lines =<< trim END
7543 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007544 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007545 return {}
7546 enddef
7547 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007548 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007549 endclass
7550 def Bar()
7551 var a = A.new()
7552 a.Fn = "abc"
7553 a.Fn = Foo
7554 enddef
7555 test_garbagecollect_now()
7556 Bar()
7557 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007558 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 +02007559
7560 " object variable without any type. Should be set to the initialization
7561 " expression type. Try assigning a different type from script level.
7562 let lines =<< trim END
7563 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007564 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007565 return {}
7566 enddef
7567 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007568 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007569 endclass
7570 var a = A.new()
7571 test_garbagecollect_now()
7572 a.Fn = "abc"
7573 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007574 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 10)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007575
7576 " object variable without any type. Should be set to the initialization
7577 " expression type. Try assigning a different type at object def level.
7578 let lines =<< trim END
7579 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007580 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007581 return {}
7582 enddef
7583 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007584 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007585 def Bar()
7586 this.Fn = "abc"
7587 this.Fn = Foo
7588 enddef
7589 endclass
7590 var a = A.new()
7591 test_garbagecollect_now()
7592 a.Bar()
7593 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007594 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 +02007595
7596 " object variable without any type. Should be set to the initialization
7597 " expression type. Try assigning a different type at script def level.
7598 let lines =<< trim END
7599 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007600 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007601 return {}
7602 enddef
7603 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007604 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007605 endclass
7606 def Bar()
7607 var a = A.new()
7608 a.Fn = "abc"
7609 a.Fn = Foo
7610 enddef
7611 test_garbagecollect_now()
7612 Bar()
7613 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007614 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 +02007615
7616 " object variable with 'any" type. Can be assigned different types.
7617 let lines =<< trim END
7618 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007619 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007620 return {}
7621 enddef
7622 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007623 public var Fn: any = Foo
7624 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007625 endclass
7626
7627 var a = A.new()
7628 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007629 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007630 a.Fn = "abc"
7631 test_garbagecollect_now()
7632 assert_equal('string', typename(a.Fn))
7633 a.Fn2 = Foo
7634 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007635 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007636 a.Fn2 = "xyz"
7637 test_garbagecollect_now()
7638 assert_equal('string', typename(a.Fn2))
7639 END
7640 call v9.CheckSourceSuccess(lines)
7641
7642 " object variable with 'any" type. Can be assigned different types.
7643 let lines =<< trim END
7644 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007645 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007646 return {}
7647 enddef
7648 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007649 public var Fn: any = Foo
7650 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007651
7652 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007653 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007654 this.Fn = "abc"
7655 assert_equal('string', typename(this.Fn))
7656 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007657 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007658 this.Fn2 = "xyz"
7659 assert_equal('string', typename(this.Fn2))
7660 enddef
7661 endclass
7662
7663 var a = A.new()
7664 test_garbagecollect_now()
7665 a.Bar()
7666 test_garbagecollect_now()
7667 a.Fn = Foo
7668 a.Bar()
7669 END
7670 call v9.CheckSourceSuccess(lines)
7671
7672 " object variable with 'any" type. Can be assigned different types.
7673 let lines =<< trim END
7674 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007675 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007676 return {}
7677 enddef
7678 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007679 public var Fn: any = Foo
7680 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007681 endclass
7682
7683 def Bar()
7684 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007685 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007686 a.Fn = "abc"
7687 assert_equal('string', typename(a.Fn))
7688 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007689 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007690 a.Fn2 = "xyz"
7691 assert_equal('string', typename(a.Fn2))
7692 enddef
7693 test_garbagecollect_now()
7694 Bar()
7695 test_garbagecollect_now()
7696 Bar()
7697 END
7698 call v9.CheckSourceSuccess(lines)
7699endfunc
7700
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007701" Test for recursively calling an object method. This used to cause an
7702" use-after-free error.
7703def Test_recursive_object_method_call()
7704 var lines =<< trim END
7705 vim9script
7706 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007707 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007708 def Foo(): number
7709 if this.val >= 90
7710 return this.val
7711 endif
7712 this.val += 1
7713 return this.Foo()
7714 enddef
7715 endclass
7716 var a = A.new()
7717 assert_equal(90, a.Foo())
7718 END
7719 v9.CheckSourceSuccess(lines)
7720enddef
7721
7722" Test for recursively calling a class method.
7723def Test_recursive_class_method_call()
7724 var lines =<< trim END
7725 vim9script
7726 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007727 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007728 static def Foo(): number
7729 if val >= 90
7730 return val
7731 endif
7732 val += 1
7733 return Foo()
7734 enddef
7735 endclass
7736 assert_equal(90, A.Foo())
7737 END
7738 v9.CheckSourceSuccess(lines)
7739enddef
7740
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007741" Test for checking the argument types and the return type when assigning a
7742" funcref to make sure the invariant class type is used.
7743def Test_funcref_argtype_returntype_check()
7744 var lines =<< trim END
7745 vim9script
7746 class A
7747 endclass
7748 class B extends A
7749 endclass
7750
7751 def Foo(p: B): B
7752 return B.new()
7753 enddef
7754
7755 var Bar: func(A): A = Foo
7756 END
7757 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7758
7759 lines =<< trim END
7760 vim9script
7761 class A
7762 endclass
7763 class B extends A
7764 endclass
7765
7766 def Foo(p: B): B
7767 return B.new()
7768 enddef
7769
7770 def Baz()
7771 var Bar: func(A): A = Foo
7772 enddef
7773 Baz()
7774 END
7775 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7776enddef
7777
Ernie Rael96952b22023-10-17 18:15:01 +02007778def Test_funcref_argtype_invariance_check()
7779 var lines =<< trim END
7780 vim9script
7781
7782 class A
7783 endclass
7784 class B extends A
7785 endclass
7786 class C extends B
7787 endclass
7788
7789 var Func: func(B): number
7790 Func = (o: B): number => 3
7791 assert_equal(3, Func(B.new()))
7792 END
7793 v9.CheckSourceSuccess(lines)
7794
7795 lines =<< trim END
7796 vim9script
7797
7798 class A
7799 endclass
7800 class B extends A
7801 endclass
7802 class C extends B
7803 endclass
7804
7805 var Func: func(B): number
7806 Func = (o: A): number => 3
7807 END
7808 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7809
7810 lines =<< trim END
7811 vim9script
7812
7813 class A
7814 endclass
7815 class B extends A
7816 endclass
7817 class C extends B
7818 endclass
7819
7820 var Func: func(B): number
7821 Func = (o: C): number => 3
7822 END
7823 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7824enddef
7825
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007826" Test for using an operator (e.g. +) with an assignment
7827def Test_op_and_assignment()
7828 # Using += with a class variable
7829 var lines =<< trim END
7830 vim9script
7831 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007832 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007833 static def Foo(): list<number>
7834 val += [1]
7835 return val
7836 enddef
7837 endclass
7838 def Bar(): list<number>
7839 A.val += [2]
7840 return A.val
7841 enddef
7842 assert_equal([1], A.Foo())
7843 assert_equal([1, 2], Bar())
7844 A.val += [3]
7845 assert_equal([1, 2, 3], A.val)
7846 END
7847 v9.CheckSourceSuccess(lines)
7848
7849 # Using += with an object variable
7850 lines =<< trim END
7851 vim9script
7852 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007853 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007854 def Foo(): list<number>
7855 this.val += [1]
7856 return this.val
7857 enddef
7858 endclass
7859 def Bar(bar_a: A): list<number>
7860 bar_a.val += [2]
7861 return bar_a.val
7862 enddef
7863 var a = A.new()
7864 assert_equal([1], a.Foo())
7865 assert_equal([1, 2], Bar(a))
7866 a.val += [3]
7867 assert_equal([1, 2, 3], a.val)
7868 END
7869 v9.CheckSourceSuccess(lines)
7870enddef
7871
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007872" Test for using an object method as a funcref
7873def Test_object_funcref()
7874 # Using object method funcref from a def function
7875 var lines =<< trim END
7876 vim9script
7877 class A
7878 def Foo(): list<number>
7879 return [3, 2, 1]
7880 enddef
7881 endclass
7882 def Bar()
7883 var a = A.new()
7884 var Fn = a.Foo
7885 assert_equal([3, 2, 1], Fn())
7886 enddef
7887 Bar()
7888 END
7889 v9.CheckSourceSuccess(lines)
7890
7891 # Using object method funcref at the script level
7892 lines =<< trim END
7893 vim9script
7894 class A
7895 def Foo(): dict<number>
7896 return {a: 1, b: 2}
7897 enddef
7898 endclass
7899 var a = A.new()
7900 var Fn = a.Foo
7901 assert_equal({a: 1, b: 2}, Fn())
7902 END
7903 v9.CheckSourceSuccess(lines)
7904
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007905 # Using object method funcref at the script level
7906 lines =<< trim END
7907 vim9script
7908 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007909 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007910 def Foo(): number
7911 return this.val
7912 enddef
7913 endclass
7914 var a = A.new(345)
7915 var Fn = a.Foo
7916 assert_equal(345, Fn())
7917 END
7918 v9.CheckSourceSuccess(lines)
7919
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007920 # Using object method funcref from another object method
7921 lines =<< trim END
7922 vim9script
7923 class A
7924 def Foo(): list<number>
7925 return [3, 2, 1]
7926 enddef
7927 def Bar()
7928 var Fn = this.Foo
7929 assert_equal([3, 2, 1], Fn())
7930 enddef
7931 endclass
7932 var a = A.new()
7933 a.Bar()
7934 END
7935 v9.CheckSourceSuccess(lines)
7936
7937 # Using function() to get a object method funcref
7938 lines =<< trim END
7939 vim9script
7940 class A
7941 def Foo(l: list<any>): list<any>
7942 return l
7943 enddef
7944 endclass
7945 var a = A.new()
7946 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
7947 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7948 END
7949 v9.CheckSourceSuccess(lines)
7950
7951 # Use an object method with a function returning a funcref and then call the
7952 # funcref.
7953 lines =<< trim END
7954 vim9script
7955
7956 def Map(F: func(number): number): func(number): number
7957 return (n: number) => F(n)
7958 enddef
7959
7960 class Math
7961 def Double(n: number): number
7962 return 2 * n
7963 enddef
7964 endclass
7965
7966 const math = Math.new()
7967 assert_equal(48, Map(math.Double)(24))
7968 END
7969 v9.CheckSourceSuccess(lines)
7970
Ernie Rael03042a22023-11-11 08:53:32 +01007971 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007972 lines =<< trim END
7973 vim9script
7974 class A
7975 def _Foo()
7976 enddef
7977 endclass
7978 def Bar()
7979 var a = A.new()
7980 var Fn = a._Foo
7981 enddef
7982 Bar()
7983 END
Ernie Rael03042a22023-11-11 08:53:32 +01007984 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007985
Ernie Rael03042a22023-11-11 08:53:32 +01007986 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007987 lines =<< trim END
7988 vim9script
7989 class A
7990 def _Foo()
7991 enddef
7992 endclass
7993 var a = A.new()
7994 var Fn = a._Foo
7995 END
Ernie Rael03042a22023-11-11 08:53:32 +01007996 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007997
Ernie Rael03042a22023-11-11 08:53:32 +01007998 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007999 lines =<< trim END
8000 vim9script
8001 class A
8002 def _Foo(): list<number>
8003 return [3, 2, 1]
8004 enddef
8005 def Bar()
8006 var Fn = this._Foo
8007 assert_equal([3, 2, 1], Fn())
8008 enddef
8009 endclass
8010 var a = A.new()
8011 a.Bar()
8012 END
8013 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008014
8015 # Using object method funcref using call()
8016 lines =<< trim END
8017 vim9script
8018 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008019 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008020 def Foo(): number
8021 return this.val
8022 enddef
8023 endclass
8024
8025 def Bar(obj: A)
8026 assert_equal(123, call(obj.Foo, []))
8027 enddef
8028
8029 var a = A.new(123)
8030 Bar(a)
8031 assert_equal(123, call(a.Foo, []))
8032 END
8033 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008034enddef
8035
8036" Test for using a class method as a funcref
8037def Test_class_funcref()
8038 # Using class method funcref in a def function
8039 var lines =<< trim END
8040 vim9script
8041 class A
8042 static def Foo(): list<number>
8043 return [3, 2, 1]
8044 enddef
8045 endclass
8046 def Bar()
8047 var Fn = A.Foo
8048 assert_equal([3, 2, 1], Fn())
8049 enddef
8050 Bar()
8051 END
8052 v9.CheckSourceSuccess(lines)
8053
8054 # Using class method funcref at script level
8055 lines =<< trim END
8056 vim9script
8057 class A
8058 static def Foo(): dict<number>
8059 return {a: 1, b: 2}
8060 enddef
8061 endclass
8062 var Fn = A.Foo
8063 assert_equal({a: 1, b: 2}, Fn())
8064 END
8065 v9.CheckSourceSuccess(lines)
8066
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008067 # Using class method funcref at the script level
8068 lines =<< trim END
8069 vim9script
8070 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008071 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008072 static def Foo(): number
8073 return val
8074 enddef
8075 endclass
8076 A.val = 567
8077 var Fn = A.Foo
8078 assert_equal(567, Fn())
8079 END
8080 v9.CheckSourceSuccess(lines)
8081
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008082 # Using function() to get a class method funcref
8083 lines =<< trim END
8084 vim9script
8085 class A
8086 static def Foo(l: list<any>): list<any>
8087 return l
8088 enddef
8089 endclass
8090 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8091 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8092 END
8093 v9.CheckSourceSuccess(lines)
8094
8095 # Using a class method funcref from another class method
8096 lines =<< trim END
8097 vim9script
8098 class A
8099 static def Foo(): list<number>
8100 return [3, 2, 1]
8101 enddef
8102 static def Bar()
8103 var Fn = Foo
8104 assert_equal([3, 2, 1], Fn())
8105 enddef
8106 endclass
8107 A.Bar()
8108 END
8109 v9.CheckSourceSuccess(lines)
8110
8111 # Use a class method with a function returning a funcref and then call the
8112 # funcref.
8113 lines =<< trim END
8114 vim9script
8115
8116 def Map(F: func(number): number): func(number): number
8117 return (n: number) => F(n)
8118 enddef
8119
8120 class Math
8121 static def StaticDouble(n: number): number
8122 return 2 * n
8123 enddef
8124 endclass
8125
8126 assert_equal(48, Map(Math.StaticDouble)(24))
8127 END
8128 v9.CheckSourceSuccess(lines)
8129
Ernie Rael03042a22023-11-11 08:53:32 +01008130 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008131 lines =<< trim END
8132 vim9script
8133 class A
8134 static def _Foo()
8135 enddef
8136 endclass
8137 def Bar()
8138 var Fn = A._Foo
8139 enddef
8140 Bar()
8141 END
Ernie Rael03042a22023-11-11 08:53:32 +01008142 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008143
Ernie Rael03042a22023-11-11 08:53:32 +01008144 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008145 lines =<< trim END
8146 vim9script
8147 class A
8148 static def _Foo()
8149 enddef
8150 endclass
8151 var Fn = A._Foo
8152 END
Ernie Rael03042a22023-11-11 08:53:32 +01008153 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008154
Ernie Rael03042a22023-11-11 08:53:32 +01008155 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008156 lines =<< trim END
8157 vim9script
8158 class A
8159 static def _Foo(): list<number>
8160 return [3, 2, 1]
8161 enddef
8162 static def Bar()
8163 var Fn = _Foo
8164 assert_equal([3, 2, 1], Fn())
8165 enddef
8166 endclass
8167 A.Bar()
8168 END
8169 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008170
8171 # Using class method funcref using call()
8172 lines =<< trim END
8173 vim9script
8174 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008175 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008176 static def Foo(): number
8177 return val
8178 enddef
8179 endclass
8180
8181 def Bar()
8182 A.val = 468
8183 assert_equal(468, call(A.Foo, []))
8184 enddef
8185 Bar()
8186 assert_equal(468, call(A.Foo, []))
8187 END
8188 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008189enddef
8190
8191" Test for using an object member as a funcref
8192def Test_object_member_funcref()
8193 # Using a funcref object variable in an object method
8194 var lines =<< trim END
8195 vim9script
8196 def Foo(n: number): number
8197 return n * 10
8198 enddef
8199
8200 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008201 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008202 def Bar()
8203 assert_equal(200, this.Cb(20))
8204 enddef
8205 endclass
8206
8207 var a = A.new()
8208 a.Bar()
8209 END
8210 v9.CheckSourceSuccess(lines)
8211
8212 # Using a funcref object variable in a def method
8213 lines =<< trim END
8214 vim9script
8215 def Foo(n: number): number
8216 return n * 10
8217 enddef
8218
8219 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008220 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008221 endclass
8222
8223 def Bar()
8224 var a = A.new()
8225 assert_equal(200, a.Cb(20))
8226 enddef
8227 Bar()
8228 END
8229 v9.CheckSourceSuccess(lines)
8230
8231 # Using a funcref object variable at script level
8232 lines =<< trim END
8233 vim9script
8234 def Foo(n: number): number
8235 return n * 10
8236 enddef
8237
8238 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008239 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008240 endclass
8241
8242 var a = A.new()
8243 assert_equal(200, a.Cb(20))
8244 END
8245 v9.CheckSourceSuccess(lines)
8246
8247 # Using a funcref object variable pointing to an object method in an object
8248 # method.
8249 lines =<< trim END
8250 vim9script
8251 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008252 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008253 def Foo(n: number): number
8254 return n * 10
8255 enddef
8256 def Bar()
8257 assert_equal(200, this.Cb(20))
8258 enddef
8259 endclass
8260
8261 var a = A.new()
8262 a.Bar()
8263 END
8264 v9.CheckSourceSuccess(lines)
8265
8266 # Using a funcref object variable pointing to an object method in a def
8267 # method.
8268 lines =<< trim END
8269 vim9script
8270 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008271 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008272 def Foo(n: number): number
8273 return n * 10
8274 enddef
8275 endclass
8276
8277 def Bar()
8278 var a = A.new()
8279 assert_equal(200, a.Cb(20))
8280 enddef
8281 Bar()
8282 END
8283 v9.CheckSourceSuccess(lines)
8284
8285 # Using a funcref object variable pointing to an object method at script
8286 # level.
8287 lines =<< trim END
8288 vim9script
8289 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008290 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008291 def Foo(n: number): number
8292 return n * 10
8293 enddef
8294 endclass
8295
8296 var a = A.new()
8297 assert_equal(200, a.Cb(20))
8298 END
8299 v9.CheckSourceSuccess(lines)
8300enddef
8301
8302" Test for using a class member as a funcref
8303def Test_class_member_funcref()
8304 # Using a funcref class variable in a class method
8305 var lines =<< trim END
8306 vim9script
8307 def Foo(n: number): number
8308 return n * 10
8309 enddef
8310
8311 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008312 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008313 static def Bar()
8314 assert_equal(200, Cb(20))
8315 enddef
8316 endclass
8317
8318 A.Bar()
8319 END
8320 v9.CheckSourceSuccess(lines)
8321
8322 # Using a funcref class variable in a def method
8323 lines =<< trim END
8324 vim9script
8325 def Foo(n: number): number
8326 return n * 10
8327 enddef
8328
8329 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008330 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008331 endclass
8332
8333 def Bar()
8334 assert_equal(200, A.Cb(20))
8335 enddef
8336 Bar()
8337 END
8338 v9.CheckSourceSuccess(lines)
8339
8340 # Using a funcref class variable at script level
8341 lines =<< trim END
8342 vim9script
8343 def Foo(n: number): number
8344 return n * 10
8345 enddef
8346
8347 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008348 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008349 endclass
8350
8351 assert_equal(200, A.Cb(20))
8352 END
8353 v9.CheckSourceSuccess(lines)
8354
8355 # Using a funcref class variable pointing to a class method in a class
8356 # method.
8357 lines =<< trim END
8358 vim9script
8359 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008360 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008361 static def Foo(n: number): number
8362 return n * 10
8363 enddef
8364 static def Init()
8365 Cb = Foo
8366 enddef
8367 static def Bar()
8368 assert_equal(200, Cb(20))
8369 enddef
8370 endclass
8371
8372 A.Init()
8373 A.Bar()
8374 END
8375 v9.CheckSourceSuccess(lines)
8376
8377 # Using a funcref class variable pointing to a class method in a def method.
8378 lines =<< trim END
8379 vim9script
8380 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008381 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008382 static def Foo(n: number): number
8383 return n * 10
8384 enddef
8385 static def Init()
8386 Cb = Foo
8387 enddef
8388 endclass
8389
8390 def Bar()
8391 A.Init()
8392 assert_equal(200, A.Cb(20))
8393 enddef
8394 Bar()
8395 END
8396 v9.CheckSourceSuccess(lines)
8397
8398 # Using a funcref class variable pointing to a class method at script level.
8399 lines =<< trim END
8400 vim9script
8401 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008402 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008403 static def Foo(n: number): number
8404 return n * 10
8405 enddef
8406 static def Init()
8407 Cb = Foo
8408 enddef
8409 endclass
8410
8411 A.Init()
8412 assert_equal(200, A.Cb(20))
8413 END
8414 v9.CheckSourceSuccess(lines)
8415enddef
8416
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008417" Test for using object methods as popup callback functions
8418def Test_objmethod_popup_callback()
8419 # Use the popup from the script level
8420 var lines =<< trim END
8421 vim9script
8422
8423 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008424 var selection: number = -1
8425 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008426
8427 def PopupFilter(id: number, key: string): bool
8428 add(this.filterkeys, key)
8429 return popup_filter_yesno(id, key)
8430 enddef
8431
8432 def PopupCb(id: number, result: number)
8433 this.selection = result ? 100 : 200
8434 enddef
8435 endclass
8436
8437 var a = A.new()
8438 feedkeys('', 'xt')
8439 var winid = popup_create('Y/N?',
8440 {filter: a.PopupFilter, callback: a.PopupCb})
8441 feedkeys('y', 'xt')
8442 popup_close(winid)
8443 assert_equal(100, a.selection)
8444 assert_equal(['y'], a.filterkeys)
8445 feedkeys('', 'xt')
8446 winid = popup_create('Y/N?',
8447 {filter: a.PopupFilter, callback: a.PopupCb})
8448 feedkeys('n', 'xt')
8449 popup_close(winid)
8450 assert_equal(200, a.selection)
8451 assert_equal(['y', 'n'], a.filterkeys)
8452 END
8453 v9.CheckSourceSuccess(lines)
8454
8455 # Use the popup from a def function
8456 lines =<< trim END
8457 vim9script
8458
8459 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008460 var selection: number = -1
8461 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008462
8463 def PopupFilter(id: number, key: string): bool
8464 add(this.filterkeys, key)
8465 return popup_filter_yesno(id, key)
8466 enddef
8467
8468 def PopupCb(id: number, result: number)
8469 this.selection = result ? 100 : 200
8470 enddef
8471 endclass
8472
8473 def Foo()
8474 var a = A.new()
8475 feedkeys('', 'xt')
8476 var winid = popup_create('Y/N?',
8477 {filter: a.PopupFilter, callback: a.PopupCb})
8478 feedkeys('y', 'xt')
8479 popup_close(winid)
8480 assert_equal(100, a.selection)
8481 assert_equal(['y'], a.filterkeys)
8482 feedkeys('', 'xt')
8483 winid = popup_create('Y/N?',
8484 {filter: a.PopupFilter, callback: a.PopupCb})
8485 feedkeys('n', 'xt')
8486 popup_close(winid)
8487 assert_equal(200, a.selection)
8488 assert_equal(['y', 'n'], a.filterkeys)
8489 enddef
8490 Foo()
8491 END
8492 v9.CheckSourceSuccess(lines)
8493enddef
8494
8495" Test for using class methods as popup callback functions
8496def Test_classmethod_popup_callback()
8497 # Use the popup from the script level
8498 var lines =<< trim END
8499 vim9script
8500
8501 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008502 static var selection: number = -1
8503 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008504
8505 static def PopupFilter(id: number, key: string): bool
8506 add(filterkeys, key)
8507 return popup_filter_yesno(id, key)
8508 enddef
8509
8510 static def PopupCb(id: number, result: number)
8511 selection = result ? 100 : 200
8512 enddef
8513 endclass
8514
8515 feedkeys('', 'xt')
8516 var winid = popup_create('Y/N?',
8517 {filter: A.PopupFilter, callback: A.PopupCb})
8518 feedkeys('y', 'xt')
8519 popup_close(winid)
8520 assert_equal(100, A.selection)
8521 assert_equal(['y'], A.filterkeys)
8522 feedkeys('', 'xt')
8523 winid = popup_create('Y/N?',
8524 {filter: A.PopupFilter, callback: A.PopupCb})
8525 feedkeys('n', 'xt')
8526 popup_close(winid)
8527 assert_equal(200, A.selection)
8528 assert_equal(['y', 'n'], A.filterkeys)
8529 END
8530 v9.CheckSourceSuccess(lines)
8531
8532 # Use the popup from a def function
8533 lines =<< trim END
8534 vim9script
8535
8536 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008537 static var selection: number = -1
8538 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008539
8540 static def PopupFilter(id: number, key: string): bool
8541 add(filterkeys, key)
8542 return popup_filter_yesno(id, key)
8543 enddef
8544
8545 static def PopupCb(id: number, result: number)
8546 selection = result ? 100 : 200
8547 enddef
8548 endclass
8549
8550 def Foo()
8551 feedkeys('', 'xt')
8552 var winid = popup_create('Y/N?',
8553 {filter: A.PopupFilter, callback: A.PopupCb})
8554 feedkeys('y', 'xt')
8555 popup_close(winid)
8556 assert_equal(100, A.selection)
8557 assert_equal(['y'], A.filterkeys)
8558 feedkeys('', 'xt')
8559 winid = popup_create('Y/N?',
8560 {filter: A.PopupFilter, callback: A.PopupCb})
8561 feedkeys('n', 'xt')
8562 popup_close(winid)
8563 assert_equal(200, A.selection)
8564 assert_equal(['y', 'n'], A.filterkeys)
8565 enddef
8566 Foo()
8567 END
8568 v9.CheckSourceSuccess(lines)
8569enddef
8570
8571" Test for using an object method as a timer callback function
8572def Test_objmethod_timer_callback()
8573 # Use the timer callback from script level
8574 var lines =<< trim END
8575 vim9script
8576
8577 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008578 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008579 def TimerCb(timerID: number)
8580 this.timerTick = 6
8581 enddef
8582 endclass
8583
8584 var a = A.new()
8585 timer_start(0, a.TimerCb)
8586 var maxWait = 5
8587 while maxWait > 0 && a.timerTick == -1
8588 :sleep 10m
8589 maxWait -= 1
8590 endwhile
8591 assert_equal(6, a.timerTick)
8592 END
8593 v9.CheckSourceSuccess(lines)
8594
8595 # Use the timer callback from a def function
8596 lines =<< trim END
8597 vim9script
8598
8599 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008600 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008601 def TimerCb(timerID: number)
8602 this.timerTick = 6
8603 enddef
8604 endclass
8605
8606 def Foo()
8607 var a = A.new()
8608 timer_start(0, a.TimerCb)
8609 var maxWait = 5
8610 while maxWait > 0 && a.timerTick == -1
8611 :sleep 10m
8612 maxWait -= 1
8613 endwhile
8614 assert_equal(6, a.timerTick)
8615 enddef
8616 Foo()
8617 END
8618 v9.CheckSourceSuccess(lines)
8619enddef
8620
8621" Test for using a class method as a timer callback function
8622def Test_classmethod_timer_callback()
8623 # Use the timer callback from script level
8624 var lines =<< trim END
8625 vim9script
8626
8627 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008628 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008629 static def TimerCb(timerID: number)
8630 timerTick = 6
8631 enddef
8632 endclass
8633
8634 timer_start(0, A.TimerCb)
8635 var maxWait = 5
8636 while maxWait > 0 && A.timerTick == -1
8637 :sleep 10m
8638 maxWait -= 1
8639 endwhile
8640 assert_equal(6, A.timerTick)
8641 END
8642 v9.CheckSourceSuccess(lines)
8643
8644 # Use the timer callback from a def function
8645 lines =<< trim END
8646 vim9script
8647
8648 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008649 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008650 static def TimerCb(timerID: number)
8651 timerTick = 6
8652 enddef
8653 endclass
8654
8655 def Foo()
8656 timer_start(0, A.TimerCb)
8657 var maxWait = 5
8658 while maxWait > 0 && A.timerTick == -1
8659 :sleep 10m
8660 maxWait -= 1
8661 endwhile
8662 assert_equal(6, A.timerTick)
8663 enddef
8664 Foo()
8665 END
8666 v9.CheckSourceSuccess(lines)
8667enddef
8668
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008669" Test for using a class variable as the first and/or second operand of a binary
8670" operator.
8671def Test_class_variable_as_operands()
8672 var lines =<< trim END
8673 vim9script
8674 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008675 static var truthy: bool = true
8676 public static var TruthyFn: func
8677 static var list: list<any> = []
8678 static var four: number = 4
8679 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008680
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008681 static def Str(): string
8682 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008683 enddef
8684
8685 static def Four(): number
8686 return four
8687 enddef
8688
8689 static def List(): list<any>
8690 return list
8691 enddef
8692
8693 static def Truthy(): bool
8694 return truthy
8695 enddef
8696
8697 def TestOps()
8698 assert_true(Tests.truthy == truthy)
8699 assert_true(truthy == Tests.truthy)
8700 assert_true(Tests.list isnot [])
8701 assert_true([] isnot Tests.list)
8702 assert_equal(2, Tests.four >> 1)
8703 assert_equal(16, 1 << Tests.four)
8704 assert_equal(8, Tests.four + four)
8705 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008706 assert_equal('hellohello', Tests.str .. str)
8707 assert_equal('hellohello', str .. Tests.str)
8708
8709 # Using class variable for list indexing
8710 var l = range(10)
8711 assert_equal(4, l[Tests.four])
8712 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8713
8714 # Using class variable for Dict key
8715 var d = {hello: 'abc'}
8716 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008717 enddef
8718 endclass
8719
8720 def TestOps2()
8721 assert_true(Tests.truthy == Tests.Truthy())
8722 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008723 assert_true(Tests.truthy == Tests.TruthyFn())
8724 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008725 assert_true(Tests.list is Tests.List())
8726 assert_true(Tests.List() is Tests.list)
8727 assert_equal(2, Tests.four >> 1)
8728 assert_equal(16, 1 << Tests.four)
8729 assert_equal(8, Tests.four + Tests.Four())
8730 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008731 assert_equal('hellohello', Tests.str .. Tests.Str())
8732 assert_equal('hellohello', Tests.Str() .. Tests.str)
8733
8734 # Using class variable for list indexing
8735 var l = range(10)
8736 assert_equal(4, l[Tests.four])
8737 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8738
8739 # Using class variable for Dict key
8740 var d = {hello: 'abc'}
8741 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008742 enddef
8743
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008744 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008745 var t = Tests.new()
8746 t.TestOps()
8747 TestOps2()
8748
8749 assert_true(Tests.truthy == Tests.Truthy())
8750 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008751 assert_true(Tests.truthy == Tests.TruthyFn())
8752 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008753 assert_true(Tests.list is Tests.List())
8754 assert_true(Tests.List() is Tests.list)
8755 assert_equal(2, Tests.four >> 1)
8756 assert_equal(16, 1 << Tests.four)
8757 assert_equal(8, Tests.four + Tests.Four())
8758 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008759 assert_equal('hellohello', Tests.str .. Tests.Str())
8760 assert_equal('hellohello', Tests.Str() .. Tests.str)
8761
8762 # Using class variable for list indexing
8763 var l = range(10)
8764 assert_equal(4, l[Tests.four])
8765 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8766
8767 # Using class variable for Dict key
8768 var d = {hello: 'abc'}
8769 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008770 END
8771 v9.CheckSourceSuccess(lines)
8772enddef
8773
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008774" Test for checking the type of the key used to access an object dict member.
8775def Test_dict_member_key_type_check()
8776 var lines =<< trim END
8777 vim9script
8778
8779 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01008780 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008781 endclass
8782
8783 class Test extends State
8784 def ObjMethodTests()
8785 var cursor: number = 0
8786 var z: number = 0
8787 [this.numbers[cursor]] = ['zero.1']
8788 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8789 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8790 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8791 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8792 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8793 [this.numbers[cursor], z] = ['zero.4', 1]
8794 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8795 [z, this.numbers[cursor]] = [1, 'zero.5']
8796 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8797 enddef
8798
8799 static def ClassMethodTests(that: State)
8800 var cursor: number = 0
8801 var z: number = 0
8802 [that.numbers[cursor]] = ['zero.1']
8803 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8804 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8805 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8806 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8807 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8808 [that.numbers[cursor], z] = ['zero.4', 1]
8809 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8810 [z, that.numbers[cursor]] = [1, 'zero.5']
8811 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8812 enddef
8813
8814 def new()
8815 enddef
8816
8817 def newMethodTests()
8818 var cursor: number = 0
8819 var z: number
8820 [this.numbers[cursor]] = ['zero.1']
8821 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8822 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8823 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8824 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8825 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8826 [this.numbers[cursor], z] = ['zero.4', 1]
8827 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8828 [z, this.numbers[cursor]] = [1, 'zero.5']
8829 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8830 enddef
8831 endclass
8832
8833 def DefFuncTests(that: Test)
8834 var cursor: number = 0
8835 var z: number
8836 [that.numbers[cursor]] = ['zero.1']
8837 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8838 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8839 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8840 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8841 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8842 [that.numbers[cursor], z] = ['zero.4', 1]
8843 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8844 [z, that.numbers[cursor]] = [1, 'zero.5']
8845 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8846 enddef
8847
8848 Test.newMethodTests()
8849 Test.new().ObjMethodTests()
8850 Test.ClassMethodTests(Test.new())
8851 DefFuncTests(Test.new())
8852
8853 const test: Test = Test.new()
8854 var cursor: number = 0
8855 [test.numbers[cursor], cursor] = ['zero', 1]
8856 [cursor, test.numbers[cursor]] = [1, 'one']
8857 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8858 END
8859 v9.CheckSourceSuccess(lines)
8860
8861 lines =<< trim END
8862 vim9script
8863
8864 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008865 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008866
8867 def new()
8868 enddef
8869
8870 def Foo()
8871 var z: number
8872 [this.numbers.a, z] = [{}, 10]
8873 enddef
8874 endclass
8875
8876 var a = A.new()
8877 a.Foo()
8878 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008879 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008880
8881 lines =<< trim END
8882 vim9script
8883
8884 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008885 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008886
8887 def new()
8888 enddef
8889
8890 def Foo()
8891 var x: string = 'a'
8892 var y: number
8893 [this.numbers[x], y] = [{}, 10]
8894 enddef
8895 endclass
8896
8897 var a = A.new()
8898 a.Foo()
8899 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008900 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008901enddef
8902
mityua5550692023-11-25 15:41:20 +01008903def Test_compile_many_def_functions_in_funcref_instr()
8904 # This used to crash Vim. This is reproducible only when run on new instance
8905 # of Vim.
8906 var lines =<< trim END
8907 vim9script
8908
8909 class A
8910 def new()
8911 this.TakeFunc(this.F00)
8912 enddef
8913
8914 def TakeFunc(F: func)
8915 enddef
8916
8917 def F00()
8918 this.F01()
8919 this.F02()
8920 this.F03()
8921 this.F04()
8922 this.F05()
8923 this.F06()
8924 this.F07()
8925 this.F08()
8926 this.F09()
8927 this.F10()
8928 this.F11()
8929 this.F12()
8930 this.F13()
8931 this.F14()
8932 this.F15()
8933 this.F16()
8934 this.F17()
8935 this.F18()
8936 this.F19()
8937 this.F20()
8938 this.F21()
8939 this.F22()
8940 this.F23()
8941 this.F24()
8942 this.F25()
8943 this.F26()
8944 this.F27()
8945 this.F28()
8946 this.F29()
8947 this.F30()
8948 this.F31()
8949 this.F32()
8950 this.F33()
8951 this.F34()
8952 this.F35()
8953 this.F36()
8954 this.F37()
8955 this.F38()
8956 this.F39()
8957 this.F40()
8958 this.F41()
8959 this.F42()
8960 this.F43()
8961 this.F44()
8962 this.F45()
8963 this.F46()
8964 this.F47()
8965 enddef
8966
8967 def F01()
8968 enddef
8969 def F02()
8970 enddef
8971 def F03()
8972 enddef
8973 def F04()
8974 enddef
8975 def F05()
8976 enddef
8977 def F06()
8978 enddef
8979 def F07()
8980 enddef
8981 def F08()
8982 enddef
8983 def F09()
8984 enddef
8985 def F10()
8986 enddef
8987 def F11()
8988 enddef
8989 def F12()
8990 enddef
8991 def F13()
8992 enddef
8993 def F14()
8994 enddef
8995 def F15()
8996 enddef
8997 def F16()
8998 enddef
8999 def F17()
9000 enddef
9001 def F18()
9002 enddef
9003 def F19()
9004 enddef
9005 def F20()
9006 enddef
9007 def F21()
9008 enddef
9009 def F22()
9010 enddef
9011 def F23()
9012 enddef
9013 def F24()
9014 enddef
9015 def F25()
9016 enddef
9017 def F26()
9018 enddef
9019 def F27()
9020 enddef
9021 def F28()
9022 enddef
9023 def F29()
9024 enddef
9025 def F30()
9026 enddef
9027 def F31()
9028 enddef
9029 def F32()
9030 enddef
9031 def F33()
9032 enddef
9033 def F34()
9034 enddef
9035 def F35()
9036 enddef
9037 def F36()
9038 enddef
9039 def F37()
9040 enddef
9041 def F38()
9042 enddef
9043 def F39()
9044 enddef
9045 def F40()
9046 enddef
9047 def F41()
9048 enddef
9049 def F42()
9050 enddef
9051 def F43()
9052 enddef
9053 def F44()
9054 enddef
9055 def F45()
9056 enddef
9057 def F46()
9058 enddef
9059 def F47()
9060 enddef
9061 endclass
9062
9063 A.new()
9064 END
9065 writefile(lines, 'Xscript', 'D')
9066 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9067 assert_equal(0, v:shell_error)
9068enddef
9069
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009070" Test for 'final' class and object variables
9071def Test_final_class_object_variable()
9072 # Test for changing a final object variable from an object function
9073 var lines =<< trim END
9074 vim9script
9075 class A
9076 final foo: string = "abc"
9077 def Foo()
9078 this.foo = "def"
9079 enddef
9080 endclass
9081 defcompile A.Foo
9082 END
9083 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9084
9085 # Test for changing a final object variable from the 'new' function
9086 lines =<< trim END
9087 vim9script
9088 class A
9089 final s1: string
9090 final s2: string
9091 def new(this.s1)
9092 this.s2 = 'def'
9093 enddef
9094 endclass
9095 var a = A.new('abc')
9096 assert_equal('abc', a.s1)
9097 assert_equal('def', a.s2)
9098 END
9099 v9.CheckSourceSuccess(lines)
9100
9101 # Test for a final class variable
9102 lines =<< trim END
9103 vim9script
9104 class A
9105 static final s1: string = "abc"
9106 endclass
9107 assert_equal('abc', A.s1)
9108 END
9109 v9.CheckSourceSuccess(lines)
9110
9111 # Test for changing a final class variable from a class function
9112 lines =<< trim END
9113 vim9script
9114 class A
9115 static final s1: string = "abc"
9116 static def Foo()
9117 s1 = "def"
9118 enddef
9119 endclass
9120 A.Foo()
9121 END
9122 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9123
9124 # Test for changing a public final class variable at script level
9125 lines =<< trim END
9126 vim9script
9127 class A
9128 public static final s1: string = "abc"
9129 endclass
9130 assert_equal('abc', A.s1)
9131 A.s1 = 'def'
9132 END
9133 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9134
9135 # Test for changing a public final class variable from a class function
9136 lines =<< trim END
9137 vim9script
9138 class A
9139 public static final s1: string = "abc"
9140 static def Foo()
9141 s1 = "def"
9142 enddef
9143 endclass
9144 A.Foo()
9145 END
9146 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9147
9148 # Test for changing a public final class variable from a function
9149 lines =<< trim END
9150 vim9script
9151 class A
9152 public static final s1: string = "abc"
9153 endclass
9154 def Foo()
9155 A.s1 = 'def'
9156 enddef
9157 defcompile
9158 END
9159 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9160
9161 # Test for using a final variable of composite type
9162 lines =<< trim END
9163 vim9script
9164 class A
9165 public final l: list<number>
9166 def new()
9167 this.l = [1, 2]
9168 enddef
9169 def Foo()
9170 this.l[0] = 3
9171 this.l->add(4)
9172 enddef
9173 endclass
9174 var a = A.new()
9175 assert_equal([1, 2], a.l)
9176 a.Foo()
9177 assert_equal([3, 2, 4], a.l)
9178 END
9179 v9.CheckSourceSuccess(lines)
9180
9181 # Test for changing a final variable of composite type from another object
9182 # function
9183 lines =<< trim END
9184 vim9script
9185 class A
9186 public final l: list<number> = [1, 2]
9187 def Foo()
9188 this.l = [3, 4]
9189 enddef
9190 endclass
9191 var a = A.new()
9192 a.Foo()
9193 END
9194 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9195
9196 # Test for modifying a final variable of composite type at script level
9197 lines =<< trim END
9198 vim9script
9199 class A
9200 public final l: list<number> = [1, 2]
9201 endclass
9202 var a = A.new()
9203 a.l[0] = 3
9204 a.l->add(4)
9205 assert_equal([3, 2, 4], a.l)
9206 END
9207 v9.CheckSourceSuccess(lines)
9208
9209 # Test for modifying a final variable of composite type from a function
9210 lines =<< trim END
9211 vim9script
9212 class A
9213 public final l: list<number> = [1, 2]
9214 endclass
9215 def Foo()
9216 var a = A.new()
9217 a.l[0] = 3
9218 a.l->add(4)
9219 assert_equal([3, 2, 4], a.l)
9220 enddef
9221 Foo()
9222 END
9223 v9.CheckSourceSuccess(lines)
9224
9225 # Test for modifying a final variable of composite type from another object
9226 # function
9227 lines =<< trim END
9228 vim9script
9229 class A
9230 public final l: list<number> = [1, 2]
9231 def Foo()
9232 this.l[0] = 3
9233 this.l->add(4)
9234 enddef
9235 endclass
9236 var a = A.new()
9237 a.Foo()
9238 assert_equal([3, 2, 4], a.l)
9239 END
9240 v9.CheckSourceSuccess(lines)
9241
9242 # Test for assigning a new value to a final variable of composite type at
9243 # script level
9244 lines =<< trim END
9245 vim9script
9246 class A
9247 public final l: list<number> = [1, 2]
9248 endclass
9249 var a = A.new()
9250 a.l = [3, 4]
9251 END
9252 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9253
9254 # Test for assigning a new value to a final variable of composite type from
9255 # another object function
9256 lines =<< trim END
9257 vim9script
9258 class A
9259 public final l: list<number> = [1, 2]
9260 def Foo()
9261 this.l = [3, 4]
9262 enddef
9263 endclass
9264 var a = A.new()
9265 a.Foo()
9266 END
9267 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9268
9269 # Test for assigning a new value to a final variable of composite type from
9270 # another function
9271 lines =<< trim END
9272 vim9script
9273 class A
9274 public final l: list<number> = [1, 2]
9275 endclass
9276 def Foo()
9277 var a = A.new()
9278 a.l = [3, 4]
9279 enddef
9280 Foo()
9281 END
9282 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9283
9284 # Error case: Use 'final' with just a variable name
9285 lines =<< trim END
9286 vim9script
9287 class A
9288 final foo
9289 endclass
9290 var a = A.new()
9291 END
9292 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9293
9294 # Error case: Use 'final' followed by 'public'
9295 lines =<< trim END
9296 vim9script
9297 class A
9298 final public foo: number
9299 endclass
9300 var a = A.new()
9301 END
9302 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9303
9304 # Error case: Use 'final' followed by 'static'
9305 lines =<< trim END
9306 vim9script
9307 class A
9308 final static foo: number
9309 endclass
9310 var a = A.new()
9311 END
9312 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9313
9314 # Error case: 'final' cannot be used in an interface
9315 lines =<< trim END
9316 vim9script
9317 interface A
9318 final foo: number = 10
9319 endinterface
9320 END
9321 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9322
9323 # Error case: 'final' not supported for an object method
9324 lines =<< trim END
9325 vim9script
9326 class A
9327 final def Foo()
9328 enddef
9329 endclass
9330 END
9331 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9332
9333 # Error case: 'final' not supported for a class method
9334 lines =<< trim END
9335 vim9script
9336 class A
9337 static final def Foo()
9338 enddef
9339 endclass
9340 END
9341 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9342enddef
9343
9344" Test for 'const' class and object variables
9345def Test_const_class_object_variable()
9346 # Test for changing a const object variable from an object function
9347 var lines =<< trim END
9348 vim9script
9349 class A
9350 const foo: string = "abc"
9351 def Foo()
9352 this.foo = "def"
9353 enddef
9354 endclass
9355 defcompile A.Foo
9356 END
9357 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9358
9359 # Test for changing a const object variable from the 'new' function
9360 lines =<< trim END
9361 vim9script
9362 class A
9363 const s1: string
9364 const s2: string
9365 def new(this.s1)
9366 this.s2 = 'def'
9367 enddef
9368 endclass
9369 var a = A.new('abc')
9370 assert_equal('abc', a.s1)
9371 assert_equal('def', a.s2)
9372 END
9373 v9.CheckSourceSuccess(lines)
9374
9375 # Test for changing a const object variable from an object method called from
9376 # the 'new' function
9377 lines =<< trim END
9378 vim9script
9379 class A
9380 const s1: string = 'abc'
9381 def new()
9382 this.ChangeStr()
9383 enddef
9384 def ChangeStr()
9385 this.s1 = 'def'
9386 enddef
9387 endclass
9388 var a = A.new()
9389 END
9390 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9391
9392 # Test for a const class variable
9393 lines =<< trim END
9394 vim9script
9395 class A
9396 static const s1: string = "abc"
9397 endclass
9398 assert_equal('abc', A.s1)
9399 END
9400 v9.CheckSourceSuccess(lines)
9401
9402 # Test for changing a const class variable from a class function
9403 lines =<< trim END
9404 vim9script
9405 class A
9406 static const s1: string = "abc"
9407 static def Foo()
9408 s1 = "def"
9409 enddef
9410 endclass
9411 A.Foo()
9412 END
9413 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9414
9415 # Test for changing a public const class variable at script level
9416 lines =<< trim END
9417 vim9script
9418 class A
9419 public static const s1: string = "abc"
9420 endclass
9421 assert_equal('abc', A.s1)
9422 A.s1 = 'def'
9423 END
9424 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9425
9426 # Test for changing a public const class variable from a class function
9427 lines =<< trim END
9428 vim9script
9429 class A
9430 public static const s1: string = "abc"
9431 static def Foo()
9432 s1 = "def"
9433 enddef
9434 endclass
9435 A.Foo()
9436 END
9437 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9438
9439 # Test for changing a public const class variable from a function
9440 lines =<< trim END
9441 vim9script
9442 class A
9443 public static const s1: string = "abc"
9444 endclass
9445 def Foo()
9446 A.s1 = 'def'
9447 enddef
9448 defcompile
9449 END
9450 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9451
9452 # Test for changing a const List item from an object function
9453 lines =<< trim END
9454 vim9script
9455 class A
9456 public const l: list<number>
9457 def new()
9458 this.l = [1, 2]
9459 enddef
9460 def Foo()
9461 this.l[0] = 3
9462 enddef
9463 endclass
9464 var a = A.new()
9465 assert_equal([1, 2], a.l)
9466 a.Foo()
9467 END
9468 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9469
9470 # Test for adding a value to a const List from an object function
9471 lines =<< trim END
9472 vim9script
9473 class A
9474 public const l: list<number>
9475 def new()
9476 this.l = [1, 2]
9477 enddef
9478 def Foo()
9479 this.l->add(3)
9480 enddef
9481 endclass
9482 var a = A.new()
9483 a.Foo()
9484 END
9485 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9486
9487 # Test for reassigning a const List from an object function
9488 lines =<< trim END
9489 vim9script
9490 class A
9491 public const l: list<number> = [1, 2]
9492 def Foo()
9493 this.l = [3, 4]
9494 enddef
9495 endclass
9496 var a = A.new()
9497 a.Foo()
9498 END
9499 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9500
9501 # Test for changing a const List item at script level
9502 lines =<< trim END
9503 vim9script
9504 class A
9505 public const l: list<number> = [1, 2]
9506 endclass
9507 var a = A.new()
9508 a.l[0] = 3
9509 END
9510 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9511
9512 # Test for adding a value to a const List item at script level
9513 lines =<< trim END
9514 vim9script
9515 class A
9516 public const l: list<number> = [1, 2]
9517 endclass
9518 var a = A.new()
9519 a.l->add(4)
9520 END
9521 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9522
9523 # Test for changing a const List item from a function
9524 lines =<< trim END
9525 vim9script
9526 class A
9527 public const l: list<number> = [1, 2]
9528 endclass
9529 def Foo()
9530 var a = A.new()
9531 a.l[0] = 3
9532 enddef
9533 Foo()
9534 END
9535 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9536
9537 # Test for adding a value to a const List item from a function
9538 lines =<< trim END
9539 vim9script
9540 class A
9541 public const l: list<number> = [1, 2]
9542 endclass
9543 def Foo()
9544 var a = A.new()
9545 a.l->add(4)
9546 enddef
9547 Foo()
9548 END
9549 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9550
9551 # Test for changing a const List item from an object method
9552 lines =<< trim END
9553 vim9script
9554 class A
9555 public const l: list<number> = [1, 2]
9556 def Foo()
9557 this.l[0] = 3
9558 enddef
9559 endclass
9560 var a = A.new()
9561 a.Foo()
9562 END
9563 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9564
9565 # Test for adding a value to a const List item from an object method
9566 lines =<< trim END
9567 vim9script
9568 class A
9569 public const l: list<number> = [1, 2]
9570 def Foo()
9571 this.l->add(4)
9572 enddef
9573 endclass
9574 var a = A.new()
9575 a.Foo()
9576 END
9577 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9578
9579 # Test for reassigning a const List object variable at script level
9580 lines =<< trim END
9581 vim9script
9582 class A
9583 public const l: list<number> = [1, 2]
9584 endclass
9585 var a = A.new()
9586 a.l = [3, 4]
9587 END
9588 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9589
9590 # Test for reassigning a const List object variable from an object method
9591 lines =<< trim END
9592 vim9script
9593 class A
9594 public const l: list<number> = [1, 2]
9595 def Foo()
9596 this.l = [3, 4]
9597 enddef
9598 endclass
9599 var a = A.new()
9600 a.Foo()
9601 END
9602 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9603
9604 # Test for reassigning a const List object variable from another function
9605 lines =<< trim END
9606 vim9script
9607 class A
9608 public const l: list<number> = [1, 2]
9609 endclass
9610 def Foo()
9611 var a = A.new()
9612 a.l = [3, 4]
9613 enddef
9614 Foo()
9615 END
9616 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9617
9618 # Error case: Use 'const' with just a variable name
9619 lines =<< trim END
9620 vim9script
9621 class A
9622 const foo
9623 endclass
9624 var a = A.new()
9625 END
9626 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9627
9628 # Error case: Use 'const' followed by 'public'
9629 lines =<< trim END
9630 vim9script
9631 class A
9632 const public foo: number
9633 endclass
9634 var a = A.new()
9635 END
9636 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9637
9638 # Error case: Use 'const' followed by 'static'
9639 lines =<< trim END
9640 vim9script
9641 class A
9642 const static foo: number
9643 endclass
9644 var a = A.new()
9645 END
9646 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9647
9648 # Error case: 'const' cannot be used in an interface
9649 lines =<< trim END
9650 vim9script
9651 interface A
9652 const foo: number = 10
9653 endinterface
9654 END
9655 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9656
9657 # Error case: 'const' not supported for an object method
9658 lines =<< trim END
9659 vim9script
9660 class A
9661 const def Foo()
9662 enddef
9663 endclass
9664 END
9665 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9666
9667 # Error case: 'const' not supported for a class method
9668 lines =<< trim END
9669 vim9script
9670 class A
9671 static const def Foo()
9672 enddef
9673 endclass
9674 END
9675 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9676enddef
9677
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009678" Test for compiling class/object methods using :defcompile
9679def Test_defcompile_class()
9680 # defcompile all the classes in the current script
9681 var lines =<< trim END
9682 vim9script
9683 class A
9684 def Foo()
9685 var i = 10
9686 enddef
9687 endclass
9688 class B
9689 def Bar()
9690 var i = 20
9691 xxx
9692 enddef
9693 endclass
9694 defcompile
9695 END
9696 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9697
9698 # defcompile a specific class
9699 lines =<< trim END
9700 vim9script
9701 class A
9702 def Foo()
9703 xxx
9704 enddef
9705 endclass
9706 class B
9707 def Bar()
9708 yyy
9709 enddef
9710 endclass
9711 defcompile B
9712 END
9713 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9714
9715 # defcompile a non-class
9716 lines =<< trim END
9717 vim9script
9718 class A
9719 def Foo()
9720 enddef
9721 endclass
9722 var X: list<number> = []
9723 defcompile X
9724 END
9725 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9726
9727 # defcompile a class twice
9728 lines =<< trim END
9729 vim9script
9730 class A
9731 def new()
9732 enddef
9733 endclass
9734 defcompile A
9735 defcompile A
9736 assert_equal('Function A.new does not need compiling', v:statusmsg)
9737 END
9738 v9.CheckSourceSuccess(lines)
9739
9740 # defcompile should not compile an imported class
9741 lines =<< trim END
9742 vim9script
9743 export class A
9744 def Foo()
9745 xxx
9746 enddef
9747 endclass
9748 END
9749 writefile(lines, 'Xdefcompileimport.vim', 'D')
9750 lines =<< trim END
9751 vim9script
9752
9753 import './Xdefcompileimport.vim'
9754 class B
9755 endclass
9756 defcompile
9757 END
9758 v9.CheckScriptSuccess(lines)
9759enddef
9760
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +01009761" Test for cases common to all the object builtin methods
9762def Test_object_builtin_method()
9763 var lines =<< trim END
9764 vim9script
9765 class A
9766 def abc()
9767 enddef
9768 endclass
9769 END
9770 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
9771
9772 for funcname in ["len", "string", "empty"]
9773 lines =<< trim eval END
9774 vim9script
9775 class A
9776 static def {funcname}(): number
9777 enddef
9778 endclass
9779 END
9780 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
9781 endfor
9782enddef
9783
9784" Test for using the empty() builtin method with an object
9785" This is a legacy function to use the test_garbagecollect_now() function.
9786func Test_object_empty()
9787 let lines =<< trim END
9788 vim9script
9789 class A
9790 def empty(): bool
9791 return true
9792 enddef
9793 endclass
9794
9795 def Foo()
9796 var afoo = A.new()
9797 assert_equal(true, empty(afoo))
9798 assert_equal(true, afoo->empty())
9799 enddef
9800
9801 var a = A.new()
9802 assert_equal(1, empty(a))
9803 assert_equal(1, a->empty())
9804 test_garbagecollect_now()
9805 assert_equal(1, empty(a))
9806 Foo()
9807 test_garbagecollect_now()
9808 Foo()
9809 END
9810 call v9.CheckSourceSuccess(lines)
9811
9812 " empty() should return 1 without a builtin method
9813 let lines =<< trim END
9814 vim9script
9815 class A
9816 endclass
9817
9818 def Foo()
9819 var afoo = A.new()
9820 assert_equal(1, empty(afoo))
9821 enddef
9822
9823 var a = A.new()
9824 assert_equal(1, empty(a))
9825 Foo()
9826 END
9827 call v9.CheckSourceSuccess(lines)
9828
9829 " Unsupported signature for the empty() method
9830 let lines =<< trim END
9831 vim9script
9832 class A
9833 def empty()
9834 enddef
9835 endclass
9836 END
9837 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
9838
9839 " Error when calling the empty() method
9840 let lines =<< trim END
9841 vim9script
9842 class A
9843 def empty(): bool
9844 throw "Failed to check emptiness"
9845 enddef
9846 endclass
9847
9848 def Foo()
9849 var afoo = A.new()
9850 var i = empty(afoo)
9851 enddef
9852
9853 var a = A.new()
9854 assert_fails('empty(a)', 'Failed to check emptiness')
9855 assert_fails('Foo()', 'Failed to check emptiness')
9856 END
9857 call v9.CheckSourceSuccess(lines)
9858
9859 " call empty() using an object from a script
9860 let lines =<< trim END
9861 vim9script
9862 class A
9863 def empty(): bool
9864 return true
9865 enddef
9866 endclass
9867 var afoo = A.new()
9868 assert_equal(true, afoo.empty())
9869 END
9870 call v9.CheckSourceSuccess(lines)
9871
9872 " call empty() using an object from a method
9873 let lines =<< trim END
9874 vim9script
9875 class A
9876 def empty(): bool
9877 return true
9878 enddef
9879 endclass
9880 def Foo()
9881 var afoo = A.new()
9882 assert_equal(true, afoo.empty())
9883 enddef
9884 Foo()
9885 END
9886 call v9.CheckSourceSuccess(lines)
9887
9888 " call empty() using "this" from an object method
9889 let lines =<< trim END
9890 vim9script
9891 class A
9892 def empty(): bool
9893 return true
9894 enddef
9895 def Foo(): bool
9896 return this.empty()
9897 enddef
9898 endclass
9899 def Bar()
9900 var abar = A.new()
9901 assert_equal(true, abar.Foo())
9902 enddef
9903 Bar()
9904 END
9905 call v9.CheckSourceSuccess(lines)
9906
9907 " Call empty() from a derived object
9908 let lines =<< trim END
9909 vim9script
9910 class A
9911 def empty(): bool
9912 return false
9913 enddef
9914 endclass
9915 class B extends A
9916 def empty(): bool
9917 return true
9918 enddef
9919 endclass
9920 def Foo(afoo: A)
9921 assert_equal(true, empty(afoo))
9922 var bfoo = B.new()
9923 assert_equal(true, empty(bfoo))
9924 enddef
9925 var b = B.new()
9926 assert_equal(1, empty(b))
9927 Foo(b)
9928 END
9929 call v9.CheckSourceSuccess(lines)
9930
9931 " Invoking empty method using an interface
9932 let lines =<< trim END
9933 vim9script
9934 interface A
9935 def empty(): bool
9936 endinterface
9937 class B implements A
9938 def empty(): bool
9939 return false
9940 enddef
9941 endclass
9942 def Foo(a: A)
9943 assert_equal(false, empty(a))
9944 enddef
9945 var b = B.new()
9946 Foo(b)
9947 END
9948 call v9.CheckSourceSuccess(lines)
9949endfunc
9950
9951" Test for using the len() builtin method with an object
9952" This is a legacy function to use the test_garbagecollect_now() function.
9953func Test_object_length()
9954 let lines =<< trim END
9955 vim9script
9956 class A
9957 var mylen: number = 0
9958 def new(n: number)
9959 this.mylen = n
9960 enddef
9961 def len(): number
9962 return this.mylen
9963 enddef
9964 endclass
9965
9966 def Foo()
9967 var afoo = A.new(12)
9968 assert_equal(12, len(afoo))
9969 assert_equal(12, afoo->len())
9970 enddef
9971
9972 var a = A.new(22)
9973 assert_equal(22, len(a))
9974 assert_equal(22, a->len())
9975 test_garbagecollect_now()
9976 assert_equal(22, len(a))
9977 Foo()
9978 test_garbagecollect_now()
9979 Foo()
9980 END
9981 call v9.CheckSourceSuccess(lines)
9982
9983 " len() should return 0 without a builtin method
9984 let lines =<< trim END
9985 vim9script
9986 class A
9987 endclass
9988
9989 def Foo()
9990 var afoo = A.new()
9991 assert_equal(0, len(afoo))
9992 enddef
9993
9994 var a = A.new()
9995 assert_equal(0, len(a))
9996 Foo()
9997 END
9998 call v9.CheckSourceSuccess(lines)
9999
10000 " Unsupported signature for the len() method
10001 let lines =<< trim END
10002 vim9script
10003 class A
10004 def len()
10005 enddef
10006 endclass
10007 END
10008 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10009
10010 " Error when calling the len() method
10011 let lines =<< trim END
10012 vim9script
10013 class A
10014 def len(): number
10015 throw "Failed to compute length"
10016 enddef
10017 endclass
10018
10019 def Foo()
10020 var afoo = A.new()
10021 var i = len(afoo)
10022 enddef
10023
10024 var a = A.new()
10025 assert_fails('len(a)', 'Failed to compute length')
10026 assert_fails('Foo()', 'Failed to compute length')
10027 END
10028 call v9.CheckSourceSuccess(lines)
10029
10030 " call len() using an object from a script
10031 let lines =<< trim END
10032 vim9script
10033 class A
10034 def len(): number
10035 return 5
10036 enddef
10037 endclass
10038 var afoo = A.new()
10039 assert_equal(5, afoo.len())
10040 END
10041 call v9.CheckSourceSuccess(lines)
10042
10043 " call len() using an object from a method
10044 let lines =<< trim END
10045 vim9script
10046 class A
10047 def len(): number
10048 return 5
10049 enddef
10050 endclass
10051 def Foo()
10052 var afoo = A.new()
10053 assert_equal(5, afoo.len())
10054 enddef
10055 Foo()
10056 END
10057 call v9.CheckSourceSuccess(lines)
10058
10059 " call len() using "this" from an object method
10060 let lines =<< trim END
10061 vim9script
10062 class A
10063 def len(): number
10064 return 8
10065 enddef
10066 def Foo(): number
10067 return this.len()
10068 enddef
10069 endclass
10070 def Bar()
10071 var abar = A.new()
10072 assert_equal(8, abar.Foo())
10073 enddef
10074 Bar()
10075 END
10076 call v9.CheckSourceSuccess(lines)
10077
10078 " Call len() from a derived object
10079 let lines =<< trim END
10080 vim9script
10081 class A
10082 def len(): number
10083 return 10
10084 enddef
10085 endclass
10086 class B extends A
10087 def len(): number
10088 return 20
10089 enddef
10090 endclass
10091 def Foo(afoo: A)
10092 assert_equal(20, len(afoo))
10093 var bfoo = B.new()
10094 assert_equal(20, len(bfoo))
10095 enddef
10096 var b = B.new()
10097 assert_equal(20, len(b))
10098 Foo(b)
10099 END
10100 call v9.CheckSourceSuccess(lines)
10101
10102 " Invoking len method using an interface
10103 let lines =<< trim END
10104 vim9script
10105 interface A
10106 def len(): number
10107 endinterface
10108 class B implements A
10109 def len(): number
10110 return 123
10111 enddef
10112 endclass
10113 def Foo(a: A)
10114 assert_equal(123, len(a))
10115 enddef
10116 var b = B.new()
10117 Foo(b)
10118 END
10119 call v9.CheckSourceSuccess(lines)
10120endfunc
10121
10122" Test for using the string() builtin method with an object
10123" This is a legacy function to use the test_garbagecollect_now() function.
10124func Test_object_string()
10125 let lines =<< trim END
10126 vim9script
10127 class A
10128 var name: string
10129 def string(): string
10130 return this.name
10131 enddef
10132 endclass
10133
10134 def Foo()
10135 var afoo = A.new("foo-A")
10136 assert_equal('foo-A', string(afoo))
10137 assert_equal('foo-A', afoo->string())
10138 enddef
10139
10140 var a = A.new("script-A")
10141 assert_equal('script-A', string(a))
10142 assert_equal('script-A', a->string())
10143 assert_equal(['script-A'], execute('echo a')->split("\n"))
10144 test_garbagecollect_now()
10145 assert_equal('script-A', string(a))
10146 Foo()
10147 test_garbagecollect_now()
10148 Foo()
10149 END
10150 call v9.CheckSourceSuccess(lines)
10151
10152 " string() should return "object of A {}" without a builtin method
10153 let lines =<< trim END
10154 vim9script
10155 class A
10156 endclass
10157
10158 def Foo()
10159 var afoo = A.new()
10160 assert_equal('object of A {}', string(afoo))
10161 enddef
10162
10163 var a = A.new()
10164 assert_equal('object of A {}', string(a))
10165 Foo()
10166 END
10167 call v9.CheckSourceSuccess(lines)
10168
10169 " Unsupported signature for the string() method
10170 let lines =<< trim END
10171 vim9script
10172 class A
10173 def string()
10174 enddef
10175 endclass
10176 END
10177 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10178
10179 " Error when calling the string() method
10180 let lines =<< trim END
10181 vim9script
10182 class A
10183 def string(): string
10184 throw "Failed to get text"
10185 enddef
10186 endclass
10187
10188 def Foo()
10189 var afoo = A.new()
10190 var i = string(afoo)
10191 enddef
10192
10193 var a = A.new()
10194 assert_fails('string(a)', 'Failed to get text')
10195 assert_fails('Foo()', 'Failed to get text')
10196 END
10197 call v9.CheckSourceSuccess(lines)
10198
10199 " call string() using an object from a script
10200 let lines =<< trim END
10201 vim9script
10202 class A
10203 def string(): string
10204 return 'A'
10205 enddef
10206 endclass
10207 var afoo = A.new()
10208 assert_equal('A', afoo.string())
10209 END
10210 call v9.CheckSourceSuccess(lines)
10211
10212 " call string() using an object from a method
10213 let lines =<< trim END
10214 vim9script
10215 class A
10216 def string(): string
10217 return 'A'
10218 enddef
10219 endclass
10220 def Foo()
10221 var afoo = A.new()
10222 assert_equal('A', afoo.string())
10223 enddef
10224 Foo()
10225 END
10226 call v9.CheckSourceSuccess(lines)
10227
10228 " call string() using "this" from an object method
10229 let lines =<< trim END
10230 vim9script
10231 class A
10232 def string(): string
10233 return 'A'
10234 enddef
10235 def Foo(): string
10236 return this.string()
10237 enddef
10238 endclass
10239 def Bar()
10240 var abar = A.new()
10241 assert_equal('A', abar.string())
10242 enddef
10243 Bar()
10244 END
10245 call v9.CheckSourceSuccess(lines)
10246
10247 " Call string() from a derived object
10248 let lines =<< trim END
10249 vim9script
10250 class A
10251 def string(): string
10252 return 'A'
10253 enddef
10254 endclass
10255 class B extends A
10256 def string(): string
10257 return 'B'
10258 enddef
10259 endclass
10260 def Foo(afoo: A)
10261 assert_equal('B', string(afoo))
10262 var bfoo = B.new()
10263 assert_equal('B', string(bfoo))
10264 enddef
10265 var b = B.new()
10266 assert_equal('B', string(b))
10267 Foo(b)
10268 END
10269 call v9.CheckSourceSuccess(lines)
10270
10271 " Invoking string method using an interface
10272 let lines =<< trim END
10273 vim9script
10274 interface A
10275 def string(): string
10276 endinterface
10277 class B implements A
10278 def string(): string
10279 return 'B'
10280 enddef
10281 endclass
10282 def Foo(a: A)
10283 assert_equal('B', string(a))
10284 enddef
10285 var b = B.new()
10286 Foo(b)
10287 END
10288 call v9.CheckSourceSuccess(lines)
10289endfunc
10290
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010291" Test for using a class in the class definition
10292def Test_Ref_Class_Within_Same_Class()
10293 var lines =<< trim END
10294 vim9script
10295 class A
10296 var n: number = 0
10297 def Equals(other: A): bool
10298 return this.n == other.n
10299 enddef
10300 endclass
10301
10302 var a1 = A.new(10)
10303 var a2 = A.new(10)
10304 var a3 = A.new(20)
10305 assert_equal(true, a1.Equals(a2))
10306 assert_equal(false, a2.Equals(a3))
10307 END
10308 v9.CheckScriptSuccess(lines)
10309
10310 lines =<< trim END
10311 vim9script
10312
10313 class Foo
10314 var num: number
10315 def Clone(): Foo
10316 return Foo.new(this.num)
10317 enddef
10318 endclass
10319
10320 var f1 = Foo.new(1)
10321
10322 def F()
10323 var f2: Foo = f1.Clone()
10324 assert_equal(false, f2 is f1)
10325 assert_equal(true, f2.num == f1.num)
10326 enddef
10327 F()
10328
10329 var f3: Foo = f1.Clone()
10330 assert_equal(false, f3 is f1)
10331 assert_equal(true, f3.num == f1.num)
10332 END
10333 v9.CheckScriptSuccess(lines)
10334
10335 # Test for trying to use a class to extend when defining the same class
10336 lines =<< trim END
10337 vim9script
10338 class A extends A
10339 endclass
10340 END
10341 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10342
10343 # Test for trying to use a class to implement when defining the same class
10344 lines =<< trim END
10345 vim9script
10346 class A implements A
10347 endclass
10348 END
10349 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10350enddef
10351
Bram Moolenaar00b28d62022-12-08 15:32:33 +000010352" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker