summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-07-04 21:09:55 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-07-04 21:09:55 +0800
commitf732640c8b1aa71c1b5d543c0ded8f6150abbde1 (patch)
treee4984ea4ff414ec396a4563decc287b4a09e0ab8
parent1b23b28c7e9f2ecc59dcf19ec2533ab2c4f3e9d9 (diff)
downloadlua-language-server-f732640c8b1aa71c1b5d543c0ded8f6150abbde1.zip
fix #1273
-rw-r--r--changelog.md1
-rw-r--r--script/vm/sign.lua10
-rw-r--r--script/vm/type.lua58
-rw-r--r--test/type_inference/init.lua26
4 files changed, 73 insertions, 22 deletions
diff --git a/changelog.md b/changelog.md
index d5430f9f..1b47c102 100644
--- a/changelog.md
+++ b/changelog.md
@@ -6,6 +6,7 @@
* `FIX` [#1256](https://github.com/sumneko/lua-language-server/issues/1256)
* `FIX` [#1257](https://github.com/sumneko/lua-language-server/issues/1257)
* `FIX` [#1269](https://github.com/sumneko/lua-language-server/issues/1269)
+* `FIX` [#1273](https://github.com/sumneko/lua-language-server/issues/1273)
* `FIX` [#1275](https://github.com/sumneko/lua-language-server/issues/1275)
## 3.4.0
diff --git a/script/vm/sign.lua b/script/vm/sign.lua
index 0022538a..a0478751 100644
--- a/script/vm/sign.lua
+++ b/script/vm/sign.lua
@@ -51,7 +51,7 @@ function mt:resolve(uri, args, removeGeneric)
end
if n.type == 'doc.type.table' then
-- { [integer]: number } -> T[]
- local tvalueNode = vm.getTableValue(uri, node, 'integer')
+ local tvalueNode = vm.getTableValue(uri, node, 'integer', true)
if tvalueNode then
resolve(object.node, tvalueNode)
end
@@ -76,8 +76,8 @@ function mt:resolve(uri, args, removeGeneric)
end
if firstField.type == 'doc.generic.name' and firstValue.type == 'doc.generic.name' then
-- { [number]: number} -> { [K]: V }
- local tfieldNode = vm.getTableKey(uri, node, 'any')
- local tvalueNode = vm.getTableValue(uri, node, 'any')
+ local tfieldNode = vm.getTableKey(uri, node, 'any', true)
+ local tvalueNode = vm.getTableValue(uri, node, 'any', true)
if tfieldNode then
resolve(firstField, tfieldNode)
end
@@ -87,13 +87,13 @@ function mt:resolve(uri, args, removeGeneric)
else
if ufieldNode:get(1).type == 'doc.generic.name' then
-- { [number]: number}|number[] -> { [K]: number }
- local tnode = vm.getTableKey(uri, node, uvalueNode)
+ local tnode = vm.getTableKey(uri, node, uvalueNode, true)
if tnode then
resolve(firstField, tnode)
end
elseif uvalueNode:get(1).type == 'doc.generic.name' then
-- { [number]: number}|number[] -> { [number]: V }
- local tnode = vm.getTableValue(uri, node, ufieldNode)
+ local tnode = vm.getTableValue(uri, node, ufieldNode, true)
if tnode then
resolve(firstValue, tnode)
end
diff --git a/script/vm/type.lua b/script/vm/type.lua
index ac3b8986..e673b2b6 100644
--- a/script/vm/type.lua
+++ b/script/vm/type.lua
@@ -192,16 +192,23 @@ end
---@param uri uri
---@param tnode vm.node
---@param knode vm.node|string
+---@param inversion? boolean
---@return vm.node?
-function vm.getTableValue(uri, tnode, knode)
+function vm.getTableValue(uri, tnode, knode, inversion)
local result = vm.createNode()
for tn in tnode:eachObject() do
if tn.type == 'doc.type.table' then
for _, field in ipairs(tn.fields) do
if field.name.type ~= 'doc.field.name'
- and vm.isSubType(uri, vm.compileNode(field.name), knode) then
- if field.extends then
- result:merge(vm.compileNode(field.extends))
+ and field.extends then
+ if inversion then
+ if vm.isSubType(uri, vm.compileNode(field.name), knode) then
+ result:merge(vm.compileNode(field.extends))
+ end
+ else
+ if vm.isSubType(uri, knode, vm.compileNode(field.name)) then
+ result:merge(vm.compileNode(field.extends))
+ end
end
end
end
@@ -211,21 +218,31 @@ function vm.getTableValue(uri, tnode, knode)
end
if tn.type == 'table' then
for _, field in ipairs(tn) do
- if field.type == 'tableindex' then
- if field.value then
- result:merge(vm.compileNode(field.value))
- end
+ if field.type == 'tableindex'
+ and field.value then
+ result:merge(vm.compileNode(field.value))
end
- if field.type == 'tablefield' then
- if vm.isSubType(uri, knode, 'string') then
- if field.value then
+ if field.type == 'tablefield'
+ and field.value then
+ if inversion then
+ if vm.isSubType(uri, 'string', knode) then
+ result:merge(vm.compileNode(field.value))
+ end
+ else
+ if vm.isSubType(uri, knode, 'string') then
result:merge(vm.compileNode(field.value))
end
end
end
- if field.type == 'tableexp' then
- if vm.isSubType(uri, knode, 'integer') and field.tindex == 1 then
- if field.value then
+ if field.type == 'tableexp'
+ and field.value
+ and field.tindex == 1 then
+ if inversion then
+ if vm.isSubType(uri, 'integer', knode) then
+ result:merge(vm.compileNode(field.value))
+ end
+ else
+ if vm.isSubType(uri, knode, 'integer') then
result:merge(vm.compileNode(field.value))
end
end
@@ -242,16 +259,23 @@ end
---@param uri uri
---@param tnode vm.node
---@param vnode vm.node|string|vm.object
+---@param inversion? boolean
---@return vm.node?
-function vm.getTableKey(uri, tnode, vnode)
+function vm.getTableKey(uri, tnode, vnode, inversion)
local result = vm.createNode()
for tn in tnode:eachObject() do
if tn.type == 'doc.type.table' then
for _, field in ipairs(tn.fields) do
if field.name.type ~= 'doc.field.name'
and field.extends then
- if vm.isSubType(uri, vm.compileNode(field.extends), vnode) then
- result:merge(vm.compileNode(field.name))
+ if inversion then
+ if vm.isSubType(uri, vm.compileNode(field.extends), vnode) then
+ result:merge(vm.compileNode(field.name))
+ end
+ else
+ if vm.isSubType(uri, vnode, vm.compileNode(field.extends)) then
+ result:merge(vm.compileNode(field.name))
+ end
end
end
end
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua
index 02e9364e..e2b42369 100644
--- a/test/type_inference/init.lua
+++ b/test/type_inference/init.lua
@@ -3324,3 +3324,29 @@ _, x = pcall(f)
print(<?x?>)
]]
+
+TEST 'string' [[
+---@type table<string|number, string>
+local t
+
+---@type number
+local n
+---@type string
+local s
+
+local <?test?> = t[n]
+local test2 = t[s] --test and test2 are unknow
+]]
+
+TEST 'string' [[
+---@type table<string|number, string>
+local t
+
+---@type number
+local n
+---@type string
+local s
+
+local test = t[n]
+local <?test2?> = t[s] --test and test2 are unknow
+]]