summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2023-01-16 17:00:56 +0800
committer最萌小汐 <sumneko@hotmail.com>2023-01-16 17:00:56 +0800
commit15fa11654114e7451d64a726f6ad9d6abbd92b35 (patch)
tree6b4cf1e91f505713e5e4a21521567f16b14d5cfa
parent158a7588081f480809e5d8b50ef098dc5ff70042 (diff)
downloadlua-language-server-15fa11654114e7451d64a726f6ad9d6abbd92b35.zip
improve type infer of recursion alias
-rw-r--r--script/cli/doc.lua2
-rw-r--r--script/core/completion/completion.lua2
-rw-r--r--script/core/hover/description.lua2
-rw-r--r--script/vm/compiler.lua14
-rw-r--r--script/vm/infer.lua34
-rw-r--r--script/vm/node.lua4
-rw-r--r--script/vm/sign.lua8
-rw-r--r--script/vm/type.lua4
-rw-r--r--test/type_inference/init.lua6
9 files changed, 34 insertions, 42 deletions
diff --git a/script/cli/doc.lua b/script/cli/doc.lua
index 3790d43b..e0d7be5e 100644
--- a/script/cli/doc.lua
+++ b/script/cli/doc.lua
@@ -160,7 +160,7 @@ local function collect(global)
if source.field.type == 'doc.field.name' then
field.name = source.field[1]
else
- field.name = ('[%s]'):format(vm.viewObject(source.field, rootUri))
+ field.name = ('[%s]'):format(vm.getInfer(source.field):view(rootUri))
end
field.type = source.type
field.file = guide.getUri(source)
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua
index 1a3eeb04..ea5e31eb 100644
--- a/script/core/completion/completion.lua
+++ b/script/core/completion/completion.lua
@@ -1216,7 +1216,7 @@ local function insertEnum(state, pos, src, enums, isInArray, mark)
or src.type == 'doc.type.boolean' then
---@cast src parser.object
enums[#enums+1] = {
- label = vm.viewObject(src, state.uri),
+ label = vm.getInfer(src):view(state.uri),
description = src.comment,
kind = define.CompletionItemKind.EnumMember,
}
diff --git a/script/core/hover/description.lua b/script/core/hover/description.lua
index bd584d74..d515313b 100644
--- a/script/core/hover/description.lua
+++ b/script/core/hover/description.lua
@@ -263,7 +263,7 @@ local function buildEnumChunk(docType, name, uri)
(enum.default and '->')
or (enum.additional and '+>')
or ' |',
- vm.viewObject(enum, uri)
+ vm.getInfer(enum):view(uri)
)
if enum.comment then
local first = true
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 7a89cbf4..a6eda13e 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -1777,6 +1777,11 @@ local compilerSwitch = util.switch()
return
end
end)
+ : case 'global'
+ : case 'generic'
+ : call(function (source)
+ vm.setNode(source, source)
+ end)
---@param source parser.object
local function compileByNode(source)
@@ -1850,7 +1855,7 @@ local function compileByParentNode(source)
end)
end
----@param source vm.object | vm.variable
+---@param source vm.node.object | vm.variable
---@return vm.node
function vm.compileNode(source)
if not source then
@@ -1866,13 +1871,6 @@ function vm.compileNode(source)
return cache
end
- if source.type == 'generic' then
- vm.setNode(source, source)
- local node = vm.getNode(source)
- ---@cast node -?
- return node
- end
-
---@cast source parser.object
vm.setNode(source, vm.createNode(), true)
if not vm.compileByGlobal(source) then
diff --git a/script/vm/infer.lua b/script/vm/infer.lua
index 7823e0ce..e78be910 100644
--- a/script/vm/infer.lua
+++ b/script/vm/infer.lua
@@ -5,9 +5,8 @@ local guide = require 'parser.guide'
local vm = require 'vm.vm'
---@class vm.infer
+---@field node vm.node
---@field views table<string, boolean>
----@field cachedView? string
----@field node? vm.node
---@field _drop table
local mt = {}
mt.__index = mt
@@ -137,7 +136,8 @@ local viewNodeSwitch;viewNodeSwitch = util.switch()
local node = vm.compileNode(source)
for c in node:eachObject() do
if guide.isLiteral(c) then
- local view = vm.viewObject(c, uri)
+ ---@cast c parser.object
+ local view = vm.getInfer(c):view(uri)
if view then
infer._drop[view] = true
end
@@ -239,7 +239,7 @@ local viewNodeSwitch;viewNodeSwitch = util.switch()
---@class vm.node
---@field lastInfer? vm.infer
----@param source vm.object | vm.node
+---@param source vm.node.object | vm.node
---@return vm.infer
function vm.getInfer(source)
---@type vm.node
@@ -289,6 +289,13 @@ end
---@param uri uri
function mt:_eraseAlias(uri)
+ local count = 0
+ for _ in pairs(self.views) do
+ count = count + 1
+ end
+ if count <= 1 then
+ return
+ end
local expandAlias = config.get(uri, 'Lua.hover.expandAlias')
for n in self.node:eachObject() do
if n.type == 'global' and n.cate == 'type' then
@@ -447,23 +454,6 @@ function mt:eachView(uri)
return next, self.views
end
----@param other vm.infer
----@return vm.infer
-function mt:merge(other)
- if self == vm.NULL then
- return other
- end
- if other == vm.NULL then
- return self
- end
-
- local infer = setmetatable({
- node = vm.createNode(self.node, other.node),
- }, mt)
-
- return infer
-end
-
---@return string?
function mt:viewLiterals()
if not self.node then
@@ -539,7 +529,7 @@ function vm.viewKey(source, uri)
if #source.types == 1 then
return vm.viewKey(source.types[1], uri)
else
- local key = vm.viewObject(source, uri)
+ local key = vm.getInfer(source):view(uri)
return '[' .. key .. ']'
end
end
diff --git a/script/vm/node.lua b/script/vm/node.lua
index cec0a36f..0ffd8c70 100644
--- a/script/vm/node.lua
+++ b/script/vm/node.lua
@@ -397,7 +397,7 @@ function mt:copy()
return vm.createNode(self)
end
----@param source vm.object | vm.variable
+---@param source vm.node.object | vm.generic
---@param node vm.node | vm.node.object
---@param cover? boolean
---@return vm.node
@@ -428,7 +428,7 @@ function vm.setNode(source, node, cover)
return me
end
----@param source vm.object | vm.variable
+---@param source vm.node.object
---@return vm.node?
function vm.getNode(source)
return vm.nodeCache[source]
diff --git a/script/vm/sign.lua b/script/vm/sign.lua
index 10b08884..1f434475 100644
--- a/script/vm/sign.lua
+++ b/script/vm/sign.lua
@@ -193,7 +193,11 @@ function mt:resolve(uri, args)
goto CONTINUE
end
end
- local view = vm.viewObject(obj, uri)
+ if obj.type == 'variable'
+ or obj.type == 'local' then
+ goto CONTINUE
+ end
+ local view = vm.getInfer(obj):view(uri)
if view then
knownTypes[view] = true
end
@@ -219,7 +223,7 @@ function mt:resolve(uri, args)
goto CONTINUE
end
end
- local view = vm.viewObject(n, uri)
+ local view = vm.getInfer(n):view(uri)
if knownTypes[view] then
goto CONTINUE
end
diff --git a/script/vm/type.lua b/script/vm/type.lua
index 14a7fe6e..32385736 100644
--- a/script/vm/type.lua
+++ b/script/vm/type.lua
@@ -724,14 +724,14 @@ function vm.viewTypeErrorMessage(uri, errs)
lparams[paramName] = 'table'
elseif value.type == 'generic' then
---@cast value vm.generic
- lparams[paramName] = vm.viewObject(value, uri)
+ lparams[paramName] = vm.getInfer(value):view(uri)
elseif value.type == 'variable' then
else
---@cast value -string, -vm.global, -vm.node, -vm.generic, -vm.variable
if paramName == 'key' then
lparams[paramName] = vm.viewKey(value, uri)
else
- lparams[paramName] = vm.viewObject(value, uri)
+ lparams[paramName] = vm.getInfer(value):view(uri)
or vm.getInfer(value):view(uri)
end
end
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua
index 9172ca92..4fbefd48 100644
--- a/test/type_inference/init.lua
+++ b/test/type_inference/init.lua
@@ -2552,21 +2552,21 @@ end
print(<?x?>)
]]
-TEST 'table<unknown, true>' [[
+TEST 'table<xxx, true>' [[
---@alias xxx table<xxx, true>
---@type xxx
local <?t?>
]]
-TEST 'unknown[][]' [[
+TEST 'xxx[][]' [[
---@alias xxx xxx[]
---@type xxx
local <?t?>
]]
-TEST 'fun(x: fun(x: unknown))' [[
+TEST 'fun(x: fun(x: xxx))' [[
---@alias xxx fun(x: xxx)
---@type xxx