Skip to content

Commit c0702f0

Browse files
committed
more test
1 parent 46f6f7a commit c0702f0

File tree

5 files changed

+239
-70
lines changed

5 files changed

+239
-70
lines changed

script/LuaJIT/c-parser/ctypes.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,17 +292,43 @@ end
292292
local base_types = {
293293
["char"] = true,
294294
["const"] = true,
295+
["bool"] = true,
295296
["double"] = true,
296297
["float"] = true,
297298
["int"] = true,
298299
["long"] = true,
299300
["short"] = true,
300301
["signed"] = true,
302+
["__signed"] = true,
303+
["__signed__"] = true,
301304
["unsigned"] = true,
302305
["void"] = true,
303306
["volatile"] = true,
307+
["ptrdiff_t"] = true,
308+
["size_t"] = true,
309+
["ssize_t"] = true,
310+
["wchar_t"] = true,
311+
["int8_t"] = true,
312+
["int16_t"] = true,
313+
["int32_t"] = true,
314+
["int64_t"] = true,
315+
["uint8_t"] = true,
316+
["uint16_t"] = true,
317+
["uint32_t"] = true,
318+
["uint64_t"] = true,
319+
["intptr_t"] = true,
320+
["uintptr_t"] = true,
321+
["__int8"] = true,
322+
["__int16"] = true,
323+
["__int32"] = true,
324+
["__int64"] = true,
304325
["_Bool"] = true,
326+
["__ptr32"] = true,
327+
["__ptr64"] = true,
305328
["_Complex"] = true,
329+
["complex"] = true,
330+
["__complex"] = true,
331+
["__complex__"] = true,
306332
["*"] = true,
307333
}
308334

script/LuaJIT/init.lua

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,61 @@ local knownTypes = {
4646
["__complex"] = 1,
4747
["__complex__"] = 1,
4848
]]
49+
["unsignedchar"] = 'integer',
50+
["unsignedshort"] = 'integer',
51+
["unsignedint"] = 'integer',
52+
["unsignedlong"] = 'integer',
53+
["signedchar"] = 'integer',
54+
["signedshort"] = 'integer',
55+
["signedint"] = 'integer',
56+
["signedlong"] = 'integer',
4957
}
5058

5159
local constName <const> = 'm'
5260

61+
---@class ffi.builder
5362
local builder = { switch_ast = util.switch() }
5463

64+
function builder:getTypeAst(name)
65+
for i, asts in ipairs(self.globalAsts) do
66+
if asts[name] then
67+
return asts[name]
68+
end
69+
end
70+
end
71+
72+
function builder:needDeref(ast)
73+
if not ast then
74+
return false
75+
end
76+
if ast.type == 'typedef' then
77+
-- maybe no name
78+
ast = ast.def[1]
79+
if type(ast) ~= 'table' then
80+
return self:needDeref(self:getTypeAst(ast))
81+
end
82+
end
83+
if ast.type == 'struct' or ast.type == 'union' then
84+
return true
85+
else
86+
return false
87+
end
88+
end
89+
5590
function builder:getType(name)
5691
if type(name) == 'table' then
5792
local t = ""
58-
local isStruct = false
93+
local isStruct
5994
for _, n in ipairs(name) do
6095
if type(n) == 'table' then
61-
t = t .. n.name
62-
isStruct = true
63-
else
64-
t = t .. n
96+
n = n.name
97+
end
98+
if not isStruct then
99+
isStruct = self:needDeref(self:getTypeAst(n))
65100
end
101+
t = t .. n
66102
end
103+
-- deref 一级指针
67104
if isStruct and t:sub(#t) == '*' then
68105
t = t:sub(1, #t - 1)
69106
end
@@ -76,10 +113,18 @@ function builder:getType(name)
76113
end
77114

78115
function builder:isVoid(ast)
116+
if not ast then
117+
return false
118+
end
79119
if ast.type == 'typedef' then
80-
return self:isVoid(ast.def[1])
120+
return self:isVoid(self:getTypeAst(ast.def[1]) or ast.def[1])
121+
end
122+
123+
local typename = type(ast.type) == 'table' and ast.type[1] or ast
124+
if typename == 'void' then
125+
return true
81126
end
82-
return #ast.type == 1 and ast.type[1] == 'void'
127+
return self:isVoid(self:getTypeAst(typename))
83128
end
84129

85130
function builder:buildStructOrUnion(lines, ast, tt, name)
@@ -110,11 +155,11 @@ end
110155

111156
function builder:buildTypedef(lines, ast, tt, name)
112157
local def = tt.def[1]
113-
if not def.name then
158+
if type(def) == 'table' and not def.name then
114159
-- 这个时候没有主类型,只有一个别名,直接创建一个别名结构体
115160
self.switch_ast(def.type, self, lines, def, def, name)
116161
else
117-
lines[#lines+1] = ('---@alias %s %s'):format(name, self:getType(def.name))
162+
lines[#lines+1] = ('---@alias %s %s'):format(name, self:getType(def))
118163
end
119164
end
120165

@@ -134,15 +179,20 @@ builder.switch_ast
134179
:call(builder.buildTypedef)
135180

136181

182+
local firstline = ('---@meta \n ---@class %s \n local %s = {}'):format(namespace, constName)
137183
local m = {}
138184
function m.compileCodes(codes)
139-
local b = setmetatable({}, { __index = builder })
140-
local lines = { ('---@meta \n ---@class %s \n local %s = {}'):format(namespace, constName) }
185+
---@class ffi.builder
186+
local b = setmetatable({ globalAsts = {} }, { __index = builder })
187+
188+
local lines
141189
for _, code in ipairs(codes) do
142190
local asts = cdriver.process_context(code)
143191
if not asts then
144192
goto continue
145193
end
194+
lines = lines or { firstline }
195+
table.insert(b.globalAsts, asts)
146196
for _, ast in ipairs(asts) do
147197
local tt = ast.type
148198
if tt.name then

test/ffi/builder.lua

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
local luajit = require 'LuaJIT'
2+
local util = require 'utility'
3+
rawset(_G, 'TEST', true)
4+
5+
local function removeEmpty(lines)
6+
local removeLines = {}
7+
for i, v in ipairs(lines) do
8+
if v ~= '\n' then
9+
removeLines[#removeLines+1] = v:gsub('^%s+', '')
10+
end
11+
end
12+
return removeLines
13+
end
14+
15+
local function formatLines(lines)
16+
table.remove(lines, 1)
17+
return removeEmpty(lines)
18+
end
19+
20+
---@param str string
21+
local function splitLines(str)
22+
local lines = {}
23+
local i = 1
24+
for line in str:gmatch("[^\r\n]+") do
25+
lines[i] = line
26+
i = i + 1
27+
end
28+
return lines
29+
end
30+
31+
function TEST(wanted)
32+
wanted = removeEmpty(splitLines(wanted))
33+
return function (script)
34+
local lines = formatLines(luajit.compileCodes({ script }))
35+
assert(util.equal(wanted, lines), util.dump(lines))
36+
end
37+
end
38+
39+
TEST[[
40+
---@param a boolean
41+
---@param b boolean
42+
---@param c integer
43+
---@param d integer
44+
function m.test(a, b, c, d) end
45+
]] [[
46+
void test(bool a, _Bool b, size_t c, ssize_t d);
47+
]]
48+
49+
TEST[[
50+
---@param a integer
51+
---@param b integer
52+
---@param c integer
53+
---@param d integer
54+
function m.test(a, b, c, d) end
55+
]] [[
56+
void test(int8_t a, int16_t b, int32_t c, int64_t d);
57+
]]
58+
59+
TEST[[
60+
---@param a integer
61+
---@param b integer
62+
---@param c integer
63+
---@param d integer
64+
function m.test(a, b, c, d) end
65+
]] [[
66+
void test(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
67+
]]
68+
69+
TEST[[
70+
---@param a integer
71+
---@param b integer
72+
---@param c integer
73+
---@param d integer
74+
function m.test(a, b, c, d) end
75+
]] [[
76+
void test(unsigned char a, unsigned short b, unsigned long c, unsigned int d);
77+
]]
78+
79+
TEST[[
80+
---@param a integer
81+
---@param b integer
82+
---@param c integer
83+
---@param d integer
84+
function m.test(a, b, c, d) end
85+
]] [[
86+
void test(unsigned char a, unsigned short b, unsigned long c, unsigned int d);
87+
]]
88+
89+
TEST[[
90+
---@param a integer
91+
---@param b integer
92+
---@param c integer
93+
---@param d integer
94+
function m.test(a, b, c, d) end
95+
]] [[
96+
void test(signed char a, signed short b, signed long c, signed int d);
97+
]]
98+
99+
TEST[[
100+
---@param a integer
101+
---@param b integer
102+
---@param c integer
103+
---@param d integer
104+
function m.test(a, b, c, d) end
105+
]] [[
106+
void test(char a, short b, long c, int d);
107+
]]
108+
109+
TEST[[
110+
---@param a number
111+
---@param b number
112+
---@param c integer
113+
---@param d integer
114+
function m.test(a, b, c, d) end
115+
]] [[
116+
void test(float a, double b, int8_t c, uint8_t d);
117+
]]
118+
119+
TEST [[
120+
---@alias H ffi.namespace*.void
121+
122+
function m.test() end
123+
]] [[
124+
typedef void H;
125+
126+
H test();
127+
]]
128+
129+
TEST [[
130+
---@class ffi.namespace*.a
131+
132+
---@param a ffi.namespace*.a
133+
function m.test(a) end
134+
]] [[
135+
typedef struct {} a;
136+
137+
void test(a* a);
138+
]]
139+
140+
TEST [[
141+
---@class ffi.namespace*.struct@a
142+
---@field a integer
143+
---@field b ffi.namespace*.char*
144+
145+
---@param a ffi.namespace*.struct@a
146+
function m.test(a) end
147+
]] [[
148+
struct a {int a;char* b;};
149+
150+
void test(struct a* a);
151+
]]

test/ffi/compiler.lua

Lines changed: 0 additions & 58 deletions
This file was deleted.

test/ffi/init.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ lclient():start(function (languageClient)
1818

1919
require 'ffi.cdef'
2020
require 'ffi.parser'
21-
require 'ffi.compiler'
21+
require 'ffi.builder'
2222
end)

0 commit comments

Comments
 (0)