summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
authorsumneko <sumneko@hotmail.com>2019-04-25 17:54:28 +0800
committersumneko <sumneko@hotmail.com>2019-04-25 17:54:28 +0800
commit7b326c86ab117428e6361f6977e6c4e8aa42a9da (patch)
tree60c12f78de393aa1380aa0f6627e9a3467c4152d /server/src
parent39e7ac384e45781331fc8c33a6a76746d770f031 (diff)
downloadlua-language-server-7b326c86ab117428e6361f6977e6c4e8aa42a9da.zip
参数自动完成与诊断
Diffstat (limited to 'server/src')
-rw-r--r--server/src/core/completion.lua18
-rw-r--r--server/src/core/diagnostics.lua52
-rw-r--r--server/src/vm/function.lua8
3 files changed, 76 insertions, 2 deletions
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')