-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfs-thread-override.lua
71 lines (54 loc) · 2.42 KB
/
fs-thread-override.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
-- Creates a new overload of any function that has a callback accepting a thread
--
-- We do this to make sure returns in case of async versions getting a thread passed are correct (and not use a uv_fs_t return)
--
-- Although, how to handle this highly depend on the language server identifying the user passing a thread instead of a function
-- due to a bug in sumneko's language server, returns are always every possible return despite the context
-- see https://github.com/sumneko/lua-language-server/issues/1146
--
-- This only outputs the new definitions and does not replace old ones. The copy-paste process is manual, since it doesn't take much effort
local re = require('re')
local fs = require('fs')
local compile = re.compile
local extract_meta = compile [[
def <- {| (section / .)+ |}
section <- {| tags_section function_def |}
tags_section <- {:meta: (&'---' tag)+ :}
tag <- '---@' [^ ]+ [^%nl]+ %nl
function_def <- {:func: 'function fs.' fun_name s 'end' :}
fun_name <- ([^%nl] !'Sync' !'end')+
s <- ' '*
]]
local source = fs.readFileSync('../library/fs.lua')
local output = {}
local meta = extract_meta:match(source)
local buffer = {}
for _, def in ipairs(meta) do
local optional, callback_params = def.meta:match('%-%-%-@param callback(%??) fun(%b())')
if not callback_params then goto continue end
callback_params = callback_params:gsub('[%(%)]', '')
local name = def.func:match('function (fs%.[^%(]+)')
if buffer.name and name ~= buffer.name then
output[#output+1] = table.concat(buffer, '\n') .. '\n\n'
buffer = {}
end
local old_meta = def.meta:gsub(' ?|? ?thread', '') .. def.func
-- not the main definition rather just an overload of it
-- remove the thread option if any and leave the rest as is
if optional ~= '?' then
buffer.name = name
buffer[#buffer+1] = old_meta:gsub('\n*$', '')
goto continue
end
local returns = {}
for name, optional, value in callback_params:gmatch('([%w_]+)(%??) *: * ([^%),]+)') do
returns[#returns+1] = value .. optional .. ' ' .. name
end
returns = table.concat(returns, ', ') .. '\n---@nodiscard'
local new_meta = def.meta:gsub('%-%-%-@param callback%? .-\n', '%-%-%-@param callback thread\n')
:gsub('%-%-%[email protected]\n', '%-%-%-@return ' .. returns)
:gsub('\n*$', '')
output[#output+1] = old_meta .. '\n' .. new_meta .. '\n' .. def.func
::continue::
end
fs.writeFileSync('./fs-thread-override-output.lua', table.concat(output, '\n'))