summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-03-04 15:09:20 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-03-04 15:09:20 +0800
commit84cde0cbd4b18e38a2f97d65c75129677652fbe1 (patch)
treecaa6431c56938171a555fa1229afecf6dfeffb33 /server/src
parent6364d0aad94bae584c6b5574621ba340e4673378 (diff)
downloadlua-language-server-84cde0cbd4b18e38a2f97d65c75129677652fbe1.zip
暂存
Diffstat (limited to 'server/src')
-rw-r--r--server/src/core/diagnostics.lua47
-rw-r--r--server/src/vm/function.lua32
-rw-r--r--server/src/vm/library.lua5
-rw-r--r--server/src/vm/source.lua9
-rw-r--r--server/src/vm/value.lua8
-rw-r--r--server/src/vm/vm.lua17
6 files changed, 80 insertions, 38 deletions
diff --git a/server/src/core/diagnostics.lua b/server/src/core/diagnostics.lua
index 613e31c0..a08cace4 100644
--- a/server/src/core/diagnostics.lua
+++ b/server/src/core/diagnostics.lua
@@ -200,26 +200,29 @@ function mt:searchNewLineCall(callback)
end
function mt:searchRedundantParameters(callback)
- local results = self.results
- for _, call in ipairs(results.calls) do
- if call.func.hasDots then
- goto NEXT_CALL
+ self.vm:eachSource(function (source)
+ local call, args = source:bindCall()
+ if not call then
+ return
end
- if not call.func.args then
- goto NEXT_CALL
+ local func = call:getFunction()
+ if not func then
+ return
end
- local max = #call.func.args
- local passed = #call.args
+ -- 参数中有 ... ,不用再检查了
+ if func:hasDots() then
+ return
+ end
+ local max = #func.args
+ if func:getObject() then
+ max = max + 1
+ end
+ local passed = #args
for i = max + 1, passed do
- local source = call.args[i]
- if source.start then
- callback(source.start, source.finish, max, passed)
- else
- log.error('No start: ', table.dump(source))
- end
+ local extra = args[i]
+ callback(extra.source.start, extra.source.finish, max, passed)
end
- ::NEXT_CALL::
- end
+ end)
end
function mt:doDiagnostics(func, code, callback)
@@ -290,11 +293,11 @@ return function (vm, lines, uri)
}
end)
-- 调用函数时的参数数量是否超过函数的接收数量
- --session:doDiagnostics(session.searchRedundantParameters, --'remainder-parameters', function (max, passed)
- -- return {
- -- level = DiagnosticSeverity.Information,
- -- message = lang.script('DIAG_OVER_MAX_ARGS', max, passed),
- -- }
- --end)
+ session:doDiagnostics(session.searchRedundantParameters, 'remainder-parameters', function (max, passed)
+ return {
+ level = DiagnosticSeverity.Information,
+ message = lang.script('DIAG_OVER_MAX_ARGS', max, passed),
+ }
+ end)
return session.datas
end
diff --git a/server/src/vm/function.lua b/server/src/vm/function.lua
index a6835f5b..145e5eda 100644
--- a/server/src/vm/function.lua
+++ b/server/src/vm/function.lua
@@ -125,6 +125,10 @@ function mt:setObject(value, source)
self._objectSource = source
end
+function mt:getObject()
+ return self._objectValue, self._objectSource
+end
+
function mt:hasRuned()
return self._runed > 0
end
@@ -135,6 +139,10 @@ function mt:run()
return
end
+ if self._runed > 1 then
+ --return
+ end
+
-- 第一次运行函数时,创建函数的参数
if self._runed ~= 1 then
return
@@ -157,22 +165,33 @@ function mt:setArgs(values)
for i = 1, #values do
self.argValues[i] = values[i]
end
- if self.dots then
- local dotsIndex = #self.args
- for i = dotsIndex, #values do
- self.dots:set(i - dotsIndex + 1, values[i])
- end
- end
end
function mt:createArg(arg)
if arg.type == 'name' then
local loc = createLocal(arg[1], arg, createValue('any', arg))
self:saveLocal(arg[1], loc)
+ self.args[#self.args+1] = loc
elseif arg.type == '...' then
+ self._dots = createDots()
end
end
+function mt:createLibArg(arg)
+ if arg.type == '...' then
+ self._dots = createDots()
+ else
+ local name = arg.name or '_'
+ local loc = createLocal(name, nil, createValue('any'))
+ self:saveLocal(name, loc)
+ self.args[#self.args+1] = loc
+ end
+end
+
+function mt:hasDots()
+ return self._dots ~= nil
+end
+
function mt:createArgs()
if not self.source then
return
@@ -194,6 +213,7 @@ return function (source)
local self = setmetatable({
source = source,
locals = {},
+ args = {},
}, mt)
self:push()
return self
diff --git a/server/src/vm/library.lua b/server/src/vm/library.lua
index 263b8d73..4545b1b5 100644
--- a/server/src/vm/library.lua
+++ b/server/src/vm/library.lua
@@ -15,6 +15,11 @@ function buildLibValue(lib)
value = createValue('function')
local func = createFunction()
value:setFunction(func)
+ if lib.args then
+ for _, arg in ipairs(lib.args) do
+ func:createLibArg(arg)
+ end
+ end
if lib.returns then
for i, rtn in ipairs(lib.returns) do
if rtn.type == '...' then
diff --git a/server/src/vm/source.lua b/server/src/vm/source.lua
index 6685b95f..a06b8e8a 100644
--- a/server/src/vm/source.lua
+++ b/server/src/vm/source.lua
@@ -40,6 +40,15 @@ function mt:bindValue(value, action)
end
end
+function mt:bindCall(func, args)
+ if func then
+ self._bindCall = func
+ self._bindCallArgs = args
+ else
+ return self._bindCall, self._bindCallArgs
+ end
+end
+
function mt:action()
return self._action
end
diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua
index 0f2a8193..66f15da2 100644
--- a/server/src/vm/value.lua
+++ b/server/src/vm/value.lua
@@ -167,8 +167,14 @@ function mt:mergeValue(value)
self._child[k] = v
end
end
+ local hasSource = {}
+ for _, info in ipairs(self) do
+ hasSource[info.source] = true
+ end
for _, info in ipairs(value) do
- self[#self+1] = info
+ if not hasSource[info.source] then
+ self[#self+1] = info
+ end
end
if value._meta then
self._meta = value._meta
diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua
index 1113a083..9e19199e 100644
--- a/server/src/vm/vm.lua
+++ b/server/src/vm/vm.lua
@@ -314,15 +314,15 @@ function mt:call(value, values, source)
end
end
else
- if not func.built then
+ if not func.source then
func:setReturn(1, self:createValue('any', source))
end
end
- if not source.hasRuned and func.built then
+ if not source.hasRuned and func.source then
source.hasRuned = true
func:setArgs(values)
- self:runFunction(value)
+ self:runFunction(func)
end
return func:getReturn()
@@ -473,6 +473,7 @@ function mt:getSimple(simple, max)
if object then
table.insert(args, 1, object)
end
+ source:bindCall(func, args)
value = self:call(func, args, source) or createValue('any')
elseif source.type == 'index' then
local child = source[1]
@@ -503,8 +504,8 @@ end
function mt:getBinary(exp)
local v1 = self:getExp(exp[1])
local v2 = self:getExp(exp[2])
- v1 = self:getFirstInMulti(v1)
- v2 = self:getFirstInMulti(v2)
+ v1 = self:getFirstInMulti(v1) or createValue('nil', exp[1])
+ v2 = self:getFirstInMulti(v2) or createValue('nil', exp[2])
local op = exp.op
-- TODO 搜索元方法
if op == 'or' then
@@ -690,9 +691,7 @@ function mt:doReturn(action)
end
local values = self:unpackList(action)
local func = self:getCurrentFunction()
- local n = 0
- values:eachValue(function (value)
- n = n + 1
+ values:eachValue(function (n, value)
func:setReturn(n, value)
end)
end
@@ -1128,7 +1127,7 @@ return function (ast, lsp, uri)
end
local suc, res = xpcall(compile, log.error, ast, lsp, uri)
if not suc then
- return nil
+ return nil, res
end
return res
end