diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-07-04 21:09:55 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-07-04 21:09:55 +0800 |
commit | f732640c8b1aa71c1b5d543c0ded8f6150abbde1 (patch) | |
tree | e4984ea4ff414ec396a4563decc287b4a09e0ab8 | |
parent | 1b23b28c7e9f2ecc59dcf19ec2533ab2c4f3e9d9 (diff) | |
download | lua-language-server-f732640c8b1aa71c1b5d543c0ded8f6150abbde1.zip |
fix #1273
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | script/vm/sign.lua | 10 | ||||
-rw-r--r-- | script/vm/type.lua | 58 | ||||
-rw-r--r-- | test/type_inference/init.lua | 26 |
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 +]] |