diff options
author | sumneko <sumneko@hotmail.com> | 2019-04-25 17:54:28 +0800 |
---|---|---|
committer | sumneko <sumneko@hotmail.com> | 2019-04-25 17:54:28 +0800 |
commit | 7b326c86ab117428e6361f6977e6c4e8aa42a9da (patch) | |
tree | 60c12f78de393aa1380aa0f6627e9a3467c4152d /server | |
parent | 39e7ac384e45781331fc8c33a6a76746d770f031 (diff) | |
download | lua-language-server-7b326c86ab117428e6361f6977e6c4e8aa42a9da.zip |
参数自动完成与诊断
Diffstat (limited to 'server')
-rw-r--r-- | server/main.lua | 2 | ||||
-rw-r--r-- | server/src/core/completion.lua | 18 | ||||
-rw-r--r-- | server/src/core/diagnostics.lua | 52 | ||||
-rw-r--r-- | server/src/vm/function.lua | 8 | ||||
-rw-r--r-- | server/test/completion/init.lua | 22 | ||||
-rw-r--r-- | server/test/diagnostics/init.lua | 33 |
6 files changed, 129 insertions, 6 deletions
diff --git a/server/main.lua b/server/main.lua index 685fce01..ac7860c5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -22,7 +22,7 @@ local function tryDebugger() log.info('Debugger startup, listen port: 11411') end -pcall(tryDebugger) +--pcall(tryDebugger) require 'utility' require 'global_protect' diff --git a/server/src/core/completion.lua b/server/src/core/completion.lua index 3162a48e..eb4e9a1d 100644 --- a/server/src/core/completion.lua +++ b/server/src/core/completion.lua @@ -324,6 +324,21 @@ local function searchCloseGlobal(vm, source, word, callback) end) end +local function searchParams(vm, source, word, callback) + ---@type function + local func = source:get 'arg' + local emmyParams = func:getEmmyParams() + if not emmyParams then + return + end + for _, param in ipairs(emmyParams) do + local name = param:getName() + if matchKey(word, name) then + callback(name, param:getSource(), CompletionItemKind.Interface) + end + end +end + local function searchKeyWords(vm, source, word, callback) for _, key in ipairs(KEYS) do if matchKey(word, key) then @@ -387,6 +402,7 @@ local function searchAsLocal(vm, source, word, callback) end local function searchAsArg(vm, source, word, callback) + searchParams(vm, source, word, callback) searchCloseGlobal(vm, source, word, callback) end @@ -422,7 +438,7 @@ local function searchEmmyFunctionParam(vm, source, word, callback) end for _, arg in ipairs(func.args) do if matchKey(word, arg.name) then - callback(arg.name, arg, CompletionItemKind.Unit) + callback(arg.name, arg, CompletionItemKind.Interface) end end end diff --git a/server/src/core/diagnostics.lua b/server/src/core/diagnostics.lua index 140873c5..f9d6f818 100644 --- a/server/src/core/diagnostics.lua +++ b/server/src/core/diagnostics.lua @@ -507,7 +507,57 @@ function mt:checkEmmyAlias(source, callback) end end +function mt:checkEmmyParam(source, callback, mark) + local func = source:get 'emmy function' + if not func then + return + end + if mark[func] then + return + end + mark[func] = true + + -- 检查不存在的参数 + local emmyParams = func:getEmmyParams() + local funcParams = {} + if func.args then + for _, arg in ipairs(func.args) do + funcParams[arg.name] = true + end + end + for _, param in ipairs(emmyParams) do + local name = param:getName() + if not funcParams[name] then + callback(param:getSource()[1].start, param:getSource()[1].finish, lang.script.DIAG_INEXISTENT_PARAM) + end + end + + -- 检查重复的param + local lists = {} + for _, param in ipairs(emmyParams) do + local name = param:getName() + if not lists[name] then + lists[name] = {} + end + lists[name][#lists[name]+1] = param:getSource()[1] + end + for _, list in pairs(lists) do + if #list > 1 then + local related = {} + for _, src in ipairs(list) do + related[#related+1] = { + src.start, + src.finish, + src.uri, + } + callback(src.start, src.finish, lang.script.DIAG_DUPLICATE_PARAM) + end + end + end +end + function mt:searchEmmyLua(callback) + local mark = {} self.vm:eachSource(function (source) if source.type == 'emmyClass' then self:checkEmmyClass(source, callback) @@ -515,6 +565,8 @@ function mt:searchEmmyLua(callback) self:checkEmmyType(source, callback) elseif source.type == 'emmyAlias' then self:checkEmmyAlias(source, callback) + elseif source.type == 'emmyParam' then + self:checkEmmyParam(source, callback, mark) end end) end diff --git a/server/src/vm/function.lua b/server/src/vm/function.lua index 9b0811bf..8bc38970 100644 --- a/server/src/vm/function.lua +++ b/server/src/vm/function.lua @@ -6,6 +6,7 @@ local listMgr = require 'vm.list' local Watch = setmetatable({}, {__mode = 'kv'}) +---@class function local mt = {} mt.__index = mt mt.type = 'function' @@ -291,7 +292,7 @@ end function mt:createArg(vm, arg) vm:instantSource(arg) - arg:set('arg', true) + arg:set('arg', self) if arg.type == 'name' then local emmyParam = self:findEmmyParamByName(arg[1]) local value = valueMgr.create('nil', arg) @@ -384,11 +385,16 @@ function mt:setEmmyParams(params) if params then self._emmyParams = params for _, param in ipairs(params) do + param:getSource():set('emmy function', self) param:getSource()[1]:set('emmy function', self) end end end +function mt:getEmmyParams() + return self._emmyParams +end + local function create(source) if not source then error('Function need source') diff --git a/server/test/completion/init.lua b/server/test/completion/init.lua index 340af415..f8d1bef0 100644 --- a/server/test/completion/init.lua +++ b/server/test/completion/init.lua @@ -851,14 +851,30 @@ end { { label = 'a', - kind = CompletionItemKind.Unit, + kind = CompletionItemKind.Interface, }, { label = 'b', - kind = CompletionItemKind.Unit, + kind = CompletionItemKind.Interface, }, { label = 'c', - kind = CompletionItemKind.Unit, + kind = CompletionItemKind.Interface, + }, +} + +TEST [[ +---@param xyz Class +---@param xxx Class +function f(x$) +]] +{ + { + label = 'xyz', + kind = CompletionItemKind.Interface, + }, + { + label = 'xxx', + kind = CompletionItemKind.Interface, }, } diff --git a/server/test/diagnostics/init.lua b/server/test/diagnostics/init.lua index 827df06a..60c029bb 100644 --- a/server/test/diagnostics/init.lua +++ b/server/test/diagnostics/init.lua @@ -382,3 +382,36 @@ TEST [[ ---@class B ---@alias <!A B!> ]] + +TEST [[ +---@param x <!Class!> +]] + +TEST [[ +---@class Class +---@param <!y!> Class +local function f(x) + return x +end +f() +]] + +TEST [[ +---@class Class +---@param <!y!> Class +function F(x) + return x +end +F() +]] + +TEST [[ +---@class Class +---@param <!x!> Class +---@param y Class +---@param <!x!> Class +local function f(x, y) + return x, y +end +f() +]] |