1- local searchCode = require ' plugins.ffi.searchCode'
2- local cdefRerence = require ' plugins.ffi.cdefRerence'
3- local cdriver = require ' plugins.ffi.c-parser.cdriver'
4- local util = require ' plugins.ffi.c-parser.util'
5- local utility = require ' utility'
6- local SDBMHash = require ' SDBMHash'
7- local ws = require ' workspace'
8- local files = require ' files'
9- local await = require ' await'
10- local config = require ' config'
11- local fs = require ' bee.filesystem'
12- local scope = require ' workspace.scope'
1+ local searchCode = require ' plugins.ffi.searchCode'
2+ local cdefRerence = require ' plugins.ffi.cdefRerence'
3+ local cdriver = require ' plugins.ffi.c-parser.cdriver'
4+ local util = require ' plugins.ffi.c-parser.util'
5+ local utility = require ' utility'
6+ local SDBMHash = require ' SDBMHash'
7+ local config = require ' config'
8+ local fs = require ' bee.filesystem'
9+ local scope = require ' workspace.scope'
1310
14- local namespace <const> = ' ffi.namespace*.'
11+ local namespace <const> = ' ffi.namespace*.'
1512
1613-- TODO:supprot 32bit ffi, need config
17- local knownTypes = {
14+ local knownTypes = {
1815 [" bool" ] = ' boolean' ,
1916 [" char" ] = ' integer' ,
2017 [" short" ] = ' integer' ,
@@ -63,10 +60,33 @@ local knownTypes = {
6360 [" signedlong" ] = ' integer' ,
6461}
6562
66- local constName <const> = ' m'
63+ local blackKeyWord <const> = {
64+ [' and' ] = " _and" ,
65+ [' do' ] = " _do" ,
66+ [' elseif' ] = " _elseif" ,
67+ [' end' ] = " _end" ,
68+ [' false' ] = " _false" ,
69+ [' function' ] = " _function" ,
70+ [' in' ] = " _in" ,
71+ [' local' ] = " _local" ,
72+ [' nil' ] = " _nil" ,
73+ [' not' ] = " _not" ,
74+ [' or' ] = " _or" ,
75+ [' repeat' ] = " _repeat" ,
76+ [' then' ] = " _then" ,
77+ [' true' ] = " _true" ,
78+ }
79+
80+ local invaildKeyWord <const> = {
81+ const = true ,
82+ restrict = true ,
83+ volatile = true ,
84+ }
85+
86+ local constName <const> = ' m'
6787
6888--- @class ffi.builder
69- local builder = { switch_ast = utility .switch () }
89+ local builder = { switch_ast = utility .switch () }
7090
7191function builder :getTypeAst (name )
7292 for i , asts in ipairs (self .globalAsts ) do
@@ -98,14 +118,22 @@ function builder:getType(name)
98118 if type (name ) == ' table' then
99119 local t = " "
100120 local isStruct
121+ if name .type then
122+ t = t .. name .type .. " @"
123+ name = name .name
124+ end
101125 for _ , n in ipairs (name ) do
102126 if type (n ) == ' table' then
103127 n = n .full_name
104128 end
129+ if invaildKeyWord [n ] then
130+ goto continue
131+ end
105132 if not isStruct then
106133 isStruct = self :needDeref (self :getTypeAst (n ))
107134 end
108135 t = t .. n
136+ :: continue::
109137 end
110138 -- deref 一级指针
111139 if isStruct and t :sub (# t ) == ' *' then
@@ -145,11 +173,15 @@ local function getArrayType(arr)
145173 return res
146174end
147175
176+ local function getValidName (name )
177+ return blackKeyWord [name ] or name
178+ end
179+
148180function builder :buildStructOrUnion (lines , tt , name )
149181 lines [# lines + 1 ] = ' ---@class ' .. self :getType (name )
150182 for _ , field in ipairs (tt .fields or {}) do
151183 if field .name and field .type then
152- lines [# lines + 1 ] = (' ---@field %s %s%s' ):format (field .name , self :getType (field .type ),
184+ lines [# lines + 1 ] = (' ---@field %s %s%s' ):format (getValidName ( field .name ) , self :getType (field .type ),
153185 getArrayType (field .isarray ))
154186 end
155187 end
158190function builder :buildFunction (lines , tt , name )
159191 local param_names = {}
160192 for i , param in ipairs (tt .params or {}) do
161- lines [# lines + 1 ] = (' ---@param %s %s%s' ):format (param .name , self :getType (param .type ), getArrayType (param .idxs ))
162- param_names [# param_names + 1 ] = param .name
193+ local param_name = getValidName (param .name )
194+ lines [# lines + 1 ] = (' ---@param %s %s%s' ):format (param_name , self :getType (param .type ), getArrayType (param .idxs ))
195+ param_names [# param_names + 1 ] = param_name
163196 end
164197 if tt .vararg then
165198 param_names [# param_names + 1 ] = ' ...'
@@ -178,7 +211,7 @@ function builder:buildTypedef(lines, tt, name)
178211 -- 这个时候没有主类型,只有一个别名,直接创建一个别名结构体
179212 self .switch_ast (def .type , self , lines , def , name )
180213 else
181- lines [# lines + 1 ] = (' ---@alias %s %s' ):format (name , self :getType (def ))
214+ lines [# lines + 1 ] = (' ---@alias %s %s' ):format (self : getType ( name ) , self :getType (def ))
182215 end
183216end
184217
@@ -322,72 +355,18 @@ function m.compileCodes(codes)
322355 return lines
323356end
324357
325- local function createDir (uri )
326- local dir = scope .getScope (uri ).uri or ' default'
327- local fileDir = fs .path (METAPATH ) / (' %08x' ):format (SDBMHash ():hash (dir ))
328- fs .create_directories (fileDir )
329- return fileDir
330- end
331-
332- local builder
333- function m .initBuilder (fileDir )
334- fileDir = fileDir or createDir ()
335- --- @async
336- return function (uri )
337- local refs = cdefRerence ()
338- if not refs or # refs == 0 then
339- return
340- end
341-
342- local codes = searchCode (refs , uri )
343- if not codes then
344- return
345- end
346-
347- local texts = m .compileCodes (codes )
348- if not texts then
349- return
350- end
351- local hash = (' %08x' ):format (SDBMHash ():hash (uri ))
352- local encoding = config .get (nil , ' Lua.runtime.fileEncoding' )
353- local filePath = fileDir / table.concat ({ hash , encoding }, ' _' )
354-
355- utility .saveFile (tostring (filePath ) .. ' .d.lua' , table.concat (texts , ' \n ' ))
358+ function m .build_single (codes , fileDir , uri )
359+ local texts = m .compileCodes (codes )
360+ if not texts then
361+ return
356362 end
357- end
358363
359- files .watch (function (ev , uri )
360- if ev == ' compiler' or ev == ' update' then
361- if builder then
362- await .call (function () --- @async
363- builder (uri )
364- end )
365- end
366- end
367- end )
364+ local hash = (' %08x' ):format (SDBMHash ():hash (uri ))
365+ local encoding = config .get (nil , ' Lua.runtime.fileEncoding' )
366+ local filePath = fileDir / table.concat ({ hash , encoding }, ' _' )
368367
369- ws .watch (function (ev , uri )
370- -- TODO
371- do return end
372- if ev == ' startReload' then
373- if config .get (uri , ' Lua.runtime.version' ) ~= ' LuaJIT' then
374- return
375- end
376- await .call (function () --- @async
377- ws .awaitReady (uri )
378- local fileDir = createDir (uri )
379- builder = m .initBuilder (fileDir )
380- local client = require ' client'
381- client .setConfig {
382- {
383- key = ' Lua.workspace.library' ,
384- action = ' add' ,
385- value = tostring (fileDir ),
386- uri = uri ,
387- }
388- }
389- end )
390- end
391- end )
368+ utility .saveFile (tostring (filePath ) .. ' .d.lua' , table.concat (texts , ' \n ' ))
369+ return true
370+ end
392371
393372return m
0 commit comments