@@ -16,13 +16,14 @@ local f = require "plenary.functional"
16
16
local exports = {}
17
17
18
18
--- @generic V
19
- --- @alias PlenaryIteratorsIterator fun ( table : V[] , i ?: integer ): integer , V ?
19
+ --- @alias PlenaryIteratorsIterator fun ( param : string | V[] , i ?: integer ): integer ?, string | V | nil
20
20
21
21
--- @class PlenaryIterator
22
22
--- @field gen PlenaryIteratorsIterator
23
- --- @field param table
23
+ --- @field param string | table
24
24
--- @field state ? integer
25
- --- @overload fun ( param ?: table , state ?: integer ): integer , any ?
25
+ --- @overload fun ( param ?: string | table , state ?: integer ): integer ?, any ?
26
+
26
27
local Iterator = {}
27
28
Iterator .__index = Iterator
28
29
@@ -35,6 +36,11 @@ Iterator.__index = Iterator
35
36
--- So instead we do not return param and state as multivals when doing wrap
36
37
--- This causes the first loop iteration to call param and state with nil because we didn't return them as multivals
37
38
--- We have to use or to check for nil and default to interal starting state and param
39
+ --- @generic T
40
+ --- @param param ? string | T[]
41
+ --- @param state ? integer
42
+ --- @return integer i
43
+ --- @return string | T v
38
44
function Iterator :__call (param , state )
39
45
return self .gen (param or self .param , state or self .state )
40
46
end
46
52
47
53
-- A special hack for zip/chain to skip last two state, if a wrapped iterator
48
54
-- has been passed
55
+ --- @param ... any
56
+ --- @return integer
49
57
local numargs = function (...)
50
58
local n = select (" #" , ... )
51
59
if n >= 3 then
@@ -63,13 +71,21 @@ local numargs = function(...)
63
71
return n
64
72
end
65
73
74
+ --- @param state_x ? integer
75
+ --- @param ... any
76
+ --- @return ...
66
77
local return_if_not_empty = function (state_x , ...)
67
78
if state_x == nil then
68
79
return nil
69
80
end
70
81
return ...
71
82
end
72
83
84
+ --- @param fun function
85
+ --- @param state_x ? integer
86
+ --- @param ... any
87
+ --- @return integer ?
88
+ --- @return ...
73
89
local call_if_not_empty = function (fun , state_x , ...)
74
90
if state_x == nil then
75
91
return nil
80
96
---- ----------------------------------------------------------------------------
81
97
-- Basic Functions
82
98
---- ----------------------------------------------------------------------------
99
+ --- @param _param any
100
+ --- @param _state any
101
+ --- @return nil
83
102
local nil_gen = function (_param , _state )
84
103
return nil
85
104
end
86
105
87
106
local pairs_gen = pairs {}
88
107
108
+ --- @generic K , V
109
+ --- @param map table<K , V>
110
+ --- @param key K
111
+ --- @return K key
112
+ --- @return K key
113
+ --- @return V value
89
114
local map_gen = function (map , key )
90
115
local value
91
116
key , value = pairs_gen (map , key )
94
119
95
120
--- @param param string
96
121
--- @param state integer
97
- --- @return integer ? state
98
- --- @return string ? r
122
+ --- @return integer state
123
+ --- @return string r
99
124
local string_gen = function (param , state )
100
125
state = state + 1
101
126
if state > # param then
@@ -105,18 +130,12 @@ local string_gen = function(param, state)
105
130
return state , r
106
131
end
107
132
108
- --- @generic T : table , U : table
109
- --- @alias PlenaryIteratorsRawiterTable fun ( obj : T | PlenaryIterator , param ?: string , state ?: integer ): PlenaryIteratorsIterator , T | U | nil , integer ?
110
-
111
- --- @generic T : table , U : table
112
- --- @param obj T | PlenaryIterator
113
- --- @param param ? string
133
+ --- @param obj string | function | table | PlenaryIterator
134
+ --- @param param ? string | table
114
135
--- @param state ? integer
115
136
--- @return PlenaryIteratorsIterator gen
116
- --- @return T | U | nil param
137
+ --- @return string | table | nil param
117
138
--- @return integer ? state
118
- --- @overload fun ( obj : PlenaryIteratorsIterator , param : any , state ?: integer ): PlenaryIteratorsIterator , any , integer ?
119
- --- @overload fun ( obj : string ): PlenaryIteratorsIterator , string ?, integer ?
120
139
local rawiter = function (obj , param , state )
121
140
assert (obj ~= nil , " invalid iterator" )
122
141
151
170
--- Wraps the iterator triplet into a table to allow metamethods and calling with method form
152
171
--- Important! We do not return param and state as multivals like the original luafun
153
172
--- See the __call metamethod for more information
154
- --- @param gen any
155
- --- @param param any
156
- --- @param state any
173
+ --- @param gen PlenaryIteratorsIterator
174
+ --- @param param ? string | table
175
+ --- @param state ? integer
157
176
--- @return PlenaryIterator
158
177
local function wrap (gen , param , state )
159
178
return setmetatable ({
@@ -165,17 +184,17 @@ end
165
184
166
185
--- Unwrap an iterator metatable into the iterator triplet
167
186
--- @param self PlenaryIterator
168
- --- @return any
169
- --- @return any
170
- --- @return any
187
+ --- @return PlenaryIteratorsIterator gen
188
+ --- @return string | table param
189
+ --- @return integer ? state
171
190
local unwrap = function (self )
172
191
return self .gen , self .param , self .state
173
192
end
174
193
175
194
--- Create an iterator from an object
176
- --- @param obj any
177
- --- @param param any ( optional )
178
- --- @param state any ( optional )
195
+ --- @param obj string | function | table | PlenaryIterator
196
+ --- @param param ? table
197
+ --- @param state ? integer
179
198
--- @return PlenaryIterator
180
199
local iter = function (obj , param , state )
181
200
return wrap (rawiter (obj , param , state ))
@@ -185,13 +204,15 @@ exports.iter = iter
185
204
exports .wrap = wrap
186
205
exports .unwrap = unwrap
187
206
207
+ --- @param fn PlenaryIteratorsIterator
188
208
function Iterator :for_each (fn )
189
209
local param , state = self .param , self .state
190
210
repeat
191
211
state = call_if_not_empty (fn , self .gen (param , state ))
192
212
until state == nil
193
213
end
194
214
215
+ --- @return PlenaryIterator
195
216
function Iterator :stateful ()
196
217
return wrap (
197
218
co .wrap (function ()
228
249
---- ----------------------------------------------------------------------------
229
250
-- Generators
230
251
---- ----------------------------------------------------------------------------
252
+ --- @param param { [1] : integer , [2] : integer }
253
+ --- @param state ? integer
254
+ --- @return integer ? state
255
+ --- @return integer ? state
231
256
local range_gen = function (param , state )
232
257
local stop , step = param [1 ], param [2 ]
233
258
state = state + step
@@ -237,6 +262,10 @@ local range_gen = function(param, state)
237
262
return state , state
238
263
end
239
264
265
+ --- @param param { [1] : integer , [2] : integer }
266
+ --- @param state ? integer
267
+ --- @return integer ? state
268
+ --- @return integer ? state
240
269
local range_rev_gen = function (param , state )
241
270
local stop , step = param [1 ], param [2 ]
242
271
state = state + step
@@ -247,9 +276,9 @@ local range_rev_gen = function(param, state)
247
276
end
248
277
249
278
--- Creates a range iterator
250
- --- @param start number
251
- --- @param stop number
252
- --- @param step number
279
+ --- @param start integer
280
+ --- @param stop ? integer
281
+ --- @param step ? integer
253
282
--- @return PlenaryIterator
254
283
local range = function (start , stop , step )
255
284
if step == nil then
@@ -276,21 +305,35 @@ local range = function(start, stop, step)
276
305
end
277
306
exports .range = range
278
307
308
+ --- @generic T
309
+ --- @param param_x T[]
310
+ --- @param state_x integer
311
+ --- @return integer state
312
+ --- @return T ...
279
313
local duplicate_table_gen = function (param_x , state_x )
280
314
return state_x + 1 , unpack (param_x )
281
315
end
282
316
317
+ --- @param param_x fun ( state : integer ): ...
318
+ --- @param state_x integer
319
+ --- @return integer state
320
+ --- @return any ...
283
321
local duplicate_fun_gen = function (param_x , state_x )
284
322
return state_x + 1 , param_x (state_x )
285
323
end
286
324
325
+ --- @generic T
326
+ --- @param param_x T
327
+ --- @param state_x integer
328
+ --- @return integer state
329
+ --- @return T param
287
330
local duplicate_gen = function (param_x , state_x )
288
331
return state_x + 1 , param_x
289
332
end
290
333
291
334
--- Creates an infinite iterator that will yield the arguments
292
335
--- If multiple arguments are passed, the args will be packed and unpacked
293
- --- @param ...: the arguments to duplicate
336
+ --- @param ... any the arguments to duplicate
294
337
--- @return PlenaryIterator
295
338
local duplicate = function (...)
296
339
if select (" #" , ... ) <= 1 then
@@ -303,7 +346,7 @@ exports.duplicate = duplicate
303
346
304
347
--- Creates an iterator from a function
305
348
--- NOTE: if the function is a closure and modifies state, the resulting iterator will not be stateless
306
- --- @param fun function
349
+ --- @param fun fun ( state : integer ): ...
307
350
--- @return PlenaryIterator
308
351
local from_fun = function (fun )
309
352
assert (type (fun ) == " function" )
@@ -327,17 +370,25 @@ local ones = function()
327
370
end
328
371
exports .ones = ones
329
372
373
+ --- @param param_x { [1] : integer , [2] : integer }
374
+ --- @param _state_x any
375
+ --- @return 0
376
+ --- @return integer
330
377
local rands_gen = function (param_x , _state_x )
331
378
return 0 , math.random (param_x [1 ], param_x [2 ])
332
379
end
333
380
381
+ --- @param _param_x any
382
+ --- @param _state_x any
383
+ --- @return 0
384
+ --- @return float
334
385
local rands_nil_gen = function (_param_x , _state_x )
335
386
return 0 , math.random ()
336
387
end
337
388
338
389
--- Creates an infinite iterator that will yield random values.
339
- --- @param n number
340
- --- @param m number
390
+ --- @param n integer
391
+ --- @param m integer
341
392
--- @return PlenaryIterator
342
393
local rands = function (n , m )
343
394
if n == nil and m == nil then
@@ -355,6 +406,10 @@ local rands = function(n, m)
355
406
end
356
407
exports .rands = rands
357
408
409
+ --- @param param { [1] : string , [2] : string }
410
+ --- @param state ? integer
411
+ --- @return integer ?
412
+ --- @return string ?
358
413
local split_gen = function (param , state )
359
414
local input , sep = param [1 ], param [2 ]
360
415
local input_len = # input
@@ -375,8 +430,8 @@ local split_gen = function(param, state)
375
430
end
376
431
377
432
--- Return an iterator of substrings separated by a string
378
- --- @param input string : the string to split
379
- --- @param sep string : the separator to find and split based on
433
+ --- @param input string the string to split
434
+ --- @param sep string the separator to find and split based on
380
435
--- @return PlenaryIterator
381
436
local split = function (input , sep )
382
437
return wrap (split_gen , { input , sep }, 1 )
@@ -385,13 +440,15 @@ exports.split = split
385
440
386
441
--- Splits a string based on a single space
387
442
--- An alias for split(input, " ")
388
- --- @param input any
389
- --- @return any
443
+ --- @param input string
444
+ --- @return PlenaryIterator
390
445
local words = function (input )
391
446
return split (input , " " )
392
447
end
393
448
exports .words = words
394
449
450
+ --- @param input string
451
+ --- @return PlenaryIterator
395
452
local lines = function (input )
396
453
-- TODO: platform specific linebreaks
397
454
return split (input , " \n " )
@@ -401,27 +458,45 @@ exports.lines = lines
401
458
---- ----------------------------------------------------------------------------
402
459
-- Transformations
403
460
---- ----------------------------------------------------------------------------
461
+ --- @alias PlenaryIteratorsLoop fun ( i ?: integer , v ?: any )
462
+
463
+ --- @param param { [1] : PlenaryIteratorsIterator , [2] : string | table , [3] : PlenaryIteratorsLoop }
464
+ --- @param state ? integer
465
+ --- @return integer ?
466
+ --- @return ...
404
467
local map_gen2 = function (param , state )
405
468
local gen_x , param_x , fun = param [1 ], param [2 ], param [3 ]
406
469
return call_if_not_empty (fun , gen_x (param_x , state ))
407
470
end
408
471
409
472
--- Iterator adapter that maps the previous iterator with a function
410
- --- @param fun function : The function to map with. Will be called on each element
473
+ --- @param fun PlenaryIteratorsLoop The function to map with. Will be called on each element
411
474
--- @return PlenaryIterator
412
475
function Iterator :map (fun )
413
476
return wrap (map_gen2 , { self .gen , self .param , fun }, self .state )
414
477
end
415
478
479
+ --- @alias PlenaryIteratorsFlattenParam { [1] : PlenaryIteratorsIterator , [2] : string | table , [3] : integer }
480
+
416
481
local flatten_gen1
417
482
do
483
+ --- @param new_iter PlenaryIterator
484
+ --- @param state_x ? integer
485
+ --- @param ...
486
+ --- @return PlenaryIteratorsFlattenParam ?
487
+ --- @return ...
418
488
local it = function (new_iter , state_x , ...)
419
489
if state_x == nil then
420
490
return nil
421
491
end
422
492
return { new_iter .gen , new_iter .param , state_x }, ...
423
493
end
424
494
495
+ --- @param state PlenaryIteratorsFlattenParam
496
+ --- @param state_x ? integer
497
+ --- @param ... unknown
498
+ --- @return PlenaryIteratorsFlattenParam ?
499
+ --- @return ...
425
500
flatten_gen1 = function (state , state_x , ...)
426
501
if state_x == nil then
427
502
return nil
432
507
-- experimental part
433
508
if getmetatable (first_arg ) == Iterator then
434
509
-- attach the iterator to the rest
435
- local new_iter = (first_arg .. wrap (state [1 ], state [2 ], state_x )):flatten ()
510
+ local new_iter = (first_arg .. wrap (state [1 ], state [2 ], state_x )):flatten () --[[ @as PlenaryIterator ]]
436
511
-- advance the iterator by one
437
512
return it (new_iter , new_iter .gen (new_iter .param , new_iter .state ))
438
513
end
441
516
end
442
517
end
443
518
519
+ --- @param _ any
520
+ --- @param state ? PlenaryIteratorsFlattenParam
521
+ --- @return PlearyIteratorsFlattenParam ?
522
+ --- @return ...
444
523
local flatten_gen = function (_ , state )
445
524
if state == nil then
446
525
return
0 commit comments