summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorsumneko <sumneko@hotmail.com>2019-04-29 20:22:14 +0800
committersumneko <sumneko@hotmail.com>2019-04-29 20:22:14 +0800
commiteec1da3f170a0fc90844860f0c877e38765466b1 (patch)
tree35821229794dd6923c4803db64775154b3e9c714 /server
parent9a1b32c07764bfa441d184d97ae90d271bfb9012 (diff)
downloadlua-language-server-eec1da3f170a0fc90844860f0c877e38765466b1.zip
emmy.vararg
Diffstat (limited to 'server')
-rw-r--r--server/src/emmy/generic.lua2
-rw-r--r--server/src/emmy/param.lua6
-rw-r--r--server/src/vm/emmy.lua14
-rw-r--r--server/src/vm/function.lua38
-rw-r--r--server/src/vm/multi.lua8
-rw-r--r--server/src/vm/vm.lua6
-rw-r--r--server/test/hover/init.lua45
7 files changed, 97 insertions, 22 deletions
diff --git a/server/src/emmy/generic.lua b/server/src/emmy/generic.lua
index d47ee585..82fd0c4b 100644
--- a/server/src/emmy/generic.lua
+++ b/server/src/emmy/generic.lua
@@ -6,7 +6,7 @@ mt.__index = mt
mt.type = 'emmy.generic'
function mt:getName()
- return self.name
+ return self.name:getName()
end
function mt:setValue(value)
diff --git a/server/src/emmy/param.lua b/server/src/emmy/param.lua
index 84474db6..9a2d407f 100644
--- a/server/src/emmy/param.lua
+++ b/server/src/emmy/param.lua
@@ -31,9 +31,13 @@ end
return function (manager, source)
local self = setmetatable({
- name = source[1][1],
source = source.id,
_manager = manager,
}, mt)
+ if source.type == 'emmyParam' then
+ self.name = source[1][1]
+ elseif source.type == 'emmyVararg' then
+ self.name = '...'
+ end
return self
end
diff --git a/server/src/vm/emmy.lua b/server/src/vm/emmy.lua
index 500c4711..1dd67d7d 100644
--- a/server/src/vm/emmy.lua
+++ b/server/src/vm/emmy.lua
@@ -24,6 +24,7 @@ function mt:doEmmy(action)
elseif tp == 'emmyGeneric' then
self:doEmmyGeneric(action)
elseif tp == 'emmyVararg' then
+ self:doEmmyVararg(action)
elseif tp == 'emmyLanguage' then
elseif tp == 'emmyArrayType' then
elseif tp == 'emmyTableType' then
@@ -209,6 +210,19 @@ function mt:doEmmyGeneric(action)
self._emmyGeneric = generic
end
+function mt:doEmmyVararg(action)
+ ---@type emmyMgr
+ local emmyMgr = self.emmyMgr
+ self:instantSource(action)
+ local type = self:getGenericByType(action[1]) or self:buildEmmyType(action[1])
+ local param = emmyMgr:addParam(action, type)
+ action:set('emmy.param', param)
+ self:addEmmyParam(param)
+ if self.lsp then
+ self.lsp.global:markGet(self:getUri())
+ end
+end
+
function mt:doEmmyIncomplete(action)
self:instantSource(action)
end
diff --git a/server/src/vm/function.lua b/server/src/vm/function.lua
index 5c9019aa..6eb6fc1f 100644
--- a/server/src/vm/function.lua
+++ b/server/src/vm/function.lua
@@ -261,6 +261,10 @@ function mt:run(vm)
loc:setValue(self.argValues[i])
local emmyParam = self:findEmmyParamByName(loc:getName())
if emmyParam then
+ local typeObj = emmyParam:bindType()
+ if typeObj then
+ loc:getValue():setEmmy(typeObj)
+ end
local genericObj = emmyParam:bindGeneric()
if genericObj then
genericObj:setValue(loc:getValue())
@@ -268,9 +272,34 @@ function mt:run(vm)
end
end
if self._dots then
+ local emmyParam = self:findEmmyParamByName('...')
self._dots = createMulti()
for i = #self.args + 1, #self.argValues do
- self._dots:push(self.argValues[i])
+ local value = self.argValues[i]
+ self._dots:push(value)
+ if emmyParam then
+ local typeObj = emmyParam:bindType()
+ if typeObj then
+ value:setEmmy(typeObj)
+ end
+ local genericObj = emmyParam:bindGeneric()
+ if genericObj then
+ genericObj:setValue(value)
+ end
+ end
+ end
+ if emmyParam then
+ local typeObj = emmyParam:bindType()
+ if typeObj then
+ self._dots:setEmmy(typeObj)
+ end
+ local genericObj = emmyParam:bindGeneric()
+ if genericObj then
+ local value = self._dots:first()
+ if value then
+ genericObj:setValue(value)
+ end
+ end
end
end
@@ -321,14 +350,7 @@ function mt:createArg(vm, arg)
vm:instantSource(arg)
arg:set('arg', self)
if arg.type == 'name' then
- local emmyParam = self:findEmmyParamByName(arg[1])
local value = valueMgr.create('nil', arg)
- if emmyParam then
- local typeObj = emmyParam:bindType()
- if typeObj then
- value:setEmmy(typeObj)
- end
- end
local loc = localMgr.create(arg[1], arg, value)
self:saveUpvalue(arg[1], loc)
self.args[#self.args+1] = loc
diff --git a/server/src/vm/multi.lua b/server/src/vm/multi.lua
index 809b5244..c2748a26 100644
--- a/server/src/vm/multi.lua
+++ b/server/src/vm/multi.lua
@@ -66,6 +66,14 @@ function mt:merge(other)
end)
end
+function mt:setEmmy(emmy)
+ self._emmy = emmy
+end
+
+function mt:getEmmy()
+ return self._emmy
+end
+
return function ()
local self = setmetatable({}, mt)
return self
diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua
index d1c05f36..d057c1cd 100644
--- a/server/src/vm/vm.lua
+++ b/server/src/vm/vm.lua
@@ -823,6 +823,9 @@ function mt:doSet(action)
local value = self:getExp(exps)
local values = {}
if value.type == 'multi' then
+ if not emmy then
+ emmy = value:getEmmy()
+ end
value:eachValue(function (i, v)
values[i] = v
end)
@@ -846,6 +849,9 @@ function mt:doLocal(action)
local value = self:getExp(exps)
values = {}
if value.type == 'multi' then
+ if not emmy then
+ emmy = value:getEmmy()
+ end
value:eachValue(function (i, v)
values[i] = v
end)
diff --git a/server/test/hover/init.lua b/server/test/hover/init.lua
index 24cf8789..5e46bf26 100644
--- a/server/test/hover/init.lua
+++ b/server/test/hover/init.lua
@@ -609,15 +609,36 @@ function f()
-> A|B, C
]]
---TEST [[
------@generic T
------@param x T
------@return T
---local function f(x)
---end
---
---local <?r?> = f(1)
---]]
---[[
---local r: number = 1
---]]
+TEST [[
+---@generic T
+---@param x T
+---@return T
+local function f(x)
+end
+
+local <?r?> = f(1)
+]]
+[[
+local r: number
+]]
+
+TEST [[
+---@vararg Class
+local function f(...)
+ local _, <?x?> = ...
+end
+f(1, 2, 3)
+]]
+[[
+local x: *Class = 2
+]]
+
+TEST [[
+---@vararg Class
+local function f(...)
+ local _, <?x?> = ...
+end
+]]
+[[
+local x: *Class {}
+]]