diff options
-rw-r--r-- | changelog.md | 3 | ||||
-rw-r--r-- | script/vm/compiler.lua | 28 | ||||
-rw-r--r-- | script/vm/sign.lua | 13 | ||||
-rw-r--r-- | test/type_inference/init.lua | 31 |
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 |