summaryrefslogtreecommitdiff
path: root/script/core/hover/table.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script/core/hover/table.lua')
-rw-r--r--script/core/hover/table.lua93
1 files changed, 56 insertions, 37 deletions
diff --git a/script/core/hover/table.lua b/script/core/hover/table.lua
index e8c9b95d..b83f3dcb 100644
--- a/script/core/hover/table.lua
+++ b/script/core/hover/table.lua
@@ -16,23 +16,23 @@ local function formatKey(key)
return ('[%s]'):format(key)
end
-local function buildAsHash(keys, inferMap, literalMap, optMap, reachMax)
+local function buildAsHash(keys, typeMap, literalMap, optMap, reachMax)
local lines = {}
lines[#lines+1] = '{'
for _, key in ipairs(keys) do
- local inferView = inferMap[key]
+ local typeView = typeMap[key]
local literalView = literalMap[key]
if literalView then
lines[#lines+1] = (' %s%s: %s = %s,'):format(
formatKey(key),
optMap[key] and '?' or '',
- inferView,
+ typeView,
literalView)
else
lines[#lines+1] = (' %s%s: %s,'):format(
formatKey(key),
optMap[key] and '?' or '',
- inferView
+ typeView
)
end
end
@@ -43,27 +43,27 @@ local function buildAsHash(keys, inferMap, literalMap, optMap, reachMax)
return table.concat(lines, '\n')
end
-local function buildAsConst(keys, inferMap, literalMap, optMap, reachMax)
+local function buildAsConst(keys, typeMap, literalMap, optMap, reachMax)
table.sort(keys, function (a, b)
return tonumber(literalMap[a]) < tonumber(literalMap[b])
end)
local lines = {}
lines[#lines+1] = '{'
for _, key in ipairs(keys) do
- local inferView = inferMap[key]
+ local typeView = typeMap[key]
local literalView = literalMap[key]
if literalView then
lines[#lines+1] = (' %s%s: %s = %s,'):format(
formatKey(key),
optMap[key] and '?' or '',
- inferView,
+ typeView,
literalView
)
else
lines[#lines+1] = (' %s%s: %s,'):format(
formatKey(key),
optMap[key] and '?' or '',
- inferView
+ typeView
)
end
end
@@ -82,11 +82,11 @@ local typeSorter = {
local function getKeyMap(fields)
local keys = {}
- local mark = {}
+ local map = {}
for _, field in ipairs(fields) do
local key = vm.getKeyName(field)
- if key and not mark[key] then
- mark[key] = true
+ if key and not map[key] then
+ map[key] = true
keys[#keys+1] = key
end
end
@@ -107,68 +107,87 @@ local function getKeyMap(fields)
return tsa < tsb
end
end)
- return keys
+ return keys, map
end
----@async
-local function getFieldMap(fields, keys)
- local fieldMap = {}
- for _, key in ipairs(keys) do
- fieldMap[key] = {
- infer = nil,
- literal = nil,
- opt = false,
- }
- end
+local function getOptMap(fields, keyMap)
+ local optMap = {}
for _, field in ipairs(fields) do
if field.type == 'doc.field.name' then
if field.parent.optional then
local key = vm.getKeyName(field)
- fieldMap[key].opt = true
+ if keyMap[key] then
+ optMap[key] = true
+ end
end
end
if field.type == 'doc.type.field' then
if field.optional then
local key = vm.getKeyName(field)
- fieldMap[key].opt = true
+ if keyMap[key] then
+ optMap[key] = true
+ end
end
end
end
- return fieldMap
+ return optMap
+end
+
+---@async
+local function getInferMap(fields, keyMap)
+ ---@type table<string, vm.infer>
+ local inferMap = {}
+ for _, field in ipairs(fields) do
+ local key = vm.getKeyName(field)
+ if not keyMap[key] then
+ goto CONTINUE
+ end
+ await.delay()
+ local ifr = infer.getInfer(field)
+ if inferMap[key] then
+ inferMap[key]:merge(ifr)
+ else
+ inferMap[key] = ifr
+ end
+ ::CONTINUE::
+ end
+ return inferMap
end
---@async
return function (source)
- local maxFields = config.get(guide.getUri(source), 'Lua.hover.previewFields')
+ local uri = guide.getUri(source)
+ local maxFields = config.get(uri, 'Lua.hover.previewFields')
if maxFields <= 0 then
return 'table'
end
- local fields = vm.getFields(source)
- local keys = getKeyMap(fields)
- local fieldMap = getFieldMap(fields, keys)
-
+ local fields = vm.getFields(source)
+ local keys, map = getKeyMap(fields)
if #keys == 0 then
return '{}'
end
- local inferMap = {}
- local literalMap = {}
-
local reachMax = #keys - maxFields
if #keys > maxFields then
for i = maxFields + 1, #keys do
+ map[keys[i]] = nil
keys[i] = nil
end
end
+ local optMap = getOptMap(fields, map)
+ local inferMap = getInferMap(fields, map)
+
+ local typeMap = {}
+ local literalMap = {}
local isConsts = true
for i = 1, #keys do
await.delay()
local key = keys[i]
- inferMap[key] = infer.viewType(source, key)
- literalMap[key] = infer.viewLiterals(source, key)
+ typeMap[key] = inferMap[key]:view('unknown', uri)
+ literalMap[key] = inferMap[key]:viewLiterals()
if not tonumber(literalMap[key]) then
isConsts = false
end
@@ -177,9 +196,9 @@ return function (source)
local result
if isConsts then
- result = buildAsConst(keys, inferMap, literalMap, optMap, reachMax)
+ result = buildAsConst(keys, typeMap, literalMap, optMap, reachMax)
else
- result = buildAsHash(keys, inferMap, literalMap, optMap, reachMax)
+ result = buildAsHash(keys, typeMap, literalMap, optMap, reachMax)
end
--if timeUp then