blob: 77a2102c2d69138d7047b2756c2b22dfbc51f160 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +010038 # Only the complete word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010070 # Try to define a class with the same name as an existing variable
71 lines =<< trim END
72 vim9script
73 var Something: list<number> = [1]
74 class Thing
75 endclass
76 interface Api
77 endinterface
78 class Something extends Thing implements Api
79 var v1: string = ''
80 def Foo()
81 enddef
82 endclass
83 END
84 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 7)
85
zeertzjqe7102202024-02-13 20:32:04 +010086 # Use old "this." prefixed member variable declaration syntax (without initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +010087 lines =<< trim END
88 vim9script
89 class Something
90 this.count: number
91 endclass
92 END
93 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
94
zeertzjqe7102202024-02-13 20:32:04 +010095 # Use old "this." prefixed member variable declaration syntax (with initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +010096 lines =<< trim END
97 vim9script
98 class Something
99 this.count: number = 42
100 endclass
101 END
102 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
103
104 # Use old "this." prefixed member variable declaration syntax (type inferred)
105 lines =<< trim END
106 vim9script
107 class Something
108 this.count = 42
109 endclass
110 END
111 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
112
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200113 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000114 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200115 vim9script
116 class Something
117 this
118 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000119 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100120 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000121
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200122 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000123 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200124 vim9script
125 class Something
126 this.
127 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000128 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100129 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000130
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200131 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000132 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200133 vim9script
134 class Something
135 this .count
136 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000137 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100138 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000139
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200140 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000141 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200142 vim9script
143 class Something
144 this. count
145 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000146 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100147 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000148
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200149 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000150 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200151 vim9script
152 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100153 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200154 that.count
155 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000156 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200157 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000158
Doug Kearns74da0ee2023-12-14 20:26:26 +0100159 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000160 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200161 vim9script
162 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100163 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200164 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000165 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100166 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
167
168 # Use "variable" instead of "var" for member variable declaration (with initialization)
169 lines =<< trim END
170 vim9script
171 class Something
172 variable count: number = 42
173 endclass
174 END
175 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
176
177 # Use "variable" instead of "var" for member variable declaration (type inferred)
178 lines =<< trim END
179 vim9script
180 class Something
181 variable count = 42
182 endclass
183 END
184 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000185
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200186 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000187 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200188 vim9script
189 class Something
190 def new()
191 this.state = 0
192 enddef
193 endclass
194 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000195 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200196 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000197
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200198 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000199 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200200 vim9script
201 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100202 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200203 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200205 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000206
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200207 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000208 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200209 vim9script
210 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100211 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000213 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200214 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000215
Doug Kearns74da0ee2023-12-14 20:26:26 +0100216 # Missing ":var" in a "var" member variable declaration (without initialization)
217 lines =<< trim END
218 vim9script
219 class Something
220 var: number
221 endclass
222 END
223 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
224
225 # Missing ":var" in a "var" member variable declaration (with initialization)
226 lines =<< trim END
227 vim9script
228 class Something
229 var: number = 42
230 endclass
231 END
232 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
233
234 # Missing ":var" in a "var" member variable declaration (type inferred)
235 lines =<< trim END
236 vim9script
237 class Something
238 var = 42
239 endclass
240 END
241 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
242
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200243 # Test for unsupported comment specifier
244 lines =<< trim END
245 vim9script
246 class Something
247 # comment
248 #{
249 endclass
250 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200251 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200252
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200253 # Test for using class as a bool
254 lines =<< trim END
255 vim9script
256 class A
257 endclass
258 if A
259 endif
260 END
Ernie Raele75fde62023-12-21 17:18:54 +0100261 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200262
263 # Test for using object as a bool
264 lines =<< trim END
265 vim9script
266 class A
267 endclass
268 var a = A.new()
269 if a
270 endif
271 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200272 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200273
274 # Test for using class as a float
275 lines =<< trim END
276 vim9script
277 class A
278 endclass
279 sort([1.1, A], 'f')
280 END
Ernie Raelfa831102023-12-14 20:06:39 +0100281 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200282
283 # Test for using object as a float
284 lines =<< trim END
285 vim9script
286 class A
287 endclass
288 var a = A.new()
289 sort([1.1, a], 'f')
290 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200291 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200292
293 # Test for using class as a string
294 lines =<< trim END
295 vim9script
296 class A
297 endclass
298 :exe 'call ' .. A
299 END
Ernie Raele75fde62023-12-21 17:18:54 +0100300 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200301
302 # Test for using object as a string
303 lines =<< trim END
304 vim9script
305 class A
306 endclass
307 var a = A.new()
308 :exe 'call ' .. a
309 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200310 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200311
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200312 # Test creating a class with member variables and methods, calling a object
313 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000314 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200315 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000316
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200317 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100318 var lnum: number
319 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000320
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200321 # make a nicely formatted string
322 def ToString(): string
323 return $'({this.lnum}, {this.col})'
324 enddef
325 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000326
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200327 # use the automatically generated new() method
328 var pos = TextPosition.new(2, 12)
329 assert_equal(2, pos.lnum)
330 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000331
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200332 # call an object method
333 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000334
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200335 assert_equal(v:t_class, type(TextPosition))
336 assert_equal(v:t_object, type(pos))
337 assert_equal('class<TextPosition>', typename(TextPosition))
338 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000339 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200340 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200341
342 # When referencing object methods, space cannot be used after a "."
343 lines =<< trim END
344 vim9script
345 class A
346 def Foo(): number
347 return 10
348 enddef
349 endclass
350 var a = A.new()
351 var v = a. Foo()
352 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200353 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200354
355 # Using an object without specifying a method or a member variable
356 lines =<< trim END
357 vim9script
358 class A
359 def Foo(): number
360 return 10
361 enddef
362 endclass
363 var a = A.new()
364 var v = a.
365 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200366 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200367
368 # Error when parsing the arguments of an object method.
369 lines =<< trim END
370 vim9script
371 class A
372 def Foo()
373 enddef
374 endclass
375 var a = A.new()
376 var v = a.Foo(,)
377 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200378 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200379
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200380 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200381 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200382 vim9script
383 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100384 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200385 X: 1
386 }
387 endclass
388 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200389 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200390 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000391enddef
392
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200393" Tests for object/class methods in a class
394def Test_class_def_method()
395 # Using the "public" keyword when defining an object method
396 var lines =<< trim END
397 vim9script
398 class A
399 public def Foo()
400 enddef
401 endclass
402 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100403 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200404
405 # Using the "public" keyword when defining a class method
406 lines =<< trim END
407 vim9script
408 class A
409 public static def Foo()
410 enddef
411 endclass
412 END
413 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
414
Ernie Rael03042a22023-11-11 08:53:32 +0100415 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200416 lines =<< trim END
417 vim9script
418 class A
419 public def _Foo()
420 enddef
421 endclass
422 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100423 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200424
Ernie Rael03042a22023-11-11 08:53:32 +0100425 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200426 lines =<< trim END
427 vim9script
428 class A
429 public static def _Foo()
430 enddef
431 endclass
432 END
433 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
434
435 # Using a "def" keyword without an object method name
436 lines =<< trim END
437 vim9script
438 class A
439 def
440 enddef
441 endclass
442 END
443 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
444
445 # Using a "def" keyword without a class method name
446 lines =<< trim END
447 vim9script
448 class A
449 static def
450 enddef
451 endclass
452 END
453 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
454enddef
455
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000456def Test_class_defined_twice()
457 # class defined twice should fail
458 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200459 vim9script
460 class There
461 endclass
462 class There
463 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000464 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200465 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000466
467 # one class, reload same script twice is OK
468 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200469 vim9script
470 class There
471 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000472 END
473 writefile(lines, 'XclassTwice.vim', 'D')
474 source XclassTwice.vim
475 source XclassTwice.vim
476enddef
477
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000478def Test_returning_null_object()
479 # this was causing an internal error
480 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200481 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000482
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200483 class BufferList
484 def Current(): any
485 return null_object
486 enddef
487 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000488
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200489 var buffers = BufferList.new()
490 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000491 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200492 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000493enddef
494
Bram Moolenaard13dd302023-03-11 20:56:35 +0000495def Test_using_null_class()
496 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200497 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000498 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200499 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Bram Moolenaard13dd302023-03-11 20:56:35 +0000500enddef
501
Bram Moolenaar657aea72023-01-27 13:16:19 +0000502def Test_class_interface_wrong_end()
503 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200504 vim9script
505 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100506 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200507 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000508 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200509 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000510
511 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200512 vim9script
513 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100514 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200515 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000518enddef
519
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000520def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200521 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000522 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200523 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000524
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200525 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100526 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200527 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000528
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200529 var state: State
530 var db = {'xyz': 789}
531 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000532 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200533 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000534
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200535 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000536 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200537 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000538
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200539 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100540 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200541 def Method1()
542 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000543 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200544 endclass
545
546 var obj: Class
547 def Func()
548 obj.Method1()
549 enddef
550 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000551 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200552 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000553
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200554 # Pass an uninitialized object variable to a "new" function and try to call an
555 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000556 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200557 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000558
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200559 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100560 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200561 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000562
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200563 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100564 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000565
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200566 def GetBackground(): string
567 return this._bg.background
568 enddef
569 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000570
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200571 var bg: Background # UNINITIALIZED
572 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000573 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200574 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000575
576 # TODO: this should not give an error but be handled at runtime
577 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200578 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000579
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200580 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100581 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200582 def Method1()
583 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000584 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200585 endclass
586
587 var obj = null_object
588 def Func()
589 obj.Method1()
590 enddef
591 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000592 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200593 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000594enddef
595
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200596" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200597def Test_null_object_assign_compare()
598 var lines =<< trim END
599 vim9script
600
601 var nullo = null_object
602 def F(): any
603 return nullo
604 enddef
605 assert_equal('object<Unknown>', typename(F()))
606
607 var o0 = F()
608 assert_true(o0 == null_object)
609 assert_true(o0 == null)
610
611 var o1: any = nullo
612 assert_true(o1 == null_object)
613 assert_true(o1 == null)
614
615 def G()
616 var x = null_object
617 enddef
618
619 class C
620 endclass
621 var o2: C
622 assert_true(o2 == null_object)
623 assert_true(o2 == null)
624
625 o2 = null_object
626 assert_true(o2 == null)
627
628 o2 = C.new()
629 assert_true(o2 != null)
630
631 o2 = null_object
632 assert_true(o2 == null)
633 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200634 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200635enddef
636
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200637" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000638def Test_class_member_initializer()
639 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200640 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000641
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200642 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100643 var lnum: number = 1
644 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000645
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200646 # constructor with only the line number
647 def new(lnum: number)
648 this.lnum = lnum
649 enddef
650 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000651
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200652 var pos = TextPosition.new(3)
653 assert_equal(3, pos.lnum)
654 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000655
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200656 var instr = execute('disassemble TextPosition.new')
657 assert_match('new\_s*' ..
658 '0 NEW TextPosition size \d\+\_s*' ..
659 '\d PUSHNR 1\_s*' ..
660 '\d STORE_THIS 0\_s*' ..
661 '\d PUSHNR 1\_s*' ..
662 '\d STORE_THIS 1\_s*' ..
663 'this.lnum = lnum\_s*' ..
664 '\d LOAD arg\[-1]\_s*' ..
665 '\d PUSHNR 0\_s*' ..
666 '\d LOAD $0\_s*' ..
667 '\d\+ STOREINDEX object\_s*' ..
668 '\d\+ RETURN object.*',
669 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000670 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200671 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000672enddef
673
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000674def Test_member_any_used_as_object()
675 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200676 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000677
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200678 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100679 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200680 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000681
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200682 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100683 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200684 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000685
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200686 def F(outer: Outer)
687 outer.inner.value = 1
688 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000689
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200690 var inner_obj = Inner.new(0)
691 var outer_obj = Outer.new(inner_obj)
692 F(outer_obj)
693 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000694 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200695 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000696
Ernie Rael03042a22023-11-11 08:53:32 +0100697 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200698 lines =<< trim END
699 vim9script
700
701 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100702 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200703 endclass
704
705 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100706 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200707 endclass
708
709 def F(outer: Outer)
710 outer.inner._value = 'b'
711 enddef
712
713 var inner_obj = Inner.new('a')
714 var outer_obj = Outer.new(inner_obj)
715 F(outer_obj)
716 END
Ernie Rael03042a22023-11-11 08:53:32 +0100717 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200718
719 # Try modifying a non-existing variable using an "any" object
720 lines =<< trim END
721 vim9script
722
723 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100724 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200725 endclass
726
727 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100728 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200729 endclass
730
731 def F(outer: Outer)
732 outer.inner.someval = 'b'
733 enddef
734
735 var inner_obj = Inner.new('a')
736 var outer_obj = Outer.new(inner_obj)
737 F(outer_obj)
738 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200739 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000740enddef
741
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200742" Nested assignment to a object variable which is of another class type
743def Test_assignment_nested_type()
744 var lines =<< trim END
745 vim9script
746
747 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100748 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200749 endclass
750
751 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100752 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200753 endclass
754
755 def F(outer: Outer)
756 outer.inner.value = 1
757 enddef
758
759 def Test_assign_to_nested_typed_member()
760 var inner = Inner.new(0)
761 var outer = Outer.new(inner)
762 F(outer)
763 assert_equal(1, inner.value)
764 enddef
765
766 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200767
768 var script_inner = Inner.new(0)
769 var script_outer = Outer.new(script_inner)
770 script_outer.inner.value = 1
771 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200772 END
773 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200774
775 # Assignment where target item is read only in :def
776 lines =<< trim END
777 vim9script
778
779 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100780 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200781 endclass
782
783 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100784 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200785 endclass
786
787 def F(outer: Outer)
788 outer.inner.value = 1
789 enddef
790
791 def Test_assign_to_nested_typed_member()
792 var inner = Inner.new(0)
793 var outer = Outer.new(inner)
794 F(outer)
795 assert_equal(1, inner.value)
796 enddef
797
798 Test_assign_to_nested_typed_member()
799 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200800 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200801
802 # Assignment where target item is read only script level
803 lines =<< trim END
804 vim9script
805
806 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100807 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200808 endclass
809
810 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100811 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200812 endclass
813
814 def F(outer: Outer)
815 outer.inner.value = 1
816 enddef
817
818 var script_inner = Inner.new(0)
819 var script_outer = Outer.new(script_inner)
820 script_outer.inner.value = 1
821 assert_equal(1, script_inner.value)
822 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200823 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200824enddef
825
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000826def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200827 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000828 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200829 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000830
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200831 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100832 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000833
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200834 def Add(n: number)
835 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100836 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200837 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100838
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200839 var f = Foo.new(3)
840 f.Add(17)
841 assert_equal(20, f.x)
842
843 def AddToFoo(obj: Foo)
844 obj.x += 3
845 enddef
846
847 AddToFoo(f)
848 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000849 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200850 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000851enddef
852
Bram Moolenaarf4508042023-01-15 16:54:57 +0000853def Test_list_of_objects()
854 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200855 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000856
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200857 class Foo
858 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000859 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200860 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000861
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200862 def ProcessList(fooList: list<Foo>)
863 for foo in fooList
864 foo.Add()
865 endfor
866 enddef
867
868 var l: list<Foo> = [Foo.new()]
869 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000870 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200871 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000872enddef
873
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000874def Test_expr_after_using_object()
875 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200876 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000877
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200878 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100879 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200880 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000881
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200882 def Foo(): Something
883 var v = Something.new()
884 echo 'in Foo(): ' .. typename(v)
885 return v
886 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000887
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200888 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000889 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200890 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000891enddef
892
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000893def Test_class_default_new()
894 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200895 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000896
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200897 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100898 var lnum: number = 1
899 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200900 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000901
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200902 var pos = TextPosition.new()
903 assert_equal(1, pos.lnum)
904 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000905
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200906 pos = TextPosition.new(v:none, v:none)
907 assert_equal(1, pos.lnum)
908 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000909
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200910 pos = TextPosition.new(3, 22)
911 assert_equal(3, pos.lnum)
912 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000913
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200914 pos = TextPosition.new(v:none, 33)
915 assert_equal(1, pos.lnum)
916 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000917 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200918 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000919
920 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200921 vim9script
922 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100923 var name: string
924 var age: number = 42
925 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000926
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200927 def new(this.name, this.age = v:none, this.education = v:none)
928 enddef
929 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000930
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200931 var piet = Person.new("Piet")
932 assert_equal("Piet", piet.name)
933 assert_equal(42, piet.age)
934 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000935
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200936 var chris = Person.new("Chris", 4, "none")
937 assert_equal("Chris", chris.name)
938 assert_equal(4, chris.age)
939 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000940 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200941 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000942
943 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200944 vim9script
945 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100946 var name: string
947 var age: number = 42
948 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +0000949
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200950 def new(this.name, this.age = v:none, this.education = v:none)
951 enddef
952 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000953
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200954 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000955 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200956 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200957
958 # Using a specific value to initialize an instance variable in the new()
959 # method.
960 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200961 vim9script
962 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100963 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200964 def new(this.val = 'a')
965 enddef
966 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200967 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200968 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000969enddef
970
h-east2261c892023-08-16 21:49:54 +0900971def Test_class_new_with_object_member()
972 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200973 vim9script
h-east2261c892023-08-16 21:49:54 +0900974
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200975 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +0100976 var str: string
977 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200978 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +0900979 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200980 def newVals(this.str, this.num)
981 enddef
982 endclass
h-east2261c892023-08-16 21:49:54 +0900983
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200984 def Check()
985 try
986 var c = C.new('cats', 2)
987 assert_equal('cats', c.str)
988 assert_equal(2, c.num)
989
990 c = C.newVals('dogs', 4)
991 assert_equal('dogs', c.str)
992 assert_equal(4, c.num)
993 catch
994 assert_report($'Unexpected exception was caught: {v:exception}')
995 endtry
996 enddef
997
998 Check()
h-east2261c892023-08-16 21:49:54 +0900999 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001000 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001001
1002 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001003 vim9script
1004
1005 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001006 var str: string
1007 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001008 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001009 enddef
1010 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001011
1012 def Check()
1013 try
1014 var c = C.new(1, 2)
1015 catch
1016 assert_report($'Unexpected exception was caught: {v:exception}')
1017 endtry
1018 enddef
1019
1020 Check()
h-eastdb385522023-09-28 22:18:19 +02001021 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001022 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001023
1024 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001025 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001026
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001027 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001028 var str: string
1029 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001030 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001031 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001032 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001033
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001034 def Check()
1035 try
1036 var c = C.newVals('dogs', 'apes')
1037 catch
1038 assert_report($'Unexpected exception was caught: {v:exception}')
1039 endtry
1040 enddef
1041
1042 Check()
1043 END
1044 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1045
1046 lines =<< trim END
1047 vim9script
1048
1049 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001050 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001051 def new(str: any)
1052 enddef
1053 endclass
1054
1055 def Check()
1056 try
1057 var c = C.new(1)
1058 catch
1059 assert_report($'Unexpected exception was caught: {v:exception}')
1060 endtry
1061 enddef
1062
1063 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001064 END
1065 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001066
1067 # Try using "this." argument in a class method
1068 lines =<< trim END
1069 vim9script
1070 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001071 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001072 static def Foo(this.val: number)
1073 enddef
1074 endclass
1075 END
1076 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1077
1078 # Try using "this." argument in an object method
1079 lines =<< trim END
1080 vim9script
1081 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001082 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001083 def Foo(this.val: number)
1084 enddef
1085 endclass
1086 END
1087 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001088enddef
1089
Bram Moolenaar74e12742022-12-13 21:14:28 +00001090def Test_class_object_member_inits()
1091 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001092 vim9script
1093 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001094 var lnum: number
1095 var col = 1
1096 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001097 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001098
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001099 var pos = TextPosition.new()
1100 assert_equal(0, pos.lnum)
1101 assert_equal(1, pos.col)
1102 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001103 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001104 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001105
1106 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001107 vim9script
1108 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001109 var lnum
1110 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001111 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001112 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001113 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001114
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001115 # If the type is not specified for a member, then it should be set during
1116 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001117 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001118 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001119
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001120 var init_count = 0
1121 def Init(): string
1122 init_count += 1
1123 return 'foo'
1124 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001125
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001126 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001127 var str1 = Init()
1128 var str2: string = Init()
1129 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001130 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001131
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001132 assert_equal(init_count, 0)
1133 var a = A.new()
1134 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001135 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001136 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001137
1138 # Test for initializing an object member with an unknown variable/type
1139 lines =<< trim END
1140 vim9script
1141 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001142 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001143 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001144 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001145 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001146 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001147
1148 # Test for initializing an object member with an special type
1149 lines =<< trim END
1150 vim9script
1151 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001152 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001153 endclass
1154 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001155 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001156enddef
1157
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001158" Test for instance variable access
1159def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001160 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001161 vim9script
1162 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001163 var _one = 1
1164 var two = 2
1165 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001166
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001167 def GetOne(): number
1168 return this._one
1169 enddef
1170 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001171
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001172 var trip = Triple.new()
1173 assert_equal(1, trip.GetOne())
1174 assert_equal(2, trip.two)
1175 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001176 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001177
Ernie Rael03042a22023-11-11 08:53:32 +01001178 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001179 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1180 trip.three = 33
1181 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001182
Ernie Raeld4802ec2023-10-20 11:59:00 +02001183 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001184 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001185 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001186
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001187 # Test for a public member variable name beginning with an underscore
1188 lines =<< trim END
1189 vim9script
1190 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001191 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001192 endclass
1193 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001194 v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001195
Bram Moolenaar590162c2022-12-24 21:24:06 +00001196 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001197 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001198
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001199 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001200 var make: string
1201 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001203 def new(make_arg: string)
1204 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001205 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001206
1207 def GetMake(): string
1208 return $"make = {this.make}"
1209 enddef
1210 def GetAge(): number
1211 return this.age
1212 enddef
1213 endclass
1214
1215 var c = MyCar.new("abc")
1216 assert_equal('make = abc', c.GetMake())
1217
1218 c = MyCar.new("def")
1219 assert_equal('make = def', c.GetMake())
1220
1221 var c2 = MyCar.new("123")
1222 assert_equal('make = 123', c2.GetMake())
1223
1224 def CheckCar()
1225 assert_equal("make = def", c.GetMake())
1226 assert_equal(5, c.GetAge())
1227 enddef
1228 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001229 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001230 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001231
1232 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001233 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001234
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001235 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001236 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001237
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001238 def new(make_arg: string)
1239 this.make = make_arg
1240 enddef
1241 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001242
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001243 var c = MyCar.new("abc")
1244 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001245 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001246 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001247
1248 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001249 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001250
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001251 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001252 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001253
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001254 def Add(n: number): any
1255 this.x->add(n)
1256 return this
1257 enddef
1258 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001259
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001260 echo Foo.new().Add(1).Add(2).x
1261 echo Foo.new().Add(1).Add(2)
1262 .x
1263 echo Foo.new().Add(1)
1264 .Add(2).x
1265 echo Foo.new()
1266 .Add(1).Add(2).x
1267 echo Foo.new()
1268 .Add(1)
1269 .Add(2)
1270 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001271 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001272 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001273
1274 # Test for "public" cannot be abbreviated
1275 lines =<< trim END
1276 vim9script
1277 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001278 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001279 endclass
1280 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001281 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001282
Doug Kearns74da0ee2023-12-14 20:26:26 +01001283 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001284 lines =<< trim END
1285 vim9script
1286 class Something
1287 public val = 1
1288 endclass
1289 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001290 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001291
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001292 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001293 lines =<< trim END
1294 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001295 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001296 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001297 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001298 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001299 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001300 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001301
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001302 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001303 lines =<< trim END
1304 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001305 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001306 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001307 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001308 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001309 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001310 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001311
1312 # Modify a instance variable using the class name in a def function
1313 lines =<< trim END
1314 vim9script
1315 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001316 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001317 endclass
1318 def T()
1319 A.val = 1
1320 enddef
1321 T()
1322 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001323 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001324
1325 # Read a instance variable using the class name in a def function
1326 lines =<< trim END
1327 vim9script
1328 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001329 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001330 endclass
1331 def T()
1332 var i = A.val
1333 enddef
1334 T()
1335 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001336 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001337
1338 # Access from child class extending a class:
1339 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001340 vim9script
1341 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001342 var ro_obj_var = 10
1343 public var rw_obj_var = 20
1344 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001345 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001346
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001347 class B extends A
1348 def Foo()
1349 var x: number
1350 x = this.ro_obj_var
1351 this.ro_obj_var = 0
1352 x = this.rw_obj_var
1353 this.rw_obj_var = 0
1354 x = this._priv_obj_var
1355 this._priv_obj_var = 0
1356 enddef
1357 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001359 var b = B.new()
1360 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001361 END
1362 v9.CheckSourceSuccess(lines)
1363enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001364
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001365" Test for class variable access
1366def Test_class_variable_access()
1367 # Test for "static" cannot be abbreviated
1368 var lines =<< trim END
1369 vim9script
1370 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001371 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001372 endclass
1373 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001374 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001375
1376 # Test for "static" cannot be followed by "public".
1377 lines =<< trim END
1378 vim9script
1379 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001380 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001381 endclass
1382 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001383 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001384
1385 # A readonly class variable cannot be modified from a child class
1386 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001387 vim9script
1388 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001389 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001390 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001391
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001392 class B extends A
1393 def Foo()
1394 A.ro_class_var = 50
1395 enddef
1396 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001397
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001398 var b = B.new()
1399 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001400 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001401 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001402
Ernie Rael03042a22023-11-11 08:53:32 +01001403 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001404 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001405 vim9script
1406 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001407 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001408 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001409
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001410 class B extends A
1411 def Foo()
1412 var i = A._priv_class_var
1413 enddef
1414 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001415
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001416 var b = B.new()
1417 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001418 END
Ernie Rael03042a22023-11-11 08:53:32 +01001419 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001420
Ernie Rael03042a22023-11-11 08:53:32 +01001421 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001422 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001423 vim9script
1424 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001425 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001426 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001427
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001428 class B extends A
1429 def Foo()
1430 A._priv_class_var = 0
1431 enddef
1432 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001433
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001434 var b = B.new()
1435 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001436 END
Ernie Rael03042a22023-11-11 08:53:32 +01001437 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001438
1439 # Access from child class extending a class and from script context
1440 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001441 vim9script
1442 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001443 static var ro_class_var = 10
1444 public static var rw_class_var = 20
1445 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001446 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001447
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001448 class B extends A
1449 def Foo()
1450 var x: number
1451 x = A.ro_class_var
1452 assert_equal(10, x)
1453 x = A.rw_class_var
1454 assert_equal(25, x)
1455 A.rw_class_var = 20
1456 assert_equal(20, A.rw_class_var)
1457 enddef
1458 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001459
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001460 assert_equal(10, A.ro_class_var)
1461 assert_equal(20, A.rw_class_var)
1462 A.rw_class_var = 25
1463 assert_equal(25, A.rw_class_var)
1464 var b = B.new()
1465 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001466 END
1467 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001468enddef
1469
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001470def Test_class_object_compare()
1471 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001472 vim9script
1473 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001474 var nr = 0
1475 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001476 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001477 END
1478
1479 # used at the script level and in a compiled function
1480 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001481 var i1 = Item.new()
1482 assert_equal(i1, i1)
1483 assert_true(i1 is i1)
1484 var i2 = Item.new()
1485 assert_equal(i1, i2)
1486 assert_false(i1 is i2)
1487 var i3 = Item.new(0, 'xx')
1488 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001489
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001490 var io1 = Item.new(1, 'xx')
1491 assert_notequal(i1, io1)
1492 var io2 = Item.new(0, 'yy')
1493 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001494 END
1495
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001496 v9.CheckSourceSuccess(class_lines + test_lines)
1497 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001499
1500 for op in ['>', '>=', '<', '<=', '=~', '!~']
1501 var op_lines = [
1502 'var i1 = Item.new()',
1503 'var i2 = Item.new()',
1504 'echo i1 ' .. op .. ' i2',
1505 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001506 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001507 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001508 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001509 endfor
1510enddef
1511
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001512def Test_object_type()
1513 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001514 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001515
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001516 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001517 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001518 endclass
1519 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001520 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001521 endclass
1522 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001523 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001524 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001525
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001526 var o: One = One.new()
1527 var t: Two = Two.new()
1528 var m: TwoMore = TwoMore.new()
1529 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001530
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001531 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001532 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001533 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001534
1535 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001536 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001537
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001538 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001539 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001540 endclass
1541 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001542 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001543 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001544
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001545 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001547 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001548
1549 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001550 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001551
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001552 interface One
1553 def GetMember(): number
1554 endinterface
1555 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001556 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001557 def GetMember(): number
1558 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001559 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001560 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001561
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001562 var o: One = Two.new(5)
1563 assert_equal(5, o.GetMember())
1564 END
1565 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001566
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001567 lines =<< trim END
1568 vim9script
1569
1570 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001571 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001572 endclass
1573
1574 def Ref(name: string): func(Num): Num
1575 return (arg: Num): Num => {
1576 return eval(name)(arg)
1577 }
1578 enddef
1579
1580 const Fn = Ref('Double')
1581 var Double = (m: Num): Num => Num.new(m.n * 2)
1582
1583 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001584 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001585 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001586enddef
1587
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001588def Test_class_member()
1589 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001590 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001591 vim9script
1592 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001593 var lnum = 1
1594 var col = 1
1595 static var counter = 0
1596 static var _secret = 7
1597 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001599 static def AddToCounter(nr: number)
1600 counter += nr
1601 enddef
1602 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001603
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001604 assert_equal(0, TextPos.counter)
1605 TextPos.AddToCounter(3)
1606 assert_equal(3, TextPos.counter)
1607 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001608
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001609 def GetCounter(): number
1610 return TextPos.counter
1611 enddef
1612 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001613
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001614 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1615 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1616 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001617
Ernie Rael03042a22023-11-11 08:53:32 +01001618 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1619 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001620
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001621 assert_equal(42, TextPos.anybody)
1622 TextPos.anybody = 12
1623 assert_equal(12, TextPos.anybody)
1624 TextPos.anybody += 5
1625 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001626 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001627 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001628
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001629 # example in the help
1630 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001631 vim9script
1632 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001633 var size: number
1634 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001636 def new(this.size)
1637 totalSize += this.size
1638 enddef
1639 endclass
1640 assert_equal(0, OtherThing.totalSize)
1641 var to3 = OtherThing.new(3)
1642 assert_equal(3, OtherThing.totalSize)
1643 var to7 = OtherThing.new(7)
1644 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001645 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001646 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001647
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001648 # using static class member twice
1649 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001650 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001651
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001652 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001653 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001654
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001655 static def MacroSubstitute(s: string): string
1656 return substitute(s, '{{author}}', author, 'gi')
1657 enddef
1658 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001659
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001660 assert_equal('some text', HTML.MacroSubstitute('some text'))
1661 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001662 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001663 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001664
Ernie Rael03042a22023-11-11 08:53:32 +01001665 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001666 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001667 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001668
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001669 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001670 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001671
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001672 def Add(n: number): number
1673 const F = (): number => this._x + n
1674 return F()
1675 enddef
1676 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001677
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001678 var foo = Foo.new()
1679 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001680 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001681 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001682
Ernie Rael03042a22023-11-11 08:53:32 +01001683 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001684 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001685 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001686
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001687 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001688 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001689
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001690 def Add(n: number): number
1691 var Lam = () => {
1692 this._x = this._x + n
1693 }
1694 Lam()
1695 return this._x
1696 enddef
1697 endclass
h-east2bd6a092023-05-19 19:01:17 +01001698
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001699 var foo = Foo.new()
1700 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001701 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001702 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001703
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001704 # check shadowing
1705 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001706 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001707
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001708 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001709 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001710 def Method(count: number)
1711 echo count
1712 enddef
1713 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001714
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001715 var s = Some.new()
1716 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001717 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001718 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001719
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001720 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001721 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001722 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001723
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001724 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001725 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001726 def Method(arg: number)
1727 var count = 3
1728 echo arg count
1729 enddef
1730 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001731
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001732 var s = Some.new()
1733 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001734 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001735 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001736
1737 # Test for using an invalid type for a member variable
1738 lines =<< trim END
1739 vim9script
1740 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001741 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001742 endclass
1743 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001744 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001745
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001746 # Test for setting a member on a null object
1747 lines =<< trim END
1748 vim9script
1749 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001750 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001751 endclass
1752
1753 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001754 var obj: A
1755 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001756 enddef
1757 F()
1758 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001759 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001760
1761 # Test for accessing a member on a null object
1762 lines =<< trim END
1763 vim9script
1764 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001765 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001766 endclass
1767
1768 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001769 var obj: A
1770 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001771 enddef
1772 F()
1773 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001774 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001775
1776 # Test for setting a member on a null object, at script level
1777 lines =<< trim END
1778 vim9script
1779 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001780 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001781 endclass
1782
1783 var obj: A
1784 obj.val = ""
1785 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001786 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001787
1788 # Test for accessing a member on a null object, at script level
1789 lines =<< trim END
1790 vim9script
1791 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001792 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001793 endclass
1794
1795 var obj: A
1796 echo obj.val
1797 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001798 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001799
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001800 # Test for no space before or after the '=' when initializing a member
1801 # variable
1802 lines =<< trim END
1803 vim9script
1804 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001805 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001806 endclass
1807 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001808 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001809 lines =<< trim END
1810 vim9script
1811 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001812 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001813 endclass
1814 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001815 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001816
1817 # Access a non-existing member
1818 lines =<< trim END
1819 vim9script
1820 class A
1821 endclass
1822 var a = A.new()
1823 var v = a.bar
1824 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001825 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001826enddef
1827
Ernie Raele6c9aa52023-10-06 19:55:52 +02001828" These messages should show the defining class of the variable (base class),
1829" not the class that did the reference (super class)
1830def Test_defining_class_message()
1831 var lines =<< trim END
1832 vim9script
1833
1834 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001835 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001836 endclass
1837
1838 class Child extends Base
1839 endclass
1840
1841 var o = Child.new()
1842 var x = o._v1
1843 END
Ernie Rael03042a22023-11-11 08:53:32 +01001844 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001845 lines =<< trim END
1846 vim9script
1847
1848 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001849 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001850 endclass
1851
1852 class Child extends Base
1853 endclass
1854
1855 def F()
1856 var o = Child.new()
1857 var x = o._v1
1858 enddef
1859 F()
1860 END
Ernie Rael03042a22023-11-11 08:53:32 +01001861 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001862 lines =<< trim END
1863 vim9script
1864
1865 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001866 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001867 endclass
1868
1869 class Child extends Base
1870 endclass
1871
1872 var o = Child.new()
1873 o.v1 = []
1874 END
1875 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1876 lines =<< trim END
1877 vim9script
1878
1879 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001880 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001881 endclass
1882
1883 class Child extends Base
1884 endclass
1885
1886 def F()
1887 var o = Child.new()
1888 o.v1 = []
1889 enddef
1890 F()
1891 END
1892
Ernie Rael03042a22023-11-11 08:53:32 +01001893 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001894 # of the class hierarchy.
1895 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1896 lines =<< trim END
1897 vim9script
1898
1899 class Base0
1900 endclass
1901
1902 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01001903 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001904 endclass
1905
1906 class Child extends Base
1907 endclass
1908
1909 def F()
1910 var o = Child.new()
1911 var x = o._v1
1912 enddef
1913 F()
1914 END
Ernie Rael03042a22023-11-11 08:53:32 +01001915 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001916
Ernie Rael03042a22023-11-11 08:53:32 +01001917 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02001918 # of the class hierarchy.
1919 lines =<< trim END
1920 vim9script
1921
1922 class Base0
1923 endclass
1924
1925 class Base extends Base0
1926 endclass
1927
1928 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001929 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001930 endclass
1931
1932 def F()
1933 var o = Child.new()
1934 var x = o._v1
1935 enddef
1936 F()
1937 END
Ernie Rael03042a22023-11-11 08:53:32 +01001938 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001939enddef
1940
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001941func Test_class_garbagecollect()
1942 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001943 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001944
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001945 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01001946 var p = [2, 3]
1947 static var pl = ['a', 'b']
1948 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001949 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001950
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001951 echo Point.pl Point.pd
1952 call test_garbagecollect_now()
1953 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001954 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001955 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001956
1957 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001958 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001959
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001960 interface View
1961 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001962
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001963 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01001964 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001965 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001966
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001967 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01001968 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001969
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001970 def new()
1971 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01001972 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001973 enddef
1974 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001975
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001976 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001977
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001978 # overwrite "view", will be garbage-collected next
1979 view = MyView.new()
1980 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001981 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001982 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001983endfunc
1984
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001985" Test interface garbage collection
1986func Test_interface_garbagecollect()
1987 let lines =<< trim END
1988 vim9script
1989
1990 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01001991 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001992
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001993 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001994 endinterface
1995
1996 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01001997 static var ro_class_var: number = 10
1998 public static var rw_class_var: number = 20
1999 static var _priv_class_var: number = 30
2000 var ro_obj_var: number = 40
2001 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002002
2003 static def _ClassBar(): number
2004 return _priv_class_var
2005 enddef
2006
2007 static def ClassFoo(): number
2008 return ro_class_var + rw_class_var + A._ClassBar()
2009 enddef
2010
2011 def _ObjBar(): number
2012 return this._priv_obj_var
2013 enddef
2014
2015 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002016 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002017 enddef
2018 endclass
2019
2020 assert_equal(60, A.ClassFoo())
2021 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002022 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002023 test_garbagecollect_now()
2024 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002025 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002026 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002027 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002028endfunc
2029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002030def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002031 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002032 vim9script
2033 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002034 var value = 0
2035 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002036
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002037 def new(v: number)
2038 this.value = v
2039 ++objects
2040 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002041
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002042 static def GetCount(): number
2043 return objects
2044 enddef
2045 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002046
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002047 assert_equal(0, Value.GetCount())
2048 var v1 = Value.new(2)
2049 assert_equal(1, Value.GetCount())
2050 var v2 = Value.new(7)
2051 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002052 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002053 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002054
2055 # Test for cleaning up after a class definition failure when using class
2056 # functions.
2057 lines =<< trim END
2058 vim9script
2059 class A
2060 static def Foo()
2061 enddef
2062 aaa
2063 endclass
2064 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002065 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002066
2067 # Test for calling a class method from another class method without the class
2068 # name prefix.
2069 lines =<< trim END
2070 vim9script
2071 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002072 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002073 static def Foo(n: number)
2074 myList->add(n)
2075 enddef
2076 static def Bar()
2077 Foo(2)
2078 enddef
2079 def Baz()
2080 Foo(3)
2081 enddef
2082 endclass
2083 A.Bar()
2084 var a = A.new()
2085 a.Baz()
2086 assert_equal([1, 2, 3], A.myList)
2087 END
2088 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002089enddef
2090
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002091def Test_class_defcompile()
2092 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002093 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002094
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002095 class C
2096 def Fo(i: number): string
2097 return i
2098 enddef
2099 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002100
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002101 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002102 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002103 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002104
2105 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002106 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002107
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002108 class C
2109 static def Fc(): number
2110 return 'x'
2111 enddef
2112 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002113
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002114 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002115 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002116 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002117
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002118 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002119 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002120
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002121 class C
2122 static def new()
2123 enddef
2124 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002125
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002126 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002127 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002128 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002129
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002130 # Trying to compile a function using a non-existing class variable
2131 lines =<< trim END
2132 vim9script
2133 defcompile x.Foo()
2134 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002135 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002136
2137 # Trying to compile a function using a variable which is not a class
2138 lines =<< trim END
2139 vim9script
2140 var x: number
2141 defcompile x.Foo()
2142 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002143 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002144
2145 # Trying to compile a function without specifying the name
2146 lines =<< trim END
2147 vim9script
2148 class A
2149 endclass
2150 defcompile A.
2151 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002152 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002153
2154 # Trying to compile a non-existing class object member function
2155 lines =<< trim END
2156 vim9script
2157 class A
2158 endclass
2159 var a = A.new()
2160 defcompile a.Foo()
2161 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002162 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002163enddef
2164
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002165def Test_class_object_to_string()
2166 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002167 vim9script
2168 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002169 var lnum = 1
2170 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002171 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002172
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002173 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002174
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002175 var pos = TextPosition.new()
2176 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002177 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002178 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002179enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002180
Bram Moolenaar554d0312023-01-05 19:59:18 +00002181def Test_interface_basics()
2182 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002183 vim9script
2184 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002185 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002186 def GetCount(): number
2187 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002188 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002189 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002190
2191 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002192 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002193 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002194 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002195 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002196 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002197
2198 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002199 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002200
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002201 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002202 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 def Method(value: number)
2204 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002205 END
h-east61378a12023-04-18 19:07:29 +01002206 # The argument name and the object member name are the same, but this is not a
2207 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002208 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002209
2210 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002211 vim9script
2212 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002213 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002214 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002215 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002216 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002217
2218 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002219 vim9script
2220 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002221 var value: string
2222 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002223 def GetCount(): number
2224 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002225 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002226 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002227
2228 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002229 vim9script
2230 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002231 var value: string
2232 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002233 def GetCount(): number
2234 return 5
2235 enddef
2236 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002237 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002238 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002239
2240 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002241 vim9script
2242 export interface EnterExit
2243 def Enter(): void
2244 def Exit(): void
2245 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002246 END
2247 writefile(lines, 'XdefIntf.vim', 'D')
2248
2249 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002250 vim9script
2251 import './XdefIntf.vim' as defIntf
2252 export def With(ee: defIntf.EnterExit, F: func)
2253 ee.Enter()
2254 try
2255 F()
2256 finally
2257 ee.Exit()
2258 endtry
2259 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002260 END
2261 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002262
2263 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002264 vim9script
2265 export abstract class EnterExit
2266 def Enter(): void
2267 enddef
2268 def Exit(): void
2269 enddef
2270 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002271 END
2272 writefile(imported, 'XdefIntf2.vim', 'D')
2273
2274 lines[1] = " import './XdefIntf2.vim' as defIntf"
2275 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002276enddef
2277
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002278" Test for using string() with an interface
2279def Test_interface_to_string()
2280 var lines =<< trim END
2281 vim9script
2282 interface Intf
2283 def Method(nr: number)
2284 endinterface
2285 assert_equal("interface Intf", string(Intf))
2286 END
2287 v9.CheckSourceSuccess(lines)
2288enddef
2289
Bram Moolenaar94674f22023-01-06 18:42:20 +00002290def Test_class_implements_interface()
2291 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002292 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002293
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002294 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002295 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002296 def Method(nr: number)
2297 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002298
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002299 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002300 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002301 def Method(nr: number)
2302 echo nr
2303 enddef
2304 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002305
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002306 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002307 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002308 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002309
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002310 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002311 var member = 'abc'
2312 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002313 def Method(nr: number)
2314 echo nr
2315 enddef
2316 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002317 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002318 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002319
2320 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002321 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002322
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002323 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002324 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002325 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002326
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002327 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002328 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002329 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002330 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002331 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002332
2333 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002334 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002335
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002336 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002337 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002338 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002339
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002340 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002341 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002342 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002343 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002344 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002345
2346 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002347 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002348
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002349 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002350 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002351 def Method(nr: number)
2352 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002353
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002354 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002355 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002356 def Method(nr: number)
2357 echo nr
2358 enddef
2359 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002360 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002361 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002362
2363 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002364 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002365
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002366 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002367 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002368 def Methods(nr: number)
2369 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002370
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002371 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002372 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002373 def Method(nr: number)
2374 echo nr
2375 enddef
2376 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002377 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002378 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002379
2380 # Check different order of members in class and interface works.
2381 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002383
2384 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002385 var label: string
2386 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002387 endinterface
2388
2389 # order of members is opposite of interface
2390 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002391 public var lnum: number = 5
2392 var errpos: number = 42
2393 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002394 endclass
2395
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002396 def Test()
2397 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002398
2399 assert_equal('label', result.label)
2400 assert_equal(42, result.errpos)
2401 enddef
2402
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002403 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002404 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002405 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002406
2407 # Interface name after "extends" doesn't end in a space or NUL character
2408 lines =<< trim END
2409 vim9script
2410 interface A
2411 endinterface
2412 class B extends A"
2413 endclass
2414 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002415 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002416
2417 # Trailing characters after a class name
2418 lines =<< trim END
2419 vim9script
2420 class A bbb
2421 endclass
2422 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002423 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002424
2425 # using "implements" with a non-existing class
2426 lines =<< trim END
2427 vim9script
2428 class A implements B
2429 endclass
2430 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002431 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002432
2433 # using "implements" with a regular class
2434 lines =<< trim END
2435 vim9script
2436 class A
2437 endclass
2438 class B implements A
2439 endclass
2440 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002441 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002442
2443 # using "implements" with a variable
2444 lines =<< trim END
2445 vim9script
2446 var T: number = 10
2447 class A implements T
2448 endclass
2449 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002450 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002451
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002452 # implements should be followed by a white space
2453 lines =<< trim END
2454 vim9script
2455 interface A
2456 endinterface
2457 class B implements A;
2458 endclass
2459 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002460 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002461
LemonBoyc5d27442023-08-19 13:02:35 +02002462 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002463 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002464
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002465 interface One
2466 def IsEven(nr: number): bool
2467 endinterface
2468 class Two implements One
2469 def IsEven(nr: number): string
2470 enddef
2471 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002472 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002473 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002474
2475 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002476 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002477
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002478 interface One
2479 def IsEven(nr: number): bool
2480 endinterface
2481 class Two implements One
2482 def IsEven(nr: bool): bool
2483 enddef
2484 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002485 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002486 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002487
2488 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002489 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002490
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002491 interface One
2492 def IsEven(nr: number): bool
2493 endinterface
2494 class Two implements One
2495 def IsEven(nr: number, ...extra: list<number>): bool
2496 enddef
2497 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002498 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002499 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool', 9)
Ernie Raelcf138d42023-09-06 20:45:03 +02002500
2501 # access superclass interface members from subclass, mix variable order
2502 lines =<< trim END
2503 vim9script
2504
2505 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002506 var mvar1: number
2507 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002508 endinterface
2509
2510 # NOTE: the order is swapped
2511 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002512 var mvar2: number
2513 var mvar1: number
2514 public static var svar2: number
2515 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002516 def new()
2517 svar1 = 11
2518 svar2 = 12
2519 this.mvar1 = 111
2520 this.mvar2 = 112
2521 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002522 endclass
2523
2524 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002525 def new()
2526 this.mvar1 = 121
2527 this.mvar2 = 122
2528 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002529 endclass
2530
2531 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002532 def new()
2533 this.mvar1 = 131
2534 this.mvar2 = 132
2535 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002536 endclass
2537
Ernie Raelcf138d42023-09-06 20:45:03 +02002538 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002539 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002540 enddef
2541
2542 var oa = A.new()
2543 var ob = B.new()
2544 var oc = C.new()
2545
Ernie Raelcf138d42023-09-06 20:45:03 +02002546 assert_equal([111, 112], F2(oa))
2547 assert_equal([121, 122], F2(ob))
2548 assert_equal([131, 132], F2(oc))
2549 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002550 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002551
2552 # Access superclass interface members from subclass, mix variable order.
2553 # Two interfaces, one on A, one on B; each has both kinds of variables
2554 lines =<< trim END
2555 vim9script
2556
2557 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002558 var mvar1: number
2559 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002560 endinterface
2561
2562 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002563 var mvar3: number
2564 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002565 endinterface
2566
2567 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002568 public static var svar1: number
2569 public static var svar2: number
2570 var mvar1: number
2571 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002572 def new()
2573 svar1 = 11
2574 svar2 = 12
2575 this.mvar1 = 111
2576 this.mvar2 = 112
2577 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002578 endclass
2579
2580 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002581 static var svar3: number
2582 static var svar4: number
2583 var mvar3: number
2584 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002585 def new()
2586 svar3 = 23
2587 svar4 = 24
2588 this.mvar1 = 121
2589 this.mvar2 = 122
2590 this.mvar3 = 123
2591 this.mvar4 = 124
2592 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002593 endclass
2594
2595 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002596 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002597 def new()
2598 svar5 = 1001
2599 this.mvar1 = 131
2600 this.mvar2 = 132
2601 this.mvar3 = 133
2602 this.mvar4 = 134
2603 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002604 endclass
2605
Ernie Raelcf138d42023-09-06 20:45:03 +02002606 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002607 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002608 enddef
2609
Ernie Raelcf138d42023-09-06 20:45:03 +02002610 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002611 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002612 enddef
2613
Ernie Raelcf138d42023-09-06 20:45:03 +02002614 var oa = A.new()
2615 var ob = B.new()
2616 var oc = C.new()
2617
Ernie Raelcf138d42023-09-06 20:45:03 +02002618 assert_equal([[111, 112]], [F2(oa)])
2619 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2620 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002621 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002622 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002623
2624 # Using two interface names without a space after the ","
2625 lines =<< trim END
2626 vim9script
2627 interface A
2628 endinterface
2629 interface B
2630 endinterface
2631 class C implements A,B
2632 endclass
2633 END
2634 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2635
2636 # No interface name after a comma
2637 lines =<< trim END
2638 vim9script
2639 interface A
2640 endinterface
2641 class B implements A,
2642 endclass
2643 END
2644 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2645
2646 # No interface name after implements
2647 lines =<< trim END
2648 vim9script
2649 class A implements
2650 endclass
2651 END
2652 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002653enddef
2654
Bram Moolenaard0200c82023-01-28 15:19:40 +00002655def Test_call_interface_method()
2656 var lines =<< trim END
2657 vim9script
2658 interface Base
2659 def Enter(): void
2660 endinterface
2661
2662 class Child implements Base
2663 def Enter(): void
2664 g:result ..= 'child'
2665 enddef
2666 endclass
2667
2668 def F(obj: Base)
2669 obj.Enter()
2670 enddef
2671
2672 g:result = ''
2673 F(Child.new())
2674 assert_equal('child', g:result)
2675 unlet g:result
2676 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002677 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002678
2679 lines =<< trim END
2680 vim9script
2681 class Base
2682 def Enter(): void
2683 g:result ..= 'base'
2684 enddef
2685 endclass
2686
2687 class Child extends Base
2688 def Enter(): void
2689 g:result ..= 'child'
2690 enddef
2691 endclass
2692
2693 def F(obj: Base)
2694 obj.Enter()
2695 enddef
2696
2697 g:result = ''
2698 F(Child.new())
2699 assert_equal('child', g:result)
2700 unlet g:result
2701 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002702 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002703
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002704 # method of interface returns a value
2705 lines =<< trim END
2706 vim9script
2707 interface Base
2708 def Enter(): string
2709 endinterface
2710
2711 class Child implements Base
2712 def Enter(): string
2713 g:result ..= 'child'
2714 return "/resource"
2715 enddef
2716 endclass
2717
2718 def F(obj: Base)
2719 var r = obj.Enter()
2720 g:result ..= r
2721 enddef
2722
2723 g:result = ''
2724 F(Child.new())
2725 assert_equal('child/resource', g:result)
2726 unlet g:result
2727 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002728 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002729
2730 lines =<< trim END
2731 vim9script
2732 class Base
2733 def Enter(): string
2734 return null_string
2735 enddef
2736 endclass
2737
2738 class Child extends Base
2739 def Enter(): string
2740 g:result ..= 'child'
2741 return "/resource"
2742 enddef
2743 endclass
2744
2745 def F(obj: Base)
2746 var r = obj.Enter()
2747 g:result ..= r
2748 enddef
2749
2750 g:result = ''
2751 F(Child.new())
2752 assert_equal('child/resource', g:result)
2753 unlet g:result
2754 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002755 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002756
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002757 # No class that implements the interface.
2758 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002759 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002760
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002761 interface IWithEE
2762 def Enter(): any
2763 def Exit(): void
2764 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002765
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002766 def With1(ee: IWithEE, F: func)
2767 var r = ee.Enter()
2768 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002769
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002770 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002771 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002772 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002773enddef
2774
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002775def Test_class_used_as_type()
2776 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002777 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002778
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002779 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002780 var x = 0
2781 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002782 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002783
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002784 var p: Point
2785 p = Point.new(2, 33)
2786 assert_equal(2, p.x)
2787 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002789 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002790
2791 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002792 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002794 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002795 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002796 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002797
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002798 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002799 var x = 0
2800 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002801 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002802
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002803 var p: Point
2804 p = Point.new(2, 33)
2805 var hx = p
2806 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002807 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002808 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002809
2810 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002811 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002812
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002813 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002814 var x = 0
2815 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002816 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002817
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002818 var p: Point
2819 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002820 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002821 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002822enddef
2823
Bram Moolenaar83677162023-01-08 19:54:10 +00002824def Test_class_extends()
2825 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002826 vim9script
2827 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002828 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002829 def GetOne(): number
2830 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002831 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002832 endclass
2833 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002834 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002835 def GetTotal(): number
2836 return this.one + this.two
2837 enddef
2838 endclass
2839 var o = Child.new()
2840 assert_equal(1, o.one)
2841 assert_equal(2, o.two)
2842 assert_equal(1, o.GetOne())
2843 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002844 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002845 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002846
2847 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002848 vim9script
2849 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002850 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002851 endclass
2852 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002853 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002854 endclass
2855 var o = Child.new(3, 44)
2856 assert_equal(3, o.one)
2857 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002858 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002859 v9.CheckSourceSuccess(lines)
2860
2861 lines =<< trim END
2862 vim9script
2863 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002864 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002865 endclass
2866 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002867 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002868 endclass
2869 END
2870 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2871
2872 lines =<< trim END
2873 vim9script
2874 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01002875 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002876 endclass
2877 END
2878 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2879
2880 lines =<< trim END
2881 vim9script
2882 var SomeVar = 99
2883 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01002884 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002885 endclass
2886 END
2887 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2888
2889 lines =<< trim END
2890 vim9script
2891 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002892 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002893 def ToString(): string
2894 return this.name
2895 enddef
2896 endclass
2897
2898 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002899 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002900 def ToString(): string
2901 return super.ToString() .. ': ' .. this.age
2902 enddef
2903 endclass
2904
2905 var o = Child.new('John', 42)
2906 assert_equal('John: 42', o.ToString())
2907 END
2908 v9.CheckSourceSuccess(lines)
2909
2910 lines =<< trim END
2911 vim9script
2912 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002913 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002914 def ToString(): number
2915 return this.age
2916 enddef
2917 def ToString(): string
2918 return this.age
2919 enddef
2920 endclass
2921 END
2922 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2923
2924 lines =<< trim END
2925 vim9script
2926 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002927 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002928 def ToString(): string
2929 return super .ToString() .. ': ' .. this.age
2930 enddef
2931 endclass
2932 var o = Child.new(42)
2933 echo o.ToString()
2934 END
2935 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2936
2937 lines =<< trim END
2938 vim9script
2939 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002940 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002941 def ToString(): string
2942 return this.name
2943 enddef
2944 endclass
2945
2946 var age = 42
2947 def ToString(): string
2948 return super.ToString() .. ': ' .. age
2949 enddef
2950 echo ToString()
2951 END
2952 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2953
2954 lines =<< trim END
2955 vim9script
2956 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002957 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002958 def ToString(): string
2959 return super.ToString() .. ': ' .. this.age
2960 enddef
2961 endclass
2962 var o = Child.new(42)
2963 echo o.ToString()
2964 END
2965 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
2966
2967 lines =<< trim END
2968 vim9script
2969 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002970 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002971 static def ToString(): string
2972 return 'Base class'
2973 enddef
2974 endclass
2975
2976 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002977 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002978 def ToString(): string
2979 return Base.ToString() .. ': ' .. this.age
2980 enddef
2981 endclass
2982
2983 var o = Child.new('John', 42)
2984 assert_equal('Base class: 42', o.ToString())
2985 END
2986 v9.CheckSourceSuccess(lines)
2987
2988 lines =<< trim END
2989 vim9script
2990 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002991 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002992 def new(init: number)
2993 this.value = number + 1
2994 enddef
2995 endclass
2996 class Child extends Base
2997 def new()
2998 this.new(3)
2999 enddef
3000 endclass
3001 var c = Child.new()
3002 END
3003 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003004
3005 # base class with more than one object member
3006 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003007 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003008
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003009 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003010 var success: bool
3011 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003012 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003013
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003014 class Success extends Result
3015 def new(this.value = v:none)
3016 this.success = true
3017 enddef
3018 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003019
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003020 var v = Success.new('asdf')
3021 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003022 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003023 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003024
3025 # class name after "extends" doesn't end in a space or NUL character
3026 lines =<< trim END
3027 vim9script
3028 class A
3029 endclass
3030 class B extends A"
3031 endclass
3032 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003033 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003034enddef
3035
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003036def Test_using_base_class()
3037 var lines =<< trim END
3038 vim9script
3039
3040 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003041 def Enter(): any
3042 return null
3043 enddef
3044 def Exit(resource: any): void
3045 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003046 endclass
3047
3048 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003049 def Enter(): any
3050 return 42
3051 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003052
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003053 def Exit(resource: number): void
3054 g:result ..= '/exit'
3055 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003056 endclass
3057
3058 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003059 var r = ee.Enter()
3060 try
3061 g:result ..= r
3062 finally
3063 g:result ..= '/finally'
3064 ee.Exit(r)
3065 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003066 enddef
3067
3068 g:result = ''
3069 With(ChildEE.new())
3070 assert_equal('42/finally/exit', g:result)
3071 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003072 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003073 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003074
3075 # Using super, Child invokes Base method which has optional arg. #12471
3076 lines =<< trim END
3077 vim9script
3078
3079 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003080 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003081 def Method(arg = 0)
3082 this.success = true
3083 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003084 endclass
3085
3086 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003087 def new()
3088 super.Method()
3089 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003090 endclass
3091
3092 var obj = Child.new()
3093 assert_equal(true, obj.success)
3094 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003095 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003096enddef
3097
Bram Moolenaara86655a2023-01-12 17:06:27 +00003098def Test_class_import()
3099 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003100 vim9script
3101 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003102 var kind: string
3103 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003104 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003105 END
3106 writefile(lines, 'Xanimal.vim', 'D')
3107
3108 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003109 vim9script
3110 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003111
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003112 var a: animal.Animal
3113 a = animal.Animal.new('fish', 'Eric')
3114 assert_equal('fish', a.kind)
3115 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003116
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003117 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3118 assert_equal('cat', b.kind)
3119 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003120 END
3121 v9.CheckScriptSuccess(lines)
3122enddef
3123
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003124" Test for importing a class into a legacy script and calling the class method
3125def Test_class_method_from_legacy_script()
3126 var lines =<< trim END
3127 vim9script
3128 export class A
3129 static var name: string = 'a'
3130 static def SetName(n: string)
3131 name = n
3132 enddef
3133 endclass
3134 END
3135 writefile(lines, 'Xvim9export.vim', 'D')
3136
3137 lines =<< trim END
3138 import './Xvim9export.vim' as vim9
3139
3140 call s:vim9.A.SetName('b')
3141 call assert_equal('b', s:vim9.A.name)
3142 END
3143 v9.CheckScriptSuccess(lines)
3144enddef
3145
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003146" Test for implementing an imported interface
3147def Test_implement_imported_interface()
3148 var lines =<< trim END
3149 vim9script
3150 export interface Imp_Intf1
3151 def Fn1(): number
3152 endinterface
3153 export interface Imp_Intf2
3154 def Fn2(): number
3155 endinterface
3156 END
3157 writefile(lines, 'Ximportinterface.vim', 'D')
3158
3159 lines =<< trim END
3160 vim9script
3161 import './Ximportinterface.vim' as Xintf
3162
3163 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3164 def Fn1(): number
3165 return 10
3166 enddef
3167 def Fn2(): number
3168 return 20
3169 enddef
3170 endclass
3171 var a = A.new()
3172 assert_equal(10, a.Fn1())
3173 assert_equal(20, a.Fn2())
3174 END
3175 v9.CheckScriptSuccess(lines)
3176enddef
3177
3178" Test for extending an imported class
3179def Test_extend_imported_class()
3180 var lines =<< trim END
3181 vim9script
3182 export class Imp_C1
3183 def Fn1(): number
3184 return 5
3185 enddef
3186 endclass
3187 END
3188 writefile(lines, 'Xextendimportclass.vim', 'D')
3189
3190 lines =<< trim END
3191 vim9script
3192 import './Xextendimportclass.vim' as XClass
3193
3194 class A extends XClass.Imp_C1
3195 endclass
3196 var a = A.new()
3197 assert_equal(5, a.Fn1())
3198 END
3199 v9.CheckScriptSuccess(lines)
3200enddef
3201
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003202def Test_abstract_class()
3203 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003204 vim9script
3205 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003206 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003207 endclass
3208 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003209 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003210 endclass
3211 var p: Base = Person.new('Peter', 42)
3212 assert_equal('Peter', p.name)
3213 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003214 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003215 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003216
3217 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003218 vim9script
3219 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003220 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003221 endclass
3222 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003223 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003224 endclass
3225 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003226 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003227 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003228
3229 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003230 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003231 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003232 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003233 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003234 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003235
3236 # Abstract class cannot have a "new" function
3237 lines =<< trim END
3238 vim9script
3239 abstract class Base
3240 def new()
3241 enddef
3242 endclass
3243 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003244 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003245
3246 # extending an abstract class with class methods and variables
3247 lines =<< trim END
3248 vim9script
3249 abstract class A
3250 static var s: string = 'vim'
3251 static def Fn(): list<number>
3252 return [10]
3253 enddef
3254 endclass
3255 class B extends A
3256 endclass
3257 var b = B.new()
3258 assert_equal('vim', A.s)
3259 assert_equal([10], A.Fn())
3260 END
3261 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003262enddef
3263
Bram Moolenaar486fc252023-01-18 14:51:07 +00003264def Test_closure_in_class()
3265 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003266 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003267
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003268 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003269 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003270
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003271 def new()
3272 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3273 enddef
3274 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003275
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003276 Foo.new()
3277 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003278 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003279 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003280enddef
3281
Ernie Rael9ed53752023-12-11 17:40:46 +01003282def Test_construct_object_from_legacy()
3283 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003284 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003285 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003286
Ernie Rael9ed53752023-12-11 17:40:46 +01003287 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003288
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003289 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003290 def new(arg: string)
3291 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003292 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003293 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003294
Ernie Rael9ed53752023-12-11 17:40:46 +01003295 export def CreateA(...args: list<any>): A
3296 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003297 enddef
3298
Ernie Rael9ed53752023-12-11 17:40:46 +01003299 g:P = CreateA
3300 legacy call g:P('some_arg')
3301 assert_equal(true, newCalled)
3302 unlet g:P
3303 END
3304 v9.CheckSourceSuccess(lines)
3305
3306 lines =<< trim END
3307 vim9script
3308
3309 var newCalled = false
3310
3311 class A
3312 static def CreateA(options = {}): any
3313 return A.new()
3314 enddef
3315 def new()
3316 newCalled = true
3317 enddef
3318 endclass
3319
3320 g:P = A.CreateA
3321 legacy call g:P()
3322 assert_equal(true, newCalled)
3323 unlet g:P
3324 END
3325 v9.CheckSourceSuccess(lines)
3326
3327 # This also tests invoking "new()" with "call"
3328 lines =<< trim END
3329 vim9script
3330
3331 var createdObject: any
3332
3333 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003334 var val1: number
3335 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003336 static def CreateA(...args: list<any>): any
3337 createdObject = call(A.new, args)
3338 return createdObject
3339 enddef
3340 endclass
3341
3342 g:P = A.CreateA
3343 legacy call g:P(3, 5)
3344 assert_equal(3, createdObject.val1)
3345 assert_equal(5, createdObject.val2)
3346 legacy call g:P()
3347 assert_equal(0, createdObject.val1)
3348 assert_equal(0, createdObject.val2)
3349 legacy call g:P(7)
3350 assert_equal(7, createdObject.val1)
3351 assert_equal(0, createdObject.val2)
3352 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003353 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003354 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003355enddef
3356
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003357def Test_defer_with_object()
3358 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003359 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003360
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003361 class CWithEE
3362 def Enter()
3363 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003364 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003365 def Exit()
3366 g:result ..= "exited"
3367 enddef
3368 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003369
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003370 def With(ee: CWithEE, F: func)
3371 ee.Enter()
3372 defer ee.Exit()
3373 F()
3374 enddef
3375
3376 g:result = ''
3377 var obj = CWithEE.new()
3378 obj->With(() => {
3379 g:result ..= "called/"
3380 })
3381 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003382 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003383 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003384 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003385
3386 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003387 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003388
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003389 class BaseWithEE
3390 def Enter()
3391 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003392 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003393 def Exit()
3394 g:result ..= "exited-base"
3395 enddef
3396 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003397
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003398 class CWithEE extends BaseWithEE
3399 def Enter()
3400 g:result ..= "entered-child/"
3401 enddef
3402 def Exit()
3403 g:result ..= "exited-child"
3404 enddef
3405 endclass
3406
3407 def With(ee: BaseWithEE, F: func)
3408 ee.Enter()
3409 defer ee.Exit()
3410 F()
3411 enddef
3412
3413 g:result = ''
3414 var obj = CWithEE.new()
3415 obj->With(() => {
3416 g:result ..= "called/"
3417 })
3418 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003419 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003420 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003421 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003422enddef
3423
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003424" The following test used to crash Vim (Github issue #12676)
3425def Test_extends_method_crashes_vim()
3426 var lines =<< trim END
3427 vim9script
3428
3429 class Observer
3430 endclass
3431
3432 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003433 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003434
3435 def Set(v: any)
3436 if v != this.value
3437 this.value = v
3438 endif
3439 enddef
3440
3441 def Register(observer: Observer)
3442 enddef
3443 endclass
3444
3445 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003446 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003447 endclass
3448
3449 def Observe(obj: Property, who: Observer)
3450 obj.Register(who)
3451 enddef
3452
3453 var p = Bool.new(false)
3454 var myObserver = Observer.new()
3455
3456 Observe(p, myObserver)
3457
3458 p.Set(true)
3459 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003460 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003461enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003462
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003463" Test for calling a method in a class that is extended
3464def Test_call_method_in_extended_class()
3465 var lines =<< trim END
3466 vim9script
3467
3468 var prop_init_called = false
3469 var prop_register_called = false
3470
3471 class Property
3472 def Init()
3473 prop_init_called = true
3474 enddef
3475
3476 def Register()
3477 prop_register_called = true
3478 enddef
3479 endclass
3480
3481 class Bool extends Property
3482 endclass
3483
3484 def Observe(obj: Property)
3485 obj.Register()
3486 enddef
3487
3488 var p = Property.new()
3489 Observe(p)
3490
3491 p.Init()
3492 assert_true(prop_init_called)
3493 assert_true(prop_register_called)
3494 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003495 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003496enddef
3497
LemonBoyafe04662023-08-23 21:08:11 +02003498def Test_instanceof()
3499 var lines =<< trim END
3500 vim9script
3501
3502 class Base1
3503 endclass
3504
3505 class Base2 extends Base1
3506 endclass
3507
3508 interface Intf1
3509 endinterface
3510
3511 class Mix1 implements Intf1
3512 endclass
3513
3514 class Base3 extends Mix1
3515 endclass
3516
Ernie Rael2025af12023-12-12 16:58:00 +01003517 type AliasBase1 = Base1
3518 type AliasBase2 = Base2
3519 type AliasIntf1 = Intf1
3520 type AliasMix1 = Mix1
3521
LemonBoyafe04662023-08-23 21:08:11 +02003522 var b1 = Base1.new()
3523 var b2 = Base2.new()
3524 var b3 = Base3.new()
3525
3526 assert_true(instanceof(b1, Base1))
3527 assert_true(instanceof(b2, Base1))
3528 assert_false(instanceof(b1, Base2))
3529 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003530 assert_true(instanceof(b3, Base1, Base2, Intf1))
3531
3532 assert_true(instanceof(b1, AliasBase1))
3533 assert_true(instanceof(b2, AliasBase1))
3534 assert_false(instanceof(b1, AliasBase2))
3535 assert_true(instanceof(b3, AliasMix1))
3536 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003537
3538 def Foo()
3539 var a1 = Base1.new()
3540 var a2 = Base2.new()
3541 var a3 = Base3.new()
3542
3543 assert_true(instanceof(a1, Base1))
3544 assert_true(instanceof(a2, Base1))
3545 assert_false(instanceof(a1, Base2))
3546 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003547 assert_true(instanceof(a3, Base1, Base2, Intf1))
3548
3549 assert_true(instanceof(a1, AliasBase1))
3550 assert_true(instanceof(a2, AliasBase1))
3551 assert_false(instanceof(a1, AliasBase2))
3552 assert_true(instanceof(a3, AliasMix1))
3553 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003554 enddef
3555 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003556
3557 var o_null: Base1
3558 assert_false(instanceof(o_null, Base1))
3559
LemonBoyafe04662023-08-23 21:08:11 +02003560 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003561 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003562
3563 lines =<< trim END
3564 vim9script
3565
3566 class Base1
3567 endclass
3568 instanceof(Base1.new())
3569 END
3570 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3571
3572 lines =<< trim END
3573 vim9script
3574
3575 class Base1
3576 endclass
3577 def F()
3578 instanceof(Base1.new())
3579 enddef
3580 F()
3581 END
3582 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3583
3584 lines =<< trim END
3585 vim9script
3586
3587 class Base1
3588 endclass
3589
3590 class Base2
3591 endclass
3592
3593 var o = Base2.new()
3594 instanceof(o, Base1, Base2, 3)
3595 END
3596 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3597
3598 lines =<< trim END
3599 vim9script
3600
3601 class Base1
3602 endclass
3603
3604 class Base2
3605 endclass
3606
3607 def F()
3608 var o = Base2.new()
3609 instanceof(o, Base1, Base2, 3)
3610 enddef
3611 F()
3612 END
3613 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003614enddef
3615
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003616" Test for calling a method in the parent class that is extended partially.
3617" This used to fail with the 'E118: Too many arguments for function: Text' error
3618" message (Github issue #12524).
3619def Test_call_method_in_parent_class()
3620 var lines =<< trim END
3621 vim9script
3622
3623 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003624 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003625
3626 def SetY(lnum: number)
3627 this._lnum = lnum
3628 enddef
3629
3630 def Text(): string
3631 return ''
3632 enddef
3633 endclass
3634
3635 class Foo extends Widget
3636 def Text(): string
3637 return '<Foo>'
3638 enddef
3639 endclass
3640
3641 def Stack(w1: Widget, w2: Widget): list<Widget>
3642 w1.SetY(1)
3643 w2.SetY(2)
3644 return [w1, w2]
3645 enddef
3646
3647 var foo1 = Foo.new()
3648 var foo2 = Foo.new()
3649 var l = Stack(foo1, foo2)
3650 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003651 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003652enddef
3653
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003654" Test for calling methods from three levels of classes
3655def Test_multi_level_method_call()
3656 var lines =<< trim END
3657 vim9script
3658
3659 var A_func1: number = 0
3660 var A_func2: number = 0
3661 var A_func3: number = 0
3662 var B_func2: number = 0
3663 var B_func3: number = 0
3664 var C_func3: number = 0
3665
3666 class A
3667 def Func1()
3668 A_func1 += 1
3669 enddef
3670
3671 def Func2()
3672 A_func2 += 1
3673 enddef
3674
3675 def Func3()
3676 A_func3 += 1
3677 enddef
3678 endclass
3679
3680 class B extends A
3681 def Func2()
3682 B_func2 += 1
3683 enddef
3684
3685 def Func3()
3686 B_func3 += 1
3687 enddef
3688 endclass
3689
3690 class C extends B
3691 def Func3()
3692 C_func3 += 1
3693 enddef
3694 endclass
3695
3696 def A_CallFuncs(a: A)
3697 a.Func1()
3698 a.Func2()
3699 a.Func3()
3700 enddef
3701
3702 def B_CallFuncs(b: B)
3703 b.Func1()
3704 b.Func2()
3705 b.Func3()
3706 enddef
3707
3708 def C_CallFuncs(c: C)
3709 c.Func1()
3710 c.Func2()
3711 c.Func3()
3712 enddef
3713
3714 var cobj = C.new()
3715 A_CallFuncs(cobj)
3716 B_CallFuncs(cobj)
3717 C_CallFuncs(cobj)
3718 assert_equal(3, A_func1)
3719 assert_equal(0, A_func2)
3720 assert_equal(0, A_func3)
3721 assert_equal(3, B_func2)
3722 assert_equal(0, B_func3)
3723 assert_equal(3, C_func3)
3724 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003725 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003726enddef
3727
3728" Test for using members from three levels of classes
3729def Test_multi_level_member_access()
3730 var lines =<< trim END
3731 vim9script
3732
3733 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003734 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003735 endclass
3736
3737 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003738 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003739 endclass
3740
3741 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003742 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003743 endclass
3744
3745 def A_members(a: A)
3746 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003747 enddef
3748
3749 def B_members(b: B)
3750 b.val1 += 1
3751 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003752 enddef
3753
3754 def C_members(c: C)
3755 c.val1 += 1
3756 c.val2 += 1
3757 c.val3 += 1
3758 enddef
3759
3760 var cobj = C.new()
3761 A_members(cobj)
3762 B_members(cobj)
3763 C_members(cobj)
3764 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003765 assert_equal(2, cobj.val2)
3766 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003767 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003768 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003769enddef
3770
LemonBoy0ffc17a2023-08-20 18:09:11 +02003771" Test expansion of <stack> with class methods.
3772def Test_stack_expansion_with_methods()
3773 var lines =<< trim END
3774 vim9script
3775
3776 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003777 def M1()
3778 F0()
3779 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003780 endclass
3781
3782 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02003783 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02003784 enddef
3785
3786 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003787 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003788 enddef
3789
3790 F()
3791 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003792 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003793enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003794
3795" Test the return type of the new() constructor
3796def Test_new_return_type()
3797 # new() uses the default return type and there is no return statement
3798 var lines =<< trim END
3799 vim9script
3800
3801 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003802 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003803
3804 def new(this._bufnr)
3805 if !bufexists(this._bufnr)
3806 this._bufnr = -1
3807 endif
3808 enddef
3809 endclass
3810
3811 var c = C.new(12345)
3812 assert_equal('object<C>', typename(c))
3813
3814 var v1: C
3815 v1 = C.new(12345)
3816 assert_equal('object<C>', typename(v1))
3817
3818 def F()
3819 var v2: C
3820 v2 = C.new(12345)
3821 assert_equal('object<C>', typename(v2))
3822 enddef
3823 F()
3824 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003825 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003826
3827 # new() uses the default return type and an empty 'return' statement
3828 lines =<< trim END
3829 vim9script
3830
3831 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003832 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003833
3834 def new(this._bufnr)
3835 if !bufexists(this._bufnr)
3836 this._bufnr = -1
3837 return
3838 endif
3839 enddef
3840 endclass
3841
3842 var c = C.new(12345)
3843 assert_equal('object<C>', typename(c))
3844
3845 var v1: C
3846 v1 = C.new(12345)
3847 assert_equal('object<C>', typename(v1))
3848
3849 def F()
3850 var v2: C
3851 v2 = C.new(12345)
3852 assert_equal('object<C>', typename(v2))
3853 enddef
3854 F()
3855 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003856 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003857
3858 # new() uses "any" return type and returns "this"
3859 lines =<< trim END
3860 vim9script
3861
3862 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003863 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003864
3865 def new(this._bufnr): any
3866 if !bufexists(this._bufnr)
3867 this._bufnr = -1
3868 return this
3869 endif
3870 enddef
3871 endclass
3872 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003873 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003874
3875 # new() uses 'Dict' return type and returns a Dict
3876 lines =<< trim END
3877 vim9script
3878
3879 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003880 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003881
3882 def new(): dict<any>
3883 this._state = {}
3884 return this._state
3885 enddef
3886 endclass
3887
3888 var c = C.new()
3889 assert_equal('object<C>', typename(c))
3890 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003891 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003892enddef
3893
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003894" Test for checking a member initialization type at run time.
3895def Test_runtime_type_check_for_member_init()
3896 var lines =<< trim END
3897 vim9script
3898
3899 var retnum: bool = false
3900
3901 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003902 retnum = !retnum
3903 if retnum
3904 return 1
3905 else
3906 return "hello"
3907 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003908 enddef
3909
3910 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003911 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003912 endclass
3913
3914 var c1 = C.new()
3915 var c2 = C.new()
3916 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003917 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003918enddef
3919
3920" Test for locking a variable referring to an object and reassigning to another
3921" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003922def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003923 var lines =<< trim END
3924 vim9script
3925
3926 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003927 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003928 def new(this.val)
3929 enddef
3930 endclass
3931
3932 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3933 lockvar 2 some_dict
3934
3935 var current: C
3936 current = some_dict['c']
3937 assert_equal(3, current.val)
3938 current = some_dict['b']
3939 assert_equal(2, current.val)
3940
3941 def F()
3942 current = some_dict['c']
3943 enddef
3944
3945 def G()
3946 current = some_dict['b']
3947 enddef
3948
3949 F()
3950 assert_equal(3, current.val)
3951 G()
3952 assert_equal(2, current.val)
3953 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003954 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003955enddef
3956
Ernie Raelee865f32023-09-29 19:53:55 +02003957" Test trying to lock an object variable from various places
3958def Test_lockvar_object_variable()
3959 # An object variable lockvar has several cases:
3960 # object method, scriptlevel, scriplevel from :def, :def arg
3961 # method arg, static method arg.
3962 # Also different depths
3963
Ernie Raelee865f32023-09-29 19:53:55 +02003964 #
3965 # lockvar of read-only object variable
3966 #
3967
3968 # read-only lockvar from object method
3969 var lines =<< trim END
3970 vim9script
3971
3972 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003973 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02003974 def Lock()
3975 lockvar this.val1
3976 enddef
3977 endclass
3978 var o = C.new(3)
3979 o.Lock()
3980 END
Ernie Rael64885642023-10-04 20:16:22 +02003981 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003982
3983 # read-only lockvar from scriptlevel
3984 lines =<< trim END
3985 vim9script
3986
3987 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003988 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02003989 endclass
3990 var o = C.new(3)
3991 lockvar o.val2
3992 END
3993 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3994
3995 # read-only lockvar of scriptlevel variable from def
3996 lines =<< trim END
3997 vim9script
3998
3999 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004000 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004001 endclass
4002 var o = C.new(3)
4003 def Lock()
4004 lockvar o.val3
4005 enddef
4006 Lock()
4007 END
4008 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4009
4010 # read-only lockvar of def argument variable
4011 lines =<< trim END
4012 vim9script
4013
4014 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004015 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004016 endclass
4017 def Lock(o: C)
4018 lockvar o.val4
4019 enddef
4020 Lock(C.new(3))
4021 END
4022 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4023
4024 # TODO: the following tests use type "any" for argument. Need a run time
4025 # check for access. Probably OK as is for now.
4026
4027 # read-only lockvar from object method arg
4028 lines =<< trim END
4029 vim9script
4030
4031 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004032 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004033 def Lock(o_any: any)
4034 lockvar o_any.val5
4035 enddef
4036 endclass
4037 var o = C.new(3)
4038 o.Lock(C.new(5))
4039 END
Ernie Rael64885642023-10-04 20:16:22 +02004040 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004041
4042 # read-only lockvar from class method arg
4043 lines =<< trim END
4044 vim9script
4045
4046 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004047 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004048 static def Lock(o_any: any)
4049 lockvar o_any.val6
4050 enddef
4051 endclass
4052 var o = C.new(3)
4053 C.Lock(o)
4054 END
Ernie Rael64885642023-10-04 20:16:22 +02004055 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004056
4057 #
4058 # lockvar of public object variable
4059 #
4060
4061 # lockvar from object method
4062 lines =<< trim END
4063 vim9script
4064
4065 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004066 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004067 def Lock()
4068 lockvar this.val1
4069 enddef
4070 endclass
4071 var o = C.new(3)
4072 o.Lock()
4073 END
4074 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4075
4076 # lockvar from scriptlevel
4077 lines =<< trim END
4078 vim9script
4079
4080 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004081 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004082 endclass
4083 var o = C.new(3)
4084 lockvar o.val2
4085 END
4086 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4087
4088 # lockvar of scriptlevel variable from def
4089 lines =<< trim END
4090 vim9script
4091
4092 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004093 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004094 endclass
4095 var o = C.new(3)
4096 def Lock()
4097 lockvar o.val3
4098 enddef
4099 Lock()
4100 END
4101 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4102
4103 # lockvar of def argument variable
4104 lines =<< trim END
4105 vim9script
4106
4107 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004108 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004109 endclass
4110 def Lock(o: C)
4111 lockvar o.val4
4112 enddef
4113 Lock(C.new(3))
4114 END
4115 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4116
4117 # lockvar from object method arg
4118 lines =<< trim END
4119 vim9script
4120
4121 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004122 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004123 def Lock(o_any: any)
4124 lockvar o_any.val5
4125 enddef
4126 endclass
4127 var o = C.new(3)
4128 o.Lock(C.new(5))
4129 END
4130 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4131
4132 # lockvar from class method arg
4133 lines =<< trim END
4134 vim9script
4135
4136 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004137 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004138 static def Lock(o_any: any)
4139 lockvar o_any.val6
4140 enddef
4141 endclass
4142 var o = C.new(3)
4143 C.Lock(o)
4144 END
4145 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4146enddef
4147
4148" Test trying to lock a class variable from various places
4149def Test_lockvar_class_variable()
4150
4151 # lockvar bare static from object method
4152 var lines =<< trim END
4153 vim9script
4154
4155 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004156 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004157 def Lock()
4158 lockvar sval1
4159 enddef
4160 endclass
4161 var o = C.new()
4162 o.Lock()
4163 END
4164 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4165
4166 # lockvar C.static from object method
4167 lines =<< trim END
4168 vim9script
4169
4170 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004171 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004172 def Lock()
4173 lockvar C.sval2
4174 enddef
4175 endclass
4176 var o = C.new()
4177 o.Lock()
4178 END
4179 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4180
4181 # lockvar bare static from class method
4182 lines =<< trim END
4183 vim9script
4184
4185 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004186 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004187 static def Lock()
4188 lockvar sval3
4189 enddef
4190 endclass
4191 C.Lock()
4192 END
4193 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4194
4195 # lockvar C.static from class method
4196 lines =<< trim END
4197 vim9script
4198
4199 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004200 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004201 static def Lock()
4202 lockvar C.sval4
4203 enddef
4204 endclass
4205 C.Lock()
4206 END
4207 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4208
4209 # lockvar C.static from script level
4210 lines =<< trim END
4211 vim9script
4212
4213 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004214 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004215 endclass
4216 lockvar C.sval5
4217 END
4218 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4219
4220 # lockvar o.static from script level
4221 lines =<< trim END
4222 vim9script
4223
4224 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004225 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004226 endclass
4227 var o = C.new()
4228 lockvar o.sval6
4229 END
4230 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4231enddef
4232
4233" Test locking an argument to :def
4234def Test_lockvar_argument()
4235 # Lockvar a function arg
4236 var lines =<< trim END
4237 vim9script
4238
4239 def Lock(val: any)
4240 lockvar val
4241 enddef
4242
4243 var d = {a: 1, b: 2}
4244 Lock(d)
4245
4246 d->extend({c: 3})
4247 END
4248 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4249
4250 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4251 # class member in "C". This tests lval_root_is_arg.
4252 lines =<< trim END
4253 vim9script
4254
4255 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004256 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004257 endclass
4258
4259 def Lock2(sval: any)
4260 lockvar sval
4261 enddef
4262
4263 var o = C.new()
4264 Lock2(o)
4265 END
4266 v9.CheckSourceSuccess(lines)
4267
4268 # Lock a class.
4269 lines =<< trim END
4270 vim9script
4271
4272 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004273 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004274 endclass
4275
4276 def Lock2(sval: any)
4277 lockvar sval
4278 enddef
4279
4280 Lock2(C)
4281 END
Ernie Raelb077b582023-12-14 20:11:44 +01004282 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004283
4284 # Lock an object.
4285 lines =<< trim END
4286 vim9script
4287
4288 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004289 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004290 endclass
4291
4292 def Lock2(sval: any)
4293 lockvar sval
4294 enddef
4295
4296 Lock2(C.new())
4297 END
4298 v9.CheckSourceSuccess(lines)
4299
4300 # In this case (unlike previous) "lockvar sval" is a class member.
4301 lines =<< trim END
4302 vim9script
4303
4304 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004305 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004306 def Lock2()
4307 lockvar sval
4308 enddef
4309 endclass
4310
4311
4312 var o = C.new()
4313 o.Lock2()
4314 END
4315 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4316enddef
4317
4318" Test that this can be locked without error
4319def Test_lockvar_this()
4320 # lockvar this
4321 var lines =<< trim END
4322 vim9script
4323 class C
4324 def TLock()
4325 lockvar this
4326 enddef
4327 endclass
4328 var o = C.new()
4329 o.TLock()
4330 END
4331 v9.CheckSourceSuccess(lines)
4332
4333 # lockvar four (four letter word, but not this)
4334 lines =<< trim END
4335 vim9script
4336 class C
4337 def TLock4()
4338 var four: number
4339 lockvar four
4340 enddef
4341 endclass
4342 var o = C.new()
4343 o.TLock4()
4344 END
4345 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4346
4347 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4348 lines =<< trim END
4349 vim9script
4350 class C
4351 def TLock5()
4352 var this5: number
4353 lockvar this5
4354 enddef
4355 endclass
4356 var o = C.new()
4357 o.TLock5()
4358 END
4359 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4360enddef
4361
4362" Test some general lockvar cases
4363def Test_lockvar_general()
4364 # lockvar an object and a class. It does nothing
4365 var lines =<< trim END
4366 vim9script
4367 class C
4368 endclass
4369 var o = C.new()
4370 lockvar o
4371 lockvar C
4372 END
4373 v9.CheckSourceSuccess(lines)
4374
4375 # Lock a list element that's nested in an object variable from a :def
4376 lines =<< trim END
4377 vim9script
4378
4379 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004380 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004381 endclass
4382 def Lock2(obj: any)
4383 lockvar obj.val[1]
4384 enddef
4385
4386 var o = C.new()
4387 Lock2(o)
4388 o.val[0] = [9]
4389 assert_equal([ [9], [2], [3] ], o.val)
4390 try
4391 o.val[1] = [999]
4392 call assert_false(true, 'assign should have failed')
4393 catch
4394 assert_exception('E741:')
4395 endtry
4396 o.val[2] = [8]
4397 assert_equal([ [9], [2], [8] ], o.val)
4398 END
4399 v9.CheckSourceSuccess(lines)
4400
4401 # Lock a list element that's nested in an object variable from scriptlevel
4402 lines =<< trim END
4403 vim9script
4404
4405 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004406 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004407 endclass
4408
4409 var o = C.new()
4410 lockvar o.val[1]
4411 o.val[0] = [9]
4412 assert_equal([ [9], [2], [3] ], o.val)
4413 try
4414 o.val[1] = [999]
4415 call assert_false(true, 'assign should have failed')
4416 catch
4417 assert_exception('E741:')
4418 endtry
4419 o.val[2] = [8]
4420 assert_equal([ [9], [2], [8] ], o.val)
4421 END
4422 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004423
4424 # lock a script level variable from an object method
4425 lines =<< trim END
4426 vim9script
4427
4428 class C
4429 def Lock()
4430 lockvar l
4431 enddef
4432 endclass
4433
4434 var l = [1]
4435 C.new().Lock()
4436 l[0] = 11
4437 END
4438 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4439
Ernie Rael03042a22023-11-11 08:53:32 +01004440 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004441 # in an object fetched via a script level list
4442 lines =<< trim END
4443 vim9script
4444
4445 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004446 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004447 def Lock()
4448 lockvar lc[0]._v1[1]
4449 enddef
4450 endclass
4451
4452 var l = [[1], [2], [3]]
4453 var o = C.new(l)
4454 var lc: list<C> = [ o ]
4455
4456 o.Lock()
4457 l[0] = [22]
4458 l[1] = [33]
4459 END
4460 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4461
4462 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004463 # in a class that does not own the protected variable.
4464 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004465 # the same name.
4466 lines =<< trim END
4467 vim9script
4468
4469 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004470 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004471 def Lock(obj: any)
4472 lockvar lc[0]._v1[1]
4473 enddef
4474 endclass
4475
4476 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004477 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004478 endclass
4479
4480 var l = [[1], [2], [3]]
4481 var o = C.new(l)
4482 var lc: list<C> = [ o ]
4483
4484 var o2 = C2.new()
4485 o2.Lock(o)
4486 END
Ernie Rael03042a22023-11-11 08:53:32 +01004487 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004488enddef
4489
Ernie Rael9771b2a2023-10-07 22:05:40 +02004490" Test builtin islocked()
4491def Test_lockvar_islocked()
4492 # Can't lock class/object variable
4493 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004494 # Lock item of variable's value (a list item)
4495 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004496 var lines =<< trim END
4497 vim9script
4498
4499 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004500 var o0: list<list<number>> = [ [0], [1], [2]]
4501 var o1: list<list<number>> = [[10], [11], [12]]
4502 static var c0: list<list<number>> = [[20], [21], [22]]
4503 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004504 endclass
4505
4506 def LockIt(arg: any)
4507 lockvar arg
4508 enddef
4509
4510 def UnlockIt(arg: any)
4511 unlockvar arg
4512 enddef
4513
4514 var obj = C.new()
4515 #lockvar obj.o1 # can't lock something you can't write to
4516
4517 try
4518 lockvar obj.o1 # can't lock something you can't write to
4519 call assert_false(1, '"lockvar obj.o1" should have failed')
4520 catch
4521 call assert_exception('E1335:')
4522 endtry
4523
4524 LockIt(obj.o1) # but can lock it's value
4525 assert_equal(1, islocked("obj.o1"))
4526 assert_equal(1, islocked("obj.o1[0]"))
4527 assert_equal(1, islocked("obj.o1[1]"))
4528 UnlockIt(obj.o1)
4529 assert_equal(0, islocked("obj.o1"))
4530 assert_equal(0, islocked("obj.o1[0]"))
4531
4532 lockvar obj.o1[0]
4533 assert_equal(0, islocked("obj.o1"))
4534 assert_equal(1, islocked("obj.o1[0]"))
4535 assert_equal(0, islocked("obj.o1[1]"))
4536 unlockvar obj.o1[0]
4537 assert_equal(0, islocked("obj.o1"))
4538 assert_equal(0, islocked("obj.o1[0]"))
4539
4540 # Same thing, but with a static
4541
4542 try
4543 lockvar C.c1 # can't lock something you can't write to
4544 call assert_false(1, '"lockvar C.c1" should have failed')
4545 catch
4546 call assert_exception('E1335:')
4547 endtry
4548
4549 LockIt(C.c1) # but can lock it's value
4550 assert_equal(1, islocked("C.c1"))
4551 assert_equal(1, islocked("C.c1[0]"))
4552 assert_equal(1, islocked("C.c1[1]"))
4553 UnlockIt(C.c1)
4554 assert_equal(0, islocked("C.c1"))
4555 assert_equal(0, islocked("C.c1[0]"))
4556
4557 lockvar C.c1[0]
4558 assert_equal(0, islocked("C.c1"))
4559 assert_equal(1, islocked("C.c1[0]"))
4560 assert_equal(0, islocked("C.c1[1]"))
4561 unlockvar C.c1[0]
4562 assert_equal(0, islocked("C.c1"))
4563 assert_equal(0, islocked("C.c1[0]"))
4564 END
4565 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004566
4567 # Do islocked() from an object method
4568 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004569 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004570 vim9script
4571
4572 var l0o0 = [ [0], [1], [2]]
4573 var l0o1 = [ [10], [11], [12]]
4574 var l0c0 = [[120], [121], [122]]
4575 var l0c1 = [[130], [131], [132]]
4576
4577 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004578 var o0: list<list<number>> = l0o0
4579 var o1: list<list<number>> = l0o1
4580 static var c0: list<list<number>> = l0c0
4581 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004582 def Islocked(arg: string): number
4583 return islocked(arg)
4584 enddef
4585 static def SIslocked(arg: string): number
4586 return islocked(arg)
4587 enddef
4588 endclass
4589
4590 var l2o0 = [[20000], [20001], [20002]]
4591 var l2o1 = [[20010], [20011], [20012]]
4592 var l2c0 = [[20120], [20121], [20122]]
4593 var l2c1 = [[20130], [20131], [20132]]
4594
4595 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004596 var o0: list<list<number>> = l2o0
4597 var o1: list<list<number>> = l2o1
4598 static var c0: list<list<number>> = l2c0
4599 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004600 def Islocked(arg: string): number
4601 return islocked(arg)
4602 enddef
4603 static def SIslocked(arg: string): number
4604 return islocked(arg)
4605 enddef
4606 endclass
4607
4608 var obj0 = C0.new()
4609 var obj2 = C2.new()
4610
4611 var l = [ obj0, null_object, obj2 ]
4612
4613 # lock list, object func access through script var expr
4614 assert_equal(0, obj0.Islocked("l[0].o0"))
4615 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4616 lockvar l0o0
4617 assert_equal(1, obj0.Islocked("l[0].o0"))
4618 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4619
4620 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4621
4622 # lock list element, object func access through script var expr
4623 lockvar l0o1[1]
4624 assert_equal(0, obj0.Islocked("this.o1[0]"))
4625 assert_equal(1, obj0.Islocked("this.o1[1]"))
4626
4627 assert_equal(0, obj0.Islocked("this.o1"))
4628 lockvar l0o1
4629 assert_equal(1, obj0.Islocked("this.o1"))
4630 unlockvar l0o1
4631
4632 lockvar l0c1[1]
4633
4634 # static by class name member expr from same class
4635 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4636 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4637 # static by bare name member expr from same class
4638 assert_equal(0, obj0.Islocked("c1[0]"))
4639 assert_equal(1, obj0.Islocked("c1[1]"))
4640
4641 # static by class name member expr from other class
4642 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4643 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4644 # static by bare name member expr from other class
4645 assert_equal(0, obj2.Islocked("c1[0]"))
4646 assert_equal(0, obj2.Islocked("c1[1]"))
4647
4648
4649 # static by bare name in same class
4650 assert_equal(0, obj0.Islocked("c0"))
4651 lockvar l0c0
4652 assert_equal(1, obj0.Islocked("c0"))
4653
4654 #
4655 # similar stuff, but use static method
4656 #
4657
4658 unlockvar l0o0
4659
4660 # lock list, object func access through script var expr
4661 assert_equal(0, C0.SIslocked("l[0].o0"))
4662 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4663 lockvar l0o0
4664 assert_equal(1, C0.SIslocked("l[0].o0"))
4665 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4666
4667 unlockvar l0o1
4668
4669 # can't access "this" from class method
4670 try
4671 C0.SIslocked("this.o1[0]")
4672 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4673 catch
4674 call assert_exception('E121: Undefined variable: this')
4675 endtry
4676
4677 lockvar l0c1[1]
4678
4679 # static by class name member expr from same class
4680 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4681 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4682 # static by bare name member expr from same class
4683 assert_equal(0, C0.SIslocked("c1[0]"))
4684 assert_equal(1, C0.SIslocked("c1[1]"))
4685
4686 # static by class name member expr from other class
4687 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4688 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4689 # static by bare name member expr from other class
4690 assert_equal(0, C2.SIslocked("c1[0]"))
4691 assert_equal(0, C2.SIslocked("c1[1]"))
4692
4693
4694 # static by bare name in same class
4695 unlockvar l0c0
4696 assert_equal(0, C0.SIslocked("c0"))
4697 lockvar l0c0
4698 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004699 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004700 v9.CheckSourceSuccess(lines)
4701
4702 # Check islocked class/object from various places.
4703 lines =<< trim END
4704 vim9script
4705
4706 class C
4707 def Islocked(arg: string): number
4708 return islocked(arg)
4709 enddef
4710 static def SIslocked(arg: string): number
4711 return islocked(arg)
4712 enddef
4713 endclass
4714 var obj = C.new()
4715
4716 # object method
4717 assert_equal(0, obj.Islocked("this"))
4718 assert_equal(0, obj.Islocked("C"))
4719
4720 # class method
4721 ### assert_equal(0, C.SIslocked("this"))
4722 assert_equal(0, C.SIslocked("C"))
4723
4724 #script level
4725 var v: number
4726 v = islocked("C")
4727 assert_equal(0, v)
4728 v = islocked("obj")
4729 assert_equal(0, v)
4730 END
4731 v9.CheckSourceSuccess(lines)
4732enddef
4733
4734def Test_lockvar_islocked_notfound()
4735 # Try non-existent things
4736 var lines =<< trim END
4737 vim9script
4738
4739 class C
4740 def Islocked(arg: string): number
4741 return islocked(arg)
4742 enddef
4743 static def SIslocked(arg: string): number
4744 return islocked(arg)
4745 enddef
4746 endclass
4747 var obj = C.new()
4748 assert_equal(-1, obj.Islocked("anywhere"))
4749 assert_equal(-1, C.SIslocked("notanywhere"))
4750 END
4751 v9.CheckSourceSuccess(lines)
4752
4753 # Something not found of the form "name1.name2" is an error
4754 lines =<< trim END
4755 vim9script
4756
4757 islocked("one.two")
4758 END
4759 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4760
4761 lines =<< trim END
4762 vim9script
4763
4764 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004765 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004766 def Islocked(arg: string): number
4767 return islocked(arg)
4768 enddef
4769 endclass
4770 var obj = C.new()
4771 obj.Islocked("this.val.not_there"))
4772 END
4773 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4774
4775 lines =<< trim END
4776 vim9script
4777
4778 class C
4779 def Islocked(arg: string): number
4780 return islocked(arg)
4781 enddef
4782 endclass
4783 var obj = C.new()
4784 obj.Islocked("this.notobjmember")
4785 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004786 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004787
4788 # access a script variable through methods
4789 lines =<< trim END
4790 vim9script
4791
4792 var l = [1]
4793 class C
4794 def Islocked(arg: string): number
4795 return islocked(arg)
4796 enddef
4797 static def SIslocked(arg: string): number
4798 return islocked(arg)
4799 enddef
4800 endclass
4801 var obj = C.new()
4802 assert_equal(0, obj.Islocked("l"))
4803 assert_equal(0, C.SIslocked("l"))
4804 lockvar l
4805 assert_equal(1, obj.Islocked("l"))
4806 assert_equal(1, C.SIslocked("l"))
4807 END
4808 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004809enddef
4810
Ernie Rael03042a22023-11-11 08:53:32 +01004811" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004812def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004813 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004814 var lines =<< trim END
4815 vim9script
4816
4817 class A
4818 def _Foo(): number
4819 return 1234
4820 enddef
4821 endclass
4822 var a = A.new()
4823 a._Foo()
4824 END
Ernie Rael03042a22023-11-11 08:53:32 +01004825 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004826
Ernie Rael03042a22023-11-11 08:53:32 +01004827 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004828 lines =<< trim END
4829 vim9script
4830
4831 class A
4832 def _Foo(): number
4833 return 1234
4834 enddef
4835 endclass
4836 def T()
4837 var a = A.new()
4838 a._Foo()
4839 enddef
4840 T()
4841 END
Ernie Rael03042a22023-11-11 08:53:32 +01004842 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004843
Ernie Rael03042a22023-11-11 08:53:32 +01004844 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004845 lines =<< trim END
4846 vim9script
4847
4848 class A
4849 def _Foo(): number
4850 return 1234
4851 enddef
4852 def Bar(): number
4853 return this._Foo()
4854 enddef
4855 endclass
4856 var a = A.new()
4857 assert_equal(1234, a.Bar())
4858 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004859 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004860
Ernie Rael03042a22023-11-11 08:53:32 +01004861 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004862 lines =<< trim END
4863 vim9script
4864
4865 class A
4866 def _Foo(): number
4867 return 1234
4868 enddef
4869 def Bar(): number
4870 return this._Foo()
4871 enddef
4872 endclass
4873 def T()
4874 var a = A.new()
4875 assert_equal(1234, a.Bar())
4876 enddef
4877 T()
4878 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004879 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004880
Ernie Rael03042a22023-11-11 08:53:32 +01004881 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004882 lines =<< trim END
4883 vim9script
4884
4885 class A
4886 def _Foo(): number
4887 return 1234
4888 enddef
4889 def Bar(): number
4890 return _Foo()
4891 enddef
4892 endclass
4893 var a = A.new()
4894 a.Bar()
4895 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004896 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004897
Ernie Rael03042a22023-11-11 08:53:32 +01004898 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004899 lines =<< trim END
4900 vim9script
4901
4902 class A
4903 def _Foo(): number
4904 return 1234
4905 enddef
4906 endclass
4907 A._Foo()
4908 END
Ernie Rael03042a22023-11-11 08:53:32 +01004909 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004910
Ernie Rael03042a22023-11-11 08:53:32 +01004911 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004912 lines =<< trim END
4913 vim9script
4914
4915 class A
4916 def _Foo()
4917 enddef
4918 def _Foo()
4919 enddef
4920 endclass
4921 var a = A.new()
4922 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004923 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004924
Ernie Rael03042a22023-11-11 08:53:32 +01004925 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004926 lines =<< trim END
4927 vim9script
4928
4929 class A
4930 def _Foo()
4931 enddef
4932 def Foo()
4933 enddef
4934 endclass
4935 var a = A.new()
4936 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004937 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004938
Ernie Rael03042a22023-11-11 08:53:32 +01004939 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004940 lines =<< trim END
4941 vim9script
4942
4943 class A
4944 def Foo()
4945 enddef
4946 def _Foo()
4947 enddef
4948 endclass
4949 var a = A.new()
4950 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004951 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004952
Ernie Rael03042a22023-11-11 08:53:32 +01004953 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004954 lines =<< trim END
4955 vim9script
4956
4957 class A
4958 def Foo(): number
4959 return 100
4960 enddef
4961 def _Bar(): number
4962 return 200
4963 enddef
4964 def _Baz()
4965 assert_equal(100, this.Foo())
4966 assert_equal(200, this._Bar())
4967 enddef
4968 def T()
4969 this._Baz()
4970 enddef
4971 endclass
4972 var a = A.new()
4973 a.T()
4974 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004975 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004976
Ernie Rael03042a22023-11-11 08:53:32 +01004977 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004978 lines =<< trim END
4979 vim9script
4980
4981 class A
4982 def _Foo(): number
4983 return 100
4984 enddef
4985 endclass
4986 class B
4987 def Foo(): number
4988 var a = A.new()
4989 a._Foo()
4990 enddef
4991 endclass
4992 var b = B.new()
4993 b.Foo()
4994 END
Ernie Rael03042a22023-11-11 08:53:32 +01004995 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004996
Ernie Rael03042a22023-11-11 08:53:32 +01004997 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004998 lines =<< trim END
4999 vim9script
5000 class A
5001 def _Foo(): number
5002 return 1234
5003 enddef
5004 endclass
5005 class B extends A
5006 def Bar()
5007 enddef
5008 endclass
5009 class C extends B
5010 def Baz(): number
5011 return this._Foo()
5012 enddef
5013 endclass
5014 var c = C.new()
5015 assert_equal(1234, c.Baz())
5016 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005017 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005018
Ernie Rael03042a22023-11-11 08:53:32 +01005019 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005020 lines =<< trim END
5021 vim9script
5022 class A
5023 def _Foo(): number
5024 return 1234
5025 enddef
5026 endclass
5027 class B extends A
5028 def Bar()
5029 enddef
5030 endclass
5031 class C extends B
5032 def Baz(): number
5033 enddef
5034 endclass
5035 var c = C.new()
5036 assert_equal(1234, c._Foo())
5037 END
Ernie Rael03042a22023-11-11 08:53:32 +01005038 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005039
5040 # Using "_" prefix in a method name should fail outside of a class
5041 lines =<< trim END
5042 vim9script
5043 def _Foo(): number
5044 return 1234
5045 enddef
5046 var a = _Foo()
5047 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005048 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005049enddef
5050
Ernie Rael03042a22023-11-11 08:53:32 +01005051" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005052def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005053 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005054 var lines =<< trim END
5055 vim9script
5056
5057 class A
5058 static def _Foo(): number
5059 return 1234
5060 enddef
5061 endclass
5062 A._Foo()
5063 END
Ernie Rael03042a22023-11-11 08:53:32 +01005064 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005065
Ernie Rael03042a22023-11-11 08:53:32 +01005066 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005067 lines =<< trim END
5068 vim9script
5069
5070 class A
5071 static def _Foo(): number
5072 return 1234
5073 enddef
5074 endclass
5075 def T()
5076 A._Foo()
5077 enddef
5078 T()
5079 END
Ernie Rael03042a22023-11-11 08:53:32 +01005080 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005081
Ernie Rael03042a22023-11-11 08:53:32 +01005082 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005083 lines =<< trim END
5084 vim9script
5085
5086 class A
5087 static def _Foo(): number
5088 return 1234
5089 enddef
5090 endclass
5091 var a = A.new()
5092 a._Foo()
5093 END
Ernie Rael03042a22023-11-11 08:53:32 +01005094 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005095
Ernie Rael03042a22023-11-11 08:53:32 +01005096 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005097 lines =<< trim END
5098 vim9script
5099
5100 class A
5101 static def _Foo(): number
5102 return 1234
5103 enddef
5104 endclass
5105 def T()
5106 var a = A.new()
5107 a._Foo()
5108 enddef
5109 T()
5110 END
Ernie Rael03042a22023-11-11 08:53:32 +01005111 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005112
Ernie Rael03042a22023-11-11 08:53:32 +01005113 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005114 lines =<< trim END
5115 vim9script
5116
5117 class A
5118 static def _Foo(): number
5119 return 1234
5120 enddef
5121 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005122 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005123 enddef
5124 endclass
5125 var a = A.new()
5126 a.Bar()
5127 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005128 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005129
Ernie Rael03042a22023-11-11 08:53:32 +01005130 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005131 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005132 lines =<< trim END
5133 vim9script
5134
5135 class A
5136 static def _Foo1(): number
5137 return 1234
5138 enddef
5139 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005140 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005141 enddef
5142 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005143 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005144 enddef
5145 endclass
5146 var a = A.new()
5147 a.Bar()
5148 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005149 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005150
Ernie Rael03042a22023-11-11 08:53:32 +01005151 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005152 lines =<< trim END
5153 vim9script
5154
5155 class A
5156 static def _Foo()
5157 enddef
5158 static def Foo()
5159 enddef
5160 endclass
5161 var a = A.new()
5162 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005163 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005164
Ernie Rael03042a22023-11-11 08:53:32 +01005165 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005166 lines =<< trim END
5167 vim9script
5168
5169 class A
5170 static def _Foo(): number
5171 return 1234
5172 enddef
5173 endclass
5174 class B
5175 def Foo(): number
5176 return A._Foo()
5177 enddef
5178 endclass
5179 var b = B.new()
5180 assert_equal(1234, b.Foo())
5181 END
Ernie Rael03042a22023-11-11 08:53:32 +01005182 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005183
Ernie Rael03042a22023-11-11 08:53:32 +01005184 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005185 lines =<< trim END
5186 vim9script
5187 class A
5188 static def _Foo(): number
5189 return 1234
5190 enddef
5191 endclass
5192 class B extends A
5193 def Bar()
5194 enddef
5195 endclass
5196 class C extends B
5197 def Baz(): number
5198 return A._Foo()
5199 enddef
5200 endclass
5201 var c = C.new()
5202 assert_equal(1234, c.Baz())
5203 END
Ernie Rael03042a22023-11-11 08:53:32 +01005204 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005205
Ernie Rael03042a22023-11-11 08:53:32 +01005206 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005207 lines =<< trim END
5208 vim9script
5209 class A
5210 static def _Foo(): number
5211 return 1234
5212 enddef
5213 endclass
5214 class B extends A
5215 def Bar()
5216 enddef
5217 endclass
5218 class C extends B
5219 static def Baz(): number
5220 return A._Foo()
5221 enddef
5222 endclass
5223 assert_equal(1234, C.Baz())
5224 END
Ernie Rael03042a22023-11-11 08:53:32 +01005225 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005226
Ernie Rael03042a22023-11-11 08:53:32 +01005227 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005228 lines =<< trim END
5229 vim9script
5230 class A
5231 static def _Foo(): number
5232 return 1234
5233 enddef
5234 endclass
5235 class B extends A
5236 def Bar()
5237 enddef
5238 endclass
5239 class C extends B
5240 def Baz(): number
5241 enddef
5242 endclass
5243 var c = C.new()
5244 assert_equal(1234, C._Foo())
5245 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005246 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005247enddef
5248
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005249" Test for using the return value of a class/object method as a function
5250" argument.
5251def Test_objmethod_funcarg()
5252 var lines =<< trim END
5253 vim9script
5254
5255 class C
5256 def Foo(): string
5257 return 'foo'
5258 enddef
5259 endclass
5260
5261 def Bar(a: number, s: string): string
5262 return s
5263 enddef
5264
5265 def Baz(c: C)
5266 assert_equal('foo', Bar(10, c.Foo()))
5267 enddef
5268
5269 var t = C.new()
5270 Baz(t)
5271 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005272 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005273
5274 lines =<< trim END
5275 vim9script
5276
5277 class C
5278 static def Foo(): string
5279 return 'foo'
5280 enddef
5281 endclass
5282
5283 def Bar(a: number, s: string): string
5284 return s
5285 enddef
5286
5287 def Baz()
5288 assert_equal('foo', Bar(10, C.Foo()))
5289 enddef
5290
5291 Baz()
5292 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005293 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005294enddef
5295
Ernie Raelcf138d42023-09-06 20:45:03 +02005296def Test_static_inheritence()
5297 # subclasses get their own static copy
5298 var lines =<< trim END
5299 vim9script
5300
5301 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005302 static var _svar: number
5303 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005304 def new()
5305 _svar = 1
5306 this._mvar = 101
5307 enddef
5308 def AccessObject(): number
5309 return this._mvar
5310 enddef
5311 def AccessStaticThroughObject(): number
5312 return _svar
5313 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005314 endclass
5315
5316 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005317 def new()
5318 this._mvar = 102
5319 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005320 endclass
5321
5322 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005323 def new()
5324 this._mvar = 103
5325 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005326
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005327 def AccessPrivateStaticThroughClassName(): number
5328 assert_equal(1, A._svar)
5329 return 444
5330 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005331 endclass
5332
5333 var oa = A.new()
5334 var ob = B.new()
5335 var oc = C.new()
5336 assert_equal(101, oa.AccessObject())
5337 assert_equal(102, ob.AccessObject())
5338 assert_equal(103, oc.AccessObject())
5339
Ernie Rael03042a22023-11-11 08:53:32 +01005340 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005341
5342 # verify object properly resolves to correct static
5343 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005344 assert_equal(1, ob.AccessStaticThroughObject())
5345 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005346 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005347 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005348enddef
5349
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005350" Test for declaring duplicate object and class members
5351def Test_dup_member_variable()
5352 # Duplicate member variable
5353 var lines =<< trim END
5354 vim9script
5355 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005356 var val = 10
5357 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005358 endclass
5359 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005360 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005361
Ernie Rael03042a22023-11-11 08:53:32 +01005362 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005363 lines =<< trim END
5364 vim9script
5365 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005366 var _val = 10
5367 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005368 endclass
5369 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005370 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005371
5372 # Duplicate public member variable
5373 lines =<< trim END
5374 vim9script
5375 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005376 public var val = 10
5377 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005378 endclass
5379 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005380 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005381
Ernie Rael03042a22023-11-11 08:53:32 +01005382 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005383 lines =<< trim END
5384 vim9script
5385 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005386 var val = 10
5387 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005388 endclass
5389 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005390 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005391
Ernie Rael03042a22023-11-11 08:53:32 +01005392 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005393 lines =<< trim END
5394 vim9script
5395 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005396 var _val = 20
5397 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005398 endclass
5399 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005400 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005401
5402 # Duplicate class member variable
5403 lines =<< trim END
5404 vim9script
5405 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005406 static var s: string = "abc"
5407 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005408 endclass
5409 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005410 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005411
Ernie Rael03042a22023-11-11 08:53:32 +01005412 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005413 lines =<< trim END
5414 vim9script
5415 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005416 public static var s: string = "abc"
5417 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005418 endclass
5419 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005420 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005421
5422 # Duplicate class and object member variable
5423 lines =<< trim END
5424 vim9script
5425 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005426 static var val = 10
5427 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005428 def new()
5429 enddef
5430 endclass
5431 var c = C.new()
5432 assert_equal(10, C.val)
5433 assert_equal(20, c.val)
5434 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005435 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005436
5437 # Duplicate object member variable in a derived class
5438 lines =<< trim END
5439 vim9script
5440 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005441 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005442 endclass
5443 class B extends A
5444 endclass
5445 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005446 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005447 endclass
5448 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005449 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005450
Ernie Rael03042a22023-11-11 08:53:32 +01005451 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005452 lines =<< trim END
5453 vim9script
5454 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005455 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005456 endclass
5457 class B extends A
5458 endclass
5459 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005460 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005461 endclass
5462 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005463 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005464
Ernie Rael03042a22023-11-11 08:53:32 +01005465 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005466 lines =<< trim END
5467 vim9script
5468 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005469 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005470 endclass
5471 class B extends A
5472 endclass
5473 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005474 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005475 endclass
5476 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005477 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005478
5479 # Duplicate object member variable in a derived class
5480 lines =<< trim END
5481 vim9script
5482 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005483 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005484 endclass
5485 class B extends A
5486 endclass
5487 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005488 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005489 endclass
5490 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005491 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005492
5493 # Two member variables with a common prefix
5494 lines =<< trim END
5495 vim9script
5496 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005497 public static var svar2: number
5498 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005499 endclass
5500 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005501 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005502enddef
5503
Ernie Rael03042a22023-11-11 08:53:32 +01005504" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005505def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005506 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005507 var lines =<< trim END
5508 vim9script
5509 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005510 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005511 def GetVal(): number
5512 return this._val
5513 enddef
5514 endclass
5515 def T()
5516 var a = A.new()
5517 a._val = 20
5518 enddef
5519 T()
5520 END
Ernie Rael03042a22023-11-11 08:53:32 +01005521 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005522
Ernie Rael03042a22023-11-11 08:53:32 +01005523 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005524 lines =<< trim END
5525 vim9script
5526 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005527 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005528 endclass
5529 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005530 var a = A.new()
5531 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005532 enddef
5533 T()
5534 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005535 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005536
Ernie Rael03042a22023-11-11 08:53:32 +01005537 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005538 lines =<< trim END
5539 vim9script
5540 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005541 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005542 endclass
5543 def T()
5544 var a = A.new()
5545 var x = a._val
5546 enddef
5547 T()
5548 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005549 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005550
Ernie Rael03042a22023-11-11 08:53:32 +01005551 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005552 lines =<< trim END
5553 vim9script
5554 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005555 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005556 endclass
5557 def T()
5558 var a = A.new()
5559 a._val = 3
5560 enddef
5561 T()
5562 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005563 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005564
Ernie Rael03042a22023-11-11 08:53:32 +01005565 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005566 lines =<< trim END
5567 vim9script
5568 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005569 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005570 endclass
5571 def T()
5572 var x = A._val
5573 enddef
5574 T()
5575 END
Ernie Rael03042a22023-11-11 08:53:32 +01005576 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005577
Ernie Rael03042a22023-11-11 08:53:32 +01005578 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005579 lines =<< trim END
5580 vim9script
5581 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005582 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005583 endclass
5584 def T()
5585 A._val = 3
5586 enddef
5587 T()
5588 END
Ernie Rael03042a22023-11-11 08:53:32 +01005589 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005590enddef
5591
5592" Test for changing the member access of an interface in a implementation class
5593def Test_change_interface_member_access()
5594 var lines =<< trim END
5595 vim9script
5596 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005597 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005598 endinterface
5599 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005600 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005601 endclass
5602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005603 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005604
5605 lines =<< trim END
5606 vim9script
5607 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005608 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005609 endinterface
5610 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005611 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005612 endclass
5613 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005614 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005615enddef
5616
5617" Test for trying to change a readonly member from a def function
5618def Test_readonly_member_change_in_def_func()
5619 var lines =<< trim END
5620 vim9script
5621 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005622 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005623 endclass
5624 def T()
5625 var a = A.new()
5626 a.val = 20
5627 enddef
5628 T()
5629 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005630 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005631enddef
5632
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005633" Test for reading and writing a class member from a def function
5634def Test_modify_class_member_from_def_function()
5635 var lines =<< trim END
5636 vim9script
5637 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005638 var var1: number = 10
5639 public static var var2: list<number> = [1, 2]
5640 public static var var3: dict<number> = {a: 1, b: 2}
5641 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005642 endclass
5643 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005644 assert_equal([1, 2], A.var2)
5645 assert_equal({a: 1, b: 2}, A.var3)
5646 A.var2 = [3, 4]
5647 A.var3 = {c: 3, d: 4}
5648 assert_equal([3, 4], A.var2)
5649 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005650 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005651 enddef
5652 T()
5653 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005654 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005655enddef
5656
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005657" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005658def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005659 var lines =<< trim END
5660 vim9script
5661 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005662 public static var svar1: list<number> = [1]
5663 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005664 endclass
5665
5666 A.svar1->add(3)
5667 A.svar2->add(4)
5668 assert_equal([1, 3], A.svar1)
5669 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005670
5671 def Foo()
5672 A.svar1->add(7)
5673 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005674 assert_equal([1, 3, 7], A.svar1)
5675 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005676 enddef
5677 Foo()
5678 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005679 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005680
5681 # Cannot read from a class variable using an object in script context
5682 lines =<< trim END
5683 vim9script
5684 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005685 public var var1: number
5686 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005687 endclass
5688
5689 var a = A.new()
5690 echo a.svar2
5691 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005692 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005693
5694 # Cannot write to a class variable using an object in script context
5695 lines =<< trim END
5696 vim9script
5697 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005698 public var var1: number
5699 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005700 endclass
5701
5702 var a = A.new()
5703 a.svar2 = [2]
5704 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005705 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005706
5707 # Cannot read from a class variable using an object in def method context
5708 lines =<< trim END
5709 vim9script
5710 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005711 public var var1: number
5712 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005713 endclass
5714
5715 def T()
5716 var a = A.new()
5717 echo a.svar2
5718 enddef
5719 T()
5720 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005721 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005722
5723 # Cannot write to a class variable using an object in def method context
5724 lines =<< trim END
5725 vim9script
5726 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005727 public var var1: number
5728 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005729 endclass
5730
5731 def T()
5732 var a = A.new()
5733 a.svar2 = [2]
5734 enddef
5735 T()
5736 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005737 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005738enddef
5739
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005740" Test for using a interface method using a child object
5741def Test_interface_method_from_child()
5742 var lines =<< trim END
5743 vim9script
5744
5745 interface A
5746 def Foo(): string
5747 endinterface
5748
5749 class B implements A
5750 def Foo(): string
5751 return 'foo'
5752 enddef
5753 endclass
5754
5755 class C extends B
5756 def Bar(): string
5757 return 'bar'
5758 enddef
5759 endclass
5760
5761 def T1(a: A)
5762 assert_equal('foo', a.Foo())
5763 enddef
5764
5765 def T2(b: B)
5766 assert_equal('foo', b.Foo())
5767 enddef
5768
5769 var c = C.new()
5770 T1(c)
5771 T2(c)
5772 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005773 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005774enddef
5775
5776" Test for using an interface method using a child object when it is overridden
5777" by the child class.
5778" FIXME: This test fails.
5779" def Test_interface_overridden_method_from_child()
5780" var lines =<< trim END
5781" vim9script
5782"
5783" interface A
5784" def Foo(): string
5785" endinterface
5786"
5787" class B implements A
5788" def Foo(): string
5789" return 'b-foo'
5790" enddef
5791" endclass
5792"
5793" class C extends B
5794" def Bar(): string
5795" return 'bar'
5796" enddef
5797" def Foo(): string
5798" return 'c-foo'
5799" enddef
5800" endclass
5801"
5802" def T1(a: A)
5803" assert_equal('c-foo', a.Foo())
5804" enddef
5805"
5806" def T2(b: B)
5807" assert_equal('c-foo', b.Foo())
5808" enddef
5809"
5810" var c = C.new()
5811" T1(c)
5812" T2(c)
5813" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005814" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005815" enddef
5816
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005817" Test for abstract methods
5818def Test_abstract_method()
5819 # Use two abstract methods
5820 var lines =<< trim END
5821 vim9script
5822 abstract class A
5823 def M1(): number
5824 return 10
5825 enddef
5826 abstract def M2(): number
5827 abstract def M3(): number
5828 endclass
5829 class B extends A
5830 def M2(): number
5831 return 20
5832 enddef
5833 def M3(): number
5834 return 30
5835 enddef
5836 endclass
5837 var b = B.new()
5838 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5839 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005840 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005841
5842 # Don't define an abstract method
5843 lines =<< trim END
5844 vim9script
5845 abstract class A
5846 abstract def Foo()
5847 endclass
5848 class B extends A
5849 endclass
5850 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005851 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005852
5853 # Use abstract method in a concrete class
5854 lines =<< trim END
5855 vim9script
5856 class A
5857 abstract def Foo()
5858 endclass
5859 class B extends A
5860 endclass
5861 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005862 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005863
5864 # Use abstract method in an interface
5865 lines =<< trim END
5866 vim9script
5867 interface A
5868 abstract def Foo()
5869 endinterface
5870 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005871 def Foo()
5872 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005873 endclass
5874 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005875 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5876
5877 # Use abstract static method in an interface
5878 lines =<< trim END
5879 vim9script
5880 interface A
5881 abstract static def Foo()
5882 enddef
5883 endinterface
5884 END
5885 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5886
5887 # Use abstract static variable in an interface
5888 lines =<< trim END
5889 vim9script
5890 interface A
5891 abstract static foo: number = 10
5892 endinterface
5893 END
5894 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005895
5896 # Abbreviate the "abstract" keyword
5897 lines =<< trim END
5898 vim9script
5899 class A
5900 abs def Foo()
5901 endclass
5902 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005903 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005904
5905 # Use "abstract" with a member variable
5906 lines =<< trim END
5907 vim9script
5908 abstract class A
5909 abstract this.val = 10
5910 endclass
5911 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005912 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005913
5914 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01005915 lines =<< trim END
5916 vim9script
5917 abstract class A
5918 abstract static def Foo(): number
5919 endclass
5920 END
5921 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005922
5923 # Type mismatch between abstract method and concrete method
5924 lines =<< trim END
5925 vim9script
5926 abstract class A
5927 abstract def Foo(a: string, b: number): list<number>
5928 endclass
5929 class B extends A
5930 def Foo(a: number, b: string): list<string>
5931 return []
5932 enddef
5933 endclass
5934 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005935 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 +02005936
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005937 # Invoke an abstract method from a def function
5938 lines =<< trim END
5939 vim9script
5940 abstract class A
5941 abstract def Foo(): list<number>
5942 endclass
5943 class B extends A
5944 def Foo(): list<number>
5945 return [3, 5]
5946 enddef
5947 endclass
5948 def Bar(c: B)
5949 assert_equal([3, 5], c.Foo())
5950 enddef
5951 var b = B.new()
5952 Bar(b)
5953 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005954 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005955
5956 # Use a static method in an abstract class
5957 lines =<< trim END
5958 vim9script
5959 abstract class A
5960 static def Foo(): string
5961 return 'foo'
5962 enddef
5963 endclass
5964 assert_equal('foo', A.Foo())
5965 END
5966 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005967enddef
5968
5969" Test for calling a class method from a subclass
5970def Test_class_method_call_from_subclass()
5971 # class method call from a subclass
5972 var lines =<< trim END
5973 vim9script
5974
5975 class A
5976 static def Foo()
5977 echo "foo"
5978 enddef
5979 endclass
5980
5981 class B extends A
5982 def Bar()
5983 Foo()
5984 enddef
5985 endclass
5986
5987 var b = B.new()
5988 b.Bar()
5989 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005990 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005991enddef
5992
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005993" Test for calling a class method using an object in a def function context and
5994" script context.
5995def Test_class_method_call_using_object()
5996 # script context
5997 var lines =<< trim END
5998 vim9script
5999 class A
6000 static def Foo(): list<string>
6001 return ['a', 'b']
6002 enddef
6003 def Bar()
6004 assert_equal(['a', 'b'], A.Foo())
6005 assert_equal(['a', 'b'], Foo())
6006 enddef
6007 endclass
6008
6009 def T()
6010 assert_equal(['a', 'b'], A.Foo())
6011 var t_a = A.new()
6012 t_a.Bar()
6013 enddef
6014
6015 assert_equal(['a', 'b'], A.Foo())
6016 var a = A.new()
6017 a.Bar()
6018 T()
6019 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006020 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006021
6022 # script context
6023 lines =<< trim END
6024 vim9script
6025 class A
6026 static def Foo(): string
6027 return 'foo'
6028 enddef
6029 endclass
6030
6031 var a = A.new()
6032 assert_equal('foo', a.Foo())
6033 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006034 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006035
6036 # def function context
6037 lines =<< trim END
6038 vim9script
6039 class A
6040 static def Foo(): string
6041 return 'foo'
6042 enddef
6043 endclass
6044
6045 def T()
6046 var a = A.new()
6047 assert_equal('foo', a.Foo())
6048 enddef
6049 T()
6050 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006051 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006052enddef
6053
6054def Test_class_variable()
6055 var lines =<< trim END
6056 vim9script
6057
6058 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006059 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006060 static def ClassFunc()
6061 assert_equal(10, val)
6062 enddef
6063 def ObjFunc()
6064 assert_equal(10, val)
6065 enddef
6066 endclass
6067
6068 class B extends A
6069 endclass
6070
6071 assert_equal(10, A.val)
6072 A.ClassFunc()
6073 var a = A.new()
6074 a.ObjFunc()
6075 var b = B.new()
6076 b.ObjFunc()
6077
6078 def T1(a1: A)
6079 a1.ObjFunc()
6080 A.ClassFunc()
6081 enddef
6082 T1(b)
6083
6084 A.val = 20
6085 assert_equal(20, A.val)
6086 END
6087 v9.CheckSourceSuccess(lines)
6088
6089 # Modifying a parent class variable from a child class method
6090 lines =<< trim END
6091 vim9script
6092
6093 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006094 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006095 endclass
6096
6097 class B extends A
6098 static def ClassFunc()
6099 val = 20
6100 enddef
6101 endclass
6102 B.ClassFunc()
6103 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006104 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006105
6106 # Reading a parent class variable from a child class method
6107 lines =<< trim END
6108 vim9script
6109
6110 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006111 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006112 endclass
6113
6114 class B extends A
6115 static def ClassFunc()
6116 var i = val
6117 enddef
6118 endclass
6119 B.ClassFunc()
6120 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006121 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006122
6123 # Modifying a parent class variable from a child object method
6124 lines =<< trim END
6125 vim9script
6126
6127 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006128 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006129 endclass
6130
6131 class B extends A
6132 def ObjFunc()
6133 val = 20
6134 enddef
6135 endclass
6136 var b = B.new()
6137 b.ObjFunc()
6138 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006139 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006140
6141 # Reading a parent class variable from a child object method
6142 lines =<< trim END
6143 vim9script
6144
6145 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006146 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006147 endclass
6148
6149 class B extends A
6150 def ObjFunc()
6151 var i = val
6152 enddef
6153 endclass
6154 var b = B.new()
6155 b.ObjFunc()
6156 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006157 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006158
6159 # Modifying a class variable using an object at script level
6160 lines =<< trim END
6161 vim9script
6162
6163 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006164 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006165 endclass
6166 var a = A.new()
6167 a.val = 20
6168 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006169 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006170
6171 # Reading a class variable using an object at script level
6172 lines =<< trim END
6173 vim9script
6174
6175 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006176 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006177 endclass
6178 var a = A.new()
6179 var i = a.val
6180 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006181 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006182
6183 # Modifying a class variable using an object at function level
6184 lines =<< trim END
6185 vim9script
6186
6187 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006188 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006189 endclass
6190
6191 def T()
6192 var a = A.new()
6193 a.val = 20
6194 enddef
6195 T()
6196 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006197 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006198
6199 # Reading a class variable using an object at function level
6200 lines =<< trim END
6201 vim9script
6202
6203 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006204 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006205 endclass
6206 def T()
6207 var a = A.new()
6208 var i = a.val
6209 enddef
6210 T()
6211 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006212 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006213
6214 # Use old implicit var declaration syntax (without initialization)
6215 lines =<< trim END
6216 vim9script
6217
6218 class A
6219 static val: number
6220 endclass
6221 END
6222 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6223
6224 # Use old implicit var declaration syntax (with initialization)
6225 lines =<< trim END
6226 vim9script
6227
6228 class A
6229 static val: number = 10
6230 endclass
6231 END
6232 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6233
6234 # Use old implicit var declaration syntax (type inferred)
6235 lines =<< trim END
6236 vim9script
6237
6238 class A
6239 static val = 10
6240 endclass
6241 END
6242 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6243
6244 # Missing ":var" in "var" class variable declaration (without initialization)
6245 lines =<< trim END
6246 vim9script
6247
6248 class A
6249 static var: number
6250 endclass
6251 END
6252 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6253
6254 # Missing ":var" in "var" class variable declaration (with initialization)
6255 lines =<< trim END
6256 vim9script
6257
6258 class A
6259 static var: number = 10
6260 endclass
6261 END
6262 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6263
6264 # Missing ":var" in "var" class variable declaration (type inferred)
6265 lines =<< trim END
6266 vim9script
6267
6268 class A
6269 static var = 10
6270 endclass
6271 END
6272 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6273
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006274enddef
6275
6276" Test for using a duplicate class method and class variable in a child class
6277def Test_dup_class_member()
6278 # duplicate class variable, class method and overridden object method
6279 var lines =<< trim END
6280 vim9script
6281 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006282 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006283 static def Check()
6284 assert_equal(100, sval)
6285 enddef
6286 def GetVal(): number
6287 return sval
6288 enddef
6289 endclass
6290
6291 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006292 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006293 static def Check()
6294 assert_equal(200, sval)
6295 enddef
6296 def GetVal(): number
6297 return sval
6298 enddef
6299 endclass
6300
6301 def T1(aa: A): number
6302 return aa.GetVal()
6303 enddef
6304
6305 def T2(bb: B): number
6306 return bb.GetVal()
6307 enddef
6308
6309 assert_equal(100, A.sval)
6310 assert_equal(200, B.sval)
6311 var a = A.new()
6312 assert_equal(100, a.GetVal())
6313 var b = B.new()
6314 assert_equal(200, b.GetVal())
6315 assert_equal(200, T1(b))
6316 assert_equal(200, T2(b))
6317 END
6318 v9.CheckSourceSuccess(lines)
6319
6320 # duplicate class variable and class method
6321 lines =<< trim END
6322 vim9script
6323 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006324 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006325 static def Check()
6326 assert_equal(100, sval)
6327 enddef
6328 def GetVal(): number
6329 return sval
6330 enddef
6331 endclass
6332
6333 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006334 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006335 static def Check()
6336 assert_equal(200, sval)
6337 enddef
6338 endclass
6339
6340 def T1(aa: A): number
6341 return aa.GetVal()
6342 enddef
6343
6344 def T2(bb: B): number
6345 return bb.GetVal()
6346 enddef
6347
6348 assert_equal(100, A.sval)
6349 assert_equal(200, B.sval)
6350 var a = A.new()
6351 assert_equal(100, a.GetVal())
6352 var b = B.new()
6353 assert_equal(100, b.GetVal())
6354 assert_equal(100, T1(b))
6355 assert_equal(100, T2(b))
6356 END
6357 v9.CheckSourceSuccess(lines)
6358enddef
6359
6360" Test for calling an instance method using the class
6361def Test_instance_method_call_using_class()
6362 # Invoke an object method using a class in script context
6363 var lines =<< trim END
6364 vim9script
6365 class A
6366 def Foo()
6367 echo "foo"
6368 enddef
6369 endclass
6370 A.Foo()
6371 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006372 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006373
6374 # Invoke an object method using a class in def function context
6375 lines =<< trim END
6376 vim9script
6377 class A
6378 def Foo()
6379 echo "foo"
6380 enddef
6381 endclass
6382 def T()
6383 A.Foo()
6384 enddef
6385 T()
6386 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006387 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006388enddef
6389
6390" Test for duplicate class method and instance method
6391def Test_dup_classmethod_objmethod()
6392 # Duplicate instance method
6393 var lines =<< trim END
6394 vim9script
6395 class A
6396 static def Foo()
6397 enddef
6398 def Foo()
6399 enddef
6400 endclass
6401 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006402 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006403
Ernie Rael03042a22023-11-11 08:53:32 +01006404 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006405 lines =<< trim END
6406 vim9script
6407 class A
6408 static def Foo()
6409 enddef
6410 def _Foo()
6411 enddef
6412 endclass
6413 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006414 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006415
6416 # Duplicate class method
6417 lines =<< trim END
6418 vim9script
6419 class A
6420 def Foo()
6421 enddef
6422 static def Foo()
6423 enddef
6424 endclass
6425 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006426 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006427
Ernie Rael03042a22023-11-11 08:53:32 +01006428 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006429 lines =<< trim END
6430 vim9script
6431 class A
6432 def Foo()
6433 enddef
6434 static def _Foo()
6435 enddef
6436 endclass
6437 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006438 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006439
Ernie Rael03042a22023-11-11 08:53:32 +01006440 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006441 lines =<< trim END
6442 vim9script
6443 class A
6444 def _Foo()
6445 enddef
6446 static def _Foo()
6447 enddef
6448 endclass
6449 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006450 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006451enddef
6452
6453" Test for an instance method access level comparison with parent instance
6454" methods.
6455def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006456 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006457 var lines =<< trim END
6458 vim9script
6459 class A
6460 def Foo()
6461 enddef
6462 endclass
6463 class B extends A
6464 endclass
6465 class C extends B
6466 def _Foo()
6467 enddef
6468 endclass
6469 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006470 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006471
6472 # Public method in subclass
6473 lines =<< trim END
6474 vim9script
6475 class A
6476 def _Foo()
6477 enddef
6478 endclass
6479 class B extends A
6480 endclass
6481 class C extends B
6482 def Foo()
6483 enddef
6484 endclass
6485 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006486 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006487enddef
6488
6489def Test_extend_empty_class()
6490 var lines =<< trim END
6491 vim9script
6492 class A
6493 endclass
6494 class B extends A
6495 endclass
6496 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006497 public static var rw_class_var = 1
6498 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006499 static def ClassMethod(): number
6500 return 3
6501 enddef
6502 def ObjMethod(): number
6503 return 4
6504 enddef
6505 endclass
6506 assert_equal(1, C.rw_class_var)
6507 assert_equal(3, C.ClassMethod())
6508 var c = C.new()
6509 assert_equal(2, c.rw_obj_var)
6510 assert_equal(4, c.ObjMethod())
6511 END
6512 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006513enddef
6514
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006515" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006516" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006517def Test_interface_with_unsupported_members()
6518 var lines =<< trim END
6519 vim9script
6520 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006521 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006522 endinterface
6523 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006524 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006525
6526 lines =<< trim END
6527 vim9script
6528 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006529 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006530 endinterface
6531 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006532 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006533
6534 lines =<< trim END
6535 vim9script
6536 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006537 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006538 endinterface
6539 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006540 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006541
6542 lines =<< trim END
6543 vim9script
6544 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006545 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006546 endinterface
6547 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006548 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006549
6550 lines =<< trim END
6551 vim9script
6552 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006553 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006554 endinterface
6555 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006556 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006557
6558 lines =<< trim END
6559 vim9script
6560 interface A
6561 static def Foo(d: dict<any>): list<string>
6562 endinterface
6563 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006564 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006565
6566 lines =<< trim END
6567 vim9script
6568 interface A
6569 static def _Foo(d: dict<any>): list<string>
6570 endinterface
6571 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006572 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006573
6574 lines =<< trim END
6575 vim9script
6576 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006577 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006578 endinterface
6579 END
Ernie Rael03042a22023-11-11 08:53:32 +01006580 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006581
6582 lines =<< trim END
6583 vim9script
6584 interface A
6585 def _Foo(d: dict<any>): list<string>
6586 endinterface
6587 END
Ernie Rael03042a22023-11-11 08:53:32 +01006588 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006589enddef
6590
6591" Test for extending an interface
6592def Test_extend_interface()
6593 var lines =<< trim END
6594 vim9script
6595 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006596 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006597 def Foo()
6598 endinterface
6599 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006600 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006601 def Bar()
6602 endinterface
6603 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006604 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006605 def Foo()
6606 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006607 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006608 def Bar()
6609 enddef
6610 endclass
6611 END
6612 v9.CheckSourceSuccess(lines)
6613
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006614 # extending empty interface
6615 lines =<< trim END
6616 vim9script
6617 interface A
6618 endinterface
6619 interface B extends A
6620 endinterface
6621 class C implements B
6622 endclass
6623 END
6624 v9.CheckSourceSuccess(lines)
6625
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006626 lines =<< trim END
6627 vim9script
6628 interface A
6629 def Foo()
6630 endinterface
6631 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006632 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006633 endinterface
6634 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006635 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006636 endclass
6637 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006638 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006639
6640 lines =<< trim END
6641 vim9script
6642 interface A
6643 def Foo()
6644 endinterface
6645 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006646 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006647 endinterface
6648 class C implements A, B
6649 def Foo()
6650 enddef
6651 endclass
6652 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006653 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006654
6655 # interface cannot extend a class
6656 lines =<< trim END
6657 vim9script
6658 class A
6659 endclass
6660 interface B extends A
6661 endinterface
6662 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006663 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006664
6665 # class cannot extend an interface
6666 lines =<< trim END
6667 vim9script
6668 interface A
6669 endinterface
6670 class B extends A
6671 endclass
6672 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006673 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006674
6675 # interface cannot implement another interface
6676 lines =<< trim END
6677 vim9script
6678 interface A
6679 endinterface
6680 interface B implements A
6681 endinterface
6682 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006683 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006684
6685 # interface cannot extend multiple interfaces
6686 lines =<< trim END
6687 vim9script
6688 interface A
6689 endinterface
6690 interface B
6691 endinterface
6692 interface C extends A, B
6693 endinterface
6694 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006695 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006696
6697 # Variable type in an extended interface is of different type
6698 lines =<< trim END
6699 vim9script
6700 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006701 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006702 endinterface
6703 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006704 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006705 endinterface
6706 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006707 var val1: string
6708 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006709 endinterface
6710 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006711 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006712enddef
6713
6714" Test for a child class implementing an interface when some of the methods are
6715" defined in the parent class.
6716def Test_child_class_implements_interface()
6717 var lines =<< trim END
6718 vim9script
6719
6720 interface Intf
6721 def F1(): list<list<number>>
6722 def F2(): list<list<number>>
6723 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006724 var var1: list<dict<number>>
6725 var var2: list<dict<number>>
6726 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006727 endinterface
6728
6729 class A
6730 def A1()
6731 enddef
6732 def F3(): list<list<number>>
6733 return [[3]]
6734 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006735 var v1: list<list<number>> = [[0]]
6736 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006737 endclass
6738
6739 class B extends A
6740 def B1()
6741 enddef
6742 def F2(): list<list<number>>
6743 return [[2]]
6744 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006745 var v2: list<list<number>> = [[0]]
6746 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006747 endclass
6748
6749 class C extends B implements Intf
6750 def C1()
6751 enddef
6752 def F1(): list<list<number>>
6753 return [[1]]
6754 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006755 var v3: list<list<number>> = [[0]]
6756 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006757 endclass
6758
6759 def T(if: Intf)
6760 assert_equal([[1]], if.F1())
6761 assert_equal([[2]], if.F2())
6762 assert_equal([[3]], if.F3())
6763 assert_equal([{a: 10}], if.var1)
6764 assert_equal([{b: 20}], if.var2)
6765 assert_equal([{c: 30}], if.var3)
6766 enddef
6767
6768 var c = C.new()
6769 T(c)
6770 assert_equal([[1]], c.F1())
6771 assert_equal([[2]], c.F2())
6772 assert_equal([[3]], c.F3())
6773 assert_equal([{a: 10}], c.var1)
6774 assert_equal([{b: 20}], c.var2)
6775 assert_equal([{c: 30}], c.var3)
6776 END
6777 v9.CheckSourceSuccess(lines)
6778
6779 # One of the interface methods is not found
6780 lines =<< trim END
6781 vim9script
6782
6783 interface Intf
6784 def F1()
6785 def F2()
6786 def F3()
6787 endinterface
6788
6789 class A
6790 def A1()
6791 enddef
6792 endclass
6793
6794 class B extends A
6795 def B1()
6796 enddef
6797 def F2()
6798 enddef
6799 endclass
6800
6801 class C extends B implements Intf
6802 def C1()
6803 enddef
6804 def F1()
6805 enddef
6806 endclass
6807 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006808 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006809
6810 # One of the interface methods is of different type
6811 lines =<< trim END
6812 vim9script
6813
6814 interface Intf
6815 def F1()
6816 def F2()
6817 def F3()
6818 endinterface
6819
6820 class A
6821 def F3(): number
6822 return 0
6823 enddef
6824 def A1()
6825 enddef
6826 endclass
6827
6828 class B extends A
6829 def B1()
6830 enddef
6831 def F2()
6832 enddef
6833 endclass
6834
6835 class C extends B implements Intf
6836 def C1()
6837 enddef
6838 def F1()
6839 enddef
6840 endclass
6841 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006842 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006843
6844 # One of the interface variables is not present
6845 lines =<< trim END
6846 vim9script
6847
6848 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006849 var var1: list<dict<number>>
6850 var var2: list<dict<number>>
6851 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006852 endinterface
6853
6854 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006855 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006856 endclass
6857
6858 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006859 var v2: list<list<number>> = [[0]]
6860 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006861 endclass
6862
6863 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006864 var v3: list<list<number>> = [[0]]
6865 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006866 endclass
6867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006868 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006869
6870 # One of the interface variables is of different type
6871 lines =<< trim END
6872 vim9script
6873
6874 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006875 var var1: list<dict<number>>
6876 var var2: list<dict<number>>
6877 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006878 endinterface
6879
6880 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006881 var v1: list<list<number>> = [[0]]
6882 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006883 endclass
6884
6885 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006886 var v2: list<list<number>> = [[0]]
6887 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006888 endclass
6889
6890 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006891 var v3: list<list<number>> = [[0]]
6892 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006893 endclass
6894 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006895 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 +02006896enddef
6897
6898" Test for extending an interface with duplicate variables and methods
6899def Test_interface_extends_with_dup_members()
6900 var lines =<< trim END
6901 vim9script
6902 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006903 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006904 def Foo1(): number
6905 endinterface
6906 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006907 var n2: number
6908 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006909 def Foo2(): number
6910 def Foo1(): number
6911 endinterface
6912 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006913 var n1 = 10
6914 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006915 def Foo1(): number
6916 return 30
6917 enddef
6918 def Foo2(): number
6919 return 40
6920 enddef
6921 endclass
6922 def T1(a: A)
6923 assert_equal(10, a.n1)
6924 assert_equal(30, a.Foo1())
6925 enddef
6926 def T2(b: B)
6927 assert_equal(10, b.n1)
6928 assert_equal(20, b.n2)
6929 assert_equal(30, b.Foo1())
6930 assert_equal(40, b.Foo2())
6931 enddef
6932 var c = C.new()
6933 T1(c)
6934 T2(c)
6935 END
6936 v9.CheckSourceSuccess(lines)
6937enddef
6938
6939" Test for using "any" type for a variable in a sub-class while it has a
6940" concrete type in the interface
6941def Test_implements_using_var_type_any()
6942 var lines =<< trim END
6943 vim9script
6944 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006945 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006946 endinterface
6947 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006948 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006949 endclass
6950 var b = B.new()
6951 assert_equal([{a: '1'}, {b: '2'}], b.val)
6952 END
6953 v9.CheckSourceSuccess(lines)
6954
6955 # initialize instance variable using a different type
6956 lines =<< trim END
6957 vim9script
6958 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006959 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006960 endinterface
6961 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006962 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006963 endclass
6964 var b = B.new()
6965 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006966 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006967enddef
6968
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006969" Test for assigning to a member variable in a nested class
6970def Test_nested_object_assignment()
6971 var lines =<< trim END
6972 vim9script
6973
6974 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006975 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006976 endclass
6977
6978 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006979 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006980 endclass
6981
6982 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01006983 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006984 endclass
6985
6986 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01006987 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006988 endclass
6989
6990 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006991 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006992 enddef
6993
6994 var d = D.new()
6995 T(d)
6996 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006997 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006998enddef
6999
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007000" Test for calling methods using a null object
7001def Test_null_object_method_call()
7002 # Calling a object method using a null object in script context
7003 var lines =<< trim END
7004 vim9script
7005
7006 class C
7007 def Foo()
7008 assert_report('This method should not be executed')
7009 enddef
7010 endclass
7011
7012 var o: C
7013 o.Foo()
7014 END
7015 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7016
7017 # Calling a object method using a null object in def function context
7018 lines =<< trim END
7019 vim9script
7020
7021 class C
7022 def Foo()
7023 assert_report('This method should not be executed')
7024 enddef
7025 endclass
7026
7027 def T()
7028 var o: C
7029 o.Foo()
7030 enddef
7031 T()
7032 END
7033 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7034
7035 # Calling a object method through another class method using a null object in
7036 # script context
7037 lines =<< trim END
7038 vim9script
7039
7040 class C
7041 def Foo()
7042 assert_report('This method should not be executed')
7043 enddef
7044
7045 static def Bar(o_any: any)
7046 var o_typed: C = o_any
7047 o_typed.Foo()
7048 enddef
7049 endclass
7050
7051 var o: C
7052 C.Bar(o)
7053 END
7054 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7055
7056 # Calling a object method through another class method using a null object in
7057 # def function context
7058 lines =<< trim END
7059 vim9script
7060
7061 class C
7062 def Foo()
7063 assert_report('This method should not be executed')
7064 enddef
7065
7066 static def Bar(o_any: any)
7067 var o_typed: C = o_any
7068 o_typed.Foo()
7069 enddef
7070 endclass
7071
7072 def T()
7073 var o: C
7074 C.Bar(o)
7075 enddef
7076 T()
7077 END
7078 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7079enddef
7080
7081" Test for using a dict as an object member
7082def Test_dict_object_member()
7083 var lines =<< trim END
7084 vim9script
7085
7086 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007087 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007088 def GetState(): dict<number>
7089 return this.state
7090 enddef
7091 endclass
7092
7093 var ctx = Context.new()
7094 ctx.state->extend({a: 1})
7095 ctx.state['b'] = 2
7096 assert_equal({a: 1, b: 2}, ctx.GetState())
7097
7098 def F()
7099 ctx.state['c'] = 3
7100 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7101 enddef
7102 F()
7103 assert_equal(3, ctx.state.c)
7104 ctx.state.c = 4
7105 assert_equal(4, ctx.state.c)
7106 END
7107 v9.CheckSourceSuccess(lines)
7108enddef
7109
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007110" The following test was failing after 9.0.1914. This was caused by using a
7111" freed object from a previous method call.
7112def Test_freed_object_from_previous_method_call()
7113 var lines =<< trim END
7114 vim9script
7115
7116 class Context
7117 endclass
7118
7119 class Result
7120 endclass
7121
7122 def Failure(): Result
7123 return Result.new()
7124 enddef
7125
7126 def GetResult(ctx: Context): Result
7127 return Failure()
7128 enddef
7129
7130 def Test_GetResult()
7131 var ctx = Context.new()
7132 var result = GetResult(ctx)
7133 enddef
7134
7135 Test_GetResult()
7136 END
7137 v9.CheckSourceSuccess(lines)
7138enddef
7139
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007140" Test for duplicate object and class variable
7141def Test_duplicate_variable()
7142 # Object variable name is same as the class variable name
7143 var lines =<< trim END
7144 vim9script
7145 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007146 public static var sval: number
7147 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007148 endclass
7149 var a = A.new()
7150 END
7151 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7152
7153 # Duplicate variable name and calling a class method
7154 lines =<< trim END
7155 vim9script
7156 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007157 public static var sval: number
7158 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007159 def F1()
7160 echo this.sval
7161 enddef
7162 static def F2()
7163 echo sval
7164 enddef
7165 endclass
7166 A.F2()
7167 END
7168 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7169
7170 # Duplicate variable with an empty constructor
7171 lines =<< trim END
7172 vim9script
7173 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007174 public static var sval: number
7175 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007176 def new()
7177 enddef
7178 endclass
7179 var a = A.new()
7180 END
7181 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7182enddef
7183
7184" Test for using a reserved keyword as a variable name
7185def Test_reserved_varname()
7186 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7187 'null_function', 'null_list', 'null_partial', 'null_string',
7188 'null_channel', 'null_job', 'super', 'this']
7189
7190 var lines =<< trim eval END
7191 vim9script
7192 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007193 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007194 endclass
7195 var o = C.new()
7196 END
7197 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7198
7199 lines =<< trim eval END
7200 vim9script
7201 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007202 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007203 def new()
7204 enddef
7205 endclass
7206 var o = C.new()
7207 END
7208 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7209
7210 lines =<< trim eval END
7211 vim9script
7212 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007213 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007214 def new()
7215 enddef
7216 def F()
7217 echo this.{kword}
7218 enddef
7219 endclass
7220 var o = C.new()
7221 o.F()
7222 END
7223 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007224
7225 # class variable name
7226 if kword != 'this'
7227 lines =<< trim eval END
7228 vim9script
7229 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007230 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007231 endclass
7232 END
7233 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7234 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007235 endfor
7236enddef
7237
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007238" Test for checking the type of the arguments and the return value of a object
7239" method in an extended class.
7240def Test_extended_obj_method_type_check()
7241 var lines =<< trim END
7242 vim9script
7243
7244 class A
7245 endclass
7246 class B extends A
7247 endclass
7248 class C extends B
7249 endclass
7250
7251 class Foo
7252 def Doit(p: B): B
7253 return B.new()
7254 enddef
7255 endclass
7256
7257 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007258 def Doit(p: C): B
7259 return B.new()
7260 enddef
7261 endclass
7262 END
7263 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7264
7265 lines =<< trim END
7266 vim9script
7267
7268 class A
7269 endclass
7270 class B extends A
7271 endclass
7272 class C extends B
7273 endclass
7274
7275 class Foo
7276 def Doit(p: B): B
7277 return B.new()
7278 enddef
7279 endclass
7280
7281 class Bar extends Foo
7282 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007283 return C.new()
7284 enddef
7285 endclass
7286 END
7287 v9.CheckSourceSuccess(lines)
7288
7289 lines =<< trim END
7290 vim9script
7291
7292 class A
7293 endclass
7294 class B extends A
7295 endclass
7296 class C extends B
7297 endclass
7298
7299 class Foo
7300 def Doit(p: B): B
7301 return B.new()
7302 enddef
7303 endclass
7304
7305 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007306 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007307 return B.new()
7308 enddef
7309 endclass
7310 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007311 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 +02007312
7313 lines =<< trim END
7314 vim9script
7315
7316 class A
7317 endclass
7318 class B extends A
7319 endclass
7320 class C extends B
7321 endclass
7322
7323 class Foo
7324 def Doit(p: B): B
7325 return B.new()
7326 enddef
7327 endclass
7328
7329 class Bar extends Foo
7330 def Doit(p: B): A
7331 return A.new()
7332 enddef
7333 endclass
7334 END
7335 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 +02007336
7337 # check varargs type mismatch
7338 lines =<< trim END
7339 vim9script
7340
7341 class B
7342 def F(...xxx: list<any>)
7343 enddef
7344 endclass
7345 class C extends B
7346 def F(xxx: list<any>)
7347 enddef
7348 endclass
7349 END
7350 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 +02007351enddef
7352
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007353" Test type checking for class variable in assignments
7354func Test_class_variable_complex_type_check()
7355 " class variable with a specific type. Try assigning a different type at
7356 " script level.
7357 let lines =<< trim END
7358 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007359 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007360 return {}
7361 enddef
7362 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007363 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007364 endclass
7365 test_garbagecollect_now()
7366 A.Fn = "abc"
7367 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007368 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 +02007369
7370 " class variable with a specific type. Try assigning a different type at
7371 " class def method level.
7372 let lines =<< trim END
7373 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007374 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007375 return {}
7376 enddef
7377 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007378 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007379 def Bar()
7380 Fn = "abc"
7381 enddef
7382 endclass
7383 var a = A.new()
7384 test_garbagecollect_now()
7385 a.Bar()
7386 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007387 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 +02007388
7389 " class variable with a specific type. Try assigning a different type at
7390 " script def method level.
7391 let lines =<< trim END
7392 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007393 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007394 return {}
7395 enddef
7396 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007397 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007398 endclass
7399 def Bar()
7400 A.Fn = "abc"
7401 enddef
7402 test_garbagecollect_now()
7403 Bar()
7404 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007405 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 +02007406
7407 " class variable without any type. Should be set to the initialization
7408 " expression type. Try assigning a different type from script level.
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 = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007416 endclass
7417 test_garbagecollect_now()
7418 A.Fn = "abc"
7419 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007420 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 +02007421
7422 " class variable without any type. Should be set to the initialization
7423 " expression type. Try assigning a different type at class def level.
7424 let lines =<< trim END
7425 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007426 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007427 return {}
7428 enddef
7429 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007430 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007431 def Bar()
7432 Fn = "abc"
7433 enddef
7434 endclass
7435 var a = A.new()
7436 test_garbagecollect_now()
7437 a.Bar()
7438 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007439 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 +02007440
7441 " class variable without any type. Should be set to the initialization
7442 " expression type. Try assigning a different type at script def level.
7443 let lines =<< trim END
7444 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007445 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007446 return {}
7447 enddef
7448 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007449 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007450 endclass
7451 def Bar()
7452 A.Fn = "abc"
7453 enddef
7454 test_garbagecollect_now()
7455 Bar()
7456 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007457 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 +02007458
7459 " class variable with 'any" type. Can be assigned different types.
7460 let lines =<< trim END
7461 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007462 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007463 return {}
7464 enddef
7465 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007466 public static var Fn: any = Foo
7467 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007468 endclass
7469 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007470 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007471 A.Fn = "abc"
7472 test_garbagecollect_now()
7473 assert_equal('string', typename(A.Fn))
7474 A.Fn2 = Foo
7475 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007476 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007477 A.Fn2 = "xyz"
7478 test_garbagecollect_now()
7479 assert_equal('string', typename(A.Fn2))
7480 END
7481 call v9.CheckSourceSuccess(lines)
7482
7483 " class variable with 'any" type. Can be assigned different types.
7484 let lines =<< trim END
7485 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007486 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007487 return {}
7488 enddef
7489 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007490 public static var Fn: any = Foo
7491 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007492
7493 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007494 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007495 Fn = "abc"
7496 assert_equal('string', typename(Fn))
7497 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007498 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007499 Fn2 = "xyz"
7500 assert_equal('string', typename(Fn2))
7501 enddef
7502 endclass
7503 var a = A.new()
7504 test_garbagecollect_now()
7505 a.Bar()
7506 test_garbagecollect_now()
7507 A.Fn = Foo
7508 a.Bar()
7509 END
7510 call v9.CheckSourceSuccess(lines)
7511
7512 " class variable with 'any" type. Can be assigned different types.
7513 let lines =<< trim END
7514 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007515 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007516 return {}
7517 enddef
7518 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007519 public static var Fn: any = Foo
7520 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007521 endclass
7522
7523 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007524 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007525 A.Fn = "abc"
7526 assert_equal('string', typename(A.Fn))
7527 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007528 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007529 A.Fn2 = "xyz"
7530 assert_equal('string', typename(A.Fn2))
7531 enddef
7532 Bar()
7533 test_garbagecollect_now()
7534 A.Fn = Foo
7535 Bar()
7536 END
7537 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007538
7539 let lines =<< trim END
7540 vim9script
7541 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007542 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007543 endclass
7544 assert_equal([0z10, 0z20], A.foo)
7545 A.foo = [0z30]
7546 assert_equal([0z30], A.foo)
7547 var a = A.foo
7548 assert_equal([0z30], a)
7549 END
7550 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007551endfunc
7552
7553" Test type checking for object variable in assignments
7554func Test_object_variable_complex_type_check()
7555 " object variable with a specific type. Try assigning a different type at
7556 " script level.
7557 let lines =<< trim END
7558 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007559 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007560 return {}
7561 enddef
7562 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007563 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007564 endclass
7565 var a = A.new()
7566 test_garbagecollect_now()
7567 a.Fn = "abc"
7568 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007569 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 +02007570
7571 " object variable with a specific type. Try assigning a different type at
7572 " object def method level.
7573 let lines =<< trim END
7574 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007575 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007576 return {}
7577 enddef
7578 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007579 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007580 def Bar()
7581 this.Fn = "abc"
7582 this.Fn = Foo
7583 enddef
7584 endclass
7585 var a = A.new()
7586 test_garbagecollect_now()
7587 a.Bar()
7588 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007589 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 +02007590
7591 " object variable with a specific type. Try assigning a different type at
7592 " script def method level.
7593 let lines =<< trim END
7594 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007595 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007596 return {}
7597 enddef
7598 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007599 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007600 endclass
7601 def Bar()
7602 var a = A.new()
7603 a.Fn = "abc"
7604 a.Fn = Foo
7605 enddef
7606 test_garbagecollect_now()
7607 Bar()
7608 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007609 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 +02007610
7611 " object variable without any type. Should be set to the initialization
7612 " expression type. Try assigning a different type from script level.
7613 let lines =<< trim END
7614 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007615 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007616 return {}
7617 enddef
7618 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007619 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007620 endclass
7621 var a = A.new()
7622 test_garbagecollect_now()
7623 a.Fn = "abc"
7624 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007625 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 +02007626
7627 " object variable without any type. Should be set to the initialization
7628 " expression type. Try assigning a different type at object def level.
7629 let lines =<< trim END
7630 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007631 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007632 return {}
7633 enddef
7634 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007635 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007636 def Bar()
7637 this.Fn = "abc"
7638 this.Fn = Foo
7639 enddef
7640 endclass
7641 var a = A.new()
7642 test_garbagecollect_now()
7643 a.Bar()
7644 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007645 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007646
7647 " object variable without any type. Should be set to the initialization
7648 " expression type. Try assigning a different type at script def level.
7649 let lines =<< trim END
7650 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007651 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007652 return {}
7653 enddef
7654 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007655 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007656 endclass
7657 def Bar()
7658 var a = A.new()
7659 a.Fn = "abc"
7660 a.Fn = Foo
7661 enddef
7662 test_garbagecollect_now()
7663 Bar()
7664 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007665 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 +02007666
7667 " object variable with 'any" type. Can be assigned different types.
7668 let lines =<< trim END
7669 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007670 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007671 return {}
7672 enddef
7673 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007674 public var Fn: any = Foo
7675 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007676 endclass
7677
7678 var a = A.new()
7679 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007680 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007681 a.Fn = "abc"
7682 test_garbagecollect_now()
7683 assert_equal('string', typename(a.Fn))
7684 a.Fn2 = Foo
7685 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007686 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007687 a.Fn2 = "xyz"
7688 test_garbagecollect_now()
7689 assert_equal('string', typename(a.Fn2))
7690 END
7691 call v9.CheckSourceSuccess(lines)
7692
7693 " object variable with 'any" type. Can be assigned different types.
7694 let lines =<< trim END
7695 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007696 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007697 return {}
7698 enddef
7699 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007700 public var Fn: any = Foo
7701 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007702
7703 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007704 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007705 this.Fn = "abc"
7706 assert_equal('string', typename(this.Fn))
7707 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007708 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007709 this.Fn2 = "xyz"
7710 assert_equal('string', typename(this.Fn2))
7711 enddef
7712 endclass
7713
7714 var a = A.new()
7715 test_garbagecollect_now()
7716 a.Bar()
7717 test_garbagecollect_now()
7718 a.Fn = Foo
7719 a.Bar()
7720 END
7721 call v9.CheckSourceSuccess(lines)
7722
7723 " object variable with 'any" type. Can be assigned different types.
7724 let lines =<< trim END
7725 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007726 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007727 return {}
7728 enddef
7729 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007730 public var Fn: any = Foo
7731 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007732 endclass
7733
7734 def Bar()
7735 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007736 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007737 a.Fn = "abc"
7738 assert_equal('string', typename(a.Fn))
7739 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007740 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007741 a.Fn2 = "xyz"
7742 assert_equal('string', typename(a.Fn2))
7743 enddef
7744 test_garbagecollect_now()
7745 Bar()
7746 test_garbagecollect_now()
7747 Bar()
7748 END
7749 call v9.CheckSourceSuccess(lines)
7750endfunc
7751
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007752" Test for recursively calling an object method. This used to cause an
7753" use-after-free error.
7754def Test_recursive_object_method_call()
7755 var lines =<< trim END
7756 vim9script
7757 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007758 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007759 def Foo(): number
7760 if this.val >= 90
7761 return this.val
7762 endif
7763 this.val += 1
7764 return this.Foo()
7765 enddef
7766 endclass
7767 var a = A.new()
7768 assert_equal(90, a.Foo())
7769 END
7770 v9.CheckSourceSuccess(lines)
7771enddef
7772
7773" Test for recursively calling a class method.
7774def Test_recursive_class_method_call()
7775 var lines =<< trim END
7776 vim9script
7777 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007778 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007779 static def Foo(): number
7780 if val >= 90
7781 return val
7782 endif
7783 val += 1
7784 return Foo()
7785 enddef
7786 endclass
7787 assert_equal(90, A.Foo())
7788 END
7789 v9.CheckSourceSuccess(lines)
7790enddef
7791
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007792" Test for checking the argument types and the return type when assigning a
7793" funcref to make sure the invariant class type is used.
7794def Test_funcref_argtype_returntype_check()
7795 var lines =<< trim END
7796 vim9script
7797 class A
7798 endclass
7799 class B extends A
7800 endclass
7801
7802 def Foo(p: B): B
7803 return B.new()
7804 enddef
7805
7806 var Bar: func(A): A = Foo
7807 END
7808 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7809
7810 lines =<< trim END
7811 vim9script
7812 class A
7813 endclass
7814 class B extends A
7815 endclass
7816
7817 def Foo(p: B): B
7818 return B.new()
7819 enddef
7820
7821 def Baz()
7822 var Bar: func(A): A = Foo
7823 enddef
7824 Baz()
7825 END
7826 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7827enddef
7828
Ernie Rael96952b22023-10-17 18:15:01 +02007829def Test_funcref_argtype_invariance_check()
7830 var lines =<< trim END
7831 vim9script
7832
7833 class A
7834 endclass
7835 class B extends A
7836 endclass
7837 class C extends B
7838 endclass
7839
7840 var Func: func(B): number
7841 Func = (o: B): number => 3
7842 assert_equal(3, Func(B.new()))
7843 END
7844 v9.CheckSourceSuccess(lines)
7845
7846 lines =<< trim END
7847 vim9script
7848
7849 class A
7850 endclass
7851 class B extends A
7852 endclass
7853 class C extends B
7854 endclass
7855
7856 var Func: func(B): number
7857 Func = (o: A): number => 3
7858 END
7859 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7860
7861 lines =<< trim END
7862 vim9script
7863
7864 class A
7865 endclass
7866 class B extends A
7867 endclass
7868 class C extends B
7869 endclass
7870
7871 var Func: func(B): number
7872 Func = (o: C): number => 3
7873 END
7874 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7875enddef
7876
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007877" Test for using an operator (e.g. +) with an assignment
7878def Test_op_and_assignment()
7879 # Using += with a class variable
7880 var lines =<< trim END
7881 vim9script
7882 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007883 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007884 static def Foo(): list<number>
7885 val += [1]
7886 return val
7887 enddef
7888 endclass
7889 def Bar(): list<number>
7890 A.val += [2]
7891 return A.val
7892 enddef
7893 assert_equal([1], A.Foo())
7894 assert_equal([1, 2], Bar())
7895 A.val += [3]
7896 assert_equal([1, 2, 3], A.val)
7897 END
7898 v9.CheckSourceSuccess(lines)
7899
7900 # Using += with an object variable
7901 lines =<< trim END
7902 vim9script
7903 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007904 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007905 def Foo(): list<number>
7906 this.val += [1]
7907 return this.val
7908 enddef
7909 endclass
7910 def Bar(bar_a: A): list<number>
7911 bar_a.val += [2]
7912 return bar_a.val
7913 enddef
7914 var a = A.new()
7915 assert_equal([1], a.Foo())
7916 assert_equal([1, 2], Bar(a))
7917 a.val += [3]
7918 assert_equal([1, 2, 3], a.val)
7919 END
7920 v9.CheckSourceSuccess(lines)
7921enddef
7922
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007923" Test for using an object method as a funcref
7924def Test_object_funcref()
7925 # Using object method funcref from a def function
7926 var lines =<< trim END
7927 vim9script
7928 class A
7929 def Foo(): list<number>
7930 return [3, 2, 1]
7931 enddef
7932 endclass
7933 def Bar()
7934 var a = A.new()
7935 var Fn = a.Foo
7936 assert_equal([3, 2, 1], Fn())
7937 enddef
7938 Bar()
7939 END
7940 v9.CheckSourceSuccess(lines)
7941
7942 # Using object method funcref at the script level
7943 lines =<< trim END
7944 vim9script
7945 class A
7946 def Foo(): dict<number>
7947 return {a: 1, b: 2}
7948 enddef
7949 endclass
7950 var a = A.new()
7951 var Fn = a.Foo
7952 assert_equal({a: 1, b: 2}, Fn())
7953 END
7954 v9.CheckSourceSuccess(lines)
7955
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007956 # Using object method funcref at the script level
7957 lines =<< trim END
7958 vim9script
7959 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007960 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007961 def Foo(): number
7962 return this.val
7963 enddef
7964 endclass
7965 var a = A.new(345)
7966 var Fn = a.Foo
7967 assert_equal(345, Fn())
7968 END
7969 v9.CheckSourceSuccess(lines)
7970
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007971 # Using object method funcref from another object method
7972 lines =<< trim END
7973 vim9script
7974 class A
7975 def Foo(): list<number>
7976 return [3, 2, 1]
7977 enddef
7978 def Bar()
7979 var Fn = this.Foo
7980 assert_equal([3, 2, 1], Fn())
7981 enddef
7982 endclass
7983 var a = A.new()
7984 a.Bar()
7985 END
7986 v9.CheckSourceSuccess(lines)
7987
7988 # Using function() to get a object method funcref
7989 lines =<< trim END
7990 vim9script
7991 class A
7992 def Foo(l: list<any>): list<any>
7993 return l
7994 enddef
7995 endclass
7996 var a = A.new()
7997 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
7998 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7999 END
8000 v9.CheckSourceSuccess(lines)
8001
8002 # Use an object method with a function returning a funcref and then call the
8003 # funcref.
8004 lines =<< trim END
8005 vim9script
8006
8007 def Map(F: func(number): number): func(number): number
8008 return (n: number) => F(n)
8009 enddef
8010
8011 class Math
8012 def Double(n: number): number
8013 return 2 * n
8014 enddef
8015 endclass
8016
8017 const math = Math.new()
8018 assert_equal(48, Map(math.Double)(24))
8019 END
8020 v9.CheckSourceSuccess(lines)
8021
Ernie Rael03042a22023-11-11 08:53:32 +01008022 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008023 lines =<< trim END
8024 vim9script
8025 class A
8026 def _Foo()
8027 enddef
8028 endclass
8029 def Bar()
8030 var a = A.new()
8031 var Fn = a._Foo
8032 enddef
8033 Bar()
8034 END
Ernie Rael03042a22023-11-11 08:53:32 +01008035 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008036
Ernie Rael03042a22023-11-11 08:53:32 +01008037 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008038 lines =<< trim END
8039 vim9script
8040 class A
8041 def _Foo()
8042 enddef
8043 endclass
8044 var a = A.new()
8045 var Fn = a._Foo
8046 END
Ernie Rael03042a22023-11-11 08:53:32 +01008047 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008048
Ernie Rael03042a22023-11-11 08:53:32 +01008049 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008050 lines =<< trim END
8051 vim9script
8052 class A
8053 def _Foo(): list<number>
8054 return [3, 2, 1]
8055 enddef
8056 def Bar()
8057 var Fn = this._Foo
8058 assert_equal([3, 2, 1], Fn())
8059 enddef
8060 endclass
8061 var a = A.new()
8062 a.Bar()
8063 END
8064 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008065
8066 # Using object method funcref using call()
8067 lines =<< trim END
8068 vim9script
8069 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008070 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008071 def Foo(): number
8072 return this.val
8073 enddef
8074 endclass
8075
8076 def Bar(obj: A)
8077 assert_equal(123, call(obj.Foo, []))
8078 enddef
8079
8080 var a = A.new(123)
8081 Bar(a)
8082 assert_equal(123, call(a.Foo, []))
8083 END
8084 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008085enddef
8086
8087" Test for using a class method as a funcref
8088def Test_class_funcref()
8089 # Using class method funcref in a def function
8090 var lines =<< trim END
8091 vim9script
8092 class A
8093 static def Foo(): list<number>
8094 return [3, 2, 1]
8095 enddef
8096 endclass
8097 def Bar()
8098 var Fn = A.Foo
8099 assert_equal([3, 2, 1], Fn())
8100 enddef
8101 Bar()
8102 END
8103 v9.CheckSourceSuccess(lines)
8104
8105 # Using class method funcref at script level
8106 lines =<< trim END
8107 vim9script
8108 class A
8109 static def Foo(): dict<number>
8110 return {a: 1, b: 2}
8111 enddef
8112 endclass
8113 var Fn = A.Foo
8114 assert_equal({a: 1, b: 2}, Fn())
8115 END
8116 v9.CheckSourceSuccess(lines)
8117
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008118 # Using class method funcref at the script level
8119 lines =<< trim END
8120 vim9script
8121 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008122 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008123 static def Foo(): number
8124 return val
8125 enddef
8126 endclass
8127 A.val = 567
8128 var Fn = A.Foo
8129 assert_equal(567, Fn())
8130 END
8131 v9.CheckSourceSuccess(lines)
8132
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008133 # Using function() to get a class method funcref
8134 lines =<< trim END
8135 vim9script
8136 class A
8137 static def Foo(l: list<any>): list<any>
8138 return l
8139 enddef
8140 endclass
8141 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8142 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8143 END
8144 v9.CheckSourceSuccess(lines)
8145
8146 # Using a class method funcref from another class method
8147 lines =<< trim END
8148 vim9script
8149 class A
8150 static def Foo(): list<number>
8151 return [3, 2, 1]
8152 enddef
8153 static def Bar()
8154 var Fn = Foo
8155 assert_equal([3, 2, 1], Fn())
8156 enddef
8157 endclass
8158 A.Bar()
8159 END
8160 v9.CheckSourceSuccess(lines)
8161
8162 # Use a class method with a function returning a funcref and then call the
8163 # funcref.
8164 lines =<< trim END
8165 vim9script
8166
8167 def Map(F: func(number): number): func(number): number
8168 return (n: number) => F(n)
8169 enddef
8170
8171 class Math
8172 static def StaticDouble(n: number): number
8173 return 2 * n
8174 enddef
8175 endclass
8176
8177 assert_equal(48, Map(Math.StaticDouble)(24))
8178 END
8179 v9.CheckSourceSuccess(lines)
8180
Ernie Rael03042a22023-11-11 08:53:32 +01008181 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008182 lines =<< trim END
8183 vim9script
8184 class A
8185 static def _Foo()
8186 enddef
8187 endclass
8188 def Bar()
8189 var Fn = A._Foo
8190 enddef
8191 Bar()
8192 END
Ernie Rael03042a22023-11-11 08:53:32 +01008193 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008194
Ernie Rael03042a22023-11-11 08:53:32 +01008195 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008196 lines =<< trim END
8197 vim9script
8198 class A
8199 static def _Foo()
8200 enddef
8201 endclass
8202 var Fn = A._Foo
8203 END
Ernie Rael03042a22023-11-11 08:53:32 +01008204 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008205
Ernie Rael03042a22023-11-11 08:53:32 +01008206 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008207 lines =<< trim END
8208 vim9script
8209 class A
8210 static def _Foo(): list<number>
8211 return [3, 2, 1]
8212 enddef
8213 static def Bar()
8214 var Fn = _Foo
8215 assert_equal([3, 2, 1], Fn())
8216 enddef
8217 endclass
8218 A.Bar()
8219 END
8220 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008221
8222 # Using class method funcref using call()
8223 lines =<< trim END
8224 vim9script
8225 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008226 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008227 static def Foo(): number
8228 return val
8229 enddef
8230 endclass
8231
8232 def Bar()
8233 A.val = 468
8234 assert_equal(468, call(A.Foo, []))
8235 enddef
8236 Bar()
8237 assert_equal(468, call(A.Foo, []))
8238 END
8239 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008240enddef
8241
8242" Test for using an object member as a funcref
8243def Test_object_member_funcref()
8244 # Using a funcref object variable in an object method
8245 var lines =<< trim END
8246 vim9script
8247 def Foo(n: number): number
8248 return n * 10
8249 enddef
8250
8251 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008252 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008253 def Bar()
8254 assert_equal(200, this.Cb(20))
8255 enddef
8256 endclass
8257
8258 var a = A.new()
8259 a.Bar()
8260 END
8261 v9.CheckSourceSuccess(lines)
8262
8263 # Using a funcref object variable in a def method
8264 lines =<< trim END
8265 vim9script
8266 def Foo(n: number): number
8267 return n * 10
8268 enddef
8269
8270 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008271 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008272 endclass
8273
8274 def Bar()
8275 var a = A.new()
8276 assert_equal(200, a.Cb(20))
8277 enddef
8278 Bar()
8279 END
8280 v9.CheckSourceSuccess(lines)
8281
8282 # Using a funcref object variable at script level
8283 lines =<< trim END
8284 vim9script
8285 def Foo(n: number): number
8286 return n * 10
8287 enddef
8288
8289 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008290 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008291 endclass
8292
8293 var a = A.new()
8294 assert_equal(200, a.Cb(20))
8295 END
8296 v9.CheckSourceSuccess(lines)
8297
8298 # Using a funcref object variable pointing to an object method in an object
8299 # method.
8300 lines =<< trim END
8301 vim9script
8302 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008303 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008304 def Foo(n: number): number
8305 return n * 10
8306 enddef
8307 def Bar()
8308 assert_equal(200, this.Cb(20))
8309 enddef
8310 endclass
8311
8312 var a = A.new()
8313 a.Bar()
8314 END
8315 v9.CheckSourceSuccess(lines)
8316
8317 # Using a funcref object variable pointing to an object method in a def
8318 # method.
8319 lines =<< trim END
8320 vim9script
8321 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008322 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008323 def Foo(n: number): number
8324 return n * 10
8325 enddef
8326 endclass
8327
8328 def Bar()
8329 var a = A.new()
8330 assert_equal(200, a.Cb(20))
8331 enddef
8332 Bar()
8333 END
8334 v9.CheckSourceSuccess(lines)
8335
8336 # Using a funcref object variable pointing to an object method at script
8337 # level.
8338 lines =<< trim END
8339 vim9script
8340 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008341 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008342 def Foo(n: number): number
8343 return n * 10
8344 enddef
8345 endclass
8346
8347 var a = A.new()
8348 assert_equal(200, a.Cb(20))
8349 END
8350 v9.CheckSourceSuccess(lines)
8351enddef
8352
8353" Test for using a class member as a funcref
8354def Test_class_member_funcref()
8355 # Using a funcref class variable in a class method
8356 var lines =<< trim END
8357 vim9script
8358 def Foo(n: number): number
8359 return n * 10
8360 enddef
8361
8362 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008363 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008364 static def Bar()
8365 assert_equal(200, Cb(20))
8366 enddef
8367 endclass
8368
8369 A.Bar()
8370 END
8371 v9.CheckSourceSuccess(lines)
8372
8373 # Using a funcref class variable in a def method
8374 lines =<< trim END
8375 vim9script
8376 def Foo(n: number): number
8377 return n * 10
8378 enddef
8379
8380 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008381 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008382 endclass
8383
8384 def Bar()
8385 assert_equal(200, A.Cb(20))
8386 enddef
8387 Bar()
8388 END
8389 v9.CheckSourceSuccess(lines)
8390
8391 # Using a funcref class variable at script level
8392 lines =<< trim END
8393 vim9script
8394 def Foo(n: number): number
8395 return n * 10
8396 enddef
8397
8398 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008399 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008400 endclass
8401
8402 assert_equal(200, A.Cb(20))
8403 END
8404 v9.CheckSourceSuccess(lines)
8405
8406 # Using a funcref class variable pointing to a class method in a class
8407 # method.
8408 lines =<< trim END
8409 vim9script
8410 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008411 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008412 static def Foo(n: number): number
8413 return n * 10
8414 enddef
8415 static def Init()
8416 Cb = Foo
8417 enddef
8418 static def Bar()
8419 assert_equal(200, Cb(20))
8420 enddef
8421 endclass
8422
8423 A.Init()
8424 A.Bar()
8425 END
8426 v9.CheckSourceSuccess(lines)
8427
8428 # Using a funcref class variable pointing to a class method in a def method.
8429 lines =<< trim END
8430 vim9script
8431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008432 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008433 static def Foo(n: number): number
8434 return n * 10
8435 enddef
8436 static def Init()
8437 Cb = Foo
8438 enddef
8439 endclass
8440
8441 def Bar()
8442 A.Init()
8443 assert_equal(200, A.Cb(20))
8444 enddef
8445 Bar()
8446 END
8447 v9.CheckSourceSuccess(lines)
8448
8449 # Using a funcref class variable pointing to a class method at script level.
8450 lines =<< trim END
8451 vim9script
8452 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008453 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008454 static def Foo(n: number): number
8455 return n * 10
8456 enddef
8457 static def Init()
8458 Cb = Foo
8459 enddef
8460 endclass
8461
8462 A.Init()
8463 assert_equal(200, A.Cb(20))
8464 END
8465 v9.CheckSourceSuccess(lines)
8466enddef
8467
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008468" Test for using object methods as popup callback functions
8469def Test_objmethod_popup_callback()
8470 # Use the popup from the script level
8471 var lines =<< trim END
8472 vim9script
8473
8474 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008475 var selection: number = -1
8476 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008477
8478 def PopupFilter(id: number, key: string): bool
8479 add(this.filterkeys, key)
8480 return popup_filter_yesno(id, key)
8481 enddef
8482
8483 def PopupCb(id: number, result: number)
8484 this.selection = result ? 100 : 200
8485 enddef
8486 endclass
8487
8488 var a = A.new()
8489 feedkeys('', 'xt')
8490 var winid = popup_create('Y/N?',
8491 {filter: a.PopupFilter, callback: a.PopupCb})
8492 feedkeys('y', 'xt')
8493 popup_close(winid)
8494 assert_equal(100, a.selection)
8495 assert_equal(['y'], a.filterkeys)
8496 feedkeys('', 'xt')
8497 winid = popup_create('Y/N?',
8498 {filter: a.PopupFilter, callback: a.PopupCb})
8499 feedkeys('n', 'xt')
8500 popup_close(winid)
8501 assert_equal(200, a.selection)
8502 assert_equal(['y', 'n'], a.filterkeys)
8503 END
8504 v9.CheckSourceSuccess(lines)
8505
8506 # Use the popup from a def function
8507 lines =<< trim END
8508 vim9script
8509
8510 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008511 var selection: number = -1
8512 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008513
8514 def PopupFilter(id: number, key: string): bool
8515 add(this.filterkeys, key)
8516 return popup_filter_yesno(id, key)
8517 enddef
8518
8519 def PopupCb(id: number, result: number)
8520 this.selection = result ? 100 : 200
8521 enddef
8522 endclass
8523
8524 def Foo()
8525 var a = A.new()
8526 feedkeys('', 'xt')
8527 var winid = popup_create('Y/N?',
8528 {filter: a.PopupFilter, callback: a.PopupCb})
8529 feedkeys('y', 'xt')
8530 popup_close(winid)
8531 assert_equal(100, a.selection)
8532 assert_equal(['y'], a.filterkeys)
8533 feedkeys('', 'xt')
8534 winid = popup_create('Y/N?',
8535 {filter: a.PopupFilter, callback: a.PopupCb})
8536 feedkeys('n', 'xt')
8537 popup_close(winid)
8538 assert_equal(200, a.selection)
8539 assert_equal(['y', 'n'], a.filterkeys)
8540 enddef
8541 Foo()
8542 END
8543 v9.CheckSourceSuccess(lines)
8544enddef
8545
8546" Test for using class methods as popup callback functions
8547def Test_classmethod_popup_callback()
8548 # Use the popup from the script level
8549 var lines =<< trim END
8550 vim9script
8551
8552 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008553 static var selection: number = -1
8554 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008555
8556 static def PopupFilter(id: number, key: string): bool
8557 add(filterkeys, key)
8558 return popup_filter_yesno(id, key)
8559 enddef
8560
8561 static def PopupCb(id: number, result: number)
8562 selection = result ? 100 : 200
8563 enddef
8564 endclass
8565
8566 feedkeys('', 'xt')
8567 var winid = popup_create('Y/N?',
8568 {filter: A.PopupFilter, callback: A.PopupCb})
8569 feedkeys('y', 'xt')
8570 popup_close(winid)
8571 assert_equal(100, A.selection)
8572 assert_equal(['y'], A.filterkeys)
8573 feedkeys('', 'xt')
8574 winid = popup_create('Y/N?',
8575 {filter: A.PopupFilter, callback: A.PopupCb})
8576 feedkeys('n', 'xt')
8577 popup_close(winid)
8578 assert_equal(200, A.selection)
8579 assert_equal(['y', 'n'], A.filterkeys)
8580 END
8581 v9.CheckSourceSuccess(lines)
8582
8583 # Use the popup from a def function
8584 lines =<< trim END
8585 vim9script
8586
8587 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008588 static var selection: number = -1
8589 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008590
8591 static def PopupFilter(id: number, key: string): bool
8592 add(filterkeys, key)
8593 return popup_filter_yesno(id, key)
8594 enddef
8595
8596 static def PopupCb(id: number, result: number)
8597 selection = result ? 100 : 200
8598 enddef
8599 endclass
8600
8601 def Foo()
8602 feedkeys('', 'xt')
8603 var winid = popup_create('Y/N?',
8604 {filter: A.PopupFilter, callback: A.PopupCb})
8605 feedkeys('y', 'xt')
8606 popup_close(winid)
8607 assert_equal(100, A.selection)
8608 assert_equal(['y'], A.filterkeys)
8609 feedkeys('', 'xt')
8610 winid = popup_create('Y/N?',
8611 {filter: A.PopupFilter, callback: A.PopupCb})
8612 feedkeys('n', 'xt')
8613 popup_close(winid)
8614 assert_equal(200, A.selection)
8615 assert_equal(['y', 'n'], A.filterkeys)
8616 enddef
8617 Foo()
8618 END
8619 v9.CheckSourceSuccess(lines)
8620enddef
8621
8622" Test for using an object method as a timer callback function
8623def Test_objmethod_timer_callback()
8624 # Use the timer callback from script level
8625 var lines =<< trim END
8626 vim9script
8627
8628 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008629 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008630 def TimerCb(timerID: number)
8631 this.timerTick = 6
8632 enddef
8633 endclass
8634
8635 var a = A.new()
8636 timer_start(0, a.TimerCb)
8637 var maxWait = 5
8638 while maxWait > 0 && a.timerTick == -1
8639 :sleep 10m
8640 maxWait -= 1
8641 endwhile
8642 assert_equal(6, a.timerTick)
8643 END
8644 v9.CheckSourceSuccess(lines)
8645
8646 # Use the timer callback from a def function
8647 lines =<< trim END
8648 vim9script
8649
8650 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008651 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008652 def TimerCb(timerID: number)
8653 this.timerTick = 6
8654 enddef
8655 endclass
8656
8657 def Foo()
8658 var a = A.new()
8659 timer_start(0, a.TimerCb)
8660 var maxWait = 5
8661 while maxWait > 0 && a.timerTick == -1
8662 :sleep 10m
8663 maxWait -= 1
8664 endwhile
8665 assert_equal(6, a.timerTick)
8666 enddef
8667 Foo()
8668 END
8669 v9.CheckSourceSuccess(lines)
8670enddef
8671
8672" Test for using a class method as a timer callback function
8673def Test_classmethod_timer_callback()
8674 # Use the timer callback from script level
8675 var lines =<< trim END
8676 vim9script
8677
8678 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008679 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008680 static def TimerCb(timerID: number)
8681 timerTick = 6
8682 enddef
8683 endclass
8684
8685 timer_start(0, A.TimerCb)
8686 var maxWait = 5
8687 while maxWait > 0 && A.timerTick == -1
8688 :sleep 10m
8689 maxWait -= 1
8690 endwhile
8691 assert_equal(6, A.timerTick)
8692 END
8693 v9.CheckSourceSuccess(lines)
8694
8695 # Use the timer callback from a def function
8696 lines =<< trim END
8697 vim9script
8698
8699 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008700 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008701 static def TimerCb(timerID: number)
8702 timerTick = 6
8703 enddef
8704 endclass
8705
8706 def Foo()
8707 timer_start(0, A.TimerCb)
8708 var maxWait = 5
8709 while maxWait > 0 && A.timerTick == -1
8710 :sleep 10m
8711 maxWait -= 1
8712 endwhile
8713 assert_equal(6, A.timerTick)
8714 enddef
8715 Foo()
8716 END
8717 v9.CheckSourceSuccess(lines)
8718enddef
8719
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008720" Test for using a class variable as the first and/or second operand of a binary
8721" operator.
8722def Test_class_variable_as_operands()
8723 var lines =<< trim END
8724 vim9script
8725 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008726 static var truthy: bool = true
8727 public static var TruthyFn: func
8728 static var list: list<any> = []
8729 static var four: number = 4
8730 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008731
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008732 static def Str(): string
8733 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008734 enddef
8735
8736 static def Four(): number
8737 return four
8738 enddef
8739
8740 static def List(): list<any>
8741 return list
8742 enddef
8743
8744 static def Truthy(): bool
8745 return truthy
8746 enddef
8747
8748 def TestOps()
8749 assert_true(Tests.truthy == truthy)
8750 assert_true(truthy == Tests.truthy)
8751 assert_true(Tests.list isnot [])
8752 assert_true([] isnot Tests.list)
8753 assert_equal(2, Tests.four >> 1)
8754 assert_equal(16, 1 << Tests.four)
8755 assert_equal(8, Tests.four + four)
8756 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008757 assert_equal('hellohello', Tests.str .. str)
8758 assert_equal('hellohello', str .. Tests.str)
8759
8760 # Using class variable for list indexing
8761 var l = range(10)
8762 assert_equal(4, l[Tests.four])
8763 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8764
8765 # Using class variable for Dict key
8766 var d = {hello: 'abc'}
8767 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008768 enddef
8769 endclass
8770
8771 def TestOps2()
8772 assert_true(Tests.truthy == Tests.Truthy())
8773 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008774 assert_true(Tests.truthy == Tests.TruthyFn())
8775 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008776 assert_true(Tests.list is Tests.List())
8777 assert_true(Tests.List() is Tests.list)
8778 assert_equal(2, Tests.four >> 1)
8779 assert_equal(16, 1 << Tests.four)
8780 assert_equal(8, Tests.four + Tests.Four())
8781 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008782 assert_equal('hellohello', Tests.str .. Tests.Str())
8783 assert_equal('hellohello', Tests.Str() .. Tests.str)
8784
8785 # Using class variable for list indexing
8786 var l = range(10)
8787 assert_equal(4, l[Tests.four])
8788 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8789
8790 # Using class variable for Dict key
8791 var d = {hello: 'abc'}
8792 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008793 enddef
8794
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008795 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008796 var t = Tests.new()
8797 t.TestOps()
8798 TestOps2()
8799
8800 assert_true(Tests.truthy == Tests.Truthy())
8801 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008802 assert_true(Tests.truthy == Tests.TruthyFn())
8803 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008804 assert_true(Tests.list is Tests.List())
8805 assert_true(Tests.List() is Tests.list)
8806 assert_equal(2, Tests.four >> 1)
8807 assert_equal(16, 1 << Tests.four)
8808 assert_equal(8, Tests.four + Tests.Four())
8809 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008810 assert_equal('hellohello', Tests.str .. Tests.Str())
8811 assert_equal('hellohello', Tests.Str() .. Tests.str)
8812
8813 # Using class variable for list indexing
8814 var l = range(10)
8815 assert_equal(4, l[Tests.four])
8816 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8817
8818 # Using class variable for Dict key
8819 var d = {hello: 'abc'}
8820 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008821 END
8822 v9.CheckSourceSuccess(lines)
8823enddef
8824
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008825" Test for checking the type of the key used to access an object dict member.
8826def Test_dict_member_key_type_check()
8827 var lines =<< trim END
8828 vim9script
8829
8830 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01008831 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008832 endclass
8833
8834 class Test extends State
8835 def ObjMethodTests()
8836 var cursor: number = 0
8837 var z: number = 0
8838 [this.numbers[cursor]] = ['zero.1']
8839 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8840 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8841 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8842 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8843 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8844 [this.numbers[cursor], z] = ['zero.4', 1]
8845 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8846 [z, this.numbers[cursor]] = [1, 'zero.5']
8847 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8848 enddef
8849
8850 static def ClassMethodTests(that: State)
8851 var cursor: number = 0
8852 var z: number = 0
8853 [that.numbers[cursor]] = ['zero.1']
8854 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8855 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8856 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8857 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8858 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8859 [that.numbers[cursor], z] = ['zero.4', 1]
8860 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8861 [z, that.numbers[cursor]] = [1, 'zero.5']
8862 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8863 enddef
8864
8865 def new()
8866 enddef
8867
8868 def newMethodTests()
8869 var cursor: number = 0
8870 var z: number
8871 [this.numbers[cursor]] = ['zero.1']
8872 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8873 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8874 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8875 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8876 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8877 [this.numbers[cursor], z] = ['zero.4', 1]
8878 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8879 [z, this.numbers[cursor]] = [1, 'zero.5']
8880 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8881 enddef
8882 endclass
8883
8884 def DefFuncTests(that: Test)
8885 var cursor: number = 0
8886 var z: number
8887 [that.numbers[cursor]] = ['zero.1']
8888 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8889 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8890 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8891 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8892 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8893 [that.numbers[cursor], z] = ['zero.4', 1]
8894 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8895 [z, that.numbers[cursor]] = [1, 'zero.5']
8896 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8897 enddef
8898
8899 Test.newMethodTests()
8900 Test.new().ObjMethodTests()
8901 Test.ClassMethodTests(Test.new())
8902 DefFuncTests(Test.new())
8903
8904 const test: Test = Test.new()
8905 var cursor: number = 0
8906 [test.numbers[cursor], cursor] = ['zero', 1]
8907 [cursor, test.numbers[cursor]] = [1, 'one']
8908 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8909 END
8910 v9.CheckSourceSuccess(lines)
8911
8912 lines =<< trim END
8913 vim9script
8914
8915 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008916 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008917
8918 def new()
8919 enddef
8920
8921 def Foo()
8922 var z: number
8923 [this.numbers.a, z] = [{}, 10]
8924 enddef
8925 endclass
8926
8927 var a = A.new()
8928 a.Foo()
8929 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008930 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008931
8932 lines =<< trim END
8933 vim9script
8934
8935 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008936 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008937
8938 def new()
8939 enddef
8940
8941 def Foo()
8942 var x: string = 'a'
8943 var y: number
8944 [this.numbers[x], y] = [{}, 10]
8945 enddef
8946 endclass
8947
8948 var a = A.new()
8949 a.Foo()
8950 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008951 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008952enddef
8953
mityua5550692023-11-25 15:41:20 +01008954def Test_compile_many_def_functions_in_funcref_instr()
8955 # This used to crash Vim. This is reproducible only when run on new instance
8956 # of Vim.
8957 var lines =<< trim END
8958 vim9script
8959
8960 class A
8961 def new()
8962 this.TakeFunc(this.F00)
8963 enddef
8964
8965 def TakeFunc(F: func)
8966 enddef
8967
8968 def F00()
8969 this.F01()
8970 this.F02()
8971 this.F03()
8972 this.F04()
8973 this.F05()
8974 this.F06()
8975 this.F07()
8976 this.F08()
8977 this.F09()
8978 this.F10()
8979 this.F11()
8980 this.F12()
8981 this.F13()
8982 this.F14()
8983 this.F15()
8984 this.F16()
8985 this.F17()
8986 this.F18()
8987 this.F19()
8988 this.F20()
8989 this.F21()
8990 this.F22()
8991 this.F23()
8992 this.F24()
8993 this.F25()
8994 this.F26()
8995 this.F27()
8996 this.F28()
8997 this.F29()
8998 this.F30()
8999 this.F31()
9000 this.F32()
9001 this.F33()
9002 this.F34()
9003 this.F35()
9004 this.F36()
9005 this.F37()
9006 this.F38()
9007 this.F39()
9008 this.F40()
9009 this.F41()
9010 this.F42()
9011 this.F43()
9012 this.F44()
9013 this.F45()
9014 this.F46()
9015 this.F47()
9016 enddef
9017
9018 def F01()
9019 enddef
9020 def F02()
9021 enddef
9022 def F03()
9023 enddef
9024 def F04()
9025 enddef
9026 def F05()
9027 enddef
9028 def F06()
9029 enddef
9030 def F07()
9031 enddef
9032 def F08()
9033 enddef
9034 def F09()
9035 enddef
9036 def F10()
9037 enddef
9038 def F11()
9039 enddef
9040 def F12()
9041 enddef
9042 def F13()
9043 enddef
9044 def F14()
9045 enddef
9046 def F15()
9047 enddef
9048 def F16()
9049 enddef
9050 def F17()
9051 enddef
9052 def F18()
9053 enddef
9054 def F19()
9055 enddef
9056 def F20()
9057 enddef
9058 def F21()
9059 enddef
9060 def F22()
9061 enddef
9062 def F23()
9063 enddef
9064 def F24()
9065 enddef
9066 def F25()
9067 enddef
9068 def F26()
9069 enddef
9070 def F27()
9071 enddef
9072 def F28()
9073 enddef
9074 def F29()
9075 enddef
9076 def F30()
9077 enddef
9078 def F31()
9079 enddef
9080 def F32()
9081 enddef
9082 def F33()
9083 enddef
9084 def F34()
9085 enddef
9086 def F35()
9087 enddef
9088 def F36()
9089 enddef
9090 def F37()
9091 enddef
9092 def F38()
9093 enddef
9094 def F39()
9095 enddef
9096 def F40()
9097 enddef
9098 def F41()
9099 enddef
9100 def F42()
9101 enddef
9102 def F43()
9103 enddef
9104 def F44()
9105 enddef
9106 def F45()
9107 enddef
9108 def F46()
9109 enddef
9110 def F47()
9111 enddef
9112 endclass
9113
9114 A.new()
9115 END
9116 writefile(lines, 'Xscript', 'D')
9117 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9118 assert_equal(0, v:shell_error)
9119enddef
9120
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009121" Test for 'final' class and object variables
9122def Test_final_class_object_variable()
9123 # Test for changing a final object variable from an object function
9124 var lines =<< trim END
9125 vim9script
9126 class A
9127 final foo: string = "abc"
9128 def Foo()
9129 this.foo = "def"
9130 enddef
9131 endclass
9132 defcompile A.Foo
9133 END
9134 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9135
9136 # Test for changing a final object variable from the 'new' function
9137 lines =<< trim END
9138 vim9script
9139 class A
9140 final s1: string
9141 final s2: string
9142 def new(this.s1)
9143 this.s2 = 'def'
9144 enddef
9145 endclass
9146 var a = A.new('abc')
9147 assert_equal('abc', a.s1)
9148 assert_equal('def', a.s2)
9149 END
9150 v9.CheckSourceSuccess(lines)
9151
9152 # Test for a final class variable
9153 lines =<< trim END
9154 vim9script
9155 class A
9156 static final s1: string = "abc"
9157 endclass
9158 assert_equal('abc', A.s1)
9159 END
9160 v9.CheckSourceSuccess(lines)
9161
9162 # Test for changing a final class variable from a class function
9163 lines =<< trim END
9164 vim9script
9165 class A
9166 static final s1: string = "abc"
9167 static def Foo()
9168 s1 = "def"
9169 enddef
9170 endclass
9171 A.Foo()
9172 END
9173 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9174
9175 # Test for changing a public final class variable at script level
9176 lines =<< trim END
9177 vim9script
9178 class A
9179 public static final s1: string = "abc"
9180 endclass
9181 assert_equal('abc', A.s1)
9182 A.s1 = 'def'
9183 END
9184 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9185
9186 # Test for changing a public final class variable from a class function
9187 lines =<< trim END
9188 vim9script
9189 class A
9190 public static final s1: string = "abc"
9191 static def Foo()
9192 s1 = "def"
9193 enddef
9194 endclass
9195 A.Foo()
9196 END
9197 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9198
9199 # Test for changing a public final class variable from a function
9200 lines =<< trim END
9201 vim9script
9202 class A
9203 public static final s1: string = "abc"
9204 endclass
9205 def Foo()
9206 A.s1 = 'def'
9207 enddef
9208 defcompile
9209 END
9210 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9211
9212 # Test for using a final variable of composite type
9213 lines =<< trim END
9214 vim9script
9215 class A
9216 public final l: list<number>
9217 def new()
9218 this.l = [1, 2]
9219 enddef
9220 def Foo()
9221 this.l[0] = 3
9222 this.l->add(4)
9223 enddef
9224 endclass
9225 var a = A.new()
9226 assert_equal([1, 2], a.l)
9227 a.Foo()
9228 assert_equal([3, 2, 4], a.l)
9229 END
9230 v9.CheckSourceSuccess(lines)
9231
9232 # Test for changing a final variable of composite type from another object
9233 # function
9234 lines =<< trim END
9235 vim9script
9236 class A
9237 public final l: list<number> = [1, 2]
9238 def Foo()
9239 this.l = [3, 4]
9240 enddef
9241 endclass
9242 var a = A.new()
9243 a.Foo()
9244 END
9245 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9246
9247 # Test for modifying a final variable of composite type at script level
9248 lines =<< trim END
9249 vim9script
9250 class A
9251 public final l: list<number> = [1, 2]
9252 endclass
9253 var a = A.new()
9254 a.l[0] = 3
9255 a.l->add(4)
9256 assert_equal([3, 2, 4], a.l)
9257 END
9258 v9.CheckSourceSuccess(lines)
9259
9260 # Test for modifying a final variable of composite type from a function
9261 lines =<< trim END
9262 vim9script
9263 class A
9264 public final l: list<number> = [1, 2]
9265 endclass
9266 def Foo()
9267 var a = A.new()
9268 a.l[0] = 3
9269 a.l->add(4)
9270 assert_equal([3, 2, 4], a.l)
9271 enddef
9272 Foo()
9273 END
9274 v9.CheckSourceSuccess(lines)
9275
9276 # Test for modifying a final variable of composite type from another object
9277 # function
9278 lines =<< trim END
9279 vim9script
9280 class A
9281 public final l: list<number> = [1, 2]
9282 def Foo()
9283 this.l[0] = 3
9284 this.l->add(4)
9285 enddef
9286 endclass
9287 var a = A.new()
9288 a.Foo()
9289 assert_equal([3, 2, 4], a.l)
9290 END
9291 v9.CheckSourceSuccess(lines)
9292
9293 # Test for assigning a new value to a final variable of composite type at
9294 # script level
9295 lines =<< trim END
9296 vim9script
9297 class A
9298 public final l: list<number> = [1, 2]
9299 endclass
9300 var a = A.new()
9301 a.l = [3, 4]
9302 END
9303 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9304
9305 # Test for assigning a new value to a final variable of composite type from
9306 # another object function
9307 lines =<< trim END
9308 vim9script
9309 class A
9310 public final l: list<number> = [1, 2]
9311 def Foo()
9312 this.l = [3, 4]
9313 enddef
9314 endclass
9315 var a = A.new()
9316 a.Foo()
9317 END
9318 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9319
9320 # Test for assigning a new value to a final variable of composite type from
9321 # another function
9322 lines =<< trim END
9323 vim9script
9324 class A
9325 public final l: list<number> = [1, 2]
9326 endclass
9327 def Foo()
9328 var a = A.new()
9329 a.l = [3, 4]
9330 enddef
9331 Foo()
9332 END
9333 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9334
9335 # Error case: Use 'final' with just a variable name
9336 lines =<< trim END
9337 vim9script
9338 class A
9339 final foo
9340 endclass
9341 var a = A.new()
9342 END
9343 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9344
9345 # Error case: Use 'final' followed by 'public'
9346 lines =<< trim END
9347 vim9script
9348 class A
9349 final public foo: number
9350 endclass
9351 var a = A.new()
9352 END
9353 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9354
9355 # Error case: Use 'final' followed by 'static'
9356 lines =<< trim END
9357 vim9script
9358 class A
9359 final static foo: number
9360 endclass
9361 var a = A.new()
9362 END
9363 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9364
9365 # Error case: 'final' cannot be used in an interface
9366 lines =<< trim END
9367 vim9script
9368 interface A
9369 final foo: number = 10
9370 endinterface
9371 END
9372 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9373
9374 # Error case: 'final' not supported for an object method
9375 lines =<< trim END
9376 vim9script
9377 class A
9378 final def Foo()
9379 enddef
9380 endclass
9381 END
9382 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9383
9384 # Error case: 'final' not supported for a class method
9385 lines =<< trim END
9386 vim9script
9387 class A
9388 static final def Foo()
9389 enddef
9390 endclass
9391 END
9392 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9393enddef
9394
9395" Test for 'const' class and object variables
9396def Test_const_class_object_variable()
9397 # Test for changing a const object variable from an object function
9398 var lines =<< trim END
9399 vim9script
9400 class A
9401 const foo: string = "abc"
9402 def Foo()
9403 this.foo = "def"
9404 enddef
9405 endclass
9406 defcompile A.Foo
9407 END
9408 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9409
9410 # Test for changing a const object variable from the 'new' function
9411 lines =<< trim END
9412 vim9script
9413 class A
9414 const s1: string
9415 const s2: string
9416 def new(this.s1)
9417 this.s2 = 'def'
9418 enddef
9419 endclass
9420 var a = A.new('abc')
9421 assert_equal('abc', a.s1)
9422 assert_equal('def', a.s2)
9423 END
9424 v9.CheckSourceSuccess(lines)
9425
9426 # Test for changing a const object variable from an object method called from
9427 # the 'new' function
9428 lines =<< trim END
9429 vim9script
9430 class A
9431 const s1: string = 'abc'
9432 def new()
9433 this.ChangeStr()
9434 enddef
9435 def ChangeStr()
9436 this.s1 = 'def'
9437 enddef
9438 endclass
9439 var a = A.new()
9440 END
9441 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9442
9443 # Test for a const class variable
9444 lines =<< trim END
9445 vim9script
9446 class A
9447 static const s1: string = "abc"
9448 endclass
9449 assert_equal('abc', A.s1)
9450 END
9451 v9.CheckSourceSuccess(lines)
9452
9453 # Test for changing a const class variable from a class function
9454 lines =<< trim END
9455 vim9script
9456 class A
9457 static const s1: string = "abc"
9458 static def Foo()
9459 s1 = "def"
9460 enddef
9461 endclass
9462 A.Foo()
9463 END
9464 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9465
9466 # Test for changing a public const class variable at script level
9467 lines =<< trim END
9468 vim9script
9469 class A
9470 public static const s1: string = "abc"
9471 endclass
9472 assert_equal('abc', A.s1)
9473 A.s1 = 'def'
9474 END
9475 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9476
9477 # Test for changing a public const class variable from a class function
9478 lines =<< trim END
9479 vim9script
9480 class A
9481 public static const s1: string = "abc"
9482 static def Foo()
9483 s1 = "def"
9484 enddef
9485 endclass
9486 A.Foo()
9487 END
9488 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9489
9490 # Test for changing a public const class variable from a function
9491 lines =<< trim END
9492 vim9script
9493 class A
9494 public static const s1: string = "abc"
9495 endclass
9496 def Foo()
9497 A.s1 = 'def'
9498 enddef
9499 defcompile
9500 END
9501 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9502
9503 # Test for changing a const List item from an object function
9504 lines =<< trim END
9505 vim9script
9506 class A
9507 public const l: list<number>
9508 def new()
9509 this.l = [1, 2]
9510 enddef
9511 def Foo()
9512 this.l[0] = 3
9513 enddef
9514 endclass
9515 var a = A.new()
9516 assert_equal([1, 2], a.l)
9517 a.Foo()
9518 END
9519 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9520
9521 # Test for adding a value to a const List from an object function
9522 lines =<< trim END
9523 vim9script
9524 class A
9525 public const l: list<number>
9526 def new()
9527 this.l = [1, 2]
9528 enddef
9529 def Foo()
9530 this.l->add(3)
9531 enddef
9532 endclass
9533 var a = A.new()
9534 a.Foo()
9535 END
9536 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9537
9538 # Test for reassigning a const List from an object function
9539 lines =<< trim END
9540 vim9script
9541 class A
9542 public const l: list<number> = [1, 2]
9543 def Foo()
9544 this.l = [3, 4]
9545 enddef
9546 endclass
9547 var a = A.new()
9548 a.Foo()
9549 END
9550 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9551
9552 # Test for changing a const List item at script level
9553 lines =<< trim END
9554 vim9script
9555 class A
9556 public const l: list<number> = [1, 2]
9557 endclass
9558 var a = A.new()
9559 a.l[0] = 3
9560 END
9561 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9562
9563 # Test for adding a value to a const List item at script level
9564 lines =<< trim END
9565 vim9script
9566 class A
9567 public const l: list<number> = [1, 2]
9568 endclass
9569 var a = A.new()
9570 a.l->add(4)
9571 END
9572 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9573
9574 # Test for changing a const List item from a function
9575 lines =<< trim END
9576 vim9script
9577 class A
9578 public const l: list<number> = [1, 2]
9579 endclass
9580 def Foo()
9581 var a = A.new()
9582 a.l[0] = 3
9583 enddef
9584 Foo()
9585 END
9586 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9587
9588 # Test for adding a value to a const List item from a function
9589 lines =<< trim END
9590 vim9script
9591 class A
9592 public const l: list<number> = [1, 2]
9593 endclass
9594 def Foo()
9595 var a = A.new()
9596 a.l->add(4)
9597 enddef
9598 Foo()
9599 END
9600 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9601
9602 # Test for changing a const List item from an object method
9603 lines =<< trim END
9604 vim9script
9605 class A
9606 public const l: list<number> = [1, 2]
9607 def Foo()
9608 this.l[0] = 3
9609 enddef
9610 endclass
9611 var a = A.new()
9612 a.Foo()
9613 END
9614 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9615
9616 # Test for adding a value to a const List item from an object method
9617 lines =<< trim END
9618 vim9script
9619 class A
9620 public const l: list<number> = [1, 2]
9621 def Foo()
9622 this.l->add(4)
9623 enddef
9624 endclass
9625 var a = A.new()
9626 a.Foo()
9627 END
9628 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9629
9630 # Test for reassigning a const List object variable at script level
9631 lines =<< trim END
9632 vim9script
9633 class A
9634 public const l: list<number> = [1, 2]
9635 endclass
9636 var a = A.new()
9637 a.l = [3, 4]
9638 END
9639 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9640
9641 # Test for reassigning a const List object variable from an object method
9642 lines =<< trim END
9643 vim9script
9644 class A
9645 public const l: list<number> = [1, 2]
9646 def Foo()
9647 this.l = [3, 4]
9648 enddef
9649 endclass
9650 var a = A.new()
9651 a.Foo()
9652 END
9653 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9654
9655 # Test for reassigning a const List object variable from another function
9656 lines =<< trim END
9657 vim9script
9658 class A
9659 public const l: list<number> = [1, 2]
9660 endclass
9661 def Foo()
9662 var a = A.new()
9663 a.l = [3, 4]
9664 enddef
9665 Foo()
9666 END
9667 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9668
9669 # Error case: Use 'const' with just a variable name
9670 lines =<< trim END
9671 vim9script
9672 class A
9673 const foo
9674 endclass
9675 var a = A.new()
9676 END
9677 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9678
9679 # Error case: Use 'const' followed by 'public'
9680 lines =<< trim END
9681 vim9script
9682 class A
9683 const public foo: number
9684 endclass
9685 var a = A.new()
9686 END
9687 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9688
9689 # Error case: Use 'const' followed by 'static'
9690 lines =<< trim END
9691 vim9script
9692 class A
9693 const static foo: number
9694 endclass
9695 var a = A.new()
9696 END
9697 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9698
9699 # Error case: 'const' cannot be used in an interface
9700 lines =<< trim END
9701 vim9script
9702 interface A
9703 const foo: number = 10
9704 endinterface
9705 END
9706 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9707
9708 # Error case: 'const' not supported for an object method
9709 lines =<< trim END
9710 vim9script
9711 class A
9712 const def Foo()
9713 enddef
9714 endclass
9715 END
9716 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9717
9718 # Error case: 'const' not supported for a class method
9719 lines =<< trim END
9720 vim9script
9721 class A
9722 static const def Foo()
9723 enddef
9724 endclass
9725 END
9726 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9727enddef
9728
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009729" Test for compiling class/object methods using :defcompile
9730def Test_defcompile_class()
9731 # defcompile all the classes in the current script
9732 var lines =<< trim END
9733 vim9script
9734 class A
9735 def Foo()
9736 var i = 10
9737 enddef
9738 endclass
9739 class B
9740 def Bar()
9741 var i = 20
9742 xxx
9743 enddef
9744 endclass
9745 defcompile
9746 END
9747 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9748
9749 # defcompile a specific class
9750 lines =<< trim END
9751 vim9script
9752 class A
9753 def Foo()
9754 xxx
9755 enddef
9756 endclass
9757 class B
9758 def Bar()
9759 yyy
9760 enddef
9761 endclass
9762 defcompile B
9763 END
9764 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9765
9766 # defcompile a non-class
9767 lines =<< trim END
9768 vim9script
9769 class A
9770 def Foo()
9771 enddef
9772 endclass
9773 var X: list<number> = []
9774 defcompile X
9775 END
9776 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9777
9778 # defcompile a class twice
9779 lines =<< trim END
9780 vim9script
9781 class A
9782 def new()
9783 enddef
9784 endclass
9785 defcompile A
9786 defcompile A
9787 assert_equal('Function A.new does not need compiling', v:statusmsg)
9788 END
9789 v9.CheckSourceSuccess(lines)
9790
9791 # defcompile should not compile an imported class
9792 lines =<< trim END
9793 vim9script
9794 export class A
9795 def Foo()
9796 xxx
9797 enddef
9798 endclass
9799 END
9800 writefile(lines, 'Xdefcompileimport.vim', 'D')
9801 lines =<< trim END
9802 vim9script
9803
9804 import './Xdefcompileimport.vim'
9805 class B
9806 endclass
9807 defcompile
9808 END
9809 v9.CheckScriptSuccess(lines)
9810enddef
9811
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +01009812" Test for cases common to all the object builtin methods
9813def Test_object_builtin_method()
9814 var lines =<< trim END
9815 vim9script
9816 class A
9817 def abc()
9818 enddef
9819 endclass
9820 END
9821 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
9822
9823 for funcname in ["len", "string", "empty"]
9824 lines =<< trim eval END
9825 vim9script
9826 class A
9827 static def {funcname}(): number
9828 enddef
9829 endclass
9830 END
9831 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
9832 endfor
9833enddef
9834
9835" Test for using the empty() builtin method with an object
9836" This is a legacy function to use the test_garbagecollect_now() function.
9837func Test_object_empty()
9838 let lines =<< trim END
9839 vim9script
9840 class A
9841 def empty(): bool
9842 return true
9843 enddef
9844 endclass
9845
9846 def Foo()
9847 var afoo = A.new()
9848 assert_equal(true, empty(afoo))
9849 assert_equal(true, afoo->empty())
9850 enddef
9851
9852 var a = A.new()
9853 assert_equal(1, empty(a))
9854 assert_equal(1, a->empty())
9855 test_garbagecollect_now()
9856 assert_equal(1, empty(a))
9857 Foo()
9858 test_garbagecollect_now()
9859 Foo()
9860 END
9861 call v9.CheckSourceSuccess(lines)
9862
9863 " empty() should return 1 without a builtin method
9864 let lines =<< trim END
9865 vim9script
9866 class A
9867 endclass
9868
9869 def Foo()
9870 var afoo = A.new()
9871 assert_equal(1, empty(afoo))
9872 enddef
9873
9874 var a = A.new()
9875 assert_equal(1, empty(a))
9876 Foo()
9877 END
9878 call v9.CheckSourceSuccess(lines)
9879
9880 " Unsupported signature for the empty() method
9881 let lines =<< trim END
9882 vim9script
9883 class A
9884 def empty()
9885 enddef
9886 endclass
9887 END
9888 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
9889
9890 " Error when calling the empty() method
9891 let lines =<< trim END
9892 vim9script
9893 class A
9894 def empty(): bool
9895 throw "Failed to check emptiness"
9896 enddef
9897 endclass
9898
9899 def Foo()
9900 var afoo = A.new()
9901 var i = empty(afoo)
9902 enddef
9903
9904 var a = A.new()
9905 assert_fails('empty(a)', 'Failed to check emptiness')
9906 assert_fails('Foo()', 'Failed to check emptiness')
9907 END
9908 call v9.CheckSourceSuccess(lines)
9909
9910 " call empty() using an object from a script
9911 let lines =<< trim END
9912 vim9script
9913 class A
9914 def empty(): bool
9915 return true
9916 enddef
9917 endclass
9918 var afoo = A.new()
9919 assert_equal(true, afoo.empty())
9920 END
9921 call v9.CheckSourceSuccess(lines)
9922
9923 " call empty() using an object from a method
9924 let lines =<< trim END
9925 vim9script
9926 class A
9927 def empty(): bool
9928 return true
9929 enddef
9930 endclass
9931 def Foo()
9932 var afoo = A.new()
9933 assert_equal(true, afoo.empty())
9934 enddef
9935 Foo()
9936 END
9937 call v9.CheckSourceSuccess(lines)
9938
9939 " call empty() using "this" from an object method
9940 let lines =<< trim END
9941 vim9script
9942 class A
9943 def empty(): bool
9944 return true
9945 enddef
9946 def Foo(): bool
9947 return this.empty()
9948 enddef
9949 endclass
9950 def Bar()
9951 var abar = A.new()
9952 assert_equal(true, abar.Foo())
9953 enddef
9954 Bar()
9955 END
9956 call v9.CheckSourceSuccess(lines)
9957
9958 " Call empty() from a derived object
9959 let lines =<< trim END
9960 vim9script
9961 class A
9962 def empty(): bool
9963 return false
9964 enddef
9965 endclass
9966 class B extends A
9967 def empty(): bool
9968 return true
9969 enddef
9970 endclass
9971 def Foo(afoo: A)
9972 assert_equal(true, empty(afoo))
9973 var bfoo = B.new()
9974 assert_equal(true, empty(bfoo))
9975 enddef
9976 var b = B.new()
9977 assert_equal(1, empty(b))
9978 Foo(b)
9979 END
9980 call v9.CheckSourceSuccess(lines)
9981
9982 " Invoking empty method using an interface
9983 let lines =<< trim END
9984 vim9script
9985 interface A
9986 def empty(): bool
9987 endinterface
9988 class B implements A
9989 def empty(): bool
9990 return false
9991 enddef
9992 endclass
9993 def Foo(a: A)
9994 assert_equal(false, empty(a))
9995 enddef
9996 var b = B.new()
9997 Foo(b)
9998 END
9999 call v9.CheckSourceSuccess(lines)
10000endfunc
10001
10002" Test for using the len() builtin method with an object
10003" This is a legacy function to use the test_garbagecollect_now() function.
10004func Test_object_length()
10005 let lines =<< trim END
10006 vim9script
10007 class A
10008 var mylen: number = 0
10009 def new(n: number)
10010 this.mylen = n
10011 enddef
10012 def len(): number
10013 return this.mylen
10014 enddef
10015 endclass
10016
10017 def Foo()
10018 var afoo = A.new(12)
10019 assert_equal(12, len(afoo))
10020 assert_equal(12, afoo->len())
10021 enddef
10022
10023 var a = A.new(22)
10024 assert_equal(22, len(a))
10025 assert_equal(22, a->len())
10026 test_garbagecollect_now()
10027 assert_equal(22, len(a))
10028 Foo()
10029 test_garbagecollect_now()
10030 Foo()
10031 END
10032 call v9.CheckSourceSuccess(lines)
10033
10034 " len() should return 0 without a builtin method
10035 let lines =<< trim END
10036 vim9script
10037 class A
10038 endclass
10039
10040 def Foo()
10041 var afoo = A.new()
10042 assert_equal(0, len(afoo))
10043 enddef
10044
10045 var a = A.new()
10046 assert_equal(0, len(a))
10047 Foo()
10048 END
10049 call v9.CheckSourceSuccess(lines)
10050
10051 " Unsupported signature for the len() method
10052 let lines =<< trim END
10053 vim9script
10054 class A
10055 def len()
10056 enddef
10057 endclass
10058 END
10059 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10060
10061 " Error when calling the len() method
10062 let lines =<< trim END
10063 vim9script
10064 class A
10065 def len(): number
10066 throw "Failed to compute length"
10067 enddef
10068 endclass
10069
10070 def Foo()
10071 var afoo = A.new()
10072 var i = len(afoo)
10073 enddef
10074
10075 var a = A.new()
10076 assert_fails('len(a)', 'Failed to compute length')
10077 assert_fails('Foo()', 'Failed to compute length')
10078 END
10079 call v9.CheckSourceSuccess(lines)
10080
10081 " call len() using an object from a script
10082 let lines =<< trim END
10083 vim9script
10084 class A
10085 def len(): number
10086 return 5
10087 enddef
10088 endclass
10089 var afoo = A.new()
10090 assert_equal(5, afoo.len())
10091 END
10092 call v9.CheckSourceSuccess(lines)
10093
10094 " call len() using an object from a method
10095 let lines =<< trim END
10096 vim9script
10097 class A
10098 def len(): number
10099 return 5
10100 enddef
10101 endclass
10102 def Foo()
10103 var afoo = A.new()
10104 assert_equal(5, afoo.len())
10105 enddef
10106 Foo()
10107 END
10108 call v9.CheckSourceSuccess(lines)
10109
10110 " call len() using "this" from an object method
10111 let lines =<< trim END
10112 vim9script
10113 class A
10114 def len(): number
10115 return 8
10116 enddef
10117 def Foo(): number
10118 return this.len()
10119 enddef
10120 endclass
10121 def Bar()
10122 var abar = A.new()
10123 assert_equal(8, abar.Foo())
10124 enddef
10125 Bar()
10126 END
10127 call v9.CheckSourceSuccess(lines)
10128
10129 " Call len() from a derived object
10130 let lines =<< trim END
10131 vim9script
10132 class A
10133 def len(): number
10134 return 10
10135 enddef
10136 endclass
10137 class B extends A
10138 def len(): number
10139 return 20
10140 enddef
10141 endclass
10142 def Foo(afoo: A)
10143 assert_equal(20, len(afoo))
10144 var bfoo = B.new()
10145 assert_equal(20, len(bfoo))
10146 enddef
10147 var b = B.new()
10148 assert_equal(20, len(b))
10149 Foo(b)
10150 END
10151 call v9.CheckSourceSuccess(lines)
10152
10153 " Invoking len method using an interface
10154 let lines =<< trim END
10155 vim9script
10156 interface A
10157 def len(): number
10158 endinterface
10159 class B implements A
10160 def len(): number
10161 return 123
10162 enddef
10163 endclass
10164 def Foo(a: A)
10165 assert_equal(123, len(a))
10166 enddef
10167 var b = B.new()
10168 Foo(b)
10169 END
10170 call v9.CheckSourceSuccess(lines)
10171endfunc
10172
10173" Test for using the string() builtin method with an object
10174" This is a legacy function to use the test_garbagecollect_now() function.
10175func Test_object_string()
10176 let lines =<< trim END
10177 vim9script
10178 class A
10179 var name: string
10180 def string(): string
10181 return this.name
10182 enddef
10183 endclass
10184
10185 def Foo()
10186 var afoo = A.new("foo-A")
10187 assert_equal('foo-A', string(afoo))
10188 assert_equal('foo-A', afoo->string())
10189 enddef
10190
10191 var a = A.new("script-A")
10192 assert_equal('script-A', string(a))
10193 assert_equal('script-A', a->string())
10194 assert_equal(['script-A'], execute('echo a')->split("\n"))
10195 test_garbagecollect_now()
10196 assert_equal('script-A', string(a))
10197 Foo()
10198 test_garbagecollect_now()
10199 Foo()
10200 END
10201 call v9.CheckSourceSuccess(lines)
10202
10203 " string() should return "object of A {}" without a builtin method
10204 let lines =<< trim END
10205 vim9script
10206 class A
10207 endclass
10208
10209 def Foo()
10210 var afoo = A.new()
10211 assert_equal('object of A {}', string(afoo))
10212 enddef
10213
10214 var a = A.new()
10215 assert_equal('object of A {}', string(a))
10216 Foo()
10217 END
10218 call v9.CheckSourceSuccess(lines)
10219
10220 " Unsupported signature for the string() method
10221 let lines =<< trim END
10222 vim9script
10223 class A
10224 def string()
10225 enddef
10226 endclass
10227 END
10228 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10229
10230 " Error when calling the string() method
10231 let lines =<< trim END
10232 vim9script
10233 class A
10234 def string(): string
10235 throw "Failed to get text"
10236 enddef
10237 endclass
10238
10239 def Foo()
10240 var afoo = A.new()
10241 var i = string(afoo)
10242 enddef
10243
10244 var a = A.new()
10245 assert_fails('string(a)', 'Failed to get text')
10246 assert_fails('Foo()', 'Failed to get text')
10247 END
10248 call v9.CheckSourceSuccess(lines)
10249
10250 " call string() using an object from a script
10251 let lines =<< trim END
10252 vim9script
10253 class A
10254 def string(): string
10255 return 'A'
10256 enddef
10257 endclass
10258 var afoo = A.new()
10259 assert_equal('A', afoo.string())
10260 END
10261 call v9.CheckSourceSuccess(lines)
10262
10263 " call string() using an object from a method
10264 let lines =<< trim END
10265 vim9script
10266 class A
10267 def string(): string
10268 return 'A'
10269 enddef
10270 endclass
10271 def Foo()
10272 var afoo = A.new()
10273 assert_equal('A', afoo.string())
10274 enddef
10275 Foo()
10276 END
10277 call v9.CheckSourceSuccess(lines)
10278
10279 " call string() using "this" from an object method
10280 let lines =<< trim END
10281 vim9script
10282 class A
10283 def string(): string
10284 return 'A'
10285 enddef
10286 def Foo(): string
10287 return this.string()
10288 enddef
10289 endclass
10290 def Bar()
10291 var abar = A.new()
10292 assert_equal('A', abar.string())
10293 enddef
10294 Bar()
10295 END
10296 call v9.CheckSourceSuccess(lines)
10297
10298 " Call string() from a derived object
10299 let lines =<< trim END
10300 vim9script
10301 class A
10302 def string(): string
10303 return 'A'
10304 enddef
10305 endclass
10306 class B extends A
10307 def string(): string
10308 return 'B'
10309 enddef
10310 endclass
10311 def Foo(afoo: A)
10312 assert_equal('B', string(afoo))
10313 var bfoo = B.new()
10314 assert_equal('B', string(bfoo))
10315 enddef
10316 var b = B.new()
10317 assert_equal('B', string(b))
10318 Foo(b)
10319 END
10320 call v9.CheckSourceSuccess(lines)
10321
10322 " Invoking string method using an interface
10323 let lines =<< trim END
10324 vim9script
10325 interface A
10326 def string(): string
10327 endinterface
10328 class B implements A
10329 def string(): string
10330 return 'B'
10331 enddef
10332 endclass
10333 def Foo(a: A)
10334 assert_equal('B', string(a))
10335 enddef
10336 var b = B.new()
10337 Foo(b)
10338 END
10339 call v9.CheckSourceSuccess(lines)
10340endfunc
10341
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010342" Test for using a class in the class definition
10343def Test_Ref_Class_Within_Same_Class()
10344 var lines =<< trim END
10345 vim9script
10346 class A
10347 var n: number = 0
10348 def Equals(other: A): bool
10349 return this.n == other.n
10350 enddef
10351 endclass
10352
10353 var a1 = A.new(10)
10354 var a2 = A.new(10)
10355 var a3 = A.new(20)
10356 assert_equal(true, a1.Equals(a2))
10357 assert_equal(false, a2.Equals(a3))
10358 END
10359 v9.CheckScriptSuccess(lines)
10360
10361 lines =<< trim END
10362 vim9script
10363
10364 class Foo
10365 var num: number
10366 def Clone(): Foo
10367 return Foo.new(this.num)
10368 enddef
10369 endclass
10370
10371 var f1 = Foo.new(1)
10372
10373 def F()
10374 var f2: Foo = f1.Clone()
10375 assert_equal(false, f2 is f1)
10376 assert_equal(true, f2.num == f1.num)
10377 enddef
10378 F()
10379
10380 var f3: Foo = f1.Clone()
10381 assert_equal(false, f3 is f1)
10382 assert_equal(true, f3.num == f1.num)
10383 END
10384 v9.CheckScriptSuccess(lines)
10385
10386 # Test for trying to use a class to extend when defining the same class
10387 lines =<< trim END
10388 vim9script
10389 class A extends A
10390 endclass
10391 END
10392 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10393
10394 # Test for trying to use a class to implement when defining the same class
10395 lines =<< trim END
10396 vim9script
10397 class A implements A
10398 endclass
10399 END
10400 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10401enddef
10402
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010403" Test for using a compound operator from a lambda function in an object method
10404def Test_compound_op_in_objmethod_lambda()
10405 # Test using the "+=" operator
10406 var lines =<< trim END
10407 vim9script
10408 class A
10409 var n: number = 10
10410 def Foo()
10411 var Fn = () => {
10412 this.n += 1
10413 }
10414 Fn()
10415 enddef
10416 endclass
10417
10418 var a = A.new()
10419 a.Foo()
10420 assert_equal(11, a.n)
10421 END
10422 v9.CheckScriptSuccess(lines)
10423
10424 # Test using the "..=" operator
10425 lines =<< trim END
10426 vim9script
10427 class A
10428 var s: string = "a"
10429 def Foo()
10430 var Fn = () => {
10431 this.s ..= "a"
10432 }
10433 Fn()
10434 enddef
10435 endclass
10436
10437 var a = A.new()
10438 a.Foo()
10439 a.Foo()
10440 assert_equal("aaa", a.s)
10441 END
10442 v9.CheckScriptSuccess(lines)
10443enddef
10444
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010445" Test for using test_refcount() with a class and an object
10446def Test_class_object_refcount()
10447 var lines =<< trim END
10448 vim9script
10449 class A
10450 endclass
10451 var a: A = A.new()
10452 assert_equal(2, test_refcount(A))
10453 assert_equal(1, test_refcount(a))
10454 var b = a
10455 assert_equal(2, test_refcount(A))
10456 assert_equal(2, test_refcount(a))
10457 assert_equal(2, test_refcount(b))
10458 END
10459 v9.CheckScriptSuccess(lines)
10460enddef
10461
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010462" call a lambda function in one object from another object
10463def Test_lambda_invocation_across_classes()
10464 var lines =<< trim END
10465 vim9script
10466 class A
10467 var s: string = "foo"
10468 def GetFn(): func
10469 var Fn = (): string => {
10470 return this.s
10471 }
10472 return Fn
10473 enddef
10474 endclass
10475
10476 class B
10477 var s: string = "bar"
10478 def GetFn(): func
10479 var a = A.new()
10480 return a.GetFn()
10481 enddef
10482 endclass
10483
10484 var b = B.new()
10485 var Fn = b.GetFn()
10486 assert_equal("foo", Fn())
10487 END
10488 v9.CheckScriptSuccess(lines)
10489enddef
10490
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010491" Test for using a class member which is an object of the current class
10492def Test_current_class_object_class_member()
10493 var lines =<< trim END
10494 vim9script
10495 class A
10496 public static var obj1: A = A.new(10)
10497 var n: number
10498 endclass
10499 defcompile
10500 assert_equal(10, A.obj1.n)
10501 END
10502 v9.CheckScriptSuccess(lines)
10503enddef
10504
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020010505" Test for updating a base class variable from a base class method without the
10506" class name. This used to crash Vim (Github issue #14352).
10507def Test_use_base_class_variable_from_base_class_method()
10508 var lines =<< trim END
10509 vim9script
10510
10511 class DictKeyClass
10512 static var _obj_id_count = 1
10513 def _GenerateKey()
10514 _obj_id_count += 1
10515 enddef
10516 static def GetIdCount(): number
10517 return _obj_id_count
10518 enddef
10519 endclass
10520
10521 class C extends DictKeyClass
10522 def F()
10523 this._GenerateKey()
10524 enddef
10525 endclass
10526
10527 C.new().F()
10528 assert_equal(2, DictKeyClass.GetIdCount())
10529 END
10530 v9.CheckScriptSuccess(lines)
10531enddef
10532
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020010533" Test for accessing protected funcref object and class variables
10534def Test_protected_funcref()
10535 # protected funcref object variable
10536 var lines =<< trim END
10537 vim9script
10538 class Test1
10539 const _Id: func(any): any = (v) => v
10540 endclass
10541 var n = Test1.new()._Id(1)
10542 END
10543 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
10544
10545 # protected funcref class variable
10546 lines =<< trim END
10547 vim9script
10548 class Test2
10549 static const _Id: func(any): any = (v) => v
10550 endclass
10551 var n = Test2._Id(2)
10552 END
10553 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
10554enddef
10555
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020010556" Test for using lambda block in classes
10557def Test_lambda_block_in_class()
10558 # This used to crash Vim
10559 var lines =<< trim END
10560 vim9script
10561 class IdClass1
10562 const Id: func(number): number = (num: number): number => {
10563 # Return a ID
10564 return num * 10
10565 }
10566 endclass
10567 var id = IdClass1.new()
10568 assert_equal(20, id.Id(2))
10569 END
10570 v9.CheckScriptSuccess(lines)
10571
10572 # This used to crash Vim
10573 lines =<< trim END
10574 vim9script
10575 class IdClass2
10576 static const Id: func(number): number = (num: number): number => {
10577 # Return a ID
10578 return num * 2
10579 }
10580 endclass
10581 assert_equal(16, IdClass2.Id(8))
10582 END
10583 v9.CheckScriptSuccess(lines)
10584enddef
10585
Bram Moolenaar00b28d62022-12-08 15:32:33 +000010586" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker