Skip to content

Commit 9cc197a

Browse files
committed
support array
1 parent 74328ad commit 9cc197a

File tree

5 files changed

+93
-7
lines changed

5 files changed

+93
-7
lines changed

script/plugins/ffi/c-parser/ctypes.lua

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,25 @@ local convert_value = typed("TypeList, table -> CType?, string?", function (lst,
125125
}), nil
126126
end)
127127

128+
local function convert_fields(lst, field_src, fields)
129+
if field_src.ids then
130+
for i, id in ipairs(field_src.ids) do
131+
id.type = utility.deepCopy(field_src.type)
132+
if id.type and id[1] then
133+
for i, v in ipairs(id[1]) do
134+
table.insert(id.type, v)
135+
end
136+
if id[1].idx then
137+
id.isarray = true
138+
end
139+
id[1] = nil
140+
end
141+
table.insert(fields, id)
142+
end
143+
return true
144+
end
145+
end
146+
128147
-- Interpret field data from `field_src` and add it to `fields`.
129148
local function add_to_fields(lst, field_src, fields)
130149
if type(field_src) == "table" and not field_src.ids then
@@ -136,6 +155,9 @@ local function add_to_fields(lst, field_src, fields)
136155
return true
137156
end
138157

158+
if convert_fields(lst, field_src, fields) then
159+
return true
160+
end
139161
local field, err = convert_value(lst, field_src)
140162
if not field then
141163
return nil, err
@@ -541,7 +563,15 @@ ctypes.register_types = typed("{Decl} -> TypeList?, string?", function (parsed)
541563
return nil, err or "failed typedef"
542564
end
543565
else
544-
item.spec = util.expandSingle(item.spec)
566+
local expandSingle <const> = {
567+
["struct"] = true,
568+
["union"] = true,
569+
["enum"] = true,
570+
}
571+
local spec = util.expandSingle(item.spec)
572+
if expandSingle[spec.type] then
573+
item.spec = spec
574+
end
545575
if item.spec.type == "struct" or item.spec.type == "union" then
546576
local ok, err = register_structunion(lst, item)
547577
if not ok then

script/plugins/ffi/init.lua

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ local searchCode = require 'plugins.ffi.searchCode'
22
local cdefRerence = require 'plugins.ffi.cdefRerence'
33
local cdriver = require 'plugins.ffi.c-parser.cdriver'
44
local util = require 'plugins.ffi.c-parser.util'
5-
local utility = require 'utility'
5+
local utility = require 'utility'
66
local SDBMHash = require 'SDBMHash'
77
local ws = require 'workspace'
88
local files = require 'files'
@@ -134,19 +134,31 @@ function builder:isVoid(ast)
134134
return self:isVoid(self:getTypeAst(typename))
135135
end
136136

137+
local function getArrayType(arr)
138+
if type(arr) ~= "table" then
139+
return arr and '[]' or ''
140+
end
141+
local res = ''
142+
for i, v in ipairs(arr) do
143+
res = res .. '[]'
144+
end
145+
return res
146+
end
147+
137148
function builder:buildStructOrUnion(lines, tt, name)
138149
lines[#lines+1] = '---@class ' .. self:getType(name)
139150
for _, field in ipairs(tt.fields or {}) do
140151
if field.name and field.type then
141-
lines[#lines+1] = ('---@field %s %s'):format(field.name, self:getType(field.type))
152+
lines[#lines+1] = ('---@field %s %s%s'):format(field.name, self:getType(field.type),
153+
getArrayType(field.isarray))
142154
end
143155
end
144156
end
145157

146158
function builder:buildFunction(lines, tt, name)
147159
local param_names = {}
148160
for i, param in ipairs(tt.params or {}) do
149-
lines[#lines+1] = ('---@param %s %s'):format(param.name, self:getType(param.type))
161+
lines[#lines+1] = ('---@param %s %s%s'):format(param.name, self:getType(param.type), getArrayType(param.idxs))
150162
param_names[#param_names+1] = param.name
151163
end
152164
if tt.vararg then
@@ -213,7 +225,7 @@ do
213225
end
214226

215227
local function pushEnumValue(enumer, name, v)
216-
v = tonumber(util.expandSingle(v))
228+
v = tonumber(util.expandSingle(v))
217229
enumer[name] = v
218230
enumer[#enumer+1] = v
219231
return v

test/plugins/ffi/builder.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ function TEST(wanted)
3939
end
4040
end
4141

42+
TEST [[
43+
---@param a integer[][]
44+
function m.test(a) end
45+
]][[
46+
void test(int a[][]);
47+
]]
48+
49+
TEST [[
50+
---@class ffi.namespace*.struct@A
51+
---@field b integer[]
52+
---@field c integer[]
53+
]] [[
54+
struct A {
55+
int b[5];
56+
int c[];
57+
};
58+
]]
59+
4260
TEST [[
4361
m.B = 5
4462
m.A = 0

test/plugins/ffi/parser.lua

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,46 @@ rawset(_G, 'TEST', true)
55
local ctypes = require 'plugins.ffi.c-parser.ctypes'
66
ctypes.TESTMODE = true
77

8+
--TODO expand all singlenode
89
function TEST(wanted, full)
910
return function (script)
1011
local rrr = cdriver.process_context(script .. "$EOF$")
1112
assert(rrr)
1213
if full then
1314
for i, v in ipairs(rrr) do
14-
assert(utility.equal(v, wanted[i]))
15+
assert(utility.equal(v, wanted[i]), utility.dump(v))
1516
end
1617
else
17-
assert(utility.equal(rrr[1], wanted))
18+
assert(utility.equal(rrr[1], wanted), utility.dump(rrr[1]))
1819
end
1920
end
2021
end
2122

23+
TEST {
24+
name = "struct@A",
25+
type = {
26+
fields = {
27+
{
28+
isarray = true,
29+
name = "a",
30+
type = { "int", },
31+
},
32+
{
33+
isarray = true,
34+
name = "b",
35+
type = { "int", },
36+
},
37+
},
38+
name = "A",
39+
type = "struct",
40+
},
41+
}
42+
[[
43+
struct A {
44+
int a[5];
45+
int b[];
46+
};
47+
]]
2248

2349
TEST {
2450
name = 'union@a',

0 commit comments

Comments
 (0)