summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelog.md3
-rw-r--r--script/vm/compiler.lua28
-rw-r--r--script/vm/sign.lua13
-rw-r--r--test/type_inference/init.lua31
4 files changed, 65 insertions, 10 deletions
diff --git a/changelog.md b/changelog.md
index bb62b8a2..40d7630d 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,6 +1,6 @@
# changelog
-## 3.1.1
+## 3.2.0
* `NEW` supports infer of callback parameter
```lua
---@type string[]
@@ -23,6 +23,7 @@
local x = true
local y = x--[[@as integer]] -- y is `integer` here
```
+* `NEW` generic: resolve `T[]` by `table<integer, type>` or `---@field [integer] type`
* `NEW` diagnostic: `missing-parameter`
* `CHG` diagnostic: no longer mark `redundant-parameter` as `Unnecessary`
* `FIX` diagnostic: `unused-function` does not recognize recursion
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 883d89b9..4395eea4 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -184,7 +184,7 @@ local searchFieldSwitch = util.switch()
end)
-function vm.getClassFields(suri, node, key, ref, pushResult)
+function vm.getClassFields(suri, object, key, ref, pushResult)
local mark = {}
local function searchClass(class, searchedFields)
@@ -199,13 +199,23 @@ function vm.getClassFields(suri, node, key, ref, pushResult)
-- check ---@field
local hasFounded = {}
for _, field in ipairs(set.fields) do
- local fieldKey = guide.getKeyName(field)
- if fieldKey then
- if key == nil
- or fieldKey == key then
- if not searchedFields[fieldKey] then
+ if type(key) == 'table' then
+ local fieldNode = vm.compileNode(field.field)
+ if vm.isSubType(suri, key.name, fieldNode) then
+ if not searchedFields[key] then
pushResult(field)
- hasFounded[fieldKey] = true
+ hasFounded[key] = true
+ end
+ end
+ else
+ local fieldKey = guide.getKeyName(field)
+ if fieldKey then
+ if key == nil
+ or fieldKey == key then
+ if not searchedFields[fieldKey] then
+ pushResult(field)
+ hasFounded[fieldKey] = true
+ end
end
end
end
@@ -273,8 +283,8 @@ function vm.getClassFields(suri, node, key, ref, pushResult)
end
end
- searchClass(node)
- searchGlobal(node)
+ searchClass(object)
+ searchGlobal(object)
end
---@class parser.object
diff --git a/script/vm/sign.lua b/script/vm/sign.lua
index e997624a..78d61022 100644
--- a/script/vm/sign.lua
+++ b/script/vm/sign.lua
@@ -49,6 +49,19 @@ function mt:resolve(uri, args, removeGeneric)
-- number[] -> T[]
resolve(object.node, vm.compileNode(n.node))
end
+ if n.type == 'doc.type.table' then
+ -- { [integer]: number } -> T[]
+ local tvalueNode = vm.getTableValue(uri, node, 'integer')
+ if tvalueNode then
+ resolve(object.node, tvalueNode)
+ end
+ end
+ if n.type == 'global' and n.cate == 'type' then
+ -- ---@field [integer]: number -> T[]
+ vm.getClassFields(uri, n, globalMgr.getGlobal('type', 'integer'), false, function (field)
+ resolve(object.node, vm.compileNode(field.extends))
+ end)
+ end
end
end
if object.type == 'doc.type.table' then
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua
index 36ae8711..7a4fb754 100644
--- a/test/type_inference/init.lua
+++ b/test/type_inference/init.lua
@@ -871,6 +871,37 @@ end
]]
TEST 'boolean' [[
+---@generic T: table, V
+---@param t T
+---@return fun(table: V[], i?: integer):integer, V
+---@return T
+---@return integer i
+local function ipairs(t) end
+
+---@type table<integer, boolean>
+local t
+
+for _, <?v?> in ipairs(t) do
+end
+]]
+
+TEST 'boolean' [[
+---@generic T: table, V
+---@param t T
+---@return fun(table: V[], i?: integer):integer, V
+---@return T
+---@return integer i
+local function ipairs(t) end
+
+---@class MyClass
+---@field [integer] boolean
+local t
+
+for _, <?v?> in ipairs(t) do
+end
+]]
+
+TEST 'boolean' [[
---@generic T: table, K, V
---@param t T
---@return fun(table: table<K, V>, index: K):K, V