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'
13
10
14
- local namespace <const> = ' ffi.namespace*.'
11
+ local namespace <const> = ' ffi.namespace*.'
15
12
16
13
-- TODO:supprot 32bit ffi, need config
17
- local knownTypes = {
14
+ local knownTypes = {
18
15
[" bool" ] = ' boolean' ,
19
16
[" char" ] = ' integer' ,
20
17
[" short" ] = ' integer' ,
@@ -63,10 +60,33 @@ local knownTypes = {
63
60
[" signedlong" ] = ' integer' ,
64
61
}
65
62
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'
67
87
68
88
--- @class ffi.builder
69
- local builder = { switch_ast = utility .switch () }
89
+ local builder = { switch_ast = utility .switch () }
70
90
71
91
function builder :getTypeAst (name )
72
92
for i , asts in ipairs (self .globalAsts ) do
@@ -98,14 +118,22 @@ function builder:getType(name)
98
118
if type (name ) == ' table' then
99
119
local t = " "
100
120
local isStruct
121
+ if name .type then
122
+ t = t .. name .type .. " @"
123
+ name = name .name
124
+ end
101
125
for _ , n in ipairs (name ) do
102
126
if type (n ) == ' table' then
103
127
n = n .full_name
104
128
end
129
+ if invaildKeyWord [n ] then
130
+ goto continue
131
+ end
105
132
if not isStruct then
106
133
isStruct = self :needDeref (self :getTypeAst (n ))
107
134
end
108
135
t = t .. n
136
+ :: continue::
109
137
end
110
138
-- deref 一级指针
111
139
if isStruct and t :sub (# t ) == ' *' then
@@ -145,11 +173,15 @@ local function getArrayType(arr)
145
173
return res
146
174
end
147
175
176
+ local function getValidName (name )
177
+ return blackKeyWord [name ] or name
178
+ end
179
+
148
180
function builder :buildStructOrUnion (lines , tt , name )
149
181
lines [# lines + 1 ] = ' ---@class ' .. self :getType (name )
150
182
for _ , field in ipairs (tt .fields or {}) do
151
183
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 ),
153
185
getArrayType (field .isarray ))
154
186
end
155
187
end
158
190
function builder :buildFunction (lines , tt , name )
159
191
local param_names = {}
160
192
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
163
196
end
164
197
if tt .vararg then
165
198
param_names [# param_names + 1 ] = ' ...'
@@ -178,7 +211,7 @@ function builder:buildTypedef(lines, tt, name)
178
211
-- 这个时候没有主类型,只有一个别名,直接创建一个别名结构体
179
212
self .switch_ast (def .type , self , lines , def , name )
180
213
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 ))
182
215
end
183
216
end
184
217
@@ -322,72 +355,18 @@ function m.compileCodes(codes)
322
355
return lines
323
356
end
324
357
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
356
362
end
357
- end
358
363
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 }, ' _' )
368
367
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
392
371
393
372
return m
0 commit comments