Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 27 additions & 21 deletions nattlua/parser/node.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1034,31 +1034,37 @@ local NAN_TYPE = {}
local ANY_TYPE = {}

function META:AssociateType(obj)
self.inferred_types_done = self.inferred_types_done or {}
self.inferred_types = self.inferred_types or {}

do
local t = obj.Type
local hash = obj

if hash.Type == "symbol" then
hash = obj.Data
elseif obj.Type == "string" then
hash = obj.Data or STRING_TYPE
elseif obj.Type == "number" then
hash = obj.Data or NUMBER_TYPE

if hash ~= hash then hash = NAN_TYPE end
elseif obj.Type == "any" then
hash = ANY_TYPE
end
local done = self.inferred_types_done
local types = self.inferred_types

if not done then
done = {}
self.inferred_types_done = done
end

if not types then
types = {}
self.inferred_types = types
end

if self.inferred_types_done[hash] then return end
local obj_type = obj.Type
local hash = obj

self.inferred_types_done[hash] = true
if obj_type == "symbol" then
hash = obj.Data
elseif obj_type == "string" then
hash = obj.Data or STRING_TYPE
elseif obj_type == "number" then
hash = obj.Data or NUMBER_TYPE
if hash ~= hash then hash = NAN_TYPE end
elseif obj_type == "any" then
hash = ANY_TYPE
end

