blob: b34d2ad12c0e97a600522d6c52eb71b6c2c6ebb5 [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
Doug Kearns74da0ee2023-12-14 20:26:26 +010070 # Use old "this." prefixed member variable declaration syntax (without intialization)
71 lines =<< trim END
72 vim9script
73 class Something
74 this.count: number
75 endclass
76 END
77 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
78
79 # Use old "this." prefixed member variable declaration syntax (with intialization)
80 lines =<< trim END
81 vim9script
82 class Something
83 this.count: number = 42
84 endclass
85 END
86 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
87
88 # Use old "this." prefixed member variable declaration syntax (type inferred)
89 lines =<< trim END
90 vim9script
91 class Something
92 this.count = 42
93 endclass
94 END
95 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
96
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020097 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000098 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020099 vim9script
100 class Something
101 this
102 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000103 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100104 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000105
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200106 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000107 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200108 vim9script
109 class Something
110 this.
111 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000112 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100113 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000114
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200115 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000116 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200117 vim9script
118 class Something
119 this .count
120 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000121 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100122 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000123
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200124 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000125 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200126 vim9script
127 class Something
128 this. count
129 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000130 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100131 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000132
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200133 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000134 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200135 vim9script
136 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100137 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200138 that.count
139 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000140 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200141 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000142
Doug Kearns74da0ee2023-12-14 20:26:26 +0100143 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000144 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200145 vim9script
146 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100147 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200148 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000149 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100150 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
151
152 # Use "variable" instead of "var" for member variable declaration (with initialization)
153 lines =<< trim END
154 vim9script
155 class Something
156 variable count: number = 42
157 endclass
158 END
159 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
160
161 # Use "variable" instead of "var" for member variable declaration (type inferred)
162 lines =<< trim END
163 vim9script
164 class Something
165 variable count = 42
166 endclass
167 END
168 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000169
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200170 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000171 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200172 vim9script
173 class Something
174 def new()
175 this.state = 0
176 enddef
177 endclass
178 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000179 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200180 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000181
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200182 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000183 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200184 vim9script
185 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100186 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200187 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000188 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200189 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000190
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200191 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000192 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200193 vim9script
194 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100195 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200196 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000197 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200198 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000199
Doug Kearns74da0ee2023-12-14 20:26:26 +0100200 # Missing ":var" in a "var" member variable declaration (without initialization)
201 lines =<< trim END
202 vim9script
203 class Something
204 var: number
205 endclass
206 END
207 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
208
209 # Missing ":var" in a "var" member variable declaration (with initialization)
210 lines =<< trim END
211 vim9script
212 class Something
213 var: number = 42
214 endclass
215 END
216 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
217
218 # Missing ":var" in a "var" member variable declaration (type inferred)
219 lines =<< trim END
220 vim9script
221 class Something
222 var = 42
223 endclass
224 END
225 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
226
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200227 # Test for unsupported comment specifier
228 lines =<< trim END
229 vim9script
230 class Something
231 # comment
232 #{
233 endclass
234 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200235 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200236
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200237 # Test for using class as a bool
238 lines =<< trim END
239 vim9script
240 class A
241 endclass
242 if A
243 endif
244 END
Ernie Raele75fde62023-12-21 17:18:54 +0100245 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200246
247 # Test for using object as a bool
248 lines =<< trim END
249 vim9script
250 class A
251 endclass
252 var a = A.new()
253 if a
254 endif
255 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200256 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200257
258 # Test for using class as a float
259 lines =<< trim END
260 vim9script
261 class A
262 endclass
263 sort([1.1, A], 'f')
264 END
Ernie Raelfa831102023-12-14 20:06:39 +0100265 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200266
267 # Test for using object as a float
268 lines =<< trim END
269 vim9script
270 class A
271 endclass
272 var a = A.new()
273 sort([1.1, a], 'f')
274 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200275 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200276
277 # Test for using class as a string
278 lines =<< trim END
279 vim9script
280 class A
281 endclass
282 :exe 'call ' .. A
283 END
Ernie Raele75fde62023-12-21 17:18:54 +0100284 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200285
286 # Test for using object as a string
287 lines =<< trim END
288 vim9script
289 class A
290 endclass
291 var a = A.new()
292 :exe 'call ' .. a
293 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200294 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200295
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200296 # Test creating a class with member variables and methods, calling a object
297 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000298 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200299 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000300
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200301 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100302 var lnum: number
303 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000304
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200305 # make a nicely formatted string
306 def ToString(): string
307 return $'({this.lnum}, {this.col})'
308 enddef
309 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000310
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200311 # use the automatically generated new() method
312 var pos = TextPosition.new(2, 12)
313 assert_equal(2, pos.lnum)
314 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000315
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200316 # call an object method
317 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000318
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200319 assert_equal(v:t_class, type(TextPosition))
320 assert_equal(v:t_object, type(pos))
321 assert_equal('class<TextPosition>', typename(TextPosition))
322 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000323 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200324 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200325
326 # When referencing object methods, space cannot be used after a "."
327 lines =<< trim END
328 vim9script
329 class A
330 def Foo(): number
331 return 10
332 enddef
333 endclass
334 var a = A.new()
335 var v = a. Foo()
336 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200337 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200338
339 # Using an object without specifying a method or a member variable
340 lines =<< trim END
341 vim9script
342 class A
343 def Foo(): number
344 return 10
345 enddef
346 endclass
347 var a = A.new()
348 var v = a.
349 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200350 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200351
352 # Error when parsing the arguments of an object method.
353 lines =<< trim END
354 vim9script
355 class A
356 def Foo()
357 enddef
358 endclass
359 var a = A.new()
360 var v = a.Foo(,)
361 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200362 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200363
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200364 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200365 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200366 vim9script
367 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100368 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200369 X: 1
370 }
371 endclass
372 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200373 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200374 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000375enddef
376
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200377" Tests for object/class methods in a class
378def Test_class_def_method()
379 # Using the "public" keyword when defining an object method
380 var lines =<< trim END
381 vim9script
382 class A
383 public def Foo()
384 enddef
385 endclass
386 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100387 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200388
389 # Using the "public" keyword when defining a class method
390 lines =<< trim END
391 vim9script
392 class A
393 public static def Foo()
394 enddef
395 endclass
396 END
397 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
398
Ernie Rael03042a22023-11-11 08:53:32 +0100399 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200400 lines =<< trim END
401 vim9script
402 class A
403 public def _Foo()
404 enddef
405 endclass
406 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100407 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200408
Ernie Rael03042a22023-11-11 08:53:32 +0100409 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200410 lines =<< trim END
411 vim9script
412 class A
413 public static def _Foo()
414 enddef
415 endclass
416 END
417 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
418
419 # Using a "def" keyword without an object method name
420 lines =<< trim END
421 vim9script
422 class A
423 def
424 enddef
425 endclass
426 END
427 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
428
429 # Using a "def" keyword without a class method name
430 lines =<< trim END
431 vim9script
432 class A
433 static def
434 enddef
435 endclass
436 END
437 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
438enddef
439
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000440def Test_class_defined_twice()
441 # class defined twice should fail
442 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200443 vim9script
444 class There
445 endclass
446 class There
447 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000448 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200449 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000450
451 # one class, reload same script twice is OK
452 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200453 vim9script
454 class There
455 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000456 END
457 writefile(lines, 'XclassTwice.vim', 'D')
458 source XclassTwice.vim
459 source XclassTwice.vim
460enddef
461
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000462def Test_returning_null_object()
463 # this was causing an internal error
464 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200465 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000466
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200467 class BufferList
468 def Current(): any
469 return null_object
470 enddef
471 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000472
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200473 var buffers = BufferList.new()
474 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000475 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200476 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000477enddef
478
Bram Moolenaard13dd302023-03-11 20:56:35 +0000479def Test_using_null_class()
480 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200481 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000482 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200483 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Bram Moolenaard13dd302023-03-11 20:56:35 +0000484enddef
485
Bram Moolenaar657aea72023-01-27 13:16:19 +0000486def Test_class_interface_wrong_end()
487 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200488 vim9script
489 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100490 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200491 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000492 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200493 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000494
495 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200496 vim9script
497 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100498 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200499 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000500 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200501 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000502enddef
503
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000504def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200505 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000506 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200507 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000508
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200509 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100510 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200511 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000512
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200513 var state: State
514 var db = {'xyz': 789}
515 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000518
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200519 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000520 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200521 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000522
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200523 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100524 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200525 def Method1()
526 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000527 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200528 endclass
529
530 var obj: Class
531 def Func()
532 obj.Method1()
533 enddef
534 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000535 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200536 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000537
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200538 # Pass an uninitialized object variable to a "new" function and try to call an
539 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000540 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200541 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000542
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200543 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100544 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200545 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000546
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200547 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100548 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000549
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200550 def GetBackground(): string
551 return this._bg.background
552 enddef
553 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000554
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200555 var bg: Background # UNINITIALIZED
556 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000557 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200558 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000559
560 # TODO: this should not give an error but be handled at runtime
561 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200562 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000563
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200564 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100565 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200566 def Method1()
567 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000568 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200569 endclass
570
571 var obj = null_object
572 def Func()
573 obj.Method1()
574 enddef
575 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000576 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200577 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000578enddef
579
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200580" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200581def Test_null_object_assign_compare()
582 var lines =<< trim END
583 vim9script
584
585 var nullo = null_object
586 def F(): any
587 return nullo
588 enddef
589 assert_equal('object<Unknown>', typename(F()))
590
591 var o0 = F()
592 assert_true(o0 == null_object)
593 assert_true(o0 == null)
594
595 var o1: any = nullo
596 assert_true(o1 == null_object)
597 assert_true(o1 == null)
598
599 def G()
600 var x = null_object
601 enddef
602
603 class C
604 endclass
605 var o2: C
606 assert_true(o2 == null_object)
607 assert_true(o2 == null)
608
609 o2 = null_object
610 assert_true(o2 == null)
611
612 o2 = C.new()
613 assert_true(o2 != null)
614
615 o2 = null_object
616 assert_true(o2 == null)
617 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200618 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200619enddef
620
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200621" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000622def Test_class_member_initializer()
623 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200624 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000625
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200626 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100627 var lnum: number = 1
628 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000629
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200630 # constructor with only the line number
631 def new(lnum: number)
632 this.lnum = lnum
633 enddef
634 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200636 var pos = TextPosition.new(3)
637 assert_equal(3, pos.lnum)
638 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000639
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200640 var instr = execute('disassemble TextPosition.new')
641 assert_match('new\_s*' ..
642 '0 NEW TextPosition size \d\+\_s*' ..
643 '\d PUSHNR 1\_s*' ..
644 '\d STORE_THIS 0\_s*' ..
645 '\d PUSHNR 1\_s*' ..
646 '\d STORE_THIS 1\_s*' ..
647 'this.lnum = lnum\_s*' ..
648 '\d LOAD arg\[-1]\_s*' ..
649 '\d PUSHNR 0\_s*' ..
650 '\d LOAD $0\_s*' ..
651 '\d\+ STOREINDEX object\_s*' ..
652 '\d\+ RETURN object.*',
653 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000654 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200655 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000656enddef
657
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000658def Test_member_any_used_as_object()
659 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200660 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000661
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200662 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100663 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200664 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000665
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200666 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100667 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200668 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000669
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200670 def F(outer: Outer)
671 outer.inner.value = 1
672 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000673
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200674 var inner_obj = Inner.new(0)
675 var outer_obj = Outer.new(inner_obj)
676 F(outer_obj)
677 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000678 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200679 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000680
Ernie Rael03042a22023-11-11 08:53:32 +0100681 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200682 lines =<< trim END
683 vim9script
684
685 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100686 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200687 endclass
688
689 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100690 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200691 endclass
692
693 def F(outer: Outer)
694 outer.inner._value = 'b'
695 enddef
696
697 var inner_obj = Inner.new('a')
698 var outer_obj = Outer.new(inner_obj)
699 F(outer_obj)
700 END
Ernie Rael03042a22023-11-11 08:53:32 +0100701 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200702
703 # Try modifying a non-existing variable using an "any" object
704 lines =<< trim END
705 vim9script
706
707 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100708 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200709 endclass
710
711 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100712 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200713 endclass
714
715 def F(outer: Outer)
716 outer.inner.someval = 'b'
717 enddef
718
719 var inner_obj = Inner.new('a')
720 var outer_obj = Outer.new(inner_obj)
721 F(outer_obj)
722 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200723 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000724enddef
725
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200726" Nested assignment to a object variable which is of another class type
727def Test_assignment_nested_type()
728 var lines =<< trim END
729 vim9script
730
731 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100732 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200733 endclass
734
735 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100736 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200737 endclass
738
739 def F(outer: Outer)
740 outer.inner.value = 1
741 enddef
742
743 def Test_assign_to_nested_typed_member()
744 var inner = Inner.new(0)
745 var outer = Outer.new(inner)
746 F(outer)
747 assert_equal(1, inner.value)
748 enddef
749
750 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200751
752 var script_inner = Inner.new(0)
753 var script_outer = Outer.new(script_inner)
754 script_outer.inner.value = 1
755 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200756 END
757 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200758
759 # Assignment where target item is read only in :def
760 lines =<< trim END
761 vim9script
762
763 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100764 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200765 endclass
766
767 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100768 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200769 endclass
770
771 def F(outer: Outer)
772 outer.inner.value = 1
773 enddef
774
775 def Test_assign_to_nested_typed_member()
776 var inner = Inner.new(0)
777 var outer = Outer.new(inner)
778 F(outer)
779 assert_equal(1, inner.value)
780 enddef
781
782 Test_assign_to_nested_typed_member()
783 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200784 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200785
786 # Assignment where target item is read only script level
787 lines =<< trim END
788 vim9script
789
790 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100791 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200792 endclass
793
794 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100795 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200796 endclass
797
798 def F(outer: Outer)
799 outer.inner.value = 1
800 enddef
801
802 var script_inner = Inner.new(0)
803 var script_outer = Outer.new(script_inner)
804 script_outer.inner.value = 1
805 assert_equal(1, script_inner.value)
806 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200807 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200808enddef
809
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000810def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200811 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000812 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200813 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000814
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200815 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100816 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000817
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200818 def Add(n: number)
819 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100820 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200821 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100822
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200823 var f = Foo.new(3)
824 f.Add(17)
825 assert_equal(20, f.x)
826
827 def AddToFoo(obj: Foo)
828 obj.x += 3
829 enddef
830
831 AddToFoo(f)
832 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000833 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200834 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000835enddef
836
Bram Moolenaarf4508042023-01-15 16:54:57 +0000837def Test_list_of_objects()
838 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200839 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000840
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200841 class Foo
842 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000843 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200844 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000845
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200846 def ProcessList(fooList: list<Foo>)
847 for foo in fooList
848 foo.Add()
849 endfor
850 enddef
851
852 var l: list<Foo> = [Foo.new()]
853 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000854 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200855 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000856enddef
857
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000858def Test_expr_after_using_object()
859 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200860 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000861
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200862 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100863 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200864 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000865
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200866 def Foo(): Something
867 var v = Something.new()
868 echo 'in Foo(): ' .. typename(v)
869 return v
870 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000871
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200872 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000873 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200874 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000875enddef
876
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000877def Test_class_default_new()
878 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200879 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000880
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200881 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100882 var lnum: number = 1
883 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200884 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000885
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200886 var pos = TextPosition.new()
887 assert_equal(1, pos.lnum)
888 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000889
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200890 pos = TextPosition.new(v:none, v:none)
891 assert_equal(1, pos.lnum)
892 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000893
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200894 pos = TextPosition.new(3, 22)
895 assert_equal(3, pos.lnum)
896 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000897
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200898 pos = TextPosition.new(v:none, 33)
899 assert_equal(1, pos.lnum)
900 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000901 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200902 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000903
904 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200905 vim9script
906 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100907 var name: string
908 var age: number = 42
909 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000910
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200911 def new(this.name, this.age = v:none, this.education = v:none)
912 enddef
913 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000914
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200915 var piet = Person.new("Piet")
916 assert_equal("Piet", piet.name)
917 assert_equal(42, piet.age)
918 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000919
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200920 var chris = Person.new("Chris", 4, "none")
921 assert_equal("Chris", chris.name)
922 assert_equal(4, chris.age)
923 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000924 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200925 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000926
927 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200928 vim9script
929 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100930 var name: string
931 var age: number = 42
932 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +0000933
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200934 def new(this.name, this.age = v:none, this.education = v:none)
935 enddef
936 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000937
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200938 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000939 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200940 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200941
942 # Using a specific value to initialize an instance variable in the new()
943 # method.
944 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200945 vim9script
946 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100947 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200948 def new(this.val = 'a')
949 enddef
950 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200951 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200952 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000953enddef
954
h-east2261c892023-08-16 21:49:54 +0900955def Test_class_new_with_object_member()
956 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200957 vim9script
h-east2261c892023-08-16 21:49:54 +0900958
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200959 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +0100960 var str: string
961 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200962 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +0900963 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200964 def newVals(this.str, this.num)
965 enddef
966 endclass
h-east2261c892023-08-16 21:49:54 +0900967
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200968 def Check()
969 try
970 var c = C.new('cats', 2)
971 assert_equal('cats', c.str)
972 assert_equal(2, c.num)
973
974 c = C.newVals('dogs', 4)
975 assert_equal('dogs', c.str)
976 assert_equal(4, c.num)
977 catch
978 assert_report($'Unexpected exception was caught: {v:exception}')
979 endtry
980 enddef
981
982 Check()
h-east2261c892023-08-16 21:49:54 +0900983 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200984 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +0900985
986 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +0200987 vim9script
988
989 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +0100990 var str: string
991 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200992 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +0200993 enddef
994 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200995
996 def Check()
997 try
998 var c = C.new(1, 2)
999 catch
1000 assert_report($'Unexpected exception was caught: {v:exception}')
1001 endtry
1002 enddef
1003
1004 Check()
h-eastdb385522023-09-28 22:18:19 +02001005 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001006 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001007
1008 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001009 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001010
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001011 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001012 var str: string
1013 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001014 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001015 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001016 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001017
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001018 def Check()
1019 try
1020 var c = C.newVals('dogs', 'apes')
1021 catch
1022 assert_report($'Unexpected exception was caught: {v:exception}')
1023 endtry
1024 enddef
1025
1026 Check()
1027 END
1028 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1029
1030 lines =<< trim END
1031 vim9script
1032
1033 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001034 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001035 def new(str: any)
1036 enddef
1037 endclass
1038
1039 def Check()
1040 try
1041 var c = C.new(1)
1042 catch
1043 assert_report($'Unexpected exception was caught: {v:exception}')
1044 endtry
1045 enddef
1046
1047 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001048 END
1049 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001050
1051 # Try using "this." argument in a class method
1052 lines =<< trim END
1053 vim9script
1054 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001055 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001056 static def Foo(this.val: number)
1057 enddef
1058 endclass
1059 END
1060 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1061
1062 # Try using "this." argument in an object method
1063 lines =<< trim END
1064 vim9script
1065 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001066 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001067 def Foo(this.val: number)
1068 enddef
1069 endclass
1070 END
1071 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001072enddef
1073
Bram Moolenaar74e12742022-12-13 21:14:28 +00001074def Test_class_object_member_inits()
1075 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001076 vim9script
1077 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001078 var lnum: number
1079 var col = 1
1080 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001081 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001082
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001083 var pos = TextPosition.new()
1084 assert_equal(0, pos.lnum)
1085 assert_equal(1, pos.col)
1086 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001087 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001088 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001089
1090 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001091 vim9script
1092 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001093 var lnum
1094 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001095 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001096 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001097 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001098
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001099 # If the type is not specified for a member, then it should be set during
1100 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001101 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001102 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001103
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001104 var init_count = 0
1105 def Init(): string
1106 init_count += 1
1107 return 'foo'
1108 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001109
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001110 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001111 var str1 = Init()
1112 var str2: string = Init()
1113 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001114 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001115
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001116 assert_equal(init_count, 0)
1117 var a = A.new()
1118 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001119 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001120 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001121
1122 # Test for initializing an object member with an unknown variable/type
1123 lines =<< trim END
1124 vim9script
1125 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001126 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001127 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001128 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001129 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001130 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001131
1132 # Test for initializing an object member with an special type
1133 lines =<< trim END
1134 vim9script
1135 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001136 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001137 endclass
1138 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001139 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001140enddef
1141
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001142" Test for instance variable access
1143def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001144 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001145 vim9script
1146 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001147 var _one = 1
1148 var two = 2
1149 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001150
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001151 def GetOne(): number
1152 return this._one
1153 enddef
1154 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001155
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001156 var trip = Triple.new()
1157 assert_equal(1, trip.GetOne())
1158 assert_equal(2, trip.two)
1159 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001160 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001161
Ernie Rael03042a22023-11-11 08:53:32 +01001162 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001163 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1164 trip.three = 33
1165 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001166
Ernie Raeld4802ec2023-10-20 11:59:00 +02001167 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001168 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001169 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001170
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001171 # Test for a public member variable name beginning with an underscore
1172 lines =<< trim END
1173 vim9script
1174 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001175 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001176 endclass
1177 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001178 v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001179
Bram Moolenaar590162c2022-12-24 21:24:06 +00001180 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001181 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001182
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001183 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001184 var make: string
1185 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001186
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001187 def new(make_arg: string)
1188 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001189 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001190
1191 def GetMake(): string
1192 return $"make = {this.make}"
1193 enddef
1194 def GetAge(): number
1195 return this.age
1196 enddef
1197 endclass
1198
1199 var c = MyCar.new("abc")
1200 assert_equal('make = abc', c.GetMake())
1201
1202 c = MyCar.new("def")
1203 assert_equal('make = def', c.GetMake())
1204
1205 var c2 = MyCar.new("123")
1206 assert_equal('make = 123', c2.GetMake())
1207
1208 def CheckCar()
1209 assert_equal("make = def", c.GetMake())
1210 assert_equal(5, c.GetAge())
1211 enddef
1212 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001213 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001214 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001215
1216 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001217 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001218
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001219 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001220 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001221
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001222 def new(make_arg: string)
1223 this.make = make_arg
1224 enddef
1225 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001226
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001227 var c = MyCar.new("abc")
1228 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001229 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001230 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001231
1232 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001233 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001234
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001235 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001236 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001237
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001238 def Add(n: number): any
1239 this.x->add(n)
1240 return this
1241 enddef
1242 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001243
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001244 echo Foo.new().Add(1).Add(2).x
1245 echo Foo.new().Add(1).Add(2)
1246 .x
1247 echo Foo.new().Add(1)
1248 .Add(2).x
1249 echo Foo.new()
1250 .Add(1).Add(2).x
1251 echo Foo.new()
1252 .Add(1)
1253 .Add(2)
1254 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001255 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001256 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001257
1258 # Test for "public" cannot be abbreviated
1259 lines =<< trim END
1260 vim9script
1261 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001262 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001263 endclass
1264 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001265 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001266
Doug Kearns74da0ee2023-12-14 20:26:26 +01001267 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001268 lines =<< trim END
1269 vim9script
1270 class Something
1271 public val = 1
1272 endclass
1273 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001274 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001275
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001276 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001277 lines =<< trim END
1278 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001279 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001280 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001281 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001282 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001283 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001284 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001285
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001286 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001287 lines =<< trim END
1288 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001289 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001290 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001291 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001292 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001293 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001294 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001295
1296 # Modify a instance variable using the class name in a def function
1297 lines =<< trim END
1298 vim9script
1299 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001300 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001301 endclass
1302 def T()
1303 A.val = 1
1304 enddef
1305 T()
1306 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001307 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001308
1309 # Read a instance variable using the class name in a def function
1310 lines =<< trim END
1311 vim9script
1312 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001313 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001314 endclass
1315 def T()
1316 var i = A.val
1317 enddef
1318 T()
1319 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001320 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001321
1322 # Access from child class extending a class:
1323 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001324 vim9script
1325 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001326 var ro_obj_var = 10
1327 public var rw_obj_var = 20
1328 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001329 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001330
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001331 class B extends A
1332 def Foo()
1333 var x: number
1334 x = this.ro_obj_var
1335 this.ro_obj_var = 0
1336 x = this.rw_obj_var
1337 this.rw_obj_var = 0
1338 x = this._priv_obj_var
1339 this._priv_obj_var = 0
1340 enddef
1341 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001342
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001343 var b = B.new()
1344 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001345 END
1346 v9.CheckSourceSuccess(lines)
1347enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001348
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001349" Test for class variable access
1350def Test_class_variable_access()
1351 # Test for "static" cannot be abbreviated
1352 var lines =<< trim END
1353 vim9script
1354 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001355 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001356 endclass
1357 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001358 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001359
1360 # Test for "static" cannot be followed by "public".
1361 lines =<< trim END
1362 vim9script
1363 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001364 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001365 endclass
1366 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001367 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001368
1369 # A readonly class variable cannot be modified from a child class
1370 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001371 vim9script
1372 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001373 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001374 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001375
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001376 class B extends A
1377 def Foo()
1378 A.ro_class_var = 50
1379 enddef
1380 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001381
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001382 var b = B.new()
1383 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001384 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001385 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001386
Ernie Rael03042a22023-11-11 08:53:32 +01001387 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001388 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001389 vim9script
1390 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001391 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001392 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001393
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001394 class B extends A
1395 def Foo()
1396 var i = A._priv_class_var
1397 enddef
1398 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001399
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001400 var b = B.new()
1401 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001402 END
Ernie Rael03042a22023-11-11 08:53:32 +01001403 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001404
Ernie Rael03042a22023-11-11 08:53:32 +01001405 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001406 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001407 vim9script
1408 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001409 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001410 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001411
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001412 class B extends A
1413 def Foo()
1414 A._priv_class_var = 0
1415 enddef
1416 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001417
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001418 var b = B.new()
1419 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001420 END
Ernie Rael03042a22023-11-11 08:53:32 +01001421 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001422
1423 # Access from child class extending a class and from script context
1424 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001425 vim9script
1426 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001427 static var ro_class_var = 10
1428 public static var rw_class_var = 20
1429 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001430 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001431
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001432 class B extends A
1433 def Foo()
1434 var x: number
1435 x = A.ro_class_var
1436 assert_equal(10, x)
1437 x = A.rw_class_var
1438 assert_equal(25, x)
1439 A.rw_class_var = 20
1440 assert_equal(20, A.rw_class_var)
1441 enddef
1442 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001443
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001444 assert_equal(10, A.ro_class_var)
1445 assert_equal(20, A.rw_class_var)
1446 A.rw_class_var = 25
1447 assert_equal(25, A.rw_class_var)
1448 var b = B.new()
1449 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001450 END
1451 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001452enddef
1453
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001454def Test_class_object_compare()
1455 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001456 vim9script
1457 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001458 var nr = 0
1459 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001460 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001461 END
1462
1463 # used at the script level and in a compiled function
1464 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001465 var i1 = Item.new()
1466 assert_equal(i1, i1)
1467 assert_true(i1 is i1)
1468 var i2 = Item.new()
1469 assert_equal(i1, i2)
1470 assert_false(i1 is i2)
1471 var i3 = Item.new(0, 'xx')
1472 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001473
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001474 var io1 = Item.new(1, 'xx')
1475 assert_notequal(i1, io1)
1476 var io2 = Item.new(0, 'yy')
1477 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001478 END
1479
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001480 v9.CheckSourceSuccess(class_lines + test_lines)
1481 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001482 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001483
1484 for op in ['>', '>=', '<', '<=', '=~', '!~']
1485 var op_lines = [
1486 'var i1 = Item.new()',
1487 'var i2 = Item.new()',
1488 'echo i1 ' .. op .. ' i2',
1489 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001490 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001491 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001492 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001493 endfor
1494enddef
1495
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001496def Test_object_type()
1497 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001499
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001500 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001501 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001502 endclass
1503 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001504 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001505 endclass
1506 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001507 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001508 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001509
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001510 var o: One = One.new()
1511 var t: Two = Two.new()
1512 var m: TwoMore = TwoMore.new()
1513 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001514
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001515 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001516 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001517 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001518
1519 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001520 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001521
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001522 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001523 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001524 endclass
1525 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001526 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001527 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001528
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001529 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001530 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001531 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001532
1533 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001534 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001535
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001536 interface One
1537 def GetMember(): number
1538 endinterface
1539 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001540 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001541 def GetMember(): number
1542 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001543 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001544 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001545
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001546 var o: One = Two.new(5)
1547 assert_equal(5, o.GetMember())
1548 END
1549 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001550
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001551 lines =<< trim END
1552 vim9script
1553
1554 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001555 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001556 endclass
1557
1558 def Ref(name: string): func(Num): Num
1559 return (arg: Num): Num => {
1560 return eval(name)(arg)
1561 }
1562 enddef
1563
1564 const Fn = Ref('Double')
1565 var Double = (m: Num): Num => Num.new(m.n * 2)
1566
1567 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001568 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001569 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001570enddef
1571
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001572def Test_class_member()
1573 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001574 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001575 vim9script
1576 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001577 var lnum = 1
1578 var col = 1
1579 static var counter = 0
1580 static var _secret = 7
1581 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001582
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001583 static def AddToCounter(nr: number)
1584 counter += nr
1585 enddef
1586 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001587
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001588 assert_equal(0, TextPos.counter)
1589 TextPos.AddToCounter(3)
1590 assert_equal(3, TextPos.counter)
1591 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001592
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001593 def GetCounter(): number
1594 return TextPos.counter
1595 enddef
1596 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001598 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1599 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1600 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001601
Ernie Rael03042a22023-11-11 08:53:32 +01001602 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1603 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001604
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001605 assert_equal(42, TextPos.anybody)
1606 TextPos.anybody = 12
1607 assert_equal(12, TextPos.anybody)
1608 TextPos.anybody += 5
1609 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001610 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001611 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001612
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001613 # example in the help
1614 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001615 vim9script
1616 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001617 var size: number
1618 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001619
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001620 def new(this.size)
1621 totalSize += this.size
1622 enddef
1623 endclass
1624 assert_equal(0, OtherThing.totalSize)
1625 var to3 = OtherThing.new(3)
1626 assert_equal(3, OtherThing.totalSize)
1627 var to7 = OtherThing.new(7)
1628 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001629 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001630 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001631
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001632 # using static class member twice
1633 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001634 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001636 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001637 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001638
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001639 static def MacroSubstitute(s: string): string
1640 return substitute(s, '{{author}}', author, 'gi')
1641 enddef
1642 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001643
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001644 assert_equal('some text', HTML.MacroSubstitute('some text'))
1645 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001646 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001647 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001648
Ernie Rael03042a22023-11-11 08:53:32 +01001649 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001650 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001651 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001652
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001653 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001654 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001655
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001656 def Add(n: number): number
1657 const F = (): number => this._x + n
1658 return F()
1659 enddef
1660 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001661
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001662 var foo = Foo.new()
1663 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001664 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001665 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001666
Ernie Rael03042a22023-11-11 08:53:32 +01001667 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001668 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001669 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001670
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001671 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001672 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001673
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001674 def Add(n: number): number
1675 var Lam = () => {
1676 this._x = this._x + n
1677 }
1678 Lam()
1679 return this._x
1680 enddef
1681 endclass
h-east2bd6a092023-05-19 19:01:17 +01001682
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001683 var foo = Foo.new()
1684 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001685 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001686 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001687
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001688 # check shadowing
1689 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001690 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001691
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001692 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001693 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001694 def Method(count: number)
1695 echo count
1696 enddef
1697 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001698
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001699 var s = Some.new()
1700 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001701 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001702 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001703
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001704 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001705 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(arg: number)
1711 var count = 3
1712 echo arg count
1713 enddef
1714 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001715
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001716 var s = Some.new()
1717 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001718 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001719 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001720
1721 # Test for using an invalid type for a member variable
1722 lines =<< trim END
1723 vim9script
1724 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001725 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001726 endclass
1727 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001728 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001729
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001730 # Test for setting a member on a null object
1731 lines =<< trim END
1732 vim9script
1733 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001734 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001735 endclass
1736
1737 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001738 var obj: A
1739 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001740 enddef
1741 F()
1742 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001743 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001744
1745 # Test for accessing a member on a null object
1746 lines =<< trim END
1747 vim9script
1748 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001749 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001750 endclass
1751
1752 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001753 var obj: A
1754 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001755 enddef
1756 F()
1757 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001758 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001759
1760 # Test for setting a member on a null object, at script level
1761 lines =<< trim END
1762 vim9script
1763 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001764 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001765 endclass
1766
1767 var obj: A
1768 obj.val = ""
1769 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001770 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001771
1772 # Test for accessing a member on a null object, at script level
1773 lines =<< trim END
1774 vim9script
1775 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001776 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001777 endclass
1778
1779 var obj: A
1780 echo obj.val
1781 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001782 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001783
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001784 # Test for no space before or after the '=' when initializing a member
1785 # variable
1786 lines =<< trim END
1787 vim9script
1788 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001789 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001790 endclass
1791 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001792 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001793 lines =<< trim END
1794 vim9script
1795 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001796 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001797 endclass
1798 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001799 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001800
1801 # Access a non-existing member
1802 lines =<< trim END
1803 vim9script
1804 class A
1805 endclass
1806 var a = A.new()
1807 var v = a.bar
1808 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001809 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001810enddef
1811
Ernie Raele6c9aa52023-10-06 19:55:52 +02001812" These messages should show the defining class of the variable (base class),
1813" not the class that did the reference (super class)
1814def Test_defining_class_message()
1815 var lines =<< trim END
1816 vim9script
1817
1818 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001819 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001820 endclass
1821
1822 class Child extends Base
1823 endclass
1824
1825 var o = Child.new()
1826 var x = o._v1
1827 END
Ernie Rael03042a22023-11-11 08:53:32 +01001828 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001829 lines =<< trim END
1830 vim9script
1831
1832 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001833 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001834 endclass
1835
1836 class Child extends Base
1837 endclass
1838
1839 def F()
1840 var o = Child.new()
1841 var x = o._v1
1842 enddef
1843 F()
1844 END
Ernie Rael03042a22023-11-11 08:53:32 +01001845 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001846 lines =<< trim END
1847 vim9script
1848
1849 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001850 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001851 endclass
1852
1853 class Child extends Base
1854 endclass
1855
1856 var o = Child.new()
1857 o.v1 = []
1858 END
1859 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1860 lines =<< trim END
1861 vim9script
1862
1863 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001864 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001865 endclass
1866
1867 class Child extends Base
1868 endclass
1869
1870 def F()
1871 var o = Child.new()
1872 o.v1 = []
1873 enddef
1874 F()
1875 END
1876
Ernie Rael03042a22023-11-11 08:53:32 +01001877 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001878 # of the class hierarchy.
1879 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1880 lines =<< trim END
1881 vim9script
1882
1883 class Base0
1884 endclass
1885
1886 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01001887 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001888 endclass
1889
1890 class Child extends Base
1891 endclass
1892
1893 def F()
1894 var o = Child.new()
1895 var x = o._v1
1896 enddef
1897 F()
1898 END
Ernie Rael03042a22023-11-11 08:53:32 +01001899 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001900
Ernie Rael03042a22023-11-11 08:53:32 +01001901 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02001902 # of the class hierarchy.
1903 lines =<< trim END
1904 vim9script
1905
1906 class Base0
1907 endclass
1908
1909 class Base extends Base0
1910 endclass
1911
1912 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001913 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001914 endclass
1915
1916 def F()
1917 var o = Child.new()
1918 var x = o._v1
1919 enddef
1920 F()
1921 END
Ernie Rael03042a22023-11-11 08:53:32 +01001922 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001923enddef
1924
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001925func Test_class_garbagecollect()
1926 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001927 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001928
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001929 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01001930 var p = [2, 3]
1931 static var pl = ['a', 'b']
1932 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001933 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001934
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001935 echo Point.pl Point.pd
1936 call test_garbagecollect_now()
1937 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001938 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001939 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001940
1941 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001942 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001943
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001944 interface View
1945 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001946
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001947 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01001948 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001949 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001950
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001951 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01001952 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001953
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001954 def new()
1955 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01001956 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001957 enddef
1958 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001959
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001960 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001961
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001962 # overwrite "view", will be garbage-collected next
1963 view = MyView.new()
1964 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001965 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001966 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001967endfunc
1968
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001969" Test interface garbage collection
1970func Test_interface_garbagecollect()
1971 let lines =<< trim END
1972 vim9script
1973
1974 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01001975 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001976
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001977 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001978 endinterface
1979
1980 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01001981 static var ro_class_var: number = 10
1982 public static var rw_class_var: number = 20
1983 static var _priv_class_var: number = 30
1984 var ro_obj_var: number = 40
1985 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001986
1987 static def _ClassBar(): number
1988 return _priv_class_var
1989 enddef
1990
1991 static def ClassFoo(): number
1992 return ro_class_var + rw_class_var + A._ClassBar()
1993 enddef
1994
1995 def _ObjBar(): number
1996 return this._priv_obj_var
1997 enddef
1998
1999 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002000 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002001 enddef
2002 endclass
2003
2004 assert_equal(60, A.ClassFoo())
2005 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002006 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002007 test_garbagecollect_now()
2008 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002009 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002010 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002011 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002012endfunc
2013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002014def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002015 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002016 vim9script
2017 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002018 var value = 0
2019 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002020
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002021 def new(v: number)
2022 this.value = v
2023 ++objects
2024 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002025
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002026 static def GetCount(): number
2027 return objects
2028 enddef
2029 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002030
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002031 assert_equal(0, Value.GetCount())
2032 var v1 = Value.new(2)
2033 assert_equal(1, Value.GetCount())
2034 var v2 = Value.new(7)
2035 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002036 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002037 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002038
2039 # Test for cleaning up after a class definition failure when using class
2040 # functions.
2041 lines =<< trim END
2042 vim9script
2043 class A
2044 static def Foo()
2045 enddef
2046 aaa
2047 endclass
2048 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002049 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002050
2051 # Test for calling a class method from another class method without the class
2052 # name prefix.
2053 lines =<< trim END
2054 vim9script
2055 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002056 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002057 static def Foo(n: number)
2058 myList->add(n)
2059 enddef
2060 static def Bar()
2061 Foo(2)
2062 enddef
2063 def Baz()
2064 Foo(3)
2065 enddef
2066 endclass
2067 A.Bar()
2068 var a = A.new()
2069 a.Baz()
2070 assert_equal([1, 2, 3], A.myList)
2071 END
2072 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002073enddef
2074
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002075def Test_class_defcompile()
2076 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002077 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002078
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002079 class C
2080 def Fo(i: number): string
2081 return i
2082 enddef
2083 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002084
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002085 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002086 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002087 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002088
2089 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002090 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002091
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002092 class C
2093 static def Fc(): number
2094 return 'x'
2095 enddef
2096 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002097
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002098 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002099 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002100 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002101
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002102 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002103 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002104
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002105 class C
2106 static def new()
2107 enddef
2108 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002109
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002110 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002111 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002112 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002113
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002114 # Trying to compile a function using a non-existing class variable
2115 lines =<< trim END
2116 vim9script
2117 defcompile x.Foo()
2118 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002119 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002120
2121 # Trying to compile a function using a variable which is not a class
2122 lines =<< trim END
2123 vim9script
2124 var x: number
2125 defcompile x.Foo()
2126 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002127 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002128
2129 # Trying to compile a function without specifying the name
2130 lines =<< trim END
2131 vim9script
2132 class A
2133 endclass
2134 defcompile A.
2135 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002136 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002137
2138 # Trying to compile a non-existing class object member function
2139 lines =<< trim END
2140 vim9script
2141 class A
2142 endclass
2143 var a = A.new()
2144 defcompile a.Foo()
2145 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002146 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002147enddef
2148
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002149def Test_class_object_to_string()
2150 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002151 vim9script
2152 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002153 var lnum = 1
2154 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002155 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002156
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002157 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002158
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002159 var pos = TextPosition.new()
2160 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002161 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002162 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002163enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002164
Bram Moolenaar554d0312023-01-05 19:59:18 +00002165def Test_interface_basics()
2166 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002167 vim9script
2168 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002169 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002170 def GetCount(): number
2171 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002172 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002173 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002174
2175 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002176 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002177 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002178 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002179 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002180 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002181
2182 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002183 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002184
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002185 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002186 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002187 def Method(value: number)
2188 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002189 END
h-east61378a12023-04-18 19:07:29 +01002190 # The argument name and the object member name are the same, but this is not a
2191 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002192 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002193
2194 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002195 vim9script
2196 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002197 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002198 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002199 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002200 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002201
2202 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 vim9script
2204 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002205 var value: string
2206 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002207 def GetCount(): number
2208 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002209 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002210 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002211
2212 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002213 vim9script
2214 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002215 var value: string
2216 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002217 def GetCount(): number
2218 return 5
2219 enddef
2220 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002222 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002223
2224 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002225 vim9script
2226 export interface EnterExit
2227 def Enter(): void
2228 def Exit(): void
2229 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002230 END
2231 writefile(lines, 'XdefIntf.vim', 'D')
2232
2233 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002234 vim9script
2235 import './XdefIntf.vim' as defIntf
2236 export def With(ee: defIntf.EnterExit, F: func)
2237 ee.Enter()
2238 try
2239 F()
2240 finally
2241 ee.Exit()
2242 endtry
2243 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002244 END
2245 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002246
2247 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002248 vim9script
2249 export abstract class EnterExit
2250 def Enter(): void
2251 enddef
2252 def Exit(): void
2253 enddef
2254 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002255 END
2256 writefile(imported, 'XdefIntf2.vim', 'D')
2257
2258 lines[1] = " import './XdefIntf2.vim' as defIntf"
2259 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002260enddef
2261
Bram Moolenaar94674f22023-01-06 18:42:20 +00002262def Test_class_implements_interface()
2263 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002264 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002265
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002266 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002267 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002268 def Method(nr: number)
2269 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002270
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002271 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002272 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002273 def Method(nr: number)
2274 echo nr
2275 enddef
2276 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002277
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002278 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002279 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002280 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002281
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002282 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002283 var member = 'abc'
2284 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002285 def Method(nr: number)
2286 echo nr
2287 enddef
2288 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002289 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002290 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002291
2292 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002293 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002294
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002295 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002296 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002297 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002298
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002299 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002300 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002301 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002302 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002303 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002304
2305 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002306 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002307
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002308 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002309 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002310 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002311
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002312 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002313 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002314 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002315 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002316 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002317
2318 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002319 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002320
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002321 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002322 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002323 def Method(nr: number)
2324 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002325
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002326 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002327 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002328 def Method(nr: number)
2329 echo nr
2330 enddef
2331 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002332 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002333 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002334
2335 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002336 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002337
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002338 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002339 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002340 def Methods(nr: number)
2341 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002342
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002343 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002344 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002345 def Method(nr: number)
2346 echo nr
2347 enddef
2348 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002349 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002350 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002351
2352 # Check different order of members in class and interface works.
2353 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002354 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002355
2356 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002357 var label: string
2358 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002359 endinterface
2360
2361 # order of members is opposite of interface
2362 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002363 public var lnum: number = 5
2364 var errpos: number = 42
2365 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002366 endclass
2367
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002368 def Test()
2369 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002370
2371 assert_equal('label', result.label)
2372 assert_equal(42, result.errpos)
2373 enddef
2374
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002375 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002376 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002377 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002378
2379 # Interface name after "extends" doesn't end in a space or NUL character
2380 lines =<< trim END
2381 vim9script
2382 interface A
2383 endinterface
2384 class B extends A"
2385 endclass
2386 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002387 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002388
2389 # Trailing characters after a class name
2390 lines =<< trim END
2391 vim9script
2392 class A bbb
2393 endclass
2394 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002395 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002396
2397 # using "implements" with a non-existing class
2398 lines =<< trim END
2399 vim9script
2400 class A implements B
2401 endclass
2402 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002403 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002404
2405 # using "implements" with a regular class
2406 lines =<< trim END
2407 vim9script
2408 class A
2409 endclass
2410 class B implements A
2411 endclass
2412 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002413 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002414
2415 # using "implements" with a variable
2416 lines =<< trim END
2417 vim9script
2418 var T: number = 10
2419 class A implements T
2420 endclass
2421 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002422 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002423
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002424 # implements should be followed by a white space
2425 lines =<< trim END
2426 vim9script
2427 interface A
2428 endinterface
2429 class B implements A;
2430 endclass
2431 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002432 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002433
LemonBoyc5d27442023-08-19 13:02:35 +02002434 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002435 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002436
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002437 interface One
2438 def IsEven(nr: number): bool
2439 endinterface
2440 class Two implements One
2441 def IsEven(nr: number): string
2442 enddef
2443 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002444 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002445 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002446
2447 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002448 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002449
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002450 interface One
2451 def IsEven(nr: number): bool
2452 endinterface
2453 class Two implements One
2454 def IsEven(nr: bool): bool
2455 enddef
2456 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002457 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002458 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002459
2460 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002461 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002462
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002463 interface One
2464 def IsEven(nr: number): bool
2465 endinterface
2466 class Two implements One
2467 def IsEven(nr: number, ...extra: list<number>): bool
2468 enddef
2469 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002470 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002471 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 +02002472
2473 # access superclass interface members from subclass, mix variable order
2474 lines =<< trim END
2475 vim9script
2476
2477 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002478 var mvar1: number
2479 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002480 endinterface
2481
2482 # NOTE: the order is swapped
2483 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002484 var mvar2: number
2485 var mvar1: number
2486 public static var svar2: number
2487 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002488 def new()
2489 svar1 = 11
2490 svar2 = 12
2491 this.mvar1 = 111
2492 this.mvar2 = 112
2493 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002494 endclass
2495
2496 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002497 def new()
2498 this.mvar1 = 121
2499 this.mvar2 = 122
2500 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002501 endclass
2502
2503 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002504 def new()
2505 this.mvar1 = 131
2506 this.mvar2 = 132
2507 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002508 endclass
2509
Ernie Raelcf138d42023-09-06 20:45:03 +02002510 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002511 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002512 enddef
2513
2514 var oa = A.new()
2515 var ob = B.new()
2516 var oc = C.new()
2517
Ernie Raelcf138d42023-09-06 20:45:03 +02002518 assert_equal([111, 112], F2(oa))
2519 assert_equal([121, 122], F2(ob))
2520 assert_equal([131, 132], F2(oc))
2521 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002522 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002523
2524 # Access superclass interface members from subclass, mix variable order.
2525 # Two interfaces, one on A, one on B; each has both kinds of variables
2526 lines =<< trim END
2527 vim9script
2528
2529 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002530 var mvar1: number
2531 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002532 endinterface
2533
2534 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002535 var mvar3: number
2536 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002537 endinterface
2538
2539 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002540 public static var svar1: number
2541 public static var svar2: number
2542 var mvar1: number
2543 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002544 def new()
2545 svar1 = 11
2546 svar2 = 12
2547 this.mvar1 = 111
2548 this.mvar2 = 112
2549 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002550 endclass
2551
2552 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002553 static var svar3: number
2554 static var svar4: number
2555 var mvar3: number
2556 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002557 def new()
2558 svar3 = 23
2559 svar4 = 24
2560 this.mvar1 = 121
2561 this.mvar2 = 122
2562 this.mvar3 = 123
2563 this.mvar4 = 124
2564 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002565 endclass
2566
2567 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002568 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002569 def new()
2570 svar5 = 1001
2571 this.mvar1 = 131
2572 this.mvar2 = 132
2573 this.mvar3 = 133
2574 this.mvar4 = 134
2575 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002576 endclass
2577
Ernie Raelcf138d42023-09-06 20:45:03 +02002578 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002579 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002580 enddef
2581
Ernie Raelcf138d42023-09-06 20:45:03 +02002582 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002583 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002584 enddef
2585
Ernie Raelcf138d42023-09-06 20:45:03 +02002586 var oa = A.new()
2587 var ob = B.new()
2588 var oc = C.new()
2589
Ernie Raelcf138d42023-09-06 20:45:03 +02002590 assert_equal([[111, 112]], [F2(oa)])
2591 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2592 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002593 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002594 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002595
2596 # Using two interface names without a space after the ","
2597 lines =<< trim END
2598 vim9script
2599 interface A
2600 endinterface
2601 interface B
2602 endinterface
2603 class C implements A,B
2604 endclass
2605 END
2606 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2607
2608 # No interface name after a comma
2609 lines =<< trim END
2610 vim9script
2611 interface A
2612 endinterface
2613 class B implements A,
2614 endclass
2615 END
2616 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2617
2618 # No interface name after implements
2619 lines =<< trim END
2620 vim9script
2621 class A implements
2622 endclass
2623 END
2624 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002625enddef
2626
Bram Moolenaard0200c82023-01-28 15:19:40 +00002627def Test_call_interface_method()
2628 var lines =<< trim END
2629 vim9script
2630 interface Base
2631 def Enter(): void
2632 endinterface
2633
2634 class Child implements Base
2635 def Enter(): void
2636 g:result ..= 'child'
2637 enddef
2638 endclass
2639
2640 def F(obj: Base)
2641 obj.Enter()
2642 enddef
2643
2644 g:result = ''
2645 F(Child.new())
2646 assert_equal('child', g:result)
2647 unlet g:result
2648 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002649 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002650
2651 lines =<< trim END
2652 vim9script
2653 class Base
2654 def Enter(): void
2655 g:result ..= 'base'
2656 enddef
2657 endclass
2658
2659 class Child extends Base
2660 def Enter(): void
2661 g:result ..= 'child'
2662 enddef
2663 endclass
2664
2665 def F(obj: Base)
2666 obj.Enter()
2667 enddef
2668
2669 g:result = ''
2670 F(Child.new())
2671 assert_equal('child', g:result)
2672 unlet g:result
2673 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002674 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002675
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002676 # method of interface returns a value
2677 lines =<< trim END
2678 vim9script
2679 interface Base
2680 def Enter(): string
2681 endinterface
2682
2683 class Child implements Base
2684 def Enter(): string
2685 g:result ..= 'child'
2686 return "/resource"
2687 enddef
2688 endclass
2689
2690 def F(obj: Base)
2691 var r = obj.Enter()
2692 g:result ..= r
2693 enddef
2694
2695 g:result = ''
2696 F(Child.new())
2697 assert_equal('child/resource', g:result)
2698 unlet g:result
2699 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002700 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002701
2702 lines =<< trim END
2703 vim9script
2704 class Base
2705 def Enter(): string
2706 return null_string
2707 enddef
2708 endclass
2709
2710 class Child extends Base
2711 def Enter(): string
2712 g:result ..= 'child'
2713 return "/resource"
2714 enddef
2715 endclass
2716
2717 def F(obj: Base)
2718 var r = obj.Enter()
2719 g:result ..= r
2720 enddef
2721
2722 g:result = ''
2723 F(Child.new())
2724 assert_equal('child/resource', g:result)
2725 unlet g:result
2726 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002727 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002728
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002729 # No class that implements the interface.
2730 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002731 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002732
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002733 interface IWithEE
2734 def Enter(): any
2735 def Exit(): void
2736 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002737
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002738 def With1(ee: IWithEE, F: func)
2739 var r = ee.Enter()
2740 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002741
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002742 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002743 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002744 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002745enddef
2746
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002747def Test_class_used_as_type()
2748 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002749 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002750
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002751 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002752 var x = 0
2753 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002754 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002755
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002756 var p: Point
2757 p = Point.new(2, 33)
2758 assert_equal(2, p.x)
2759 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002760 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002761 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002762
2763 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002764 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002765
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002766 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002767 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002768 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002769
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002770 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002771 var x = 0
2772 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002773 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002774
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002775 var p: Point
2776 p = Point.new(2, 33)
2777 var hx = p
2778 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002779 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002780 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002781
2782 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002783 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002784
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002785 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002786 var x = 0
2787 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002788 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002789
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002790 var p: Point
2791 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002792 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002793 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002794enddef
2795
Bram Moolenaar83677162023-01-08 19:54:10 +00002796def Test_class_extends()
2797 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002798 vim9script
2799 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002800 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002801 def GetOne(): number
2802 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002803 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002804 endclass
2805 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002806 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002807 def GetTotal(): number
2808 return this.one + this.two
2809 enddef
2810 endclass
2811 var o = Child.new()
2812 assert_equal(1, o.one)
2813 assert_equal(2, o.two)
2814 assert_equal(1, o.GetOne())
2815 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002816 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002817 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002818
2819 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002820 vim9script
2821 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002822 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002823 endclass
2824 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002825 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002826 endclass
2827 var o = Child.new(3, 44)
2828 assert_equal(3, o.one)
2829 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002830 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002831 v9.CheckSourceSuccess(lines)
2832
2833 lines =<< trim END
2834 vim9script
2835 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002836 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002837 endclass
2838 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002839 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002840 endclass
2841 END
2842 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2843
2844 lines =<< trim END
2845 vim9script
2846 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01002847 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002848 endclass
2849 END
2850 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2851
2852 lines =<< trim END
2853 vim9script
2854 var SomeVar = 99
2855 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01002856 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002857 endclass
2858 END
2859 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2860
2861 lines =<< trim END
2862 vim9script
2863 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002864 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002865 def ToString(): string
2866 return this.name
2867 enddef
2868 endclass
2869
2870 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002871 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002872 def ToString(): string
2873 return super.ToString() .. ': ' .. this.age
2874 enddef
2875 endclass
2876
2877 var o = Child.new('John', 42)
2878 assert_equal('John: 42', o.ToString())
2879 END
2880 v9.CheckSourceSuccess(lines)
2881
2882 lines =<< trim END
2883 vim9script
2884 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002885 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002886 def ToString(): number
2887 return this.age
2888 enddef
2889 def ToString(): string
2890 return this.age
2891 enddef
2892 endclass
2893 END
2894 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2895
2896 lines =<< trim END
2897 vim9script
2898 class Child
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 var o = Child.new(42)
2905 echo o.ToString()
2906 END
2907 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2908
2909 lines =<< trim END
2910 vim9script
2911 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002912 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002913 def ToString(): string
2914 return this.name
2915 enddef
2916 endclass
2917
2918 var age = 42
2919 def ToString(): string
2920 return super.ToString() .. ': ' .. age
2921 enddef
2922 echo ToString()
2923 END
2924 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2925
2926 lines =<< trim END
2927 vim9script
2928 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002929 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002930 def ToString(): string
2931 return super.ToString() .. ': ' .. this.age
2932 enddef
2933 endclass
2934 var o = Child.new(42)
2935 echo o.ToString()
2936 END
2937 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
2938
2939 lines =<< trim END
2940 vim9script
2941 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002942 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002943 static def ToString(): string
2944 return 'Base class'
2945 enddef
2946 endclass
2947
2948 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002949 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002950 def ToString(): string
2951 return Base.ToString() .. ': ' .. this.age
2952 enddef
2953 endclass
2954
2955 var o = Child.new('John', 42)
2956 assert_equal('Base class: 42', o.ToString())
2957 END
2958 v9.CheckSourceSuccess(lines)
2959
2960 lines =<< trim END
2961 vim9script
2962 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002963 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002964 def new(init: number)
2965 this.value = number + 1
2966 enddef
2967 endclass
2968 class Child extends Base
2969 def new()
2970 this.new(3)
2971 enddef
2972 endclass
2973 var c = Child.new()
2974 END
2975 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002976
2977 # base class with more than one object member
2978 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002979 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002980
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002981 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002982 var success: bool
2983 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002984 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002985
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002986 class Success extends Result
2987 def new(this.value = v:none)
2988 this.success = true
2989 enddef
2990 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002991
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002992 var v = Success.new('asdf')
2993 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002994 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002995 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002996
2997 # class name after "extends" doesn't end in a space or NUL character
2998 lines =<< trim END
2999 vim9script
3000 class A
3001 endclass
3002 class B extends A"
3003 endclass
3004 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003005 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003006enddef
3007
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003008def Test_using_base_class()
3009 var lines =<< trim END
3010 vim9script
3011
3012 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003013 def Enter(): any
3014 return null
3015 enddef
3016 def Exit(resource: any): void
3017 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003018 endclass
3019
3020 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003021 def Enter(): any
3022 return 42
3023 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003024
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003025 def Exit(resource: number): void
3026 g:result ..= '/exit'
3027 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003028 endclass
3029
3030 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003031 var r = ee.Enter()
3032 try
3033 g:result ..= r
3034 finally
3035 g:result ..= '/finally'
3036 ee.Exit(r)
3037 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003038 enddef
3039
3040 g:result = ''
3041 With(ChildEE.new())
3042 assert_equal('42/finally/exit', g:result)
3043 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003044 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003045 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003046
3047 # Using super, Child invokes Base method which has optional arg. #12471
3048 lines =<< trim END
3049 vim9script
3050
3051 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003052 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003053 def Method(arg = 0)
3054 this.success = true
3055 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003056 endclass
3057
3058 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003059 def new()
3060 super.Method()
3061 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003062 endclass
3063
3064 var obj = Child.new()
3065 assert_equal(true, obj.success)
3066 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003067 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003068enddef
3069
Bram Moolenaara86655a2023-01-12 17:06:27 +00003070def Test_class_import()
3071 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003072 vim9script
3073 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003074 var kind: string
3075 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003076 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003077 END
3078 writefile(lines, 'Xanimal.vim', 'D')
3079
3080 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003081 vim9script
3082 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003083
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003084 var a: animal.Animal
3085 a = animal.Animal.new('fish', 'Eric')
3086 assert_equal('fish', a.kind)
3087 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003088
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003089 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3090 assert_equal('cat', b.kind)
3091 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003092 END
3093 v9.CheckScriptSuccess(lines)
3094enddef
3095
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003096" Test for implementing an imported interface
3097def Test_implement_imported_interface()
3098 var lines =<< trim END
3099 vim9script
3100 export interface Imp_Intf1
3101 def Fn1(): number
3102 endinterface
3103 export interface Imp_Intf2
3104 def Fn2(): number
3105 endinterface
3106 END
3107 writefile(lines, 'Ximportinterface.vim', 'D')
3108
3109 lines =<< trim END
3110 vim9script
3111 import './Ximportinterface.vim' as Xintf
3112
3113 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3114 def Fn1(): number
3115 return 10
3116 enddef
3117 def Fn2(): number
3118 return 20
3119 enddef
3120 endclass
3121 var a = A.new()
3122 assert_equal(10, a.Fn1())
3123 assert_equal(20, a.Fn2())
3124 END
3125 v9.CheckScriptSuccess(lines)
3126enddef
3127
3128" Test for extending an imported class
3129def Test_extend_imported_class()
3130 var lines =<< trim END
3131 vim9script
3132 export class Imp_C1
3133 def Fn1(): number
3134 return 5
3135 enddef
3136 endclass
3137 END
3138 writefile(lines, 'Xextendimportclass.vim', 'D')
3139
3140 lines =<< trim END
3141 vim9script
3142 import './Xextendimportclass.vim' as XClass
3143
3144 class A extends XClass.Imp_C1
3145 endclass
3146 var a = A.new()
3147 assert_equal(5, a.Fn1())
3148 END
3149 v9.CheckScriptSuccess(lines)
3150enddef
3151
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003152def Test_abstract_class()
3153 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003154 vim9script
3155 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003156 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003157 endclass
3158 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003159 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003160 endclass
3161 var p: Base = Person.new('Peter', 42)
3162 assert_equal('Peter', p.name)
3163 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003164 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003165 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003166
3167 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003168 vim9script
3169 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003170 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003171 endclass
3172 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003173 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003174 endclass
3175 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003176 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003177 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003178
3179 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003180 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003181 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003182 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003183 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003184 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003185
3186 # Abstract class cannot have a "new" function
3187 lines =<< trim END
3188 vim9script
3189 abstract class Base
3190 def new()
3191 enddef
3192 endclass
3193 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003194 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003195enddef
3196
Bram Moolenaar486fc252023-01-18 14:51:07 +00003197def Test_closure_in_class()
3198 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003199 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003200
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003201 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003202 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003203
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003204 def new()
3205 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3206 enddef
3207 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003208
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003209 Foo.new()
3210 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003211 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003212 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003213enddef
3214
Ernie Rael9ed53752023-12-11 17:40:46 +01003215def Test_construct_object_from_legacy()
3216 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003217 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003218 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003219
Ernie Rael9ed53752023-12-11 17:40:46 +01003220 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003221
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003222 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003223 def new(arg: string)
3224 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003225 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003226 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003227
Ernie Rael9ed53752023-12-11 17:40:46 +01003228 export def CreateA(...args: list<any>): A
3229 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003230 enddef
3231
Ernie Rael9ed53752023-12-11 17:40:46 +01003232 g:P = CreateA
3233 legacy call g:P('some_arg')
3234 assert_equal(true, newCalled)
3235 unlet g:P
3236 END
3237 v9.CheckSourceSuccess(lines)
3238
3239 lines =<< trim END
3240 vim9script
3241
3242 var newCalled = false
3243
3244 class A
3245 static def CreateA(options = {}): any
3246 return A.new()
3247 enddef
3248 def new()
3249 newCalled = true
3250 enddef
3251 endclass
3252
3253 g:P = A.CreateA
3254 legacy call g:P()
3255 assert_equal(true, newCalled)
3256 unlet g:P
3257 END
3258 v9.CheckSourceSuccess(lines)
3259
3260 # This also tests invoking "new()" with "call"
3261 lines =<< trim END
3262 vim9script
3263
3264 var createdObject: any
3265
3266 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003267 var val1: number
3268 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003269 static def CreateA(...args: list<any>): any
3270 createdObject = call(A.new, args)
3271 return createdObject
3272 enddef
3273 endclass
3274
3275 g:P = A.CreateA
3276 legacy call g:P(3, 5)
3277 assert_equal(3, createdObject.val1)
3278 assert_equal(5, createdObject.val2)
3279 legacy call g:P()
3280 assert_equal(0, createdObject.val1)
3281 assert_equal(0, createdObject.val2)
3282 legacy call g:P(7)
3283 assert_equal(7, createdObject.val1)
3284 assert_equal(0, createdObject.val2)
3285 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003286 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003287 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003288enddef
3289
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003290def Test_defer_with_object()
3291 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003292 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003293
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003294 class CWithEE
3295 def Enter()
3296 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003297 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003298 def Exit()
3299 g:result ..= "exited"
3300 enddef
3301 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003302
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003303 def With(ee: CWithEE, F: func)
3304 ee.Enter()
3305 defer ee.Exit()
3306 F()
3307 enddef
3308
3309 g:result = ''
3310 var obj = CWithEE.new()
3311 obj->With(() => {
3312 g:result ..= "called/"
3313 })
3314 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003315 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003316 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003317 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003318
3319 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003320 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003321
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003322 class BaseWithEE
3323 def Enter()
3324 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003325 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003326 def Exit()
3327 g:result ..= "exited-base"
3328 enddef
3329 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003330
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003331 class CWithEE extends BaseWithEE
3332 def Enter()
3333 g:result ..= "entered-child/"
3334 enddef
3335 def Exit()
3336 g:result ..= "exited-child"
3337 enddef
3338 endclass
3339
3340 def With(ee: BaseWithEE, F: func)
3341 ee.Enter()
3342 defer ee.Exit()
3343 F()
3344 enddef
3345
3346 g:result = ''
3347 var obj = CWithEE.new()
3348 obj->With(() => {
3349 g:result ..= "called/"
3350 })
3351 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003352 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003353 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003354 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003355enddef
3356
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003357" The following test used to crash Vim (Github issue #12676)
3358def Test_extends_method_crashes_vim()
3359 var lines =<< trim END
3360 vim9script
3361
3362 class Observer
3363 endclass
3364
3365 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003366 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003367
3368 def Set(v: any)
3369 if v != this.value
3370 this.value = v
3371 endif
3372 enddef
3373
3374 def Register(observer: Observer)
3375 enddef
3376 endclass
3377
3378 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003379 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003380 endclass
3381
3382 def Observe(obj: Property, who: Observer)
3383 obj.Register(who)
3384 enddef
3385
3386 var p = Bool.new(false)
3387 var myObserver = Observer.new()
3388
3389 Observe(p, myObserver)
3390
3391 p.Set(true)
3392 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003393 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003394enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003395
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003396" Test for calling a method in a class that is extended
3397def Test_call_method_in_extended_class()
3398 var lines =<< trim END
3399 vim9script
3400
3401 var prop_init_called = false
3402 var prop_register_called = false
3403
3404 class Property
3405 def Init()
3406 prop_init_called = true
3407 enddef
3408
3409 def Register()
3410 prop_register_called = true
3411 enddef
3412 endclass
3413
3414 class Bool extends Property
3415 endclass
3416
3417 def Observe(obj: Property)
3418 obj.Register()
3419 enddef
3420
3421 var p = Property.new()
3422 Observe(p)
3423
3424 p.Init()
3425 assert_true(prop_init_called)
3426 assert_true(prop_register_called)
3427 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003428 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003429enddef
3430
LemonBoyafe04662023-08-23 21:08:11 +02003431def Test_instanceof()
3432 var lines =<< trim END
3433 vim9script
3434
3435 class Base1
3436 endclass
3437
3438 class Base2 extends Base1
3439 endclass
3440
3441 interface Intf1
3442 endinterface
3443
3444 class Mix1 implements Intf1
3445 endclass
3446
3447 class Base3 extends Mix1
3448 endclass
3449
Ernie Rael2025af12023-12-12 16:58:00 +01003450 type AliasBase1 = Base1
3451 type AliasBase2 = Base2
3452 type AliasIntf1 = Intf1
3453 type AliasMix1 = Mix1
3454
LemonBoyafe04662023-08-23 21:08:11 +02003455 var b1 = Base1.new()
3456 var b2 = Base2.new()
3457 var b3 = Base3.new()
3458
3459 assert_true(instanceof(b1, Base1))
3460 assert_true(instanceof(b2, Base1))
3461 assert_false(instanceof(b1, Base2))
3462 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003463 assert_true(instanceof(b3, Base1, Base2, Intf1))
3464
3465 assert_true(instanceof(b1, AliasBase1))
3466 assert_true(instanceof(b2, AliasBase1))
3467 assert_false(instanceof(b1, AliasBase2))
3468 assert_true(instanceof(b3, AliasMix1))
3469 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003470
3471 def Foo()
3472 var a1 = Base1.new()
3473 var a2 = Base2.new()
3474 var a3 = Base3.new()
3475
3476 assert_true(instanceof(a1, Base1))
3477 assert_true(instanceof(a2, Base1))
3478 assert_false(instanceof(a1, Base2))
3479 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003480 assert_true(instanceof(a3, Base1, Base2, Intf1))
3481
3482 assert_true(instanceof(a1, AliasBase1))
3483 assert_true(instanceof(a2, AliasBase1))
3484 assert_false(instanceof(a1, AliasBase2))
3485 assert_true(instanceof(a3, AliasMix1))
3486 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003487 enddef
3488 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003489
3490 var o_null: Base1
3491 assert_false(instanceof(o_null, Base1))
3492
LemonBoyafe04662023-08-23 21:08:11 +02003493 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003494 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003495
3496 lines =<< trim END
3497 vim9script
3498
3499 class Base1
3500 endclass
3501 instanceof(Base1.new())
3502 END
3503 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3504
3505 lines =<< trim END
3506 vim9script
3507
3508 class Base1
3509 endclass
3510 def F()
3511 instanceof(Base1.new())
3512 enddef
3513 F()
3514 END
3515 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3516
3517 lines =<< trim END
3518 vim9script
3519
3520 class Base1
3521 endclass
3522
3523 class Base2
3524 endclass
3525
3526 var o = Base2.new()
3527 instanceof(o, Base1, Base2, 3)
3528 END
3529 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3530
3531 lines =<< trim END
3532 vim9script
3533
3534 class Base1
3535 endclass
3536
3537 class Base2
3538 endclass
3539
3540 def F()
3541 var o = Base2.new()
3542 instanceof(o, Base1, Base2, 3)
3543 enddef
3544 F()
3545 END
3546 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003547enddef
3548
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003549" Test for calling a method in the parent class that is extended partially.
3550" This used to fail with the 'E118: Too many arguments for function: Text' error
3551" message (Github issue #12524).
3552def Test_call_method_in_parent_class()
3553 var lines =<< trim END
3554 vim9script
3555
3556 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003557 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003558
3559 def SetY(lnum: number)
3560 this._lnum = lnum
3561 enddef
3562
3563 def Text(): string
3564 return ''
3565 enddef
3566 endclass
3567
3568 class Foo extends Widget
3569 def Text(): string
3570 return '<Foo>'
3571 enddef
3572 endclass
3573
3574 def Stack(w1: Widget, w2: Widget): list<Widget>
3575 w1.SetY(1)
3576 w2.SetY(2)
3577 return [w1, w2]
3578 enddef
3579
3580 var foo1 = Foo.new()
3581 var foo2 = Foo.new()
3582 var l = Stack(foo1, foo2)
3583 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003584 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003585enddef
3586
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003587" Test for calling methods from three levels of classes
3588def Test_multi_level_method_call()
3589 var lines =<< trim END
3590 vim9script
3591
3592 var A_func1: number = 0
3593 var A_func2: number = 0
3594 var A_func3: number = 0
3595 var B_func2: number = 0
3596 var B_func3: number = 0
3597 var C_func3: number = 0
3598
3599 class A
3600 def Func1()
3601 A_func1 += 1
3602 enddef
3603
3604 def Func2()
3605 A_func2 += 1
3606 enddef
3607
3608 def Func3()
3609 A_func3 += 1
3610 enddef
3611 endclass
3612
3613 class B extends A
3614 def Func2()
3615 B_func2 += 1
3616 enddef
3617
3618 def Func3()
3619 B_func3 += 1
3620 enddef
3621 endclass
3622
3623 class C extends B
3624 def Func3()
3625 C_func3 += 1
3626 enddef
3627 endclass
3628
3629 def A_CallFuncs(a: A)
3630 a.Func1()
3631 a.Func2()
3632 a.Func3()
3633 enddef
3634
3635 def B_CallFuncs(b: B)
3636 b.Func1()
3637 b.Func2()
3638 b.Func3()
3639 enddef
3640
3641 def C_CallFuncs(c: C)
3642 c.Func1()
3643 c.Func2()
3644 c.Func3()
3645 enddef
3646
3647 var cobj = C.new()
3648 A_CallFuncs(cobj)
3649 B_CallFuncs(cobj)
3650 C_CallFuncs(cobj)
3651 assert_equal(3, A_func1)
3652 assert_equal(0, A_func2)
3653 assert_equal(0, A_func3)
3654 assert_equal(3, B_func2)
3655 assert_equal(0, B_func3)
3656 assert_equal(3, C_func3)
3657 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003658 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003659enddef
3660
3661" Test for using members from three levels of classes
3662def Test_multi_level_member_access()
3663 var lines =<< trim END
3664 vim9script
3665
3666 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003667 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003668 endclass
3669
3670 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003671 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003672 endclass
3673
3674 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003675 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003676 endclass
3677
3678 def A_members(a: A)
3679 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003680 enddef
3681
3682 def B_members(b: B)
3683 b.val1 += 1
3684 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003685 enddef
3686
3687 def C_members(c: C)
3688 c.val1 += 1
3689 c.val2 += 1
3690 c.val3 += 1
3691 enddef
3692
3693 var cobj = C.new()
3694 A_members(cobj)
3695 B_members(cobj)
3696 C_members(cobj)
3697 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003698 assert_equal(2, cobj.val2)
3699 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003700 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003701 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003702enddef
3703
LemonBoy0ffc17a2023-08-20 18:09:11 +02003704" Test expansion of <stack> with class methods.
3705def Test_stack_expansion_with_methods()
3706 var lines =<< trim END
3707 vim9script
3708
3709 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003710 def M1()
3711 F0()
3712 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003713 endclass
3714
3715 def F0()
3716 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3717 enddef
3718
3719 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003720 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003721 enddef
3722
3723 F()
3724 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003725 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003726enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003727
3728" Test the return type of the new() constructor
3729def Test_new_return_type()
3730 # new() uses the default return type and there is no return statement
3731 var lines =<< trim END
3732 vim9script
3733
3734 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003735 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003736
3737 def new(this._bufnr)
3738 if !bufexists(this._bufnr)
3739 this._bufnr = -1
3740 endif
3741 enddef
3742 endclass
3743
3744 var c = C.new(12345)
3745 assert_equal('object<C>', typename(c))
3746
3747 var v1: C
3748 v1 = C.new(12345)
3749 assert_equal('object<C>', typename(v1))
3750
3751 def F()
3752 var v2: C
3753 v2 = C.new(12345)
3754 assert_equal('object<C>', typename(v2))
3755 enddef
3756 F()
3757 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003758 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003759
3760 # new() uses the default return type and an empty 'return' statement
3761 lines =<< trim END
3762 vim9script
3763
3764 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003765 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003766
3767 def new(this._bufnr)
3768 if !bufexists(this._bufnr)
3769 this._bufnr = -1
3770 return
3771 endif
3772 enddef
3773 endclass
3774
3775 var c = C.new(12345)
3776 assert_equal('object<C>', typename(c))
3777
3778 var v1: C
3779 v1 = C.new(12345)
3780 assert_equal('object<C>', typename(v1))
3781
3782 def F()
3783 var v2: C
3784 v2 = C.new(12345)
3785 assert_equal('object<C>', typename(v2))
3786 enddef
3787 F()
3788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003789 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003790
3791 # new() uses "any" return type and returns "this"
3792 lines =<< trim END
3793 vim9script
3794
3795 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003796 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003797
3798 def new(this._bufnr): any
3799 if !bufexists(this._bufnr)
3800 this._bufnr = -1
3801 return this
3802 endif
3803 enddef
3804 endclass
3805 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003806 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003807
3808 # new() uses 'Dict' return type and returns a Dict
3809 lines =<< trim END
3810 vim9script
3811
3812 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003813 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003814
3815 def new(): dict<any>
3816 this._state = {}
3817 return this._state
3818 enddef
3819 endclass
3820
3821 var c = C.new()
3822 assert_equal('object<C>', typename(c))
3823 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003824 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003825enddef
3826
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003827" Test for checking a member initialization type at run time.
3828def Test_runtime_type_check_for_member_init()
3829 var lines =<< trim END
3830 vim9script
3831
3832 var retnum: bool = false
3833
3834 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003835 retnum = !retnum
3836 if retnum
3837 return 1
3838 else
3839 return "hello"
3840 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003841 enddef
3842
3843 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003844 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003845 endclass
3846
3847 var c1 = C.new()
3848 var c2 = C.new()
3849 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003850 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003851enddef
3852
3853" Test for locking a variable referring to an object and reassigning to another
3854" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003855def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003856 var lines =<< trim END
3857 vim9script
3858
3859 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003860 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003861 def new(this.val)
3862 enddef
3863 endclass
3864
3865 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3866 lockvar 2 some_dict
3867
3868 var current: C
3869 current = some_dict['c']
3870 assert_equal(3, current.val)
3871 current = some_dict['b']
3872 assert_equal(2, current.val)
3873
3874 def F()
3875 current = some_dict['c']
3876 enddef
3877
3878 def G()
3879 current = some_dict['b']
3880 enddef
3881
3882 F()
3883 assert_equal(3, current.val)
3884 G()
3885 assert_equal(2, current.val)
3886 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003887 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003888enddef
3889
Ernie Raelee865f32023-09-29 19:53:55 +02003890" Test trying to lock an object variable from various places
3891def Test_lockvar_object_variable()
3892 # An object variable lockvar has several cases:
3893 # object method, scriptlevel, scriplevel from :def, :def arg
3894 # method arg, static method arg.
3895 # Also different depths
3896
Ernie Raelee865f32023-09-29 19:53:55 +02003897 #
3898 # lockvar of read-only object variable
3899 #
3900
3901 # read-only lockvar from object method
3902 var lines =<< trim END
3903 vim9script
3904
3905 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003906 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02003907 def Lock()
3908 lockvar this.val1
3909 enddef
3910 endclass
3911 var o = C.new(3)
3912 o.Lock()
3913 END
Ernie Rael64885642023-10-04 20:16:22 +02003914 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003915
3916 # read-only lockvar from scriptlevel
3917 lines =<< trim END
3918 vim9script
3919
3920 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003921 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02003922 endclass
3923 var o = C.new(3)
3924 lockvar o.val2
3925 END
3926 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3927
3928 # read-only lockvar of scriptlevel variable from def
3929 lines =<< trim END
3930 vim9script
3931
3932 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003933 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02003934 endclass
3935 var o = C.new(3)
3936 def Lock()
3937 lockvar o.val3
3938 enddef
3939 Lock()
3940 END
3941 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3942
3943 # read-only lockvar of def argument variable
3944 lines =<< trim END
3945 vim9script
3946
3947 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003948 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02003949 endclass
3950 def Lock(o: C)
3951 lockvar o.val4
3952 enddef
3953 Lock(C.new(3))
3954 END
3955 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3956
3957 # TODO: the following tests use type "any" for argument. Need a run time
3958 # check for access. Probably OK as is for now.
3959
3960 # read-only lockvar from object method arg
3961 lines =<< trim END
3962 vim9script
3963
3964 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003965 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02003966 def Lock(o_any: any)
3967 lockvar o_any.val5
3968 enddef
3969 endclass
3970 var o = C.new(3)
3971 o.Lock(C.new(5))
3972 END
Ernie Rael64885642023-10-04 20:16:22 +02003973 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003974
3975 # read-only lockvar from class method arg
3976 lines =<< trim END
3977 vim9script
3978
3979 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003980 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02003981 static def Lock(o_any: any)
3982 lockvar o_any.val6
3983 enddef
3984 endclass
3985 var o = C.new(3)
3986 C.Lock(o)
3987 END
Ernie Rael64885642023-10-04 20:16:22 +02003988 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003989
3990 #
3991 # lockvar of public object variable
3992 #
3993
3994 # lockvar from object method
3995 lines =<< trim END
3996 vim9script
3997
3998 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003999 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004000 def Lock()
4001 lockvar this.val1
4002 enddef
4003 endclass
4004 var o = C.new(3)
4005 o.Lock()
4006 END
4007 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4008
4009 # lockvar from scriptlevel
4010 lines =<< trim END
4011 vim9script
4012
4013 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004014 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004015 endclass
4016 var o = C.new(3)
4017 lockvar o.val2
4018 END
4019 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4020
4021 # lockvar of scriptlevel variable from def
4022 lines =<< trim END
4023 vim9script
4024
4025 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004026 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004027 endclass
4028 var o = C.new(3)
4029 def Lock()
4030 lockvar o.val3
4031 enddef
4032 Lock()
4033 END
4034 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4035
4036 # lockvar of def argument variable
4037 lines =<< trim END
4038 vim9script
4039
4040 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004041 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004042 endclass
4043 def Lock(o: C)
4044 lockvar o.val4
4045 enddef
4046 Lock(C.new(3))
4047 END
4048 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4049
4050 # lockvar from object method arg
4051 lines =<< trim END
4052 vim9script
4053
4054 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004055 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004056 def Lock(o_any: any)
4057 lockvar o_any.val5
4058 enddef
4059 endclass
4060 var o = C.new(3)
4061 o.Lock(C.new(5))
4062 END
4063 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4064
4065 # lockvar from class method arg
4066 lines =<< trim END
4067 vim9script
4068
4069 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004070 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004071 static def Lock(o_any: any)
4072 lockvar o_any.val6
4073 enddef
4074 endclass
4075 var o = C.new(3)
4076 C.Lock(o)
4077 END
4078 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4079enddef
4080
4081" Test trying to lock a class variable from various places
4082def Test_lockvar_class_variable()
4083
4084 # lockvar bare static from object method
4085 var lines =<< trim END
4086 vim9script
4087
4088 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004089 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004090 def Lock()
4091 lockvar sval1
4092 enddef
4093 endclass
4094 var o = C.new()
4095 o.Lock()
4096 END
4097 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4098
4099 # lockvar C.static from object method
4100 lines =<< trim END
4101 vim9script
4102
4103 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004104 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004105 def Lock()
4106 lockvar C.sval2
4107 enddef
4108 endclass
4109 var o = C.new()
4110 o.Lock()
4111 END
4112 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4113
4114 # lockvar bare static from class method
4115 lines =<< trim END
4116 vim9script
4117
4118 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004119 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004120 static def Lock()
4121 lockvar sval3
4122 enddef
4123 endclass
4124 C.Lock()
4125 END
4126 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4127
4128 # lockvar C.static from class method
4129 lines =<< trim END
4130 vim9script
4131
4132 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004133 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004134 static def Lock()
4135 lockvar C.sval4
4136 enddef
4137 endclass
4138 C.Lock()
4139 END
4140 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4141
4142 # lockvar C.static from script level
4143 lines =<< trim END
4144 vim9script
4145
4146 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004147 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004148 endclass
4149 lockvar C.sval5
4150 END
4151 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4152
4153 # lockvar o.static from script level
4154 lines =<< trim END
4155 vim9script
4156
4157 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004158 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004159 endclass
4160 var o = C.new()
4161 lockvar o.sval6
4162 END
4163 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4164enddef
4165
4166" Test locking an argument to :def
4167def Test_lockvar_argument()
4168 # Lockvar a function arg
4169 var lines =<< trim END
4170 vim9script
4171
4172 def Lock(val: any)
4173 lockvar val
4174 enddef
4175
4176 var d = {a: 1, b: 2}
4177 Lock(d)
4178
4179 d->extend({c: 3})
4180 END
4181 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4182
4183 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4184 # class member in "C". This tests lval_root_is_arg.
4185 lines =<< trim END
4186 vim9script
4187
4188 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004189 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004190 endclass
4191
4192 def Lock2(sval: any)
4193 lockvar sval
4194 enddef
4195
4196 var o = C.new()
4197 Lock2(o)
4198 END
4199 v9.CheckSourceSuccess(lines)
4200
4201 # Lock a class.
4202 lines =<< trim END
4203 vim9script
4204
4205 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004206 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004207 endclass
4208
4209 def Lock2(sval: any)
4210 lockvar sval
4211 enddef
4212
4213 Lock2(C)
4214 END
Ernie Raelb077b582023-12-14 20:11:44 +01004215 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004216
4217 # Lock an object.
4218 lines =<< trim END
4219 vim9script
4220
4221 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004222 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004223 endclass
4224
4225 def Lock2(sval: any)
4226 lockvar sval
4227 enddef
4228
4229 Lock2(C.new())
4230 END
4231 v9.CheckSourceSuccess(lines)
4232
4233 # In this case (unlike previous) "lockvar sval" is a class member.
4234 lines =<< trim END
4235 vim9script
4236
4237 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004238 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004239 def Lock2()
4240 lockvar sval
4241 enddef
4242 endclass
4243
4244
4245 var o = C.new()
4246 o.Lock2()
4247 END
4248 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4249enddef
4250
4251" Test that this can be locked without error
4252def Test_lockvar_this()
4253 # lockvar this
4254 var lines =<< trim END
4255 vim9script
4256 class C
4257 def TLock()
4258 lockvar this
4259 enddef
4260 endclass
4261 var o = C.new()
4262 o.TLock()
4263 END
4264 v9.CheckSourceSuccess(lines)
4265
4266 # lockvar four (four letter word, but not this)
4267 lines =<< trim END
4268 vim9script
4269 class C
4270 def TLock4()
4271 var four: number
4272 lockvar four
4273 enddef
4274 endclass
4275 var o = C.new()
4276 o.TLock4()
4277 END
4278 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4279
4280 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4281 lines =<< trim END
4282 vim9script
4283 class C
4284 def TLock5()
4285 var this5: number
4286 lockvar this5
4287 enddef
4288 endclass
4289 var o = C.new()
4290 o.TLock5()
4291 END
4292 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4293enddef
4294
4295" Test some general lockvar cases
4296def Test_lockvar_general()
4297 # lockvar an object and a class. It does nothing
4298 var lines =<< trim END
4299 vim9script
4300 class C
4301 endclass
4302 var o = C.new()
4303 lockvar o
4304 lockvar C
4305 END
4306 v9.CheckSourceSuccess(lines)
4307
4308 # Lock a list element that's nested in an object variable from a :def
4309 lines =<< trim END
4310 vim9script
4311
4312 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004313 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004314 endclass
4315 def Lock2(obj: any)
4316 lockvar obj.val[1]
4317 enddef
4318
4319 var o = C.new()
4320 Lock2(o)
4321 o.val[0] = [9]
4322 assert_equal([ [9], [2], [3] ], o.val)
4323 try
4324 o.val[1] = [999]
4325 call assert_false(true, 'assign should have failed')
4326 catch
4327 assert_exception('E741:')
4328 endtry
4329 o.val[2] = [8]
4330 assert_equal([ [9], [2], [8] ], o.val)
4331 END
4332 v9.CheckSourceSuccess(lines)
4333
4334 # Lock a list element that's nested in an object variable from scriptlevel
4335 lines =<< trim END
4336 vim9script
4337
4338 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004339 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004340 endclass
4341
4342 var o = C.new()
4343 lockvar o.val[1]
4344 o.val[0] = [9]
4345 assert_equal([ [9], [2], [3] ], o.val)
4346 try
4347 o.val[1] = [999]
4348 call assert_false(true, 'assign should have failed')
4349 catch
4350 assert_exception('E741:')
4351 endtry
4352 o.val[2] = [8]
4353 assert_equal([ [9], [2], [8] ], o.val)
4354 END
4355 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004356
4357 # lock a script level variable from an object method
4358 lines =<< trim END
4359 vim9script
4360
4361 class C
4362 def Lock()
4363 lockvar l
4364 enddef
4365 endclass
4366
4367 var l = [1]
4368 C.new().Lock()
4369 l[0] = 11
4370 END
4371 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4372
Ernie Rael03042a22023-11-11 08:53:32 +01004373 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004374 # in an object fetched via a script level list
4375 lines =<< trim END
4376 vim9script
4377
4378 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004379 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004380 def Lock()
4381 lockvar lc[0]._v1[1]
4382 enddef
4383 endclass
4384
4385 var l = [[1], [2], [3]]
4386 var o = C.new(l)
4387 var lc: list<C> = [ o ]
4388
4389 o.Lock()
4390 l[0] = [22]
4391 l[1] = [33]
4392 END
4393 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4394
4395 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004396 # in a class that does not own the protected variable.
4397 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004398 # the same name.
4399 lines =<< trim END
4400 vim9script
4401
4402 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004403 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004404 def Lock(obj: any)
4405 lockvar lc[0]._v1[1]
4406 enddef
4407 endclass
4408
4409 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004410 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004411 endclass
4412
4413 var l = [[1], [2], [3]]
4414 var o = C.new(l)
4415 var lc: list<C> = [ o ]
4416
4417 var o2 = C2.new()
4418 o2.Lock(o)
4419 END
Ernie Rael03042a22023-11-11 08:53:32 +01004420 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004421enddef
4422
Ernie Rael9771b2a2023-10-07 22:05:40 +02004423" Test builtin islocked()
4424def Test_lockvar_islocked()
4425 # Can't lock class/object variable
4426 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004427 # Lock item of variable's value (a list item)
4428 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004429 var lines =<< trim END
4430 vim9script
4431
4432 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004433 var o0: list<list<number>> = [ [0], [1], [2]]
4434 var o1: list<list<number>> = [[10], [11], [12]]
4435 static var c0: list<list<number>> = [[20], [21], [22]]
4436 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004437 endclass
4438
4439 def LockIt(arg: any)
4440 lockvar arg
4441 enddef
4442
4443 def UnlockIt(arg: any)
4444 unlockvar arg
4445 enddef
4446
4447 var obj = C.new()
4448 #lockvar obj.o1 # can't lock something you can't write to
4449
4450 try
4451 lockvar obj.o1 # can't lock something you can't write to
4452 call assert_false(1, '"lockvar obj.o1" should have failed')
4453 catch
4454 call assert_exception('E1335:')
4455 endtry
4456
4457 LockIt(obj.o1) # but can lock it's value
4458 assert_equal(1, islocked("obj.o1"))
4459 assert_equal(1, islocked("obj.o1[0]"))
4460 assert_equal(1, islocked("obj.o1[1]"))
4461 UnlockIt(obj.o1)
4462 assert_equal(0, islocked("obj.o1"))
4463 assert_equal(0, islocked("obj.o1[0]"))
4464
4465 lockvar obj.o1[0]
4466 assert_equal(0, islocked("obj.o1"))
4467 assert_equal(1, islocked("obj.o1[0]"))
4468 assert_equal(0, islocked("obj.o1[1]"))
4469 unlockvar obj.o1[0]
4470 assert_equal(0, islocked("obj.o1"))
4471 assert_equal(0, islocked("obj.o1[0]"))
4472
4473 # Same thing, but with a static
4474
4475 try
4476 lockvar C.c1 # can't lock something you can't write to
4477 call assert_false(1, '"lockvar C.c1" should have failed')
4478 catch
4479 call assert_exception('E1335:')
4480 endtry
4481
4482 LockIt(C.c1) # but can lock it's value
4483 assert_equal(1, islocked("C.c1"))
4484 assert_equal(1, islocked("C.c1[0]"))
4485 assert_equal(1, islocked("C.c1[1]"))
4486 UnlockIt(C.c1)
4487 assert_equal(0, islocked("C.c1"))
4488 assert_equal(0, islocked("C.c1[0]"))
4489
4490 lockvar C.c1[0]
4491 assert_equal(0, islocked("C.c1"))
4492 assert_equal(1, islocked("C.c1[0]"))
4493 assert_equal(0, islocked("C.c1[1]"))
4494 unlockvar C.c1[0]
4495 assert_equal(0, islocked("C.c1"))
4496 assert_equal(0, islocked("C.c1[0]"))
4497 END
4498 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004499
4500 # Do islocked() from an object method
4501 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004502 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004503 vim9script
4504
4505 var l0o0 = [ [0], [1], [2]]
4506 var l0o1 = [ [10], [11], [12]]
4507 var l0c0 = [[120], [121], [122]]
4508 var l0c1 = [[130], [131], [132]]
4509
4510 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004511 var o0: list<list<number>> = l0o0
4512 var o1: list<list<number>> = l0o1
4513 static var c0: list<list<number>> = l0c0
4514 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004515 def Islocked(arg: string): number
4516 return islocked(arg)
4517 enddef
4518 static def SIslocked(arg: string): number
4519 return islocked(arg)
4520 enddef
4521 endclass
4522
4523 var l2o0 = [[20000], [20001], [20002]]
4524 var l2o1 = [[20010], [20011], [20012]]
4525 var l2c0 = [[20120], [20121], [20122]]
4526 var l2c1 = [[20130], [20131], [20132]]
4527
4528 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004529 var o0: list<list<number>> = l2o0
4530 var o1: list<list<number>> = l2o1
4531 static var c0: list<list<number>> = l2c0
4532 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004533 def Islocked(arg: string): number
4534 return islocked(arg)
4535 enddef
4536 static def SIslocked(arg: string): number
4537 return islocked(arg)
4538 enddef
4539 endclass
4540
4541 var obj0 = C0.new()
4542 var obj2 = C2.new()
4543
4544 var l = [ obj0, null_object, obj2 ]
4545
4546 # lock list, object func access through script var expr
4547 assert_equal(0, obj0.Islocked("l[0].o0"))
4548 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4549 lockvar l0o0
4550 assert_equal(1, obj0.Islocked("l[0].o0"))
4551 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4552
4553 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4554
4555 # lock list element, object func access through script var expr
4556 lockvar l0o1[1]
4557 assert_equal(0, obj0.Islocked("this.o1[0]"))
4558 assert_equal(1, obj0.Islocked("this.o1[1]"))
4559
4560 assert_equal(0, obj0.Islocked("this.o1"))
4561 lockvar l0o1
4562 assert_equal(1, obj0.Islocked("this.o1"))
4563 unlockvar l0o1
4564
4565 lockvar l0c1[1]
4566
4567 # static by class name member expr from same class
4568 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4569 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4570 # static by bare name member expr from same class
4571 assert_equal(0, obj0.Islocked("c1[0]"))
4572 assert_equal(1, obj0.Islocked("c1[1]"))
4573
4574 # static by class name member expr from other class
4575 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4576 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4577 # static by bare name member expr from other class
4578 assert_equal(0, obj2.Islocked("c1[0]"))
4579 assert_equal(0, obj2.Islocked("c1[1]"))
4580
4581
4582 # static by bare name in same class
4583 assert_equal(0, obj0.Islocked("c0"))
4584 lockvar l0c0
4585 assert_equal(1, obj0.Islocked("c0"))
4586
4587 #
4588 # similar stuff, but use static method
4589 #
4590
4591 unlockvar l0o0
4592
4593 # lock list, object func access through script var expr
4594 assert_equal(0, C0.SIslocked("l[0].o0"))
4595 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4596 lockvar l0o0
4597 assert_equal(1, C0.SIslocked("l[0].o0"))
4598 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4599
4600 unlockvar l0o1
4601
4602 # can't access "this" from class method
4603 try
4604 C0.SIslocked("this.o1[0]")
4605 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4606 catch
4607 call assert_exception('E121: Undefined variable: this')
4608 endtry
4609
4610 lockvar l0c1[1]
4611
4612 # static by class name member expr from same class
4613 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4614 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4615 # static by bare name member expr from same class
4616 assert_equal(0, C0.SIslocked("c1[0]"))
4617 assert_equal(1, C0.SIslocked("c1[1]"))
4618
4619 # static by class name member expr from other class
4620 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4621 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4622 # static by bare name member expr from other class
4623 assert_equal(0, C2.SIslocked("c1[0]"))
4624 assert_equal(0, C2.SIslocked("c1[1]"))
4625
4626
4627 # static by bare name in same class
4628 unlockvar l0c0
4629 assert_equal(0, C0.SIslocked("c0"))
4630 lockvar l0c0
4631 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004632 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004633 v9.CheckSourceSuccess(lines)
4634
4635 # Check islocked class/object from various places.
4636 lines =<< trim END
4637 vim9script
4638
4639 class C
4640 def Islocked(arg: string): number
4641 return islocked(arg)
4642 enddef
4643 static def SIslocked(arg: string): number
4644 return islocked(arg)
4645 enddef
4646 endclass
4647 var obj = C.new()
4648
4649 # object method
4650 assert_equal(0, obj.Islocked("this"))
4651 assert_equal(0, obj.Islocked("C"))
4652
4653 # class method
4654 ### assert_equal(0, C.SIslocked("this"))
4655 assert_equal(0, C.SIslocked("C"))
4656
4657 #script level
4658 var v: number
4659 v = islocked("C")
4660 assert_equal(0, v)
4661 v = islocked("obj")
4662 assert_equal(0, v)
4663 END
4664 v9.CheckSourceSuccess(lines)
4665enddef
4666
4667def Test_lockvar_islocked_notfound()
4668 # Try non-existent things
4669 var lines =<< trim END
4670 vim9script
4671
4672 class C
4673 def Islocked(arg: string): number
4674 return islocked(arg)
4675 enddef
4676 static def SIslocked(arg: string): number
4677 return islocked(arg)
4678 enddef
4679 endclass
4680 var obj = C.new()
4681 assert_equal(-1, obj.Islocked("anywhere"))
4682 assert_equal(-1, C.SIslocked("notanywhere"))
4683 END
4684 v9.CheckSourceSuccess(lines)
4685
4686 # Something not found of the form "name1.name2" is an error
4687 lines =<< trim END
4688 vim9script
4689
4690 islocked("one.two")
4691 END
4692 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4693
4694 lines =<< trim END
4695 vim9script
4696
4697 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004698 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004699 def Islocked(arg: string): number
4700 return islocked(arg)
4701 enddef
4702 endclass
4703 var obj = C.new()
4704 obj.Islocked("this.val.not_there"))
4705 END
4706 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4707
4708 lines =<< trim END
4709 vim9script
4710
4711 class C
4712 def Islocked(arg: string): number
4713 return islocked(arg)
4714 enddef
4715 endclass
4716 var obj = C.new()
4717 obj.Islocked("this.notobjmember")
4718 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004719 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004720
4721 # access a script variable through methods
4722 lines =<< trim END
4723 vim9script
4724
4725 var l = [1]
4726 class C
4727 def Islocked(arg: string): number
4728 return islocked(arg)
4729 enddef
4730 static def SIslocked(arg: string): number
4731 return islocked(arg)
4732 enddef
4733 endclass
4734 var obj = C.new()
4735 assert_equal(0, obj.Islocked("l"))
4736 assert_equal(0, C.SIslocked("l"))
4737 lockvar l
4738 assert_equal(1, obj.Islocked("l"))
4739 assert_equal(1, C.SIslocked("l"))
4740 END
4741 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004742enddef
4743
Ernie Rael03042a22023-11-11 08:53:32 +01004744" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004745def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004746 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004747 var lines =<< trim END
4748 vim9script
4749
4750 class A
4751 def _Foo(): number
4752 return 1234
4753 enddef
4754 endclass
4755 var a = A.new()
4756 a._Foo()
4757 END
Ernie Rael03042a22023-11-11 08:53:32 +01004758 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004759
Ernie Rael03042a22023-11-11 08:53:32 +01004760 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004761 lines =<< trim END
4762 vim9script
4763
4764 class A
4765 def _Foo(): number
4766 return 1234
4767 enddef
4768 endclass
4769 def T()
4770 var a = A.new()
4771 a._Foo()
4772 enddef
4773 T()
4774 END
Ernie Rael03042a22023-11-11 08:53:32 +01004775 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004776
Ernie Rael03042a22023-11-11 08:53:32 +01004777 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004778 lines =<< trim END
4779 vim9script
4780
4781 class A
4782 def _Foo(): number
4783 return 1234
4784 enddef
4785 def Bar(): number
4786 return this._Foo()
4787 enddef
4788 endclass
4789 var a = A.new()
4790 assert_equal(1234, a.Bar())
4791 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004792 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004793
Ernie Rael03042a22023-11-11 08:53:32 +01004794 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004795 lines =<< trim END
4796 vim9script
4797
4798 class A
4799 def _Foo(): number
4800 return 1234
4801 enddef
4802 def Bar(): number
4803 return this._Foo()
4804 enddef
4805 endclass
4806 def T()
4807 var a = A.new()
4808 assert_equal(1234, a.Bar())
4809 enddef
4810 T()
4811 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004812 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004813
Ernie Rael03042a22023-11-11 08:53:32 +01004814 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004815 lines =<< trim END
4816 vim9script
4817
4818 class A
4819 def _Foo(): number
4820 return 1234
4821 enddef
4822 def Bar(): number
4823 return _Foo()
4824 enddef
4825 endclass
4826 var a = A.new()
4827 a.Bar()
4828 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004829 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004830
Ernie Rael03042a22023-11-11 08:53:32 +01004831 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004832 lines =<< trim END
4833 vim9script
4834
4835 class A
4836 def _Foo(): number
4837 return 1234
4838 enddef
4839 endclass
4840 A._Foo()
4841 END
Ernie Rael03042a22023-11-11 08:53:32 +01004842 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004843
Ernie Rael03042a22023-11-11 08:53:32 +01004844 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004845 lines =<< trim END
4846 vim9script
4847
4848 class A
4849 def _Foo()
4850 enddef
4851 def _Foo()
4852 enddef
4853 endclass
4854 var a = A.new()
4855 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004856 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004857
Ernie Rael03042a22023-11-11 08:53:32 +01004858 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004859 lines =<< trim END
4860 vim9script
4861
4862 class A
4863 def _Foo()
4864 enddef
4865 def Foo()
4866 enddef
4867 endclass
4868 var a = A.new()
4869 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004870 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004871
Ernie Rael03042a22023-11-11 08:53:32 +01004872 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004873 lines =<< trim END
4874 vim9script
4875
4876 class A
4877 def Foo()
4878 enddef
4879 def _Foo()
4880 enddef
4881 endclass
4882 var a = A.new()
4883 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004884 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004885
Ernie Rael03042a22023-11-11 08:53:32 +01004886 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004887 lines =<< trim END
4888 vim9script
4889
4890 class A
4891 def Foo(): number
4892 return 100
4893 enddef
4894 def _Bar(): number
4895 return 200
4896 enddef
4897 def _Baz()
4898 assert_equal(100, this.Foo())
4899 assert_equal(200, this._Bar())
4900 enddef
4901 def T()
4902 this._Baz()
4903 enddef
4904 endclass
4905 var a = A.new()
4906 a.T()
4907 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004908 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004909
Ernie Rael03042a22023-11-11 08:53:32 +01004910 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004911 lines =<< trim END
4912 vim9script
4913
4914 class A
4915 def _Foo(): number
4916 return 100
4917 enddef
4918 endclass
4919 class B
4920 def Foo(): number
4921 var a = A.new()
4922 a._Foo()
4923 enddef
4924 endclass
4925 var b = B.new()
4926 b.Foo()
4927 END
Ernie Rael03042a22023-11-11 08:53:32 +01004928 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004929
Ernie Rael03042a22023-11-11 08:53:32 +01004930 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004931 lines =<< trim END
4932 vim9script
4933 class A
4934 def _Foo(): number
4935 return 1234
4936 enddef
4937 endclass
4938 class B extends A
4939 def Bar()
4940 enddef
4941 endclass
4942 class C extends B
4943 def Baz(): number
4944 return this._Foo()
4945 enddef
4946 endclass
4947 var c = C.new()
4948 assert_equal(1234, c.Baz())
4949 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004950 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004951
Ernie Rael03042a22023-11-11 08:53:32 +01004952 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004953 lines =<< trim END
4954 vim9script
4955 class A
4956 def _Foo(): number
4957 return 1234
4958 enddef
4959 endclass
4960 class B extends A
4961 def Bar()
4962 enddef
4963 endclass
4964 class C extends B
4965 def Baz(): number
4966 enddef
4967 endclass
4968 var c = C.new()
4969 assert_equal(1234, c._Foo())
4970 END
Ernie Rael03042a22023-11-11 08:53:32 +01004971 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004972
4973 # Using "_" prefix in a method name should fail outside of a class
4974 lines =<< trim END
4975 vim9script
4976 def _Foo(): number
4977 return 1234
4978 enddef
4979 var a = _Foo()
4980 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004981 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004982enddef
4983
Ernie Rael03042a22023-11-11 08:53:32 +01004984" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004985def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004986 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004987 var lines =<< trim END
4988 vim9script
4989
4990 class A
4991 static def _Foo(): number
4992 return 1234
4993 enddef
4994 endclass
4995 A._Foo()
4996 END
Ernie Rael03042a22023-11-11 08:53:32 +01004997 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004998
Ernie Rael03042a22023-11-11 08:53:32 +01004999 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005000 lines =<< trim END
5001 vim9script
5002
5003 class A
5004 static def _Foo(): number
5005 return 1234
5006 enddef
5007 endclass
5008 def T()
5009 A._Foo()
5010 enddef
5011 T()
5012 END
Ernie Rael03042a22023-11-11 08:53:32 +01005013 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005014
Ernie Rael03042a22023-11-11 08:53:32 +01005015 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005016 lines =<< trim END
5017 vim9script
5018
5019 class A
5020 static def _Foo(): number
5021 return 1234
5022 enddef
5023 endclass
5024 var a = A.new()
5025 a._Foo()
5026 END
Ernie Rael03042a22023-11-11 08:53:32 +01005027 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005028
Ernie Rael03042a22023-11-11 08:53:32 +01005029 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005030 lines =<< trim END
5031 vim9script
5032
5033 class A
5034 static def _Foo(): number
5035 return 1234
5036 enddef
5037 endclass
5038 def T()
5039 var a = A.new()
5040 a._Foo()
5041 enddef
5042 T()
5043 END
Ernie Rael03042a22023-11-11 08:53:32 +01005044 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005045
Ernie Rael03042a22023-11-11 08:53:32 +01005046 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005047 lines =<< trim END
5048 vim9script
5049
5050 class A
5051 static def _Foo(): number
5052 return 1234
5053 enddef
5054 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005055 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005056 enddef
5057 endclass
5058 var a = A.new()
5059 a.Bar()
5060 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005061 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005062
Ernie Rael03042a22023-11-11 08:53:32 +01005063 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005064 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005065 lines =<< trim END
5066 vim9script
5067
5068 class A
5069 static def _Foo1(): number
5070 return 1234
5071 enddef
5072 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005073 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005074 enddef
5075 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005076 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005077 enddef
5078 endclass
5079 var a = A.new()
5080 a.Bar()
5081 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005082 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005083
Ernie Rael03042a22023-11-11 08:53:32 +01005084 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005085 lines =<< trim END
5086 vim9script
5087
5088 class A
5089 static def _Foo()
5090 enddef
5091 static def Foo()
5092 enddef
5093 endclass
5094 var a = A.new()
5095 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005096 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005097
Ernie Rael03042a22023-11-11 08:53:32 +01005098 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005099 lines =<< trim END
5100 vim9script
5101
5102 class A
5103 static def _Foo(): number
5104 return 1234
5105 enddef
5106 endclass
5107 class B
5108 def Foo(): number
5109 return A._Foo()
5110 enddef
5111 endclass
5112 var b = B.new()
5113 assert_equal(1234, b.Foo())
5114 END
Ernie Rael03042a22023-11-11 08:53:32 +01005115 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005116
Ernie Rael03042a22023-11-11 08:53:32 +01005117 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005118 lines =<< trim END
5119 vim9script
5120 class A
5121 static def _Foo(): number
5122 return 1234
5123 enddef
5124 endclass
5125 class B extends A
5126 def Bar()
5127 enddef
5128 endclass
5129 class C extends B
5130 def Baz(): number
5131 return A._Foo()
5132 enddef
5133 endclass
5134 var c = C.new()
5135 assert_equal(1234, c.Baz())
5136 END
Ernie Rael03042a22023-11-11 08:53:32 +01005137 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005138
Ernie Rael03042a22023-11-11 08:53:32 +01005139 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005140 lines =<< trim END
5141 vim9script
5142 class A
5143 static def _Foo(): number
5144 return 1234
5145 enddef
5146 endclass
5147 class B extends A
5148 def Bar()
5149 enddef
5150 endclass
5151 class C extends B
5152 static def Baz(): number
5153 return A._Foo()
5154 enddef
5155 endclass
5156 assert_equal(1234, C.Baz())
5157 END
Ernie Rael03042a22023-11-11 08:53:32 +01005158 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005159
Ernie Rael03042a22023-11-11 08:53:32 +01005160 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005161 lines =<< trim END
5162 vim9script
5163 class A
5164 static def _Foo(): number
5165 return 1234
5166 enddef
5167 endclass
5168 class B extends A
5169 def Bar()
5170 enddef
5171 endclass
5172 class C extends B
5173 def Baz(): number
5174 enddef
5175 endclass
5176 var c = C.new()
5177 assert_equal(1234, C._Foo())
5178 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005179 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005180enddef
5181
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005182" Test for using the return value of a class/object method as a function
5183" argument.
5184def Test_objmethod_funcarg()
5185 var lines =<< trim END
5186 vim9script
5187
5188 class C
5189 def Foo(): string
5190 return 'foo'
5191 enddef
5192 endclass
5193
5194 def Bar(a: number, s: string): string
5195 return s
5196 enddef
5197
5198 def Baz(c: C)
5199 assert_equal('foo', Bar(10, c.Foo()))
5200 enddef
5201
5202 var t = C.new()
5203 Baz(t)
5204 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005205 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005206
5207 lines =<< trim END
5208 vim9script
5209
5210 class C
5211 static def Foo(): string
5212 return 'foo'
5213 enddef
5214 endclass
5215
5216 def Bar(a: number, s: string): string
5217 return s
5218 enddef
5219
5220 def Baz()
5221 assert_equal('foo', Bar(10, C.Foo()))
5222 enddef
5223
5224 Baz()
5225 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005226 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005227enddef
5228
Ernie Raelcf138d42023-09-06 20:45:03 +02005229def Test_static_inheritence()
5230 # subclasses get their own static copy
5231 var lines =<< trim END
5232 vim9script
5233
5234 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005235 static var _svar: number
5236 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005237 def new()
5238 _svar = 1
5239 this._mvar = 101
5240 enddef
5241 def AccessObject(): number
5242 return this._mvar
5243 enddef
5244 def AccessStaticThroughObject(): number
5245 return _svar
5246 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005247 endclass
5248
5249 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005250 def new()
5251 this._mvar = 102
5252 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005253 endclass
5254
5255 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005256 def new()
5257 this._mvar = 103
5258 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005259
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005260 def AccessPrivateStaticThroughClassName(): number
5261 assert_equal(1, A._svar)
5262 return 444
5263 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005264 endclass
5265
5266 var oa = A.new()
5267 var ob = B.new()
5268 var oc = C.new()
5269 assert_equal(101, oa.AccessObject())
5270 assert_equal(102, ob.AccessObject())
5271 assert_equal(103, oc.AccessObject())
5272
Ernie Rael03042a22023-11-11 08:53:32 +01005273 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005274
5275 # verify object properly resolves to correct static
5276 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005277 assert_equal(1, ob.AccessStaticThroughObject())
5278 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005279 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005280 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005281enddef
5282
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005283" Test for declaring duplicate object and class members
5284def Test_dup_member_variable()
5285 # Duplicate member variable
5286 var lines =<< trim END
5287 vim9script
5288 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005289 var val = 10
5290 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005291 endclass
5292 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005293 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005294
Ernie Rael03042a22023-11-11 08:53:32 +01005295 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005296 lines =<< trim END
5297 vim9script
5298 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005299 var _val = 10
5300 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005301 endclass
5302 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005303 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005304
5305 # Duplicate public member variable
5306 lines =<< trim END
5307 vim9script
5308 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005309 public var val = 10
5310 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005311 endclass
5312 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005313 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005314
Ernie Rael03042a22023-11-11 08:53:32 +01005315 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005316 lines =<< trim END
5317 vim9script
5318 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005319 var val = 10
5320 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005321 endclass
5322 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005323 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005324
Ernie Rael03042a22023-11-11 08:53:32 +01005325 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005326 lines =<< trim END
5327 vim9script
5328 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005329 var _val = 20
5330 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005331 endclass
5332 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005333 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005334
5335 # Duplicate class member variable
5336 lines =<< trim END
5337 vim9script
5338 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005339 static var s: string = "abc"
5340 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005341 endclass
5342 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005343 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005344
Ernie Rael03042a22023-11-11 08:53:32 +01005345 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005346 lines =<< trim END
5347 vim9script
5348 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005349 public static var s: string = "abc"
5350 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005351 endclass
5352 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005353 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005354
5355 # Duplicate class and object member variable
5356 lines =<< trim END
5357 vim9script
5358 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005359 static var val = 10
5360 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005361 def new()
5362 enddef
5363 endclass
5364 var c = C.new()
5365 assert_equal(10, C.val)
5366 assert_equal(20, c.val)
5367 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005368 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005369
5370 # Duplicate object member variable in a derived class
5371 lines =<< trim END
5372 vim9script
5373 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005374 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005375 endclass
5376 class B extends A
5377 endclass
5378 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005379 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005380 endclass
5381 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005382 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005383
Ernie Rael03042a22023-11-11 08:53:32 +01005384 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005385 lines =<< trim END
5386 vim9script
5387 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005388 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005389 endclass
5390 class B extends A
5391 endclass
5392 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005393 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005394 endclass
5395 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005396 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005397
Ernie Rael03042a22023-11-11 08:53:32 +01005398 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005399 lines =<< trim END
5400 vim9script
5401 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005402 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005403 endclass
5404 class B extends A
5405 endclass
5406 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005407 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005408 endclass
5409 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005410 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005411
5412 # Duplicate object member variable in a derived class
5413 lines =<< trim END
5414 vim9script
5415 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005416 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005417 endclass
5418 class B extends A
5419 endclass
5420 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005421 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005422 endclass
5423 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005424 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005425
5426 # Two member variables with a common prefix
5427 lines =<< trim END
5428 vim9script
5429 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005430 public static var svar2: number
5431 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005432 endclass
5433 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005434 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005435enddef
5436
Ernie Rael03042a22023-11-11 08:53:32 +01005437" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005438def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005439 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005440 var lines =<< trim END
5441 vim9script
5442 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005443 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005444 def GetVal(): number
5445 return this._val
5446 enddef
5447 endclass
5448 def T()
5449 var a = A.new()
5450 a._val = 20
5451 enddef
5452 T()
5453 END
Ernie Rael03042a22023-11-11 08:53:32 +01005454 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005455
Ernie Rael03042a22023-11-11 08:53:32 +01005456 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005457 lines =<< trim END
5458 vim9script
5459 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005460 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005461 endclass
5462 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005463 var a = A.new()
5464 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005465 enddef
5466 T()
5467 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005468 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005469
Ernie Rael03042a22023-11-11 08:53:32 +01005470 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005471 lines =<< trim END
5472 vim9script
5473 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005474 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005475 endclass
5476 def T()
5477 var a = A.new()
5478 var x = a._val
5479 enddef
5480 T()
5481 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005482 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005483
Ernie Rael03042a22023-11-11 08:53:32 +01005484 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005485 lines =<< trim END
5486 vim9script
5487 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005488 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005489 endclass
5490 def T()
5491 var a = A.new()
5492 a._val = 3
5493 enddef
5494 T()
5495 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005496 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005497
Ernie Rael03042a22023-11-11 08:53:32 +01005498 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005499 lines =<< trim END
5500 vim9script
5501 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005502 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005503 endclass
5504 def T()
5505 var x = A._val
5506 enddef
5507 T()
5508 END
Ernie Rael03042a22023-11-11 08:53:32 +01005509 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005510
Ernie Rael03042a22023-11-11 08:53:32 +01005511 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005512 lines =<< trim END
5513 vim9script
5514 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005515 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005516 endclass
5517 def T()
5518 A._val = 3
5519 enddef
5520 T()
5521 END
Ernie Rael03042a22023-11-11 08:53:32 +01005522 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005523enddef
5524
5525" Test for changing the member access of an interface in a implementation class
5526def Test_change_interface_member_access()
5527 var lines =<< trim END
5528 vim9script
5529 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005530 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005531 endinterface
5532 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005533 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005534 endclass
5535 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005536 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005537
5538 lines =<< trim END
5539 vim9script
5540 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005541 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005542 endinterface
5543 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005544 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005545 endclass
5546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005547 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005548enddef
5549
5550" Test for trying to change a readonly member from a def function
5551def Test_readonly_member_change_in_def_func()
5552 var lines =<< trim END
5553 vim9script
5554 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005555 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005556 endclass
5557 def T()
5558 var a = A.new()
5559 a.val = 20
5560 enddef
5561 T()
5562 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005563 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005564enddef
5565
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005566" Test for reading and writing a class member from a def function
5567def Test_modify_class_member_from_def_function()
5568 var lines =<< trim END
5569 vim9script
5570 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005571 var var1: number = 10
5572 public static var var2: list<number> = [1, 2]
5573 public static var var3: dict<number> = {a: 1, b: 2}
5574 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005575 endclass
5576 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005577 assert_equal([1, 2], A.var2)
5578 assert_equal({a: 1, b: 2}, A.var3)
5579 A.var2 = [3, 4]
5580 A.var3 = {c: 3, d: 4}
5581 assert_equal([3, 4], A.var2)
5582 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005583 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005584 enddef
5585 T()
5586 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005587 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005588enddef
5589
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005590" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005591def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005592 var lines =<< trim END
5593 vim9script
5594 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005595 public static var svar1: list<number> = [1]
5596 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005597 endclass
5598
5599 A.svar1->add(3)
5600 A.svar2->add(4)
5601 assert_equal([1, 3], A.svar1)
5602 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005603
5604 def Foo()
5605 A.svar1->add(7)
5606 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005607 assert_equal([1, 3, 7], A.svar1)
5608 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005609 enddef
5610 Foo()
5611 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005612 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005613
5614 # Cannot read from a class variable using an object in script context
5615 lines =<< trim END
5616 vim9script
5617 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005618 public var var1: number
5619 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005620 endclass
5621
5622 var a = A.new()
5623 echo a.svar2
5624 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005625 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005626
5627 # Cannot write to a class variable using an object in script context
5628 lines =<< trim END
5629 vim9script
5630 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005631 public var var1: number
5632 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005633 endclass
5634
5635 var a = A.new()
5636 a.svar2 = [2]
5637 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005638 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005639
5640 # Cannot read from a class variable using an object in def method context
5641 lines =<< trim END
5642 vim9script
5643 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005644 public var var1: number
5645 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005646 endclass
5647
5648 def T()
5649 var a = A.new()
5650 echo a.svar2
5651 enddef
5652 T()
5653 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005654 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005655
5656 # Cannot write to a class variable using an object in def method context
5657 lines =<< trim END
5658 vim9script
5659 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005660 public var var1: number
5661 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005662 endclass
5663
5664 def T()
5665 var a = A.new()
5666 a.svar2 = [2]
5667 enddef
5668 T()
5669 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005670 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005671enddef
5672
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005673" Test for using a interface method using a child object
5674def Test_interface_method_from_child()
5675 var lines =<< trim END
5676 vim9script
5677
5678 interface A
5679 def Foo(): string
5680 endinterface
5681
5682 class B implements A
5683 def Foo(): string
5684 return 'foo'
5685 enddef
5686 endclass
5687
5688 class C extends B
5689 def Bar(): string
5690 return 'bar'
5691 enddef
5692 endclass
5693
5694 def T1(a: A)
5695 assert_equal('foo', a.Foo())
5696 enddef
5697
5698 def T2(b: B)
5699 assert_equal('foo', b.Foo())
5700 enddef
5701
5702 var c = C.new()
5703 T1(c)
5704 T2(c)
5705 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005706 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005707enddef
5708
5709" Test for using an interface method using a child object when it is overridden
5710" by the child class.
5711" FIXME: This test fails.
5712" def Test_interface_overridden_method_from_child()
5713" var lines =<< trim END
5714" vim9script
5715"
5716" interface A
5717" def Foo(): string
5718" endinterface
5719"
5720" class B implements A
5721" def Foo(): string
5722" return 'b-foo'
5723" enddef
5724" endclass
5725"
5726" class C extends B
5727" def Bar(): string
5728" return 'bar'
5729" enddef
5730" def Foo(): string
5731" return 'c-foo'
5732" enddef
5733" endclass
5734"
5735" def T1(a: A)
5736" assert_equal('c-foo', a.Foo())
5737" enddef
5738"
5739" def T2(b: B)
5740" assert_equal('c-foo', b.Foo())
5741" enddef
5742"
5743" var c = C.new()
5744" T1(c)
5745" T2(c)
5746" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005747" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005748" enddef
5749
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005750" Test for abstract methods
5751def Test_abstract_method()
5752 # Use two abstract methods
5753 var lines =<< trim END
5754 vim9script
5755 abstract class A
5756 def M1(): number
5757 return 10
5758 enddef
5759 abstract def M2(): number
5760 abstract def M3(): number
5761 endclass
5762 class B extends A
5763 def M2(): number
5764 return 20
5765 enddef
5766 def M3(): number
5767 return 30
5768 enddef
5769 endclass
5770 var b = B.new()
5771 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5772 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005773 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005774
5775 # Don't define an abstract method
5776 lines =<< trim END
5777 vim9script
5778 abstract class A
5779 abstract def Foo()
5780 endclass
5781 class B extends A
5782 endclass
5783 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005784 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005785
5786 # Use abstract method in a concrete class
5787 lines =<< trim END
5788 vim9script
5789 class A
5790 abstract def Foo()
5791 endclass
5792 class B extends A
5793 endclass
5794 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005795 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005796
5797 # Use abstract method in an interface
5798 lines =<< trim END
5799 vim9script
5800 interface A
5801 abstract def Foo()
5802 endinterface
5803 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005804 def Foo()
5805 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005806 endclass
5807 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005808 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5809
5810 # Use abstract static method in an interface
5811 lines =<< trim END
5812 vim9script
5813 interface A
5814 abstract static def Foo()
5815 enddef
5816 endinterface
5817 END
5818 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5819
5820 # Use abstract static variable in an interface
5821 lines =<< trim END
5822 vim9script
5823 interface A
5824 abstract static foo: number = 10
5825 endinterface
5826 END
5827 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005828
5829 # Abbreviate the "abstract" keyword
5830 lines =<< trim END
5831 vim9script
5832 class A
5833 abs def Foo()
5834 endclass
5835 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005836 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005837
5838 # Use "abstract" with a member variable
5839 lines =<< trim END
5840 vim9script
5841 abstract class A
5842 abstract this.val = 10
5843 endclass
5844 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005845 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005846
5847 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01005848 lines =<< trim END
5849 vim9script
5850 abstract class A
5851 abstract static def Foo(): number
5852 endclass
5853 END
5854 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005855
5856 # Type mismatch between abstract method and concrete method
5857 lines =<< trim END
5858 vim9script
5859 abstract class A
5860 abstract def Foo(a: string, b: number): list<number>
5861 endclass
5862 class B extends A
5863 def Foo(a: number, b: string): list<string>
5864 return []
5865 enddef
5866 endclass
5867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005868 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 +02005869
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005870 # Invoke an abstract method from a def function
5871 lines =<< trim END
5872 vim9script
5873 abstract class A
5874 abstract def Foo(): list<number>
5875 endclass
5876 class B extends A
5877 def Foo(): list<number>
5878 return [3, 5]
5879 enddef
5880 endclass
5881 def Bar(c: B)
5882 assert_equal([3, 5], c.Foo())
5883 enddef
5884 var b = B.new()
5885 Bar(b)
5886 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005887 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005888
5889 # Use a static method in an abstract class
5890 lines =<< trim END
5891 vim9script
5892 abstract class A
5893 static def Foo(): string
5894 return 'foo'
5895 enddef
5896 endclass
5897 assert_equal('foo', A.Foo())
5898 END
5899 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005900enddef
5901
5902" Test for calling a class method from a subclass
5903def Test_class_method_call_from_subclass()
5904 # class method call from a subclass
5905 var lines =<< trim END
5906 vim9script
5907
5908 class A
5909 static def Foo()
5910 echo "foo"
5911 enddef
5912 endclass
5913
5914 class B extends A
5915 def Bar()
5916 Foo()
5917 enddef
5918 endclass
5919
5920 var b = B.new()
5921 b.Bar()
5922 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005923 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005924enddef
5925
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005926" Test for calling a class method using an object in a def function context and
5927" script context.
5928def Test_class_method_call_using_object()
5929 # script context
5930 var lines =<< trim END
5931 vim9script
5932 class A
5933 static def Foo(): list<string>
5934 return ['a', 'b']
5935 enddef
5936 def Bar()
5937 assert_equal(['a', 'b'], A.Foo())
5938 assert_equal(['a', 'b'], Foo())
5939 enddef
5940 endclass
5941
5942 def T()
5943 assert_equal(['a', 'b'], A.Foo())
5944 var t_a = A.new()
5945 t_a.Bar()
5946 enddef
5947
5948 assert_equal(['a', 'b'], A.Foo())
5949 var a = A.new()
5950 a.Bar()
5951 T()
5952 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005953 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005954
5955 # script context
5956 lines =<< trim END
5957 vim9script
5958 class A
5959 static def Foo(): string
5960 return 'foo'
5961 enddef
5962 endclass
5963
5964 var a = A.new()
5965 assert_equal('foo', a.Foo())
5966 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005967 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005968
5969 # def function context
5970 lines =<< trim END
5971 vim9script
5972 class A
5973 static def Foo(): string
5974 return 'foo'
5975 enddef
5976 endclass
5977
5978 def T()
5979 var a = A.new()
5980 assert_equal('foo', a.Foo())
5981 enddef
5982 T()
5983 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005984 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005985enddef
5986
5987def Test_class_variable()
5988 var lines =<< trim END
5989 vim9script
5990
5991 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005992 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005993 static def ClassFunc()
5994 assert_equal(10, val)
5995 enddef
5996 def ObjFunc()
5997 assert_equal(10, val)
5998 enddef
5999 endclass
6000
6001 class B extends A
6002 endclass
6003
6004 assert_equal(10, A.val)
6005 A.ClassFunc()
6006 var a = A.new()
6007 a.ObjFunc()
6008 var b = B.new()
6009 b.ObjFunc()
6010
6011 def T1(a1: A)
6012 a1.ObjFunc()
6013 A.ClassFunc()
6014 enddef
6015 T1(b)
6016
6017 A.val = 20
6018 assert_equal(20, A.val)
6019 END
6020 v9.CheckSourceSuccess(lines)
6021
6022 # Modifying a parent class variable from a child class method
6023 lines =<< trim END
6024 vim9script
6025
6026 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006027 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006028 endclass
6029
6030 class B extends A
6031 static def ClassFunc()
6032 val = 20
6033 enddef
6034 endclass
6035 B.ClassFunc()
6036 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006037 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006038
6039 # Reading a parent class variable from a child class method
6040 lines =<< trim END
6041 vim9script
6042
6043 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006044 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006045 endclass
6046
6047 class B extends A
6048 static def ClassFunc()
6049 var i = val
6050 enddef
6051 endclass
6052 B.ClassFunc()
6053 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006054 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006055
6056 # Modifying a parent class variable from a child object method
6057 lines =<< trim END
6058 vim9script
6059
6060 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006061 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006062 endclass
6063
6064 class B extends A
6065 def ObjFunc()
6066 val = 20
6067 enddef
6068 endclass
6069 var b = B.new()
6070 b.ObjFunc()
6071 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006072 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006073
6074 # Reading a parent class variable from a child object method
6075 lines =<< trim END
6076 vim9script
6077
6078 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006079 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006080 endclass
6081
6082 class B extends A
6083 def ObjFunc()
6084 var i = val
6085 enddef
6086 endclass
6087 var b = B.new()
6088 b.ObjFunc()
6089 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006090 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006091
6092 # Modifying a class variable using an object at script level
6093 lines =<< trim END
6094 vim9script
6095
6096 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006097 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006098 endclass
6099 var a = A.new()
6100 a.val = 20
6101 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006102 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006103
6104 # Reading a class variable using an object at script level
6105 lines =<< trim END
6106 vim9script
6107
6108 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006109 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006110 endclass
6111 var a = A.new()
6112 var i = a.val
6113 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006114 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006115
6116 # Modifying a class variable using an object at function level
6117 lines =<< trim END
6118 vim9script
6119
6120 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006121 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006122 endclass
6123
6124 def T()
6125 var a = A.new()
6126 a.val = 20
6127 enddef
6128 T()
6129 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006130 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006131
6132 # Reading a class variable using an object at function level
6133 lines =<< trim END
6134 vim9script
6135
6136 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006137 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006138 endclass
6139 def T()
6140 var a = A.new()
6141 var i = a.val
6142 enddef
6143 T()
6144 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006145 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006146
6147 # Use old implicit var declaration syntax (without initialization)
6148 lines =<< trim END
6149 vim9script
6150
6151 class A
6152 static val: number
6153 endclass
6154 END
6155 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6156
6157 # Use old implicit var declaration syntax (with initialization)
6158 lines =<< trim END
6159 vim9script
6160
6161 class A
6162 static val: number = 10
6163 endclass
6164 END
6165 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6166
6167 # Use old implicit var declaration syntax (type inferred)
6168 lines =<< trim END
6169 vim9script
6170
6171 class A
6172 static val = 10
6173 endclass
6174 END
6175 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6176
6177 # Missing ":var" in "var" class variable declaration (without initialization)
6178 lines =<< trim END
6179 vim9script
6180
6181 class A
6182 static var: number
6183 endclass
6184 END
6185 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6186
6187 # Missing ":var" in "var" class variable declaration (with initialization)
6188 lines =<< trim END
6189 vim9script
6190
6191 class A
6192 static var: number = 10
6193 endclass
6194 END
6195 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6196
6197 # Missing ":var" in "var" class variable declaration (type inferred)
6198 lines =<< trim END
6199 vim9script
6200
6201 class A
6202 static var = 10
6203 endclass
6204 END
6205 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6206
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006207enddef
6208
6209" Test for using a duplicate class method and class variable in a child class
6210def Test_dup_class_member()
6211 # duplicate class variable, class method and overridden object method
6212 var lines =<< trim END
6213 vim9script
6214 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006215 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006216 static def Check()
6217 assert_equal(100, sval)
6218 enddef
6219 def GetVal(): number
6220 return sval
6221 enddef
6222 endclass
6223
6224 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006225 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006226 static def Check()
6227 assert_equal(200, sval)
6228 enddef
6229 def GetVal(): number
6230 return sval
6231 enddef
6232 endclass
6233
6234 def T1(aa: A): number
6235 return aa.GetVal()
6236 enddef
6237
6238 def T2(bb: B): number
6239 return bb.GetVal()
6240 enddef
6241
6242 assert_equal(100, A.sval)
6243 assert_equal(200, B.sval)
6244 var a = A.new()
6245 assert_equal(100, a.GetVal())
6246 var b = B.new()
6247 assert_equal(200, b.GetVal())
6248 assert_equal(200, T1(b))
6249 assert_equal(200, T2(b))
6250 END
6251 v9.CheckSourceSuccess(lines)
6252
6253 # duplicate class variable and class method
6254 lines =<< trim END
6255 vim9script
6256 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006257 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006258 static def Check()
6259 assert_equal(100, sval)
6260 enddef
6261 def GetVal(): number
6262 return sval
6263 enddef
6264 endclass
6265
6266 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006267 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006268 static def Check()
6269 assert_equal(200, sval)
6270 enddef
6271 endclass
6272
6273 def T1(aa: A): number
6274 return aa.GetVal()
6275 enddef
6276
6277 def T2(bb: B): number
6278 return bb.GetVal()
6279 enddef
6280
6281 assert_equal(100, A.sval)
6282 assert_equal(200, B.sval)
6283 var a = A.new()
6284 assert_equal(100, a.GetVal())
6285 var b = B.new()
6286 assert_equal(100, b.GetVal())
6287 assert_equal(100, T1(b))
6288 assert_equal(100, T2(b))
6289 END
6290 v9.CheckSourceSuccess(lines)
6291enddef
6292
6293" Test for calling an instance method using the class
6294def Test_instance_method_call_using_class()
6295 # Invoke an object method using a class in script context
6296 var lines =<< trim END
6297 vim9script
6298 class A
6299 def Foo()
6300 echo "foo"
6301 enddef
6302 endclass
6303 A.Foo()
6304 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006305 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006306
6307 # Invoke an object method using a class in def function context
6308 lines =<< trim END
6309 vim9script
6310 class A
6311 def Foo()
6312 echo "foo"
6313 enddef
6314 endclass
6315 def T()
6316 A.Foo()
6317 enddef
6318 T()
6319 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006320 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006321enddef
6322
6323" Test for duplicate class method and instance method
6324def Test_dup_classmethod_objmethod()
6325 # Duplicate instance method
6326 var lines =<< trim END
6327 vim9script
6328 class A
6329 static def Foo()
6330 enddef
6331 def Foo()
6332 enddef
6333 endclass
6334 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006335 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006336
Ernie Rael03042a22023-11-11 08:53:32 +01006337 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006338 lines =<< trim END
6339 vim9script
6340 class A
6341 static def Foo()
6342 enddef
6343 def _Foo()
6344 enddef
6345 endclass
6346 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006347 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006348
6349 # Duplicate class method
6350 lines =<< trim END
6351 vim9script
6352 class A
6353 def Foo()
6354 enddef
6355 static def Foo()
6356 enddef
6357 endclass
6358 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006359 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006360
Ernie Rael03042a22023-11-11 08:53:32 +01006361 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006362 lines =<< trim END
6363 vim9script
6364 class A
6365 def Foo()
6366 enddef
6367 static def _Foo()
6368 enddef
6369 endclass
6370 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006371 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006372
Ernie Rael03042a22023-11-11 08:53:32 +01006373 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006374 lines =<< trim END
6375 vim9script
6376 class A
6377 def _Foo()
6378 enddef
6379 static def _Foo()
6380 enddef
6381 endclass
6382 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006383 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006384enddef
6385
6386" Test for an instance method access level comparison with parent instance
6387" methods.
6388def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006389 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006390 var lines =<< trim END
6391 vim9script
6392 class A
6393 def Foo()
6394 enddef
6395 endclass
6396 class B extends A
6397 endclass
6398 class C extends B
6399 def _Foo()
6400 enddef
6401 endclass
6402 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006403 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006404
6405 # Public method in subclass
6406 lines =<< trim END
6407 vim9script
6408 class A
6409 def _Foo()
6410 enddef
6411 endclass
6412 class B extends A
6413 endclass
6414 class C extends B
6415 def Foo()
6416 enddef
6417 endclass
6418 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006419 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006420enddef
6421
6422def Test_extend_empty_class()
6423 var lines =<< trim END
6424 vim9script
6425 class A
6426 endclass
6427 class B extends A
6428 endclass
6429 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006430 public static var rw_class_var = 1
6431 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006432 static def ClassMethod(): number
6433 return 3
6434 enddef
6435 def ObjMethod(): number
6436 return 4
6437 enddef
6438 endclass
6439 assert_equal(1, C.rw_class_var)
6440 assert_equal(3, C.ClassMethod())
6441 var c = C.new()
6442 assert_equal(2, c.rw_obj_var)
6443 assert_equal(4, c.ObjMethod())
6444 END
6445 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006446enddef
6447
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006448" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006449" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006450def Test_interface_with_unsupported_members()
6451 var lines =<< trim END
6452 vim9script
6453 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006454 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006455 endinterface
6456 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006457 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006458
6459 lines =<< trim END
6460 vim9script
6461 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006462 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006463 endinterface
6464 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006465 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006466
6467 lines =<< trim END
6468 vim9script
6469 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006470 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006471 endinterface
6472 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006473 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006474
6475 lines =<< trim END
6476 vim9script
6477 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006478 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006479 endinterface
6480 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006481 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006482
6483 lines =<< trim END
6484 vim9script
6485 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006486 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006487 endinterface
6488 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006489 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006490
6491 lines =<< trim END
6492 vim9script
6493 interface A
6494 static def Foo(d: dict<any>): list<string>
6495 endinterface
6496 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006497 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006498
6499 lines =<< trim END
6500 vim9script
6501 interface A
6502 static def _Foo(d: dict<any>): list<string>
6503 endinterface
6504 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006505 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006506
6507 lines =<< trim END
6508 vim9script
6509 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006510 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006511 endinterface
6512 END
Ernie Rael03042a22023-11-11 08:53:32 +01006513 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006514
6515 lines =<< trim END
6516 vim9script
6517 interface A
6518 def _Foo(d: dict<any>): list<string>
6519 endinterface
6520 END
Ernie Rael03042a22023-11-11 08:53:32 +01006521 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006522enddef
6523
6524" Test for extending an interface
6525def Test_extend_interface()
6526 var lines =<< trim END
6527 vim9script
6528 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006529 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006530 def Foo()
6531 endinterface
6532 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006533 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006534 def Bar()
6535 endinterface
6536 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006537 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006538 def Foo()
6539 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006540 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006541 def Bar()
6542 enddef
6543 endclass
6544 END
6545 v9.CheckSourceSuccess(lines)
6546
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006547 # extending empty interface
6548 lines =<< trim END
6549 vim9script
6550 interface A
6551 endinterface
6552 interface B extends A
6553 endinterface
6554 class C implements B
6555 endclass
6556 END
6557 v9.CheckSourceSuccess(lines)
6558
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006559 lines =<< trim END
6560 vim9script
6561 interface A
6562 def Foo()
6563 endinterface
6564 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006565 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006566 endinterface
6567 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006568 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006569 endclass
6570 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006571 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006572
6573 lines =<< trim END
6574 vim9script
6575 interface A
6576 def Foo()
6577 endinterface
6578 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006579 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006580 endinterface
6581 class C implements A, B
6582 def Foo()
6583 enddef
6584 endclass
6585 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006586 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006587
6588 # interface cannot extend a class
6589 lines =<< trim END
6590 vim9script
6591 class A
6592 endclass
6593 interface B extends A
6594 endinterface
6595 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006596 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006597
6598 # class cannot extend an interface
6599 lines =<< trim END
6600 vim9script
6601 interface A
6602 endinterface
6603 class B extends A
6604 endclass
6605 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006606 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006607
6608 # interface cannot implement another interface
6609 lines =<< trim END
6610 vim9script
6611 interface A
6612 endinterface
6613 interface B implements A
6614 endinterface
6615 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006616 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006617
6618 # interface cannot extend multiple interfaces
6619 lines =<< trim END
6620 vim9script
6621 interface A
6622 endinterface
6623 interface B
6624 endinterface
6625 interface C extends A, B
6626 endinterface
6627 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006628 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006629
6630 # Variable type in an extended interface is of different type
6631 lines =<< trim END
6632 vim9script
6633 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006634 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006635 endinterface
6636 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006637 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006638 endinterface
6639 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006640 var val1: string
6641 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006642 endinterface
6643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006644 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006645enddef
6646
6647" Test for a child class implementing an interface when some of the methods are
6648" defined in the parent class.
6649def Test_child_class_implements_interface()
6650 var lines =<< trim END
6651 vim9script
6652
6653 interface Intf
6654 def F1(): list<list<number>>
6655 def F2(): list<list<number>>
6656 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006657 var var1: list<dict<number>>
6658 var var2: list<dict<number>>
6659 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006660 endinterface
6661
6662 class A
6663 def A1()
6664 enddef
6665 def F3(): list<list<number>>
6666 return [[3]]
6667 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006668 var v1: list<list<number>> = [[0]]
6669 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006670 endclass
6671
6672 class B extends A
6673 def B1()
6674 enddef
6675 def F2(): list<list<number>>
6676 return [[2]]
6677 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006678 var v2: list<list<number>> = [[0]]
6679 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006680 endclass
6681
6682 class C extends B implements Intf
6683 def C1()
6684 enddef
6685 def F1(): list<list<number>>
6686 return [[1]]
6687 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006688 var v3: list<list<number>> = [[0]]
6689 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006690 endclass
6691
6692 def T(if: Intf)
6693 assert_equal([[1]], if.F1())
6694 assert_equal([[2]], if.F2())
6695 assert_equal([[3]], if.F3())
6696 assert_equal([{a: 10}], if.var1)
6697 assert_equal([{b: 20}], if.var2)
6698 assert_equal([{c: 30}], if.var3)
6699 enddef
6700
6701 var c = C.new()
6702 T(c)
6703 assert_equal([[1]], c.F1())
6704 assert_equal([[2]], c.F2())
6705 assert_equal([[3]], c.F3())
6706 assert_equal([{a: 10}], c.var1)
6707 assert_equal([{b: 20}], c.var2)
6708 assert_equal([{c: 30}], c.var3)
6709 END
6710 v9.CheckSourceSuccess(lines)
6711
6712 # One of the interface methods is not found
6713 lines =<< trim END
6714 vim9script
6715
6716 interface Intf
6717 def F1()
6718 def F2()
6719 def F3()
6720 endinterface
6721
6722 class A
6723 def A1()
6724 enddef
6725 endclass
6726
6727 class B extends A
6728 def B1()
6729 enddef
6730 def F2()
6731 enddef
6732 endclass
6733
6734 class C extends B implements Intf
6735 def C1()
6736 enddef
6737 def F1()
6738 enddef
6739 endclass
6740 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006741 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006742
6743 # One of the interface methods is of different type
6744 lines =<< trim END
6745 vim9script
6746
6747 interface Intf
6748 def F1()
6749 def F2()
6750 def F3()
6751 endinterface
6752
6753 class A
6754 def F3(): number
6755 return 0
6756 enddef
6757 def A1()
6758 enddef
6759 endclass
6760
6761 class B extends A
6762 def B1()
6763 enddef
6764 def F2()
6765 enddef
6766 endclass
6767
6768 class C extends B implements Intf
6769 def C1()
6770 enddef
6771 def F1()
6772 enddef
6773 endclass
6774 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006775 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006776
6777 # One of the interface variables is not present
6778 lines =<< trim END
6779 vim9script
6780
6781 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006782 var var1: list<dict<number>>
6783 var var2: list<dict<number>>
6784 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006785 endinterface
6786
6787 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006788 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006789 endclass
6790
6791 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006792 var v2: list<list<number>> = [[0]]
6793 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006794 endclass
6795
6796 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006797 var v3: list<list<number>> = [[0]]
6798 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006799 endclass
6800 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006801 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006802
6803 # One of the interface variables is of different type
6804 lines =<< trim END
6805 vim9script
6806
6807 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006808 var var1: list<dict<number>>
6809 var var2: list<dict<number>>
6810 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006811 endinterface
6812
6813 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006814 var v1: list<list<number>> = [[0]]
6815 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006816 endclass
6817
6818 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006819 var v2: list<list<number>> = [[0]]
6820 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006821 endclass
6822
6823 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006824 var v3: list<list<number>> = [[0]]
6825 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006826 endclass
6827 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006828 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 +02006829enddef
6830
6831" Test for extending an interface with duplicate variables and methods
6832def Test_interface_extends_with_dup_members()
6833 var lines =<< trim END
6834 vim9script
6835 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006836 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006837 def Foo1(): number
6838 endinterface
6839 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006840 var n2: number
6841 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006842 def Foo2(): number
6843 def Foo1(): number
6844 endinterface
6845 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006846 var n1 = 10
6847 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006848 def Foo1(): number
6849 return 30
6850 enddef
6851 def Foo2(): number
6852 return 40
6853 enddef
6854 endclass
6855 def T1(a: A)
6856 assert_equal(10, a.n1)
6857 assert_equal(30, a.Foo1())
6858 enddef
6859 def T2(b: B)
6860 assert_equal(10, b.n1)
6861 assert_equal(20, b.n2)
6862 assert_equal(30, b.Foo1())
6863 assert_equal(40, b.Foo2())
6864 enddef
6865 var c = C.new()
6866 T1(c)
6867 T2(c)
6868 END
6869 v9.CheckSourceSuccess(lines)
6870enddef
6871
6872" Test for using "any" type for a variable in a sub-class while it has a
6873" concrete type in the interface
6874def Test_implements_using_var_type_any()
6875 var lines =<< trim END
6876 vim9script
6877 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006878 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006879 endinterface
6880 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006881 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006882 endclass
6883 var b = B.new()
6884 assert_equal([{a: '1'}, {b: '2'}], b.val)
6885 END
6886 v9.CheckSourceSuccess(lines)
6887
6888 # initialize instance variable using a different type
6889 lines =<< trim END
6890 vim9script
6891 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006892 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006893 endinterface
6894 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006895 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006896 endclass
6897 var b = B.new()
6898 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006899 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006900enddef
6901
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006902" Test for assigning to a member variable in a nested class
6903def Test_nested_object_assignment()
6904 var lines =<< trim END
6905 vim9script
6906
6907 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006908 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006909 endclass
6910
6911 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006912 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006913 endclass
6914
6915 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01006916 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006917 endclass
6918
6919 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01006920 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006921 endclass
6922
6923 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006924 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006925 enddef
6926
6927 var d = D.new()
6928 T(d)
6929 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006930 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006931enddef
6932
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006933" Test for calling methods using a null object
6934def Test_null_object_method_call()
6935 # Calling a object method using a null object in script context
6936 var lines =<< trim END
6937 vim9script
6938
6939 class C
6940 def Foo()
6941 assert_report('This method should not be executed')
6942 enddef
6943 endclass
6944
6945 var o: C
6946 o.Foo()
6947 END
6948 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6949
6950 # Calling a object method using a null object in def function context
6951 lines =<< trim END
6952 vim9script
6953
6954 class C
6955 def Foo()
6956 assert_report('This method should not be executed')
6957 enddef
6958 endclass
6959
6960 def T()
6961 var o: C
6962 o.Foo()
6963 enddef
6964 T()
6965 END
6966 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6967
6968 # Calling a object method through another class method using a null object in
6969 # script context
6970 lines =<< trim END
6971 vim9script
6972
6973 class C
6974 def Foo()
6975 assert_report('This method should not be executed')
6976 enddef
6977
6978 static def Bar(o_any: any)
6979 var o_typed: C = o_any
6980 o_typed.Foo()
6981 enddef
6982 endclass
6983
6984 var o: C
6985 C.Bar(o)
6986 END
6987 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6988
6989 # Calling a object method through another class method using a null object in
6990 # def function context
6991 lines =<< trim END
6992 vim9script
6993
6994 class C
6995 def Foo()
6996 assert_report('This method should not be executed')
6997 enddef
6998
6999 static def Bar(o_any: any)
7000 var o_typed: C = o_any
7001 o_typed.Foo()
7002 enddef
7003 endclass
7004
7005 def T()
7006 var o: C
7007 C.Bar(o)
7008 enddef
7009 T()
7010 END
7011 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7012enddef
7013
7014" Test for using a dict as an object member
7015def Test_dict_object_member()
7016 var lines =<< trim END
7017 vim9script
7018
7019 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007020 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007021 def GetState(): dict<number>
7022 return this.state
7023 enddef
7024 endclass
7025
7026 var ctx = Context.new()
7027 ctx.state->extend({a: 1})
7028 ctx.state['b'] = 2
7029 assert_equal({a: 1, b: 2}, ctx.GetState())
7030
7031 def F()
7032 ctx.state['c'] = 3
7033 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7034 enddef
7035 F()
7036 assert_equal(3, ctx.state.c)
7037 ctx.state.c = 4
7038 assert_equal(4, ctx.state.c)
7039 END
7040 v9.CheckSourceSuccess(lines)
7041enddef
7042
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007043" The following test was failing after 9.0.1914. This was caused by using a
7044" freed object from a previous method call.
7045def Test_freed_object_from_previous_method_call()
7046 var lines =<< trim END
7047 vim9script
7048
7049 class Context
7050 endclass
7051
7052 class Result
7053 endclass
7054
7055 def Failure(): Result
7056 return Result.new()
7057 enddef
7058
7059 def GetResult(ctx: Context): Result
7060 return Failure()
7061 enddef
7062
7063 def Test_GetResult()
7064 var ctx = Context.new()
7065 var result = GetResult(ctx)
7066 enddef
7067
7068 Test_GetResult()
7069 END
7070 v9.CheckSourceSuccess(lines)
7071enddef
7072
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007073" Test for duplicate object and class variable
7074def Test_duplicate_variable()
7075 # Object variable name is same as the class variable name
7076 var lines =<< trim END
7077 vim9script
7078 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007079 public static var sval: number
7080 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007081 endclass
7082 var a = A.new()
7083 END
7084 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7085
7086 # Duplicate variable name and calling a class method
7087 lines =<< trim END
7088 vim9script
7089 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007090 public static var sval: number
7091 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007092 def F1()
7093 echo this.sval
7094 enddef
7095 static def F2()
7096 echo sval
7097 enddef
7098 endclass
7099 A.F2()
7100 END
7101 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7102
7103 # Duplicate variable with an empty constructor
7104 lines =<< trim END
7105 vim9script
7106 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007107 public static var sval: number
7108 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007109 def new()
7110 enddef
7111 endclass
7112 var a = A.new()
7113 END
7114 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7115enddef
7116
7117" Test for using a reserved keyword as a variable name
7118def Test_reserved_varname()
7119 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7120 'null_function', 'null_list', 'null_partial', 'null_string',
7121 'null_channel', 'null_job', 'super', 'this']
7122
7123 var lines =<< trim eval END
7124 vim9script
7125 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007126 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007127 endclass
7128 var o = C.new()
7129 END
7130 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7131
7132 lines =<< trim eval END
7133 vim9script
7134 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007135 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007136 def new()
7137 enddef
7138 endclass
7139 var o = C.new()
7140 END
7141 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7142
7143 lines =<< trim eval END
7144 vim9script
7145 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007146 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007147 def new()
7148 enddef
7149 def F()
7150 echo this.{kword}
7151 enddef
7152 endclass
7153 var o = C.new()
7154 o.F()
7155 END
7156 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007157
7158 # class variable name
7159 if kword != 'this'
7160 lines =<< trim eval END
7161 vim9script
7162 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007163 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007164 endclass
7165 END
7166 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7167 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007168 endfor
7169enddef
7170
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007171" Test for checking the type of the arguments and the return value of a object
7172" method in an extended class.
7173def Test_extended_obj_method_type_check()
7174 var lines =<< trim END
7175 vim9script
7176
7177 class A
7178 endclass
7179 class B extends A
7180 endclass
7181 class C extends B
7182 endclass
7183
7184 class Foo
7185 def Doit(p: B): B
7186 return B.new()
7187 enddef
7188 endclass
7189
7190 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007191 def Doit(p: C): B
7192 return B.new()
7193 enddef
7194 endclass
7195 END
7196 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7197
7198 lines =<< trim END
7199 vim9script
7200
7201 class A
7202 endclass
7203 class B extends A
7204 endclass
7205 class C extends B
7206 endclass
7207
7208 class Foo
7209 def Doit(p: B): B
7210 return B.new()
7211 enddef
7212 endclass
7213
7214 class Bar extends Foo
7215 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007216 return C.new()
7217 enddef
7218 endclass
7219 END
7220 v9.CheckSourceSuccess(lines)
7221
7222 lines =<< trim END
7223 vim9script
7224
7225 class A
7226 endclass
7227 class B extends A
7228 endclass
7229 class C extends B
7230 endclass
7231
7232 class Foo
7233 def Doit(p: B): B
7234 return B.new()
7235 enddef
7236 endclass
7237
7238 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007239 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007240 return B.new()
7241 enddef
7242 endclass
7243 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007244 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 +02007245
7246 lines =<< trim END
7247 vim9script
7248
7249 class A
7250 endclass
7251 class B extends A
7252 endclass
7253 class C extends B
7254 endclass
7255
7256 class Foo
7257 def Doit(p: B): B
7258 return B.new()
7259 enddef
7260 endclass
7261
7262 class Bar extends Foo
7263 def Doit(p: B): A
7264 return A.new()
7265 enddef
7266 endclass
7267 END
7268 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 +02007269
7270 # check varargs type mismatch
7271 lines =<< trim END
7272 vim9script
7273
7274 class B
7275 def F(...xxx: list<any>)
7276 enddef
7277 endclass
7278 class C extends B
7279 def F(xxx: list<any>)
7280 enddef
7281 endclass
7282 END
7283 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 +02007284enddef
7285
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007286" Test type checking for class variable in assignments
7287func Test_class_variable_complex_type_check()
7288 " class variable with a specific type. Try assigning a different type at
7289 " script level.
7290 let lines =<< trim END
7291 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007292 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007293 return {}
7294 enddef
7295 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007296 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007297 endclass
7298 test_garbagecollect_now()
7299 A.Fn = "abc"
7300 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007301 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 +02007302
7303 " class variable with a specific type. Try assigning a different type at
7304 " class def method level.
7305 let lines =<< trim END
7306 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007307 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007308 return {}
7309 enddef
7310 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007311 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007312 def Bar()
7313 Fn = "abc"
7314 enddef
7315 endclass
7316 var a = A.new()
7317 test_garbagecollect_now()
7318 a.Bar()
7319 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007320 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 +02007321
7322 " class variable with a specific type. Try assigning a different type at
7323 " script def method level.
7324 let lines =<< trim END
7325 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007326 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007327 return {}
7328 enddef
7329 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007330 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007331 endclass
7332 def Bar()
7333 A.Fn = "abc"
7334 enddef
7335 test_garbagecollect_now()
7336 Bar()
7337 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007338 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 +02007339
7340 " class variable without any type. Should be set to the initialization
7341 " expression type. Try assigning a different type from script level.
7342 let lines =<< trim END
7343 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007344 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007345 return {}
7346 enddef
7347 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007348 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007349 endclass
7350 test_garbagecollect_now()
7351 A.Fn = "abc"
7352 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007353 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 +02007354
7355 " class variable without any type. Should be set to the initialization
7356 " expression type. Try assigning a different type at class def 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 = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007364 def Bar()
7365 Fn = "abc"
7366 enddef
7367 endclass
7368 var a = A.new()
7369 test_garbagecollect_now()
7370 a.Bar()
7371 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007372 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 +02007373
7374 " class variable without any type. Should be set to the initialization
7375 " expression type. Try assigning a different type at script def level.
7376 let lines =<< trim END
7377 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007378 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007379 return {}
7380 enddef
7381 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007382 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007383 endclass
7384 def Bar()
7385 A.Fn = "abc"
7386 enddef
7387 test_garbagecollect_now()
7388 Bar()
7389 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007390 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 +02007391
7392 " class variable with 'any" type. Can be assigned different types.
7393 let lines =<< trim END
7394 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007395 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007396 return {}
7397 enddef
7398 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007399 public static var Fn: any = Foo
7400 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007401 endclass
7402 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007403 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007404 A.Fn = "abc"
7405 test_garbagecollect_now()
7406 assert_equal('string', typename(A.Fn))
7407 A.Fn2 = Foo
7408 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007409 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007410 A.Fn2 = "xyz"
7411 test_garbagecollect_now()
7412 assert_equal('string', typename(A.Fn2))
7413 END
7414 call v9.CheckSourceSuccess(lines)
7415
7416 " class variable with 'any" type. Can be assigned different types.
7417 let lines =<< trim END
7418 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007419 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007420 return {}
7421 enddef
7422 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007423 public static var Fn: any = Foo
7424 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007425
7426 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007427 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007428 Fn = "abc"
7429 assert_equal('string', typename(Fn))
7430 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007431 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007432 Fn2 = "xyz"
7433 assert_equal('string', typename(Fn2))
7434 enddef
7435 endclass
7436 var a = A.new()
7437 test_garbagecollect_now()
7438 a.Bar()
7439 test_garbagecollect_now()
7440 A.Fn = Foo
7441 a.Bar()
7442 END
7443 call v9.CheckSourceSuccess(lines)
7444
7445 " class variable with 'any" type. Can be assigned different types.
7446 let lines =<< trim END
7447 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007448 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007449 return {}
7450 enddef
7451 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007452 public static var Fn: any = Foo
7453 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007454 endclass
7455
7456 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007457 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007458 A.Fn = "abc"
7459 assert_equal('string', typename(A.Fn))
7460 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007461 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007462 A.Fn2 = "xyz"
7463 assert_equal('string', typename(A.Fn2))
7464 enddef
7465 Bar()
7466 test_garbagecollect_now()
7467 A.Fn = Foo
7468 Bar()
7469 END
7470 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007471
7472 let lines =<< trim END
7473 vim9script
7474 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007475 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007476 endclass
7477 assert_equal([0z10, 0z20], A.foo)
7478 A.foo = [0z30]
7479 assert_equal([0z30], A.foo)
7480 var a = A.foo
7481 assert_equal([0z30], a)
7482 END
7483 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007484endfunc
7485
7486" Test type checking for object variable in assignments
7487func Test_object_variable_complex_type_check()
7488 " object variable with a specific type. Try assigning a different type at
7489 " script level.
7490 let lines =<< trim END
7491 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007492 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007493 return {}
7494 enddef
7495 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007496 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007497 endclass
7498 var a = A.new()
7499 test_garbagecollect_now()
7500 a.Fn = "abc"
7501 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007502 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 +02007503
7504 " object variable with a specific type. Try assigning a different type at
7505 " object def method level.
7506 let lines =<< trim END
7507 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007508 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007509 return {}
7510 enddef
7511 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007512 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007513 def Bar()
7514 this.Fn = "abc"
7515 this.Fn = Foo
7516 enddef
7517 endclass
7518 var a = A.new()
7519 test_garbagecollect_now()
7520 a.Bar()
7521 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007522 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 +02007523
7524 " object variable with a specific type. Try assigning a different type at
7525 " script def method level.
7526 let lines =<< trim END
7527 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007528 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007529 return {}
7530 enddef
7531 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007532 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007533 endclass
7534 def Bar()
7535 var a = A.new()
7536 a.Fn = "abc"
7537 a.Fn = Foo
7538 enddef
7539 test_garbagecollect_now()
7540 Bar()
7541 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007542 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 +02007543
7544 " object variable without any type. Should be set to the initialization
7545 " expression type. Try assigning a different type from script level.
7546 let lines =<< trim END
7547 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007548 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007549 return {}
7550 enddef
7551 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007552 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007553 endclass
7554 var a = A.new()
7555 test_garbagecollect_now()
7556 a.Fn = "abc"
7557 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007558 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 10)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007559
7560 " object variable without any type. Should be set to the initialization
7561 " expression type. Try assigning a different type at object def level.
7562 let lines =<< trim END
7563 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007564 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007565 return {}
7566 enddef
7567 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007568 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007569 def Bar()
7570 this.Fn = "abc"
7571 this.Fn = Foo
7572 enddef
7573 endclass
7574 var a = A.new()
7575 test_garbagecollect_now()
7576 a.Bar()
7577 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007578 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 +02007579
7580 " object variable without any type. Should be set to the initialization
7581 " expression type. Try assigning a different type at script def level.
7582 let lines =<< trim END
7583 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007584 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007585 return {}
7586 enddef
7587 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007588 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007589 endclass
7590 def Bar()
7591 var a = A.new()
7592 a.Fn = "abc"
7593 a.Fn = Foo
7594 enddef
7595 test_garbagecollect_now()
7596 Bar()
7597 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007598 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 +02007599
7600 " object variable with 'any" type. Can be assigned different types.
7601 let lines =<< trim END
7602 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007603 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007604 return {}
7605 enddef
7606 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007607 public var Fn: any = Foo
7608 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007609 endclass
7610
7611 var a = A.new()
7612 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007613 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007614 a.Fn = "abc"
7615 test_garbagecollect_now()
7616 assert_equal('string', typename(a.Fn))
7617 a.Fn2 = Foo
7618 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007619 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007620 a.Fn2 = "xyz"
7621 test_garbagecollect_now()
7622 assert_equal('string', typename(a.Fn2))
7623 END
7624 call v9.CheckSourceSuccess(lines)
7625
7626 " object variable with 'any" type. Can be assigned different types.
7627 let lines =<< trim END
7628 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007629 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007630 return {}
7631 enddef
7632 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007633 public var Fn: any = Foo
7634 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007635
7636 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007637 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007638 this.Fn = "abc"
7639 assert_equal('string', typename(this.Fn))
7640 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007641 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007642 this.Fn2 = "xyz"
7643 assert_equal('string', typename(this.Fn2))
7644 enddef
7645 endclass
7646
7647 var a = A.new()
7648 test_garbagecollect_now()
7649 a.Bar()
7650 test_garbagecollect_now()
7651 a.Fn = Foo
7652 a.Bar()
7653 END
7654 call v9.CheckSourceSuccess(lines)
7655
7656 " object variable with 'any" type. Can be assigned different types.
7657 let lines =<< trim END
7658 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007659 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007660 return {}
7661 enddef
7662 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007663 public var Fn: any = Foo
7664 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007665 endclass
7666
7667 def Bar()
7668 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007669 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007670 a.Fn = "abc"
7671 assert_equal('string', typename(a.Fn))
7672 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007673 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007674 a.Fn2 = "xyz"
7675 assert_equal('string', typename(a.Fn2))
7676 enddef
7677 test_garbagecollect_now()
7678 Bar()
7679 test_garbagecollect_now()
7680 Bar()
7681 END
7682 call v9.CheckSourceSuccess(lines)
7683endfunc
7684
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007685" Test for recursively calling an object method. This used to cause an
7686" use-after-free error.
7687def Test_recursive_object_method_call()
7688 var lines =<< trim END
7689 vim9script
7690 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007691 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007692 def Foo(): number
7693 if this.val >= 90
7694 return this.val
7695 endif
7696 this.val += 1
7697 return this.Foo()
7698 enddef
7699 endclass
7700 var a = A.new()
7701 assert_equal(90, a.Foo())
7702 END
7703 v9.CheckSourceSuccess(lines)
7704enddef
7705
7706" Test for recursively calling a class method.
7707def Test_recursive_class_method_call()
7708 var lines =<< trim END
7709 vim9script
7710 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007711 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007712 static def Foo(): number
7713 if val >= 90
7714 return val
7715 endif
7716 val += 1
7717 return Foo()
7718 enddef
7719 endclass
7720 assert_equal(90, A.Foo())
7721 END
7722 v9.CheckSourceSuccess(lines)
7723enddef
7724
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007725" Test for checking the argument types and the return type when assigning a
7726" funcref to make sure the invariant class type is used.
7727def Test_funcref_argtype_returntype_check()
7728 var lines =<< trim END
7729 vim9script
7730 class A
7731 endclass
7732 class B extends A
7733 endclass
7734
7735 def Foo(p: B): B
7736 return B.new()
7737 enddef
7738
7739 var Bar: func(A): A = Foo
7740 END
7741 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7742
7743 lines =<< trim END
7744 vim9script
7745 class A
7746 endclass
7747 class B extends A
7748 endclass
7749
7750 def Foo(p: B): B
7751 return B.new()
7752 enddef
7753
7754 def Baz()
7755 var Bar: func(A): A = Foo
7756 enddef
7757 Baz()
7758 END
7759 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7760enddef
7761
Ernie Rael96952b22023-10-17 18:15:01 +02007762def Test_funcref_argtype_invariance_check()
7763 var lines =<< trim END
7764 vim9script
7765
7766 class A
7767 endclass
7768 class B extends A
7769 endclass
7770 class C extends B
7771 endclass
7772
7773 var Func: func(B): number
7774 Func = (o: B): number => 3
7775 assert_equal(3, Func(B.new()))
7776 END
7777 v9.CheckSourceSuccess(lines)
7778
7779 lines =<< trim END
7780 vim9script
7781
7782 class A
7783 endclass
7784 class B extends A
7785 endclass
7786 class C extends B
7787 endclass
7788
7789 var Func: func(B): number
7790 Func = (o: A): number => 3
7791 END
7792 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7793
7794 lines =<< trim END
7795 vim9script
7796
7797 class A
7798 endclass
7799 class B extends A
7800 endclass
7801 class C extends B
7802 endclass
7803
7804 var Func: func(B): number
7805 Func = (o: C): number => 3
7806 END
7807 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7808enddef
7809
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007810" Test for using an operator (e.g. +) with an assignment
7811def Test_op_and_assignment()
7812 # Using += with a class variable
7813 var lines =<< trim END
7814 vim9script
7815 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007816 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007817 static def Foo(): list<number>
7818 val += [1]
7819 return val
7820 enddef
7821 endclass
7822 def Bar(): list<number>
7823 A.val += [2]
7824 return A.val
7825 enddef
7826 assert_equal([1], A.Foo())
7827 assert_equal([1, 2], Bar())
7828 A.val += [3]
7829 assert_equal([1, 2, 3], A.val)
7830 END
7831 v9.CheckSourceSuccess(lines)
7832
7833 # Using += with an object variable
7834 lines =<< trim END
7835 vim9script
7836 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007837 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007838 def Foo(): list<number>
7839 this.val += [1]
7840 return this.val
7841 enddef
7842 endclass
7843 def Bar(bar_a: A): list<number>
7844 bar_a.val += [2]
7845 return bar_a.val
7846 enddef
7847 var a = A.new()
7848 assert_equal([1], a.Foo())
7849 assert_equal([1, 2], Bar(a))
7850 a.val += [3]
7851 assert_equal([1, 2, 3], a.val)
7852 END
7853 v9.CheckSourceSuccess(lines)
7854enddef
7855
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007856" Test for using an object method as a funcref
7857def Test_object_funcref()
7858 # Using object method funcref from a def function
7859 var lines =<< trim END
7860 vim9script
7861 class A
7862 def Foo(): list<number>
7863 return [3, 2, 1]
7864 enddef
7865 endclass
7866 def Bar()
7867 var a = A.new()
7868 var Fn = a.Foo
7869 assert_equal([3, 2, 1], Fn())
7870 enddef
7871 Bar()
7872 END
7873 v9.CheckSourceSuccess(lines)
7874
7875 # Using object method funcref at the script level
7876 lines =<< trim END
7877 vim9script
7878 class A
7879 def Foo(): dict<number>
7880 return {a: 1, b: 2}
7881 enddef
7882 endclass
7883 var a = A.new()
7884 var Fn = a.Foo
7885 assert_equal({a: 1, b: 2}, Fn())
7886 END
7887 v9.CheckSourceSuccess(lines)
7888
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007889 # Using object method funcref at the script level
7890 lines =<< trim END
7891 vim9script
7892 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007893 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007894 def Foo(): number
7895 return this.val
7896 enddef
7897 endclass
7898 var a = A.new(345)
7899 var Fn = a.Foo
7900 assert_equal(345, Fn())
7901 END
7902 v9.CheckSourceSuccess(lines)
7903
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007904 # Using object method funcref from another object method
7905 lines =<< trim END
7906 vim9script
7907 class A
7908 def Foo(): list<number>
7909 return [3, 2, 1]
7910 enddef
7911 def Bar()
7912 var Fn = this.Foo
7913 assert_equal([3, 2, 1], Fn())
7914 enddef
7915 endclass
7916 var a = A.new()
7917 a.Bar()
7918 END
7919 v9.CheckSourceSuccess(lines)
7920
7921 # Using function() to get a object method funcref
7922 lines =<< trim END
7923 vim9script
7924 class A
7925 def Foo(l: list<any>): list<any>
7926 return l
7927 enddef
7928 endclass
7929 var a = A.new()
7930 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
7931 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7932 END
7933 v9.CheckSourceSuccess(lines)
7934
7935 # Use an object method with a function returning a funcref and then call the
7936 # funcref.
7937 lines =<< trim END
7938 vim9script
7939
7940 def Map(F: func(number): number): func(number): number
7941 return (n: number) => F(n)
7942 enddef
7943
7944 class Math
7945 def Double(n: number): number
7946 return 2 * n
7947 enddef
7948 endclass
7949
7950 const math = Math.new()
7951 assert_equal(48, Map(math.Double)(24))
7952 END
7953 v9.CheckSourceSuccess(lines)
7954
Ernie Rael03042a22023-11-11 08:53:32 +01007955 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007956 lines =<< trim END
7957 vim9script
7958 class A
7959 def _Foo()
7960 enddef
7961 endclass
7962 def Bar()
7963 var a = A.new()
7964 var Fn = a._Foo
7965 enddef
7966 Bar()
7967 END
Ernie Rael03042a22023-11-11 08:53:32 +01007968 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007969
Ernie Rael03042a22023-11-11 08:53:32 +01007970 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007971 lines =<< trim END
7972 vim9script
7973 class A
7974 def _Foo()
7975 enddef
7976 endclass
7977 var a = A.new()
7978 var Fn = a._Foo
7979 END
Ernie Rael03042a22023-11-11 08:53:32 +01007980 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007981
Ernie Rael03042a22023-11-11 08:53:32 +01007982 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007983 lines =<< trim END
7984 vim9script
7985 class A
7986 def _Foo(): list<number>
7987 return [3, 2, 1]
7988 enddef
7989 def Bar()
7990 var Fn = this._Foo
7991 assert_equal([3, 2, 1], Fn())
7992 enddef
7993 endclass
7994 var a = A.new()
7995 a.Bar()
7996 END
7997 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007998
7999 # Using object method funcref using call()
8000 lines =<< trim END
8001 vim9script
8002 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008003 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008004 def Foo(): number
8005 return this.val
8006 enddef
8007 endclass
8008
8009 def Bar(obj: A)
8010 assert_equal(123, call(obj.Foo, []))
8011 enddef
8012
8013 var a = A.new(123)
8014 Bar(a)
8015 assert_equal(123, call(a.Foo, []))
8016 END
8017 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008018enddef
8019
8020" Test for using a class method as a funcref
8021def Test_class_funcref()
8022 # Using class method funcref in a def function
8023 var lines =<< trim END
8024 vim9script
8025 class A
8026 static def Foo(): list<number>
8027 return [3, 2, 1]
8028 enddef
8029 endclass
8030 def Bar()
8031 var Fn = A.Foo
8032 assert_equal([3, 2, 1], Fn())
8033 enddef
8034 Bar()
8035 END
8036 v9.CheckSourceSuccess(lines)
8037
8038 # Using class method funcref at script level
8039 lines =<< trim END
8040 vim9script
8041 class A
8042 static def Foo(): dict<number>
8043 return {a: 1, b: 2}
8044 enddef
8045 endclass
8046 var Fn = A.Foo
8047 assert_equal({a: 1, b: 2}, Fn())
8048 END
8049 v9.CheckSourceSuccess(lines)
8050
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008051 # Using class method funcref at the script level
8052 lines =<< trim END
8053 vim9script
8054 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008055 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008056 static def Foo(): number
8057 return val
8058 enddef
8059 endclass
8060 A.val = 567
8061 var Fn = A.Foo
8062 assert_equal(567, Fn())
8063 END
8064 v9.CheckSourceSuccess(lines)
8065
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008066 # Using function() to get a class method funcref
8067 lines =<< trim END
8068 vim9script
8069 class A
8070 static def Foo(l: list<any>): list<any>
8071 return l
8072 enddef
8073 endclass
8074 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8075 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8076 END
8077 v9.CheckSourceSuccess(lines)
8078
8079 # Using a class method funcref from another class method
8080 lines =<< trim END
8081 vim9script
8082 class A
8083 static def Foo(): list<number>
8084 return [3, 2, 1]
8085 enddef
8086 static def Bar()
8087 var Fn = Foo
8088 assert_equal([3, 2, 1], Fn())
8089 enddef
8090 endclass
8091 A.Bar()
8092 END
8093 v9.CheckSourceSuccess(lines)
8094
8095 # Use a class method with a function returning a funcref and then call the
8096 # funcref.
8097 lines =<< trim END
8098 vim9script
8099
8100 def Map(F: func(number): number): func(number): number
8101 return (n: number) => F(n)
8102 enddef
8103
8104 class Math
8105 static def StaticDouble(n: number): number
8106 return 2 * n
8107 enddef
8108 endclass
8109
8110 assert_equal(48, Map(Math.StaticDouble)(24))
8111 END
8112 v9.CheckSourceSuccess(lines)
8113
Ernie Rael03042a22023-11-11 08:53:32 +01008114 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008115 lines =<< trim END
8116 vim9script
8117 class A
8118 static def _Foo()
8119 enddef
8120 endclass
8121 def Bar()
8122 var Fn = A._Foo
8123 enddef
8124 Bar()
8125 END
Ernie Rael03042a22023-11-11 08:53:32 +01008126 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008127
Ernie Rael03042a22023-11-11 08:53:32 +01008128 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008129 lines =<< trim END
8130 vim9script
8131 class A
8132 static def _Foo()
8133 enddef
8134 endclass
8135 var Fn = A._Foo
8136 END
Ernie Rael03042a22023-11-11 08:53:32 +01008137 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008138
Ernie Rael03042a22023-11-11 08:53:32 +01008139 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008140 lines =<< trim END
8141 vim9script
8142 class A
8143 static def _Foo(): list<number>
8144 return [3, 2, 1]
8145 enddef
8146 static def Bar()
8147 var Fn = _Foo
8148 assert_equal([3, 2, 1], Fn())
8149 enddef
8150 endclass
8151 A.Bar()
8152 END
8153 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008154
8155 # Using class method funcref using call()
8156 lines =<< trim END
8157 vim9script
8158 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008159 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008160 static def Foo(): number
8161 return val
8162 enddef
8163 endclass
8164
8165 def Bar()
8166 A.val = 468
8167 assert_equal(468, call(A.Foo, []))
8168 enddef
8169 Bar()
8170 assert_equal(468, call(A.Foo, []))
8171 END
8172 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008173enddef
8174
8175" Test for using an object member as a funcref
8176def Test_object_member_funcref()
8177 # Using a funcref object variable in an object method
8178 var lines =<< trim END
8179 vim9script
8180 def Foo(n: number): number
8181 return n * 10
8182 enddef
8183
8184 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008185 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008186 def Bar()
8187 assert_equal(200, this.Cb(20))
8188 enddef
8189 endclass
8190
8191 var a = A.new()
8192 a.Bar()
8193 END
8194 v9.CheckSourceSuccess(lines)
8195
8196 # Using a funcref object variable in a def method
8197 lines =<< trim END
8198 vim9script
8199 def Foo(n: number): number
8200 return n * 10
8201 enddef
8202
8203 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008204 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008205 endclass
8206
8207 def Bar()
8208 var a = A.new()
8209 assert_equal(200, a.Cb(20))
8210 enddef
8211 Bar()
8212 END
8213 v9.CheckSourceSuccess(lines)
8214
8215 # Using a funcref object variable at script level
8216 lines =<< trim END
8217 vim9script
8218 def Foo(n: number): number
8219 return n * 10
8220 enddef
8221
8222 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008223 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008224 endclass
8225
8226 var a = A.new()
8227 assert_equal(200, a.Cb(20))
8228 END
8229 v9.CheckSourceSuccess(lines)
8230
8231 # Using a funcref object variable pointing to an object method in an object
8232 # method.
8233 lines =<< trim END
8234 vim9script
8235 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008236 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008237 def Foo(n: number): number
8238 return n * 10
8239 enddef
8240 def Bar()
8241 assert_equal(200, this.Cb(20))
8242 enddef
8243 endclass
8244
8245 var a = A.new()
8246 a.Bar()
8247 END
8248 v9.CheckSourceSuccess(lines)
8249
8250 # Using a funcref object variable pointing to an object method in a def
8251 # method.
8252 lines =<< trim END
8253 vim9script
8254 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008255 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008256 def Foo(n: number): number
8257 return n * 10
8258 enddef
8259 endclass
8260
8261 def Bar()
8262 var a = A.new()
8263 assert_equal(200, a.Cb(20))
8264 enddef
8265 Bar()
8266 END
8267 v9.CheckSourceSuccess(lines)
8268
8269 # Using a funcref object variable pointing to an object method at script
8270 # level.
8271 lines =<< trim END
8272 vim9script
8273 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008274 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008275 def Foo(n: number): number
8276 return n * 10
8277 enddef
8278 endclass
8279
8280 var a = A.new()
8281 assert_equal(200, a.Cb(20))
8282 END
8283 v9.CheckSourceSuccess(lines)
8284enddef
8285
8286" Test for using a class member as a funcref
8287def Test_class_member_funcref()
8288 # Using a funcref class variable in a class method
8289 var lines =<< trim END
8290 vim9script
8291 def Foo(n: number): number
8292 return n * 10
8293 enddef
8294
8295 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008296 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008297 static def Bar()
8298 assert_equal(200, Cb(20))
8299 enddef
8300 endclass
8301
8302 A.Bar()
8303 END
8304 v9.CheckSourceSuccess(lines)
8305
8306 # Using a funcref class variable in a def method
8307 lines =<< trim END
8308 vim9script
8309 def Foo(n: number): number
8310 return n * 10
8311 enddef
8312
8313 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008314 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008315 endclass
8316
8317 def Bar()
8318 assert_equal(200, A.Cb(20))
8319 enddef
8320 Bar()
8321 END
8322 v9.CheckSourceSuccess(lines)
8323
8324 # Using a funcref class variable at script level
8325 lines =<< trim END
8326 vim9script
8327 def Foo(n: number): number
8328 return n * 10
8329 enddef
8330
8331 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008332 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008333 endclass
8334
8335 assert_equal(200, A.Cb(20))
8336 END
8337 v9.CheckSourceSuccess(lines)
8338
8339 # Using a funcref class variable pointing to a class method in a class
8340 # method.
8341 lines =<< trim END
8342 vim9script
8343 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008344 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008345 static def Foo(n: number): number
8346 return n * 10
8347 enddef
8348 static def Init()
8349 Cb = Foo
8350 enddef
8351 static def Bar()
8352 assert_equal(200, Cb(20))
8353 enddef
8354 endclass
8355
8356 A.Init()
8357 A.Bar()
8358 END
8359 v9.CheckSourceSuccess(lines)
8360
8361 # Using a funcref class variable pointing to a class method in a def method.
8362 lines =<< trim END
8363 vim9script
8364 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008365 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008366 static def Foo(n: number): number
8367 return n * 10
8368 enddef
8369 static def Init()
8370 Cb = Foo
8371 enddef
8372 endclass
8373
8374 def Bar()
8375 A.Init()
8376 assert_equal(200, A.Cb(20))
8377 enddef
8378 Bar()
8379 END
8380 v9.CheckSourceSuccess(lines)
8381
8382 # Using a funcref class variable pointing to a class method at script level.
8383 lines =<< trim END
8384 vim9script
8385 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008386 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008387 static def Foo(n: number): number
8388 return n * 10
8389 enddef
8390 static def Init()
8391 Cb = Foo
8392 enddef
8393 endclass
8394
8395 A.Init()
8396 assert_equal(200, A.Cb(20))
8397 END
8398 v9.CheckSourceSuccess(lines)
8399enddef
8400
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008401" Test for using object methods as popup callback functions
8402def Test_objmethod_popup_callback()
8403 # Use the popup from the script level
8404 var lines =<< trim END
8405 vim9script
8406
8407 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008408 var selection: number = -1
8409 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008410
8411 def PopupFilter(id: number, key: string): bool
8412 add(this.filterkeys, key)
8413 return popup_filter_yesno(id, key)
8414 enddef
8415
8416 def PopupCb(id: number, result: number)
8417 this.selection = result ? 100 : 200
8418 enddef
8419 endclass
8420
8421 var a = A.new()
8422 feedkeys('', 'xt')
8423 var winid = popup_create('Y/N?',
8424 {filter: a.PopupFilter, callback: a.PopupCb})
8425 feedkeys('y', 'xt')
8426 popup_close(winid)
8427 assert_equal(100, a.selection)
8428 assert_equal(['y'], a.filterkeys)
8429 feedkeys('', 'xt')
8430 winid = popup_create('Y/N?',
8431 {filter: a.PopupFilter, callback: a.PopupCb})
8432 feedkeys('n', 'xt')
8433 popup_close(winid)
8434 assert_equal(200, a.selection)
8435 assert_equal(['y', 'n'], a.filterkeys)
8436 END
8437 v9.CheckSourceSuccess(lines)
8438
8439 # Use the popup from a def function
8440 lines =<< trim END
8441 vim9script
8442
8443 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008444 var selection: number = -1
8445 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008446
8447 def PopupFilter(id: number, key: string): bool
8448 add(this.filterkeys, key)
8449 return popup_filter_yesno(id, key)
8450 enddef
8451
8452 def PopupCb(id: number, result: number)
8453 this.selection = result ? 100 : 200
8454 enddef
8455 endclass
8456
8457 def Foo()
8458 var a = A.new()
8459 feedkeys('', 'xt')
8460 var winid = popup_create('Y/N?',
8461 {filter: a.PopupFilter, callback: a.PopupCb})
8462 feedkeys('y', 'xt')
8463 popup_close(winid)
8464 assert_equal(100, a.selection)
8465 assert_equal(['y'], a.filterkeys)
8466 feedkeys('', 'xt')
8467 winid = popup_create('Y/N?',
8468 {filter: a.PopupFilter, callback: a.PopupCb})
8469 feedkeys('n', 'xt')
8470 popup_close(winid)
8471 assert_equal(200, a.selection)
8472 assert_equal(['y', 'n'], a.filterkeys)
8473 enddef
8474 Foo()
8475 END
8476 v9.CheckSourceSuccess(lines)
8477enddef
8478
8479" Test for using class methods as popup callback functions
8480def Test_classmethod_popup_callback()
8481 # Use the popup from the script level
8482 var lines =<< trim END
8483 vim9script
8484
8485 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008486 static var selection: number = -1
8487 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008488
8489 static def PopupFilter(id: number, key: string): bool
8490 add(filterkeys, key)
8491 return popup_filter_yesno(id, key)
8492 enddef
8493
8494 static def PopupCb(id: number, result: number)
8495 selection = result ? 100 : 200
8496 enddef
8497 endclass
8498
8499 feedkeys('', 'xt')
8500 var winid = popup_create('Y/N?',
8501 {filter: A.PopupFilter, callback: A.PopupCb})
8502 feedkeys('y', 'xt')
8503 popup_close(winid)
8504 assert_equal(100, A.selection)
8505 assert_equal(['y'], A.filterkeys)
8506 feedkeys('', 'xt')
8507 winid = popup_create('Y/N?',
8508 {filter: A.PopupFilter, callback: A.PopupCb})
8509 feedkeys('n', 'xt')
8510 popup_close(winid)
8511 assert_equal(200, A.selection)
8512 assert_equal(['y', 'n'], A.filterkeys)
8513 END
8514 v9.CheckSourceSuccess(lines)
8515
8516 # Use the popup from a def function
8517 lines =<< trim END
8518 vim9script
8519
8520 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008521 static var selection: number = -1
8522 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008523
8524 static def PopupFilter(id: number, key: string): bool
8525 add(filterkeys, key)
8526 return popup_filter_yesno(id, key)
8527 enddef
8528
8529 static def PopupCb(id: number, result: number)
8530 selection = result ? 100 : 200
8531 enddef
8532 endclass
8533
8534 def Foo()
8535 feedkeys('', 'xt')
8536 var winid = popup_create('Y/N?',
8537 {filter: A.PopupFilter, callback: A.PopupCb})
8538 feedkeys('y', 'xt')
8539 popup_close(winid)
8540 assert_equal(100, A.selection)
8541 assert_equal(['y'], A.filterkeys)
8542 feedkeys('', 'xt')
8543 winid = popup_create('Y/N?',
8544 {filter: A.PopupFilter, callback: A.PopupCb})
8545 feedkeys('n', 'xt')
8546 popup_close(winid)
8547 assert_equal(200, A.selection)
8548 assert_equal(['y', 'n'], A.filterkeys)
8549 enddef
8550 Foo()
8551 END
8552 v9.CheckSourceSuccess(lines)
8553enddef
8554
8555" Test for using an object method as a timer callback function
8556def Test_objmethod_timer_callback()
8557 # Use the timer callback from script level
8558 var lines =<< trim END
8559 vim9script
8560
8561 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008562 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008563 def TimerCb(timerID: number)
8564 this.timerTick = 6
8565 enddef
8566 endclass
8567
8568 var a = A.new()
8569 timer_start(0, a.TimerCb)
8570 var maxWait = 5
8571 while maxWait > 0 && a.timerTick == -1
8572 :sleep 10m
8573 maxWait -= 1
8574 endwhile
8575 assert_equal(6, a.timerTick)
8576 END
8577 v9.CheckSourceSuccess(lines)
8578
8579 # Use the timer callback from a def function
8580 lines =<< trim END
8581 vim9script
8582
8583 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008584 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008585 def TimerCb(timerID: number)
8586 this.timerTick = 6
8587 enddef
8588 endclass
8589
8590 def Foo()
8591 var a = A.new()
8592 timer_start(0, a.TimerCb)
8593 var maxWait = 5
8594 while maxWait > 0 && a.timerTick == -1
8595 :sleep 10m
8596 maxWait -= 1
8597 endwhile
8598 assert_equal(6, a.timerTick)
8599 enddef
8600 Foo()
8601 END
8602 v9.CheckSourceSuccess(lines)
8603enddef
8604
8605" Test for using a class method as a timer callback function
8606def Test_classmethod_timer_callback()
8607 # Use the timer callback from script level
8608 var lines =<< trim END
8609 vim9script
8610
8611 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008612 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008613 static def TimerCb(timerID: number)
8614 timerTick = 6
8615 enddef
8616 endclass
8617
8618 timer_start(0, A.TimerCb)
8619 var maxWait = 5
8620 while maxWait > 0 && A.timerTick == -1
8621 :sleep 10m
8622 maxWait -= 1
8623 endwhile
8624 assert_equal(6, A.timerTick)
8625 END
8626 v9.CheckSourceSuccess(lines)
8627
8628 # Use the timer callback from a def function
8629 lines =<< trim END
8630 vim9script
8631
8632 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008633 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008634 static def TimerCb(timerID: number)
8635 timerTick = 6
8636 enddef
8637 endclass
8638
8639 def Foo()
8640 timer_start(0, A.TimerCb)
8641 var maxWait = 5
8642 while maxWait > 0 && A.timerTick == -1
8643 :sleep 10m
8644 maxWait -= 1
8645 endwhile
8646 assert_equal(6, A.timerTick)
8647 enddef
8648 Foo()
8649 END
8650 v9.CheckSourceSuccess(lines)
8651enddef
8652
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008653" Test for using a class variable as the first and/or second operand of a binary
8654" operator.
8655def Test_class_variable_as_operands()
8656 var lines =<< trim END
8657 vim9script
8658 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008659 static var truthy: bool = true
8660 public static var TruthyFn: func
8661 static var list: list<any> = []
8662 static var four: number = 4
8663 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008664
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008665 static def Str(): string
8666 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008667 enddef
8668
8669 static def Four(): number
8670 return four
8671 enddef
8672
8673 static def List(): list<any>
8674 return list
8675 enddef
8676
8677 static def Truthy(): bool
8678 return truthy
8679 enddef
8680
8681 def TestOps()
8682 assert_true(Tests.truthy == truthy)
8683 assert_true(truthy == Tests.truthy)
8684 assert_true(Tests.list isnot [])
8685 assert_true([] isnot Tests.list)
8686 assert_equal(2, Tests.four >> 1)
8687 assert_equal(16, 1 << Tests.four)
8688 assert_equal(8, Tests.four + four)
8689 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008690 assert_equal('hellohello', Tests.str .. str)
8691 assert_equal('hellohello', str .. Tests.str)
8692
8693 # Using class variable for list indexing
8694 var l = range(10)
8695 assert_equal(4, l[Tests.four])
8696 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8697
8698 # Using class variable for Dict key
8699 var d = {hello: 'abc'}
8700 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008701 enddef
8702 endclass
8703
8704 def TestOps2()
8705 assert_true(Tests.truthy == Tests.Truthy())
8706 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008707 assert_true(Tests.truthy == Tests.TruthyFn())
8708 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008709 assert_true(Tests.list is Tests.List())
8710 assert_true(Tests.List() is Tests.list)
8711 assert_equal(2, Tests.four >> 1)
8712 assert_equal(16, 1 << Tests.four)
8713 assert_equal(8, Tests.four + Tests.Four())
8714 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008715 assert_equal('hellohello', Tests.str .. Tests.Str())
8716 assert_equal('hellohello', Tests.Str() .. Tests.str)
8717
8718 # Using class variable for list indexing
8719 var l = range(10)
8720 assert_equal(4, l[Tests.four])
8721 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8722
8723 # Using class variable for Dict key
8724 var d = {hello: 'abc'}
8725 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008726 enddef
8727
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008728 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008729 var t = Tests.new()
8730 t.TestOps()
8731 TestOps2()
8732
8733 assert_true(Tests.truthy == Tests.Truthy())
8734 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008735 assert_true(Tests.truthy == Tests.TruthyFn())
8736 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008737 assert_true(Tests.list is Tests.List())
8738 assert_true(Tests.List() is Tests.list)
8739 assert_equal(2, Tests.four >> 1)
8740 assert_equal(16, 1 << Tests.four)
8741 assert_equal(8, Tests.four + Tests.Four())
8742 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008743 assert_equal('hellohello', Tests.str .. Tests.Str())
8744 assert_equal('hellohello', Tests.Str() .. Tests.str)
8745
8746 # Using class variable for list indexing
8747 var l = range(10)
8748 assert_equal(4, l[Tests.four])
8749 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8750
8751 # Using class variable for Dict key
8752 var d = {hello: 'abc'}
8753 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008754 END
8755 v9.CheckSourceSuccess(lines)
8756enddef
8757
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008758" Test for checking the type of the key used to access an object dict member.
8759def Test_dict_member_key_type_check()
8760 var lines =<< trim END
8761 vim9script
8762
8763 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01008764 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008765 endclass
8766
8767 class Test extends State
8768 def ObjMethodTests()
8769 var cursor: number = 0
8770 var z: number = 0
8771 [this.numbers[cursor]] = ['zero.1']
8772 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8773 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8774 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8775 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8776 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8777 [this.numbers[cursor], z] = ['zero.4', 1]
8778 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8779 [z, this.numbers[cursor]] = [1, 'zero.5']
8780 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8781 enddef
8782
8783 static def ClassMethodTests(that: State)
8784 var cursor: number = 0
8785 var z: number = 0
8786 [that.numbers[cursor]] = ['zero.1']
8787 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8788 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8789 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8790 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8791 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8792 [that.numbers[cursor], z] = ['zero.4', 1]
8793 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8794 [z, that.numbers[cursor]] = [1, 'zero.5']
8795 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8796 enddef
8797
8798 def new()
8799 enddef
8800
8801 def newMethodTests()
8802 var cursor: number = 0
8803 var z: number
8804 [this.numbers[cursor]] = ['zero.1']
8805 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8806 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8807 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8808 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8809 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8810 [this.numbers[cursor], z] = ['zero.4', 1]
8811 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8812 [z, this.numbers[cursor]] = [1, 'zero.5']
8813 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8814 enddef
8815 endclass
8816
8817 def DefFuncTests(that: Test)
8818 var cursor: number = 0
8819 var z: number
8820 [that.numbers[cursor]] = ['zero.1']
8821 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8822 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8823 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8824 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8825 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8826 [that.numbers[cursor], z] = ['zero.4', 1]
8827 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8828 [z, that.numbers[cursor]] = [1, 'zero.5']
8829 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8830 enddef
8831
8832 Test.newMethodTests()
8833 Test.new().ObjMethodTests()
8834 Test.ClassMethodTests(Test.new())
8835 DefFuncTests(Test.new())
8836
8837 const test: Test = Test.new()
8838 var cursor: number = 0
8839 [test.numbers[cursor], cursor] = ['zero', 1]
8840 [cursor, test.numbers[cursor]] = [1, 'one']
8841 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8842 END
8843 v9.CheckSourceSuccess(lines)
8844
8845 lines =<< trim END
8846 vim9script
8847
8848 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008849 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008850
8851 def new()
8852 enddef
8853
8854 def Foo()
8855 var z: number
8856 [this.numbers.a, z] = [{}, 10]
8857 enddef
8858 endclass
8859
8860 var a = A.new()
8861 a.Foo()
8862 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008863 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008864
8865 lines =<< trim END
8866 vim9script
8867
8868 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008869 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008870
8871 def new()
8872 enddef
8873
8874 def Foo()
8875 var x: string = 'a'
8876 var y: number
8877 [this.numbers[x], y] = [{}, 10]
8878 enddef
8879 endclass
8880
8881 var a = A.new()
8882 a.Foo()
8883 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008884 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008885enddef
8886
mityua5550692023-11-25 15:41:20 +01008887def Test_compile_many_def_functions_in_funcref_instr()
8888 # This used to crash Vim. This is reproducible only when run on new instance
8889 # of Vim.
8890 var lines =<< trim END
8891 vim9script
8892
8893 class A
8894 def new()
8895 this.TakeFunc(this.F00)
8896 enddef
8897
8898 def TakeFunc(F: func)
8899 enddef
8900
8901 def F00()
8902 this.F01()
8903 this.F02()
8904 this.F03()
8905 this.F04()
8906 this.F05()
8907 this.F06()
8908 this.F07()
8909 this.F08()
8910 this.F09()
8911 this.F10()
8912 this.F11()
8913 this.F12()
8914 this.F13()
8915 this.F14()
8916 this.F15()
8917 this.F16()
8918 this.F17()
8919 this.F18()
8920 this.F19()
8921 this.F20()
8922 this.F21()
8923 this.F22()
8924 this.F23()
8925 this.F24()
8926 this.F25()
8927 this.F26()
8928 this.F27()
8929 this.F28()
8930 this.F29()
8931 this.F30()
8932 this.F31()
8933 this.F32()
8934 this.F33()
8935 this.F34()
8936 this.F35()
8937 this.F36()
8938 this.F37()
8939 this.F38()
8940 this.F39()
8941 this.F40()
8942 this.F41()
8943 this.F42()
8944 this.F43()
8945 this.F44()
8946 this.F45()
8947 this.F46()
8948 this.F47()
8949 enddef
8950
8951 def F01()
8952 enddef
8953 def F02()
8954 enddef
8955 def F03()
8956 enddef
8957 def F04()
8958 enddef
8959 def F05()
8960 enddef
8961 def F06()
8962 enddef
8963 def F07()
8964 enddef
8965 def F08()
8966 enddef
8967 def F09()
8968 enddef
8969 def F10()
8970 enddef
8971 def F11()
8972 enddef
8973 def F12()
8974 enddef
8975 def F13()
8976 enddef
8977 def F14()
8978 enddef
8979 def F15()
8980 enddef
8981 def F16()
8982 enddef
8983 def F17()
8984 enddef
8985 def F18()
8986 enddef
8987 def F19()
8988 enddef
8989 def F20()
8990 enddef
8991 def F21()
8992 enddef
8993 def F22()
8994 enddef
8995 def F23()
8996 enddef
8997 def F24()
8998 enddef
8999 def F25()
9000 enddef
9001 def F26()
9002 enddef
9003 def F27()
9004 enddef
9005 def F28()
9006 enddef
9007 def F29()
9008 enddef
9009 def F30()
9010 enddef
9011 def F31()
9012 enddef
9013 def F32()
9014 enddef
9015 def F33()
9016 enddef
9017 def F34()
9018 enddef
9019 def F35()
9020 enddef
9021 def F36()
9022 enddef
9023 def F37()
9024 enddef
9025 def F38()
9026 enddef
9027 def F39()
9028 enddef
9029 def F40()
9030 enddef
9031 def F41()
9032 enddef
9033 def F42()
9034 enddef
9035 def F43()
9036 enddef
9037 def F44()
9038 enddef
9039 def F45()
9040 enddef
9041 def F46()
9042 enddef
9043 def F47()
9044 enddef
9045 endclass
9046
9047 A.new()
9048 END
9049 writefile(lines, 'Xscript', 'D')
9050 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9051 assert_equal(0, v:shell_error)
9052enddef
9053
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009054" Test for 'final' class and object variables
9055def Test_final_class_object_variable()
9056 # Test for changing a final object variable from an object function
9057 var lines =<< trim END
9058 vim9script
9059 class A
9060 final foo: string = "abc"
9061 def Foo()
9062 this.foo = "def"
9063 enddef
9064 endclass
9065 defcompile A.Foo
9066 END
9067 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9068
9069 # Test for changing a final object variable from the 'new' function
9070 lines =<< trim END
9071 vim9script
9072 class A
9073 final s1: string
9074 final s2: string
9075 def new(this.s1)
9076 this.s2 = 'def'
9077 enddef
9078 endclass
9079 var a = A.new('abc')
9080 assert_equal('abc', a.s1)
9081 assert_equal('def', a.s2)
9082 END
9083 v9.CheckSourceSuccess(lines)
9084
9085 # Test for a final class variable
9086 lines =<< trim END
9087 vim9script
9088 class A
9089 static final s1: string = "abc"
9090 endclass
9091 assert_equal('abc', A.s1)
9092 END
9093 v9.CheckSourceSuccess(lines)
9094
9095 # Test for changing a final class variable from a class function
9096 lines =<< trim END
9097 vim9script
9098 class A
9099 static final s1: string = "abc"
9100 static def Foo()
9101 s1 = "def"
9102 enddef
9103 endclass
9104 A.Foo()
9105 END
9106 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9107
9108 # Test for changing a public final class variable at script level
9109 lines =<< trim END
9110 vim9script
9111 class A
9112 public static final s1: string = "abc"
9113 endclass
9114 assert_equal('abc', A.s1)
9115 A.s1 = 'def'
9116 END
9117 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9118
9119 # Test for changing a public final class variable from a class function
9120 lines =<< trim END
9121 vim9script
9122 class A
9123 public static final s1: string = "abc"
9124 static def Foo()
9125 s1 = "def"
9126 enddef
9127 endclass
9128 A.Foo()
9129 END
9130 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9131
9132 # Test for changing a public final class variable from a function
9133 lines =<< trim END
9134 vim9script
9135 class A
9136 public static final s1: string = "abc"
9137 endclass
9138 def Foo()
9139 A.s1 = 'def'
9140 enddef
9141 defcompile
9142 END
9143 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9144
9145 # Test for using a final variable of composite type
9146 lines =<< trim END
9147 vim9script
9148 class A
9149 public final l: list<number>
9150 def new()
9151 this.l = [1, 2]
9152 enddef
9153 def Foo()
9154 this.l[0] = 3
9155 this.l->add(4)
9156 enddef
9157 endclass
9158 var a = A.new()
9159 assert_equal([1, 2], a.l)
9160 a.Foo()
9161 assert_equal([3, 2, 4], a.l)
9162 END
9163 v9.CheckSourceSuccess(lines)
9164
9165 # Test for changing a final variable of composite type from another object
9166 # function
9167 lines =<< trim END
9168 vim9script
9169 class A
9170 public final l: list<number> = [1, 2]
9171 def Foo()
9172 this.l = [3, 4]
9173 enddef
9174 endclass
9175 var a = A.new()
9176 a.Foo()
9177 END
9178 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9179
9180 # Test for modifying a final variable of composite type at script level
9181 lines =<< trim END
9182 vim9script
9183 class A
9184 public final l: list<number> = [1, 2]
9185 endclass
9186 var a = A.new()
9187 a.l[0] = 3
9188 a.l->add(4)
9189 assert_equal([3, 2, 4], a.l)
9190 END
9191 v9.CheckSourceSuccess(lines)
9192
9193 # Test for modifying a final variable of composite type from a function
9194 lines =<< trim END
9195 vim9script
9196 class A
9197 public final l: list<number> = [1, 2]
9198 endclass
9199 def Foo()
9200 var a = A.new()
9201 a.l[0] = 3
9202 a.l->add(4)
9203 assert_equal([3, 2, 4], a.l)
9204 enddef
9205 Foo()
9206 END
9207 v9.CheckSourceSuccess(lines)
9208
9209 # Test for modifying a final variable of composite type from another object
9210 # function
9211 lines =<< trim END
9212 vim9script
9213 class A
9214 public final l: list<number> = [1, 2]
9215 def Foo()
9216 this.l[0] = 3
9217 this.l->add(4)
9218 enddef
9219 endclass
9220 var a = A.new()
9221 a.Foo()
9222 assert_equal([3, 2, 4], a.l)
9223 END
9224 v9.CheckSourceSuccess(lines)
9225
9226 # Test for assigning a new value to a final variable of composite type at
9227 # script level
9228 lines =<< trim END
9229 vim9script
9230 class A
9231 public final l: list<number> = [1, 2]
9232 endclass
9233 var a = A.new()
9234 a.l = [3, 4]
9235 END
9236 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9237
9238 # Test for assigning a new value to a final variable of composite type from
9239 # another object function
9240 lines =<< trim END
9241 vim9script
9242 class A
9243 public final l: list<number> = [1, 2]
9244 def Foo()
9245 this.l = [3, 4]
9246 enddef
9247 endclass
9248 var a = A.new()
9249 a.Foo()
9250 END
9251 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9252
9253 # Test for assigning a new value to a final variable of composite type from
9254 # another function
9255 lines =<< trim END
9256 vim9script
9257 class A
9258 public final l: list<number> = [1, 2]
9259 endclass
9260 def Foo()
9261 var a = A.new()
9262 a.l = [3, 4]
9263 enddef
9264 Foo()
9265 END
9266 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9267
9268 # Error case: Use 'final' with just a variable name
9269 lines =<< trim END
9270 vim9script
9271 class A
9272 final foo
9273 endclass
9274 var a = A.new()
9275 END
9276 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9277
9278 # Error case: Use 'final' followed by 'public'
9279 lines =<< trim END
9280 vim9script
9281 class A
9282 final public foo: number
9283 endclass
9284 var a = A.new()
9285 END
9286 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9287
9288 # Error case: Use 'final' followed by 'static'
9289 lines =<< trim END
9290 vim9script
9291 class A
9292 final static foo: number
9293 endclass
9294 var a = A.new()
9295 END
9296 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9297
9298 # Error case: 'final' cannot be used in an interface
9299 lines =<< trim END
9300 vim9script
9301 interface A
9302 final foo: number = 10
9303 endinterface
9304 END
9305 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9306
9307 # Error case: 'final' not supported for an object method
9308 lines =<< trim END
9309 vim9script
9310 class A
9311 final def Foo()
9312 enddef
9313 endclass
9314 END
9315 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9316
9317 # Error case: 'final' not supported for a class method
9318 lines =<< trim END
9319 vim9script
9320 class A
9321 static final def Foo()
9322 enddef
9323 endclass
9324 END
9325 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9326enddef
9327
9328" Test for 'const' class and object variables
9329def Test_const_class_object_variable()
9330 # Test for changing a const object variable from an object function
9331 var lines =<< trim END
9332 vim9script
9333 class A
9334 const foo: string = "abc"
9335 def Foo()
9336 this.foo = "def"
9337 enddef
9338 endclass
9339 defcompile A.Foo
9340 END
9341 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9342
9343 # Test for changing a const object variable from the 'new' function
9344 lines =<< trim END
9345 vim9script
9346 class A
9347 const s1: string
9348 const s2: string
9349 def new(this.s1)
9350 this.s2 = 'def'
9351 enddef
9352 endclass
9353 var a = A.new('abc')
9354 assert_equal('abc', a.s1)
9355 assert_equal('def', a.s2)
9356 END
9357 v9.CheckSourceSuccess(lines)
9358
9359 # Test for changing a const object variable from an object method called from
9360 # the 'new' function
9361 lines =<< trim END
9362 vim9script
9363 class A
9364 const s1: string = 'abc'
9365 def new()
9366 this.ChangeStr()
9367 enddef
9368 def ChangeStr()
9369 this.s1 = 'def'
9370 enddef
9371 endclass
9372 var a = A.new()
9373 END
9374 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9375
9376 # Test for a const class variable
9377 lines =<< trim END
9378 vim9script
9379 class A
9380 static const s1: string = "abc"
9381 endclass
9382 assert_equal('abc', A.s1)
9383 END
9384 v9.CheckSourceSuccess(lines)
9385
9386 # Test for changing a const class variable from a class function
9387 lines =<< trim END
9388 vim9script
9389 class A
9390 static const s1: string = "abc"
9391 static def Foo()
9392 s1 = "def"
9393 enddef
9394 endclass
9395 A.Foo()
9396 END
9397 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9398
9399 # Test for changing a public const class variable at script level
9400 lines =<< trim END
9401 vim9script
9402 class A
9403 public static const s1: string = "abc"
9404 endclass
9405 assert_equal('abc', A.s1)
9406 A.s1 = 'def'
9407 END
9408 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9409
9410 # Test for changing a public const class variable from a class function
9411 lines =<< trim END
9412 vim9script
9413 class A
9414 public static const s1: string = "abc"
9415 static def Foo()
9416 s1 = "def"
9417 enddef
9418 endclass
9419 A.Foo()
9420 END
9421 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9422
9423 # Test for changing a public const class variable from a function
9424 lines =<< trim END
9425 vim9script
9426 class A
9427 public static const s1: string = "abc"
9428 endclass
9429 def Foo()
9430 A.s1 = 'def'
9431 enddef
9432 defcompile
9433 END
9434 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9435
9436 # Test for changing a const List item from an object function
9437 lines =<< trim END
9438 vim9script
9439 class A
9440 public const l: list<number>
9441 def new()
9442 this.l = [1, 2]
9443 enddef
9444 def Foo()
9445 this.l[0] = 3
9446 enddef
9447 endclass
9448 var a = A.new()
9449 assert_equal([1, 2], a.l)
9450 a.Foo()
9451 END
9452 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9453
9454 # Test for adding a value to a const List from an object function
9455 lines =<< trim END
9456 vim9script
9457 class A
9458 public const l: list<number>
9459 def new()
9460 this.l = [1, 2]
9461 enddef
9462 def Foo()
9463 this.l->add(3)
9464 enddef
9465 endclass
9466 var a = A.new()
9467 a.Foo()
9468 END
9469 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9470
9471 # Test for reassigning a const List from an object function
9472 lines =<< trim END
9473 vim9script
9474 class A
9475 public const l: list<number> = [1, 2]
9476 def Foo()
9477 this.l = [3, 4]
9478 enddef
9479 endclass
9480 var a = A.new()
9481 a.Foo()
9482 END
9483 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9484
9485 # Test for changing a const List item at script level
9486 lines =<< trim END
9487 vim9script
9488 class A
9489 public const l: list<number> = [1, 2]
9490 endclass
9491 var a = A.new()
9492 a.l[0] = 3
9493 END
9494 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9495
9496 # Test for adding a value to a const List item at script level
9497 lines =<< trim END
9498 vim9script
9499 class A
9500 public const l: list<number> = [1, 2]
9501 endclass
9502 var a = A.new()
9503 a.l->add(4)
9504 END
9505 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9506
9507 # Test for changing a const List item from a function
9508 lines =<< trim END
9509 vim9script
9510 class A
9511 public const l: list<number> = [1, 2]
9512 endclass
9513 def Foo()
9514 var a = A.new()
9515 a.l[0] = 3
9516 enddef
9517 Foo()
9518 END
9519 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9520
9521 # Test for adding a value to a const List item from a function
9522 lines =<< trim END
9523 vim9script
9524 class A
9525 public const l: list<number> = [1, 2]
9526 endclass
9527 def Foo()
9528 var a = A.new()
9529 a.l->add(4)
9530 enddef
9531 Foo()
9532 END
9533 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9534
9535 # Test for changing a const List item from an object method
9536 lines =<< trim END
9537 vim9script
9538 class A
9539 public const l: list<number> = [1, 2]
9540 def Foo()
9541 this.l[0] = 3
9542 enddef
9543 endclass
9544 var a = A.new()
9545 a.Foo()
9546 END
9547 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9548
9549 # Test for adding a value to a const List item from an object method
9550 lines =<< trim END
9551 vim9script
9552 class A
9553 public const l: list<number> = [1, 2]
9554 def Foo()
9555 this.l->add(4)
9556 enddef
9557 endclass
9558 var a = A.new()
9559 a.Foo()
9560 END
9561 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9562
9563 # Test for reassigning a const List object variable 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 = [3, 4]
9571 END
9572 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9573
9574 # Test for reassigning a const List object variable from an object method
9575 lines =<< trim END
9576 vim9script
9577 class A
9578 public const l: list<number> = [1, 2]
9579 def Foo()
9580 this.l = [3, 4]
9581 enddef
9582 endclass
9583 var a = A.new()
9584 a.Foo()
9585 END
9586 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9587
9588 # Test for reassigning a const List object variable from another 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 = [3, 4]
9597 enddef
9598 Foo()
9599 END
9600 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9601
9602 # Error case: Use 'const' with just a variable name
9603 lines =<< trim END
9604 vim9script
9605 class A
9606 const foo
9607 endclass
9608 var a = A.new()
9609 END
9610 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9611
9612 # Error case: Use 'const' followed by 'public'
9613 lines =<< trim END
9614 vim9script
9615 class A
9616 const public foo: number
9617 endclass
9618 var a = A.new()
9619 END
9620 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9621
9622 # Error case: Use 'const' followed by 'static'
9623 lines =<< trim END
9624 vim9script
9625 class A
9626 const static foo: number
9627 endclass
9628 var a = A.new()
9629 END
9630 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9631
9632 # Error case: 'const' cannot be used in an interface
9633 lines =<< trim END
9634 vim9script
9635 interface A
9636 const foo: number = 10
9637 endinterface
9638 END
9639 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9640
9641 # Error case: 'const' not supported for an object method
9642 lines =<< trim END
9643 vim9script
9644 class A
9645 const def Foo()
9646 enddef
9647 endclass
9648 END
9649 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9650
9651 # Error case: 'const' not supported for a class method
9652 lines =<< trim END
9653 vim9script
9654 class A
9655 static const def Foo()
9656 enddef
9657 endclass
9658 END
9659 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9660enddef
9661
Yegappan Lakshmananff6f0d52023-12-21 16:46:18 +01009662" Test for using double underscore prefix in a class/object method name.
9663def Test_method_double_underscore_prefix()
9664 # class method
9665 var lines =<< trim END
9666 vim9script
9667 class A
9668 static def __foo()
9669 echo "foo"
9670 enddef
9671 endclass
9672 defcompile
9673 END
9674 v9.CheckSourceFailure(lines, 'E1034: Cannot use reserved name __foo()', 3)
9675
9676 # object method
9677 lines =<< trim END
9678 vim9script
9679 class A
9680 def __foo()
9681 echo "foo"
9682 enddef
9683 endclass
9684 defcompile
9685 END
9686 v9.CheckSourceFailure(lines, 'E1034: Cannot use reserved name __foo()', 3)
9687enddef
9688
Bram Moolenaar00b28d62022-12-08 15:32:33 +00009689" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker