Skip to content

Commit

Permalink
ensure all type functions are called with typesystem environment
Browse files Browse the repository at this point in the history
  • Loading branch information
CapsAdmin committed Oct 8, 2024
1 parent 520ce77 commit 18ca899
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 42 deletions.
12 changes: 12 additions & 0 deletions nattlua/analyzer/operators/call.lua
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,19 @@ do

if ok then return ok end

local function_node = self:GetFunctionBodyNode()
local is_type_function = function_node and
(
function_node.kind == "local_type_function" or
function_node.kind == "type_function"
)

if is_type_function then analyzer:PushAnalyzerEnvironment("typesystem") end

local ok, err = call_function_internal(analyzer, self, input)

if is_type_function then analyzer:PopAnalyzerEnvironment() end

analyzer:PopCallFrame()
return ok, err
end
Expand Down
5 changes: 0 additions & 5 deletions nattlua/c_declarations/analyzer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ local function cast(self, node)
size = LNumber(tonumber(node.size) or math.huge)
end

self.analyzer:PushAnalyzerEnvironment("typesystem")
local tup = self.analyzer:Call(self.env.FFIArray, Tuple({size, cast(self, assert(node.of))}))
self.analyzer:PopAnalyzerEnvironment()
return tup:Unpack()
elseif node.type == "pointer" then
if
Expand All @@ -38,12 +36,9 @@ local function cast(self, node)
return Any() -- TODO: is this true?
end


self.analyzer:PushAnalyzerEnvironment("typesystem")
local res = (
self.analyzer:Call(self.env.FFIPointer, Tuple({cast(self, assert(node.of))})):Unpack()
)
self.analyzer:PopAnalyzerEnvironment()

if self:GetContextRef("function_argument") == true then
if
Expand Down
80 changes: 43 additions & 37 deletions test/tests/nattlua/analyzer/metatable.lua
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ analyze(
return self
end
local x = {} as CData<|{foo = number}, "struct 66", false|>
local x = _ as CData<|{foo = number}, "struct 66", false|>
local y = x + 2
]],
Expand All @@ -852,119 +852,125 @@ analyze(
analyze[[
local type meta = {}
type meta.__index = meta
type meta.@Self = {value = ref {[any] = any}}
type meta.@Self = {
value = ref {[any] = any}
}
function meta:__index<|key: any|>
local obj = setmetatable<|{value = {[any] = any}}, meta|>
self.value[key] = obj | self.value[key]
return obj | any
end
function meta:__newindex<|key: any, val: any|>
self.value[key] = self.value[key] | val
end
function meta:__add<|other: any|>
return Widen(other)
end
function meta:__concat<|other: any|>
return Widen(other)
end
function meta:__len<||>
return number
end
function meta:__unm<||>
return any
end
function meta:__bnot<||>
return any
end
function meta:__sub<|b: any|>
return Widen(b)
end
function meta:__mul<|b: any|>
return Widen(b)
end
function meta:__div<|b: any|>
return Widen(b)
end
function meta:__idiv<|b: any|>
return Widen(b)
end
function meta:__mod<|b: any|>
return Widen(b)
end
function meta:__pow<|b: any|>
return Widen(b)
end
function meta:__band<|b: any|>
return Widen(b)
end
function meta:__bor<|b: any|>
return Widen(b)
end
function meta:__bxor<|b: any|>
return Widen(b)
end
function meta:__shl<|b: any|>
return Widen(b)
end
function meta:__shr<|b: any|>
return Widen(b)
end
function meta:__eq<|b: any|>
return boolean
end
function meta:__lt<|b: any|>
return Widen(b)
end
function meta:__le<|b: any|>
return Widen(b)
end
function meta:__call<|...: ...any|>
local ret = setmetatable<|{value = {[any] = any}}, meta|>
self.value = function=((...))>((ret)) | self.value
return ret
end
local function InferenceObject<||>
return setmetatable<|{value = {[any] = any}}, meta|>
end
local type lib = InferenceObject<||>
lib.foo.bar = true
lib.foo(1,2,3)
attest.equal<|lib, { ["value"] = { [any] = any } as {
[any] = any,
["foo"] = any | { ["value"] = { [any] = any } },
["bar"] = any | true,
["value"] = any | function=(1, 2, 3)>({ ["value"] = { [any] = any } },)
} }
lib.foo(1, 2, 3)
attest.equal<|
lib,
{
["value"] = {
[any] = any,
["foo"] = any | {
["value"] = {
[any] = any,
["bar"] = any | true,
} as {[any] = any},
} | {
["value"] = {
[any] = any,
["value"] = any | self | function=(1)>({["value"] = {[any] = any}}),
} as {[any] = any},
},
} as {[any] = any},
}
|>
]]
analyze[[
Expand Down

0 comments on commit 18ca899

Please sign in to comment.