diff options
-rw-r--r-- | server/src/emmy/generic.lua | 2 | ||||
-rw-r--r-- | server/src/emmy/param.lua | 6 | ||||
-rw-r--r-- | server/src/vm/emmy.lua | 14 | ||||
-rw-r--r-- | server/src/vm/function.lua | 38 | ||||
-rw-r--r-- | server/src/vm/multi.lua | 8 | ||||
-rw-r--r-- | server/src/vm/vm.lua | 6 | ||||
-rw-r--r-- | server/test/hover/init.lua | 45 |
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 {} +]] |