diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-04-01 02:02:06 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-04-01 02:02:06 +0800 |
commit | bf6538f45636c4f3bceba6e3f4bbdaef3d21a071 (patch) | |
tree | ac1205da6e910b1677bf7e2ff59417710527fa72 /script | |
parent | c1ca4d8af0cefd6222b76f83341774857cef44ec (diff) | |
download | lua-language-server-bf6538f45636c4f3bceba6e3f4bbdaef3d21a071.zip |
cleanup
Diffstat (limited to 'script')
-rw-r--r-- | script/core/hover/table.lua | 42 | ||||
-rw-r--r-- | script/vm/infer.lua | 134 | ||||
-rw-r--r-- | script/vm/union.lua | 2 |
3 files changed, 107 insertions, 71 deletions
diff --git a/script/core/hover/table.lua b/script/core/hover/table.lua index 4ad5e552..e8c9b95d 100644 --- a/script/core/hover/table.lua +++ b/script/core/hover/table.lua @@ -85,12 +85,6 @@ local function getKeyMap(fields) local mark = {} for _, field in ipairs(fields) do local key = vm.getKeyName(field) - local tp = vm.getKeyType(field) - if tp == 'number' or tp == 'integer' then - key = tonumber(key) - elseif tp == 'boolean' then - key = key == 'true' - end if key and not mark[key] then mark[key] = true keys[#keys+1] = key @@ -116,35 +110,31 @@ local function getKeyMap(fields) return keys end -local function getOptionalMap(fields) - local optionals = {} +---@async +local function getFieldMap(fields, keys) + local fieldMap = {} + for _, key in ipairs(keys) do + fieldMap[key] = { + infer = nil, + literal = nil, + opt = false, + } + end for _, field in ipairs(fields) do if field.type == 'doc.field.name' then if field.parent.optional then local key = vm.getKeyName(field) - local tp = vm.getKeyType(field) - if tp == 'number' or tp == 'integer' then - key = tonumber(key) - elseif tp == 'boolean' then - key = key == 'true' - end - optionals[key] = true + fieldMap[key].opt = true end end if field.type == 'doc.type.field' then if field.optional then local key = vm.getKeyName(field) - local tp = vm.getKeyType(field) - if tp == 'number' or tp == 'integer' then - key = tonumber(key) - elseif tp == 'boolean' then - key = key == 'true' - end - optionals[key] = true + fieldMap[key].opt = true end end end - return optionals + return fieldMap end ---@async @@ -154,9 +144,9 @@ return function (source) return 'table' end - local fields = vm.getFields(source) - local keys = getKeyMap(fields) - local optMap = getOptionalMap(fields) + local fields = vm.getFields(source) + local keys = getKeyMap(fields) + local fieldMap = getFieldMap(fields, keys) if #keys == 0 then return '{}' diff --git a/script/vm/infer.lua b/script/vm/infer.lua index 31a08b74..6a435e97 100644 --- a/script/vm/infer.lua +++ b/script/vm/infer.lua @@ -3,14 +3,16 @@ local nodeMgr = require 'vm.node' local config = require 'config' local guide = require 'parser.guide' local compiler = require 'vm.compiler' +local union = require 'vm.union' ---@class vm.infer-manager local m = {} ---@class vm.infer ---@field views table<string, boolean> ----@field source? parser.object ---@field cachedView? string +---@field node? vm.node +---@field uri? uri local mt = {} mt.__index = mt mt.hasNumber = false @@ -19,9 +21,8 @@ mt.hasClass = false mt.isParam = false mt.isLocal = false mt.hasDocFunction = false -mt.expandAlias = false -local nullInfer = setmetatable({ views = {} }, mt) +local nullInfer = setmetatable({}, mt) local inferSorted = { ['boolean'] = - 100, @@ -129,29 +130,6 @@ local viewNodeSwitch = util.switch() return ('fun(%s)%s'):format(argView, regView) end) ----@param infer vm.infer -local function eraseAlias(infer) - local node = compiler.compileNode(infer.source) - for n in nodeMgr.eachNode(node) do - if n.type == 'global' and n.cate == 'type' then - for _, set in ipairs(n:getSets()) do - if set.type == 'doc.alias' then - if infer.expandAlias then - infer.views[n.name] = nil - else - for _, ext in ipairs(set.extends.types) do - local view = viewNodeSwitch(ext.type, ext, {}) - if view and view ~= n.name then - infer.views[view] = nil - end - end - end - end - end - end - end -end - ---@param source parser.object ---@return vm.infer function m.getInfer(source) @@ -163,43 +141,82 @@ function m.getInfer(source) return node.lastInfer end local infer = setmetatable({ - source = source, - views = {} + node = node, + uri = guide.getUri(source), }, mt) - infer.expandAlias = config.get(guide.getUri(source), 'Lua.hover.expandAlias') if node.type == 'union' then node.lastInfer = infer end - for n in nodeMgr.eachNode(node) do - local view = viewNodeSwitch(n.type, n, infer) - if view then - infer.views[view] = true - end + + return infer +end + +function mt:_trim() + if self.hasNumber then + self.views['integer'] = nil end - if infer.hasNumber then - infer.views['integer'] = nil + if self.hasDocFunction then + self.views['function'] = nil end - if infer.hasDocFunction then - infer.views['function'] = nil + if self.hasTable and not self.hasClass then + self.views['table'] = true end - if infer.hasTable and not infer.hasClass then - infer.views['table'] = true + if self.hasClass then + self:_eraseAlias() end - if infer.hasClass then - eraseAlias(infer) +end + +function mt:_eraseAlias() + local expandAlias = config.get(self.uri, 'Lua.hover.expandAlias') + for n in nodeMgr.eachNode(self.node) do + if n.type == 'global' and n.cate == 'type' then + for _, set in ipairs(n:getSets()) do + if set.type == 'doc.alias' then + if expandAlias then + self.views[n.name] = nil + else + for _, ext in ipairs(set.extends.types) do + local view = viewNodeSwitch(ext.type, ext, {}) + if view and view ~= n.name then + self.views[view] = nil + end + end + end + end + end + end end - return infer end ---@param tp string ---@return boolean function mt:hasType(tp) + self:_computeViews() return self.views[tp] == true end +function mt:_computeViews() + if self.views then + return + end + + self.views = {} + + for n in nodeMgr.eachNode(self.node) do + local view = viewNodeSwitch(n.type, n, self) + if view then + self.views[view] = true + end + end + + self:_trim() +end + ---@param default? string ---@return string function mt:view(default) + self:_computeViews() + if self.views['any'] then return 'any' end @@ -227,7 +244,7 @@ function mt:view(default) end) local max = #array - local limit = config.get(guide.getUri(self.source), 'Lua.hover.enumsLimit') + local limit = config.get(self.uri, 'Lua.hover.enumsLimit') if max > limit then local view = string.format('%s...(+%d)' @@ -247,6 +264,35 @@ function mt:view(default) end end +---@param other vm.infer +---@param uri? uri +---@return vm.infer +function mt:merge(other, uri) + local infer = setmetatable({ + node = union(self.node, other.node), + uri = uri or self.uri, + views = {}, + }, mt) + + for view in pairs(self.views) do + infer.views[view] = true + end + for view in pairs(other.views) do + infer.views[view] = true + end + + infer.hasClass = self.hasClass or other.hasClass + infer.hasDocFunction = self.hasDocFunction or other.hasDocFunction + infer.hasNumber = self.hasNumber or other.hasNumber + infer.hasTable = self.hasTable or other.hasTable + infer.isLocal = self.isLocal or other.isLocal + infer.isParam = self.isParam or other.isParam + + infer:_trim() + + return infer +end + ---@param source parser.object ---@return string? function m.viewLiterals(source) diff --git a/script/vm/union.lua b/script/vm/union.lua index 10aebda1..809dd78f 100644 --- a/script/vm/union.lua +++ b/script/vm/union.lua @@ -7,7 +7,7 @@ mt.type = 'union' mt.optional = nil mt.lastInfer = nil ----@param me parser.object +---@param me vm.node ---@param node vm.node ---@return vm.node.union local function createUnion(me, node) |