diff options
-rw-r--r-- | changelog.md | 10 | ||||
-rw-r--r-- | script/core/noder.lua | 60 | ||||
-rw-r--r-- | test.lua | 2 | ||||
-rw-r--r-- | test/completion/init.lua | 6 | ||||
-rw-r--r-- | test/type_inference/init.lua | 29 |
5 files changed, 100 insertions, 7 deletions
diff --git a/changelog.md b/changelog.md index bf52362f..3b2a029c 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,16 @@ ## 2.1.0 * `NEW` supports local config file, using `--configpath="config.json"`, [learn more here](https://github.com/sumneko/lua-language-server/wiki/Setting-without-VSCode) * `NEW` goto `type definition` +* `NEW` infer type by callback param: + ```lua + ---@param callback fun(value: string) + local function work(callback) + end + + work(function (value) + -- value is string here + end) + ``` * `CHG` [#549](https://github.com/sumneko/lua-language-server/issues/549) * `CHG` diagnostics: always ignore the ignored files even if they are opened * `FIX` completion: `type() ==` may does not work diff --git a/script/core/noder.lua b/script/core/noder.lua index b8690ba4..42079a9c 100644 --- a/script/core/noder.lua +++ b/script/core/noder.lua @@ -535,7 +535,46 @@ local function bindValue(noders, source, id) end end -local function compileCall(noders, call, sourceID, returnIndex) +local function compileCallParam(noders, call, sourceID) + if not sourceID then + return + end + if not call.args then + return + end + local node = call.node + local fixIndex = 0 + if call.node.special == 'pcall' then + fixIndex = 1 + node = call.args[1] + elseif call.node.special == 'xpcall' then + fixIndex = 2 + node = call.args[1] + end + local nodeID = getID(node) + if not nodeID then + return + end + for firstIndex, callArg in ipairs(call.args) do + firstIndex = firstIndex - fixIndex + if firstIndex > 0 and callArg.type == 'function' then + if callArg.args then + for secondIndex, funcParam in ipairs(callArg.args) do + local paramID = ('%s%s%s%s%s'):format( + nodeID, + PARAM_INDEX, + firstIndex, + PARAM_INDEX, + secondIndex + ) + pushForward(noders, getID(funcParam), paramID) + end + end + end + end +end + +local function compileCallReturn(noders, call, sourceID, returnIndex) if not sourceID then return end @@ -732,13 +771,14 @@ function m.compileNode(noders, source) end if source.type == 'call' then if source.parent.type ~= 'select' then - compileCall(noders, source, id, 1) + compileCallReturn(noders, source, id, 1) end + compileCallParam(noders, source, id) end if source.type == 'select' then if source.vararg.type == 'call' then local call = source.vararg - compileCall(noders, call, id, source.sindex) + compileCallReturn(noders, call, id, source.sindex) end if source.vararg.type == 'varargs' then pushForward(noders, id, getID(source.vararg)) @@ -754,6 +794,14 @@ function m.compileNode(noders, source) ) pushForward(noders, returnID, getID(rtn)) end + for index, param in ipairs(source.args) do + local paramID = ('%s%s%s'):format( + id, + PARAM_INDEX, + index + ) + pushForward(noders, paramID, getID(param.extends)) + end end -- @type fun(x: T):T 的情况 local docType = getDocStateWithoutCrossFunction(source) @@ -857,6 +905,12 @@ function m.compileNode(noders, source) if param then pushForward(noders, getID(param), getID(doc)) param.docParam = doc + local paramID = ('%s%s%s'):format( + id, + PARAM_INDEX, + paramIndex + ) + pushForward(noders, paramID, getID(doc.extends)) end end end @@ -9,7 +9,7 @@ local fs = require 'bee.filesystem' ROOT = fs.path(rootPath) TEST = true DEVELOP = true -FOOTPRINT = true +--FOOTPRINT = true --TRACE = true LOGPATH = LOGPATH or (ROOT .. '/log') METAPATH = METAPATH or (ROOT .. '/meta') diff --git a/test/completion/init.lua b/test/completion/init.lua index 0f96949d..327d72a4 100644 --- a/test/completion/init.lua +++ b/test/completion/init.lua @@ -2580,11 +2580,11 @@ t.GGG$ ]] { { - label = 't.GGG', - kind = define.CompletionItemKind.Enum, + label = 'GGG', + kind = define.CompletionItemKind.Field, }, { - label = 't.GGG()', + label = 'GGG()', kind = define.CompletionItemKind.Function, }, } diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua index 3ec1cf19..3df73863 100644 --- a/test/type_inference/init.lua +++ b/test/type_inference/init.lua @@ -828,6 +828,13 @@ TEST 'fun():number, boolean' [[ local <?t?> ]] +--[[ +l:value +l:work|&1|&1 +f:|&1|&1 +dfun:|&1 +dn:Class +]] TEST 'Class' [[ ---@class Class @@ -838,3 +845,25 @@ end work(function (<?value?>) end) ]] + +TEST 'Class' [[ +---@class Class + +---@param callback fun(value: Class) +function work(callback) +end + +pcall(work, function (<?value?>) +end) +]] + +TEST 'Class' [[ +---@class Class + +---@param callback fun(value: Class) +function work(callback) +end + +xpcall(work, debug.traceback, function (<?value?>) +end) +]] |