self.inferred_types[#self.inferred_types + 1] = obj
if done[hash] then return end

done[hash] = true
types[#types + 1] = obj
end

function META:GetAssociatedTypes()
Expand Down
16 changes: 1 addition & 15 deletions nattlua/types/number.lua
Original file line number Diff line number Diff line change
Expand Up @@ -92,21 +92,7 @@ end
function META.Equal(a--[[#: TNumber]], b--[[#: TBaseType]])
if a.Type ~= b.Type then return false, "types differ" end

do
return a.Hash == b.Hash
end

if a.Data == b.Data then return true, "max values are equal" end

if not a.Data and not b.Data then
return true, "no literal data in either value"
else
if a:IsNan() and b:IsNan() then return true, "both values are nan" end

return a.Data == b.Data, "literal values are equal"
end

return false, "values are not equal"
return a.Hash == b.Hash, "hash values are equal"
end

function META:IsLiteral()
Expand Down
35 changes: 28 additions & 7 deletions nattlua/types/table.lua
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,11 @@ function META:__tostring()
local contract = self:GetContract()

if contract and contract.Type == "table" and contract ~= self then
for i, keyval in ipairs(contract:GetData()) do
local contract_data = contract:GetData()
local contract_len = #contract_data

for i = 1, contract_len do
local keyval = contract_data[i]
local table_kv = self:FindKeyValExact(keyval.key)
local key = tostring(table_kv and table_kv.key or "nil")
local val = tostring(table_kv and table_kv.val or "nil")
Expand All @@ -244,7 +248,11 @@ function META:__tostring()
end
end
else
for i, keyval in ipairs(self.Data) do
local data = self.Data
local len = #data

for i = 1, len do
local keyval = data[i]
local key, val = tostring(keyval.key), tostring(keyval.val)
s[i] = indent .. "[" .. key .. "]" .. " = " .. val
end
Expand All @@ -264,8 +272,11 @@ function META:GetArrayLength()
if contract and contract ~= self then return contract:GetArrayLength() end

local len = 0
local data = self.Data
local data_len = #data

for _, kv in ipairs(self.Data) do
for i = 1, data_len do
local kv = data[i]
if kv.key:IsNumeric() then
if kv.key:IsLiteral() then
-- TODO: not very accurate
Expand Down Expand Up @@ -335,7 +346,11 @@ function META:FollowsContract(contract--[[#: TTable]])
end
end

for _, keyval in ipairs(self.Data) do
local data = self.Data
local len = #data

for i = 1, len do
local keyval = data[i]
if not keyval.val:IsNil() then
local res, err = contract:FindKeyValExact(keyval.key)

Expand All @@ -356,8 +371,11 @@ function META:FollowsContract(contract--[[#: TTable]])
end

function META:CanBeEmpty()
for _, keyval in ipairs(self.Data) do
if not keyval.val:CanBeNil() then return false end
local data = self.Data
local len = #data

for i = 1, len do
if not data[i].val:CanBeNil() then return false end
end

return true
Expand Down Expand Up @@ -675,8 +693,11 @@ function META:FindKeyValWide(key--[[#: TBaseType]], reverse--[[#: boolean | nil]
if keyval then return keyval end

local reasons = {}
local data = self.Data
local len = #data

for i, keyval in ipairs(self.Data) do
for i = 1, len do
local keyval = data[i]
if key:Equal(keyval.key) then return keyval end

local ok, reason
Expand Down
20 changes: 14 additions & 6 deletions nattlua/types/tuple.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ function META:GetHash(visited)

visited[self] = "*circular*"
local types = {}
local data = self.Data
local len = #data

for i, v in ipairs(self.Data) do
types[i] = v:GetHash(visited)
for i = 1, len do
types[i] = data[i]:GetHash(visited)
end

visited[self] = table.concat(types, ",")
Expand All @@ -65,9 +67,11 @@ function META:__tostring()

self.suppress = true
local strings--[[#: List<|string|>]] = {}
local data = self.Data
local len = #data

for i, v in ipairs(self.Data) do
strings[i] = tostring(v)
for i = 1, len do
strings[i] = tostring(data[i])
end

if self.Remainder then table.insert(strings, tostring(self.Remainder)) end
Expand Down Expand Up @@ -125,9 +129,13 @@ function META:Copy(map--[[#: Map<|any, any|> | nil]], copy_tables)

local copy = META.New({})
map[self] = copy

local data = self.Data
local copy_data = copy.Data
local len = #data

for i, v in ipairs(self.Data) do
copy.Data[i] = copy_val(v, map, copy_tables)
for i = 1, len do
copy_data[i] = copy_val(data[i], map, copy_tables)
end

copy.Repeat = self.Repeat
Expand Down
34 changes: 22 additions & 12 deletions nattlua/types/union.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,9 @@ function META.Equal(
end

function META:GetHash(visited)--[[#: string]]
if self:GetCardinality() == 1 then
return (self.Data[1]--[[# as any]]):GetHash()
local data = self.Data
if #data == 1 then
return (data[1]--[[# as any]]):GetHash()
end

visited = visited or {}
Expand All @@ -91,13 +92,14 @@ function META:GetHash(visited)--[[#: string]]

visited[self] = "*circular*"
local types = {}
local len = #data

for i, v in ipairs(self.Data) do
types[i] = v:GetHash(visited)
for i = 1, len do
types[i] = data[i]:GetHash(visited)
end

table_sort(types)
visited[self] = table.concat(types, "|")
visited[self] = table_concat(types, "|")
return visited[self]--[[# as string]]
end

Expand All @@ -110,9 +112,12 @@ function META:__tostring()

local s = {}
self.suppress = true

local data = self.Data
local len = #data

for i, v in ipairs(self.Data) do
s[i] = tostring(v)
for i = 1, len do
s[i] = tostring(data[i])
end

if not s[1] then
Expand All @@ -122,7 +127,7 @@ function META:__tostring()

self.suppress = false

if #s == 1 then return (s[1]--[[# as string]]) .. "|" end
if len == 1 then return (s[1]--[[# as string]]) .. "|" end

table_sort(s, sort)
return table_concat(s, " | ")
Expand Down Expand Up @@ -155,11 +160,16 @@ local function remove(self--[[#: TUnion]], index--[[#: number]])
end

local function find_index(self--[[#: TUnion]], obj--[[#: any]])
for i = 1, #self.Data do
local v = self.Data[i]--[[# as any]]
local data = self.Data
local len = #data
local obj_type = obj.Type

if v:Equal(obj) then
if v.Type ~= "function" or v:GetFunctionBodyNode() == obj:GetFunctionBodyNode() then
for i = 1, len do
local v = data[i]--[[# as any]]

-- Check type first before expensive Equal call
if v.Type == obj_type and v:Equal(obj) then
if obj_type ~= "function" or v:GetFunctionBodyNode() == obj:GetFunctionBodyNode() then
return i
end
end
Expand Down