diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/libs/@lua/basic.lni | 34 | ||||
-rw-r--r-- | server/src/core/hover/hover.lua | 4 | ||||
-rw-r--r-- | server/src/emmy/arrayType.lua | 36 | ||||
-rw-r--r-- | server/src/emmy/manager.lua | 29 | ||||
-rw-r--r-- | server/src/vm/emmy.lua | 14 | ||||
-rw-r--r-- | server/src/vm/ipairs.lua | 43 | ||||
-rw-r--r-- | server/src/vm/library.lua | 7 | ||||
-rw-r--r-- | server/src/vm/local.lua | 5 | ||||
-rw-r--r-- | server/src/vm/value.lua | 16 | ||||
-rw-r--r-- | server/src/vm/vm.lua | 9 | ||||
-rw-r--r-- | server/test/hover/init.lua | 49 |
11 files changed, 215 insertions, 31 deletions
diff --git a/server/libs/@lua/basic.lni b/server/libs/@lua/basic.lni index a90a029e..61db69c9 100644 --- a/server/libs/@lua/basic.lni +++ b/server/libs/@lua/basic.lni @@ -127,32 +127,26 @@ name = 'object' name = 'metatable' type = 'table' +[@ipairs] +special = '@ipairs' +[[.args]] +type = 'table' +`````````` +name = 'i' +type = 'integer' +[[.returns]] +name = 'i' +type = 'integer' +`````````` +type = 'object' + [ipairs] +special = 'ipairs' [[.args]] name = 't' type = 'table' [[.returns]] name = 'iterator' -type = 'function' -args = { - 1 = { - name = 'table', - type = 'table', - }, - 2 = { - name = 'i', - type = 'integer', - } -} -returns = { - 1 = { - name = 'i', - type = 'integer', - }, - 2 = { - name = 'object', - }, -} `````````` name = 't' type = 'table' diff --git a/server/src/core/hover/hover.lua b/server/src/core/hover/hover.lua index 550129a4..12d6fbe5 100644 --- a/server/src/core/hover/hover.lua +++ b/server/src/core/hover/hover.lua @@ -100,6 +100,10 @@ local function unpackTable(value) lines[#lines+1] = ('%s: %s'):format(key, child:getType()) end end) + local emmy = value:getEmmy() + if emmy and emmy.type == 'emmy.arrayType' then + lines[#lines+1] = ('[*integer]: %s'):format(emmy:getName()) + end if #lines == 0 then return '{}' end diff --git a/server/src/emmy/arrayType.lua b/server/src/emmy/arrayType.lua new file mode 100644 index 00000000..3c6a7b7b --- /dev/null +++ b/server/src/emmy/arrayType.lua @@ -0,0 +1,36 @@ +local listMgr = require 'vm.list' + +---@class EmmyArrayType +local mt = {} +mt.__index = mt +mt.type = 'emmy.arrayType' + +function mt:getType() + return 'table' +end + +function mt:getName() + return self.name +end + +function mt:getSource() + return listMgr.get(self.source) +end + +function mt:setValue(value) + self.value = value + self:getSource():get('emmy.typeUnit'):setValue(value) +end + +function mt:getValue() + return self.value +end + +return function (manager, source) + local self = setmetatable({ + name = source[1], + source = source.id, + _manager = manager, + }, mt) + return self +end diff --git a/server/src/emmy/manager.lua b/server/src/emmy/manager.lua index ce766988..45fc1c3d 100644 --- a/server/src/emmy/manager.lua +++ b/server/src/emmy/manager.lua @@ -1,12 +1,13 @@ -local listMgr = require 'vm.list' -local newClass = require 'emmy.class' -local newType = require 'emmy.type' -local newTypeUnit = require 'emmy.typeUnit' -local newAlias = require 'emmy.alias' -local newParam = require 'emmy.param' -local newReturn = require 'emmy.return' -local newField = require 'emmy.field' -local newGeneric = require 'emmy.generic' +local listMgr = require 'vm.list' +local newClass = require 'emmy.class' +local newType = require 'emmy.type' +local newTypeUnit = require 'emmy.typeUnit' +local newAlias = require 'emmy.alias' +local newParam = require 'emmy.param' +local newReturn = require 'emmy.return' +local newField = require 'emmy.field' +local newGeneric = require 'emmy.generic' +local newArrayType = require 'emmy.arrayType' local mt = {} mt.__index = mt @@ -99,6 +100,16 @@ function mt:addType(source) return typeObj end +function mt:addArrayType(source) + local typeObj = newArrayType(self, source) + local typeUnit = newTypeUnit(self, source) + local list = self:getClass(source[1]) + typeUnit:setParent(typeObj) + list[source.id] = typeUnit + source:set('emmy.typeUnit', typeUnit) + return typeObj +end + function mt:addAlias(source, typeObj) local aliasName = source[1][1] local aliasObj = newAlias(self, source) diff --git a/server/src/vm/emmy.lua b/server/src/vm/emmy.lua index 1dd67d7d..cf6d7026 100644 --- a/server/src/vm/emmy.lua +++ b/server/src/vm/emmy.lua @@ -27,6 +27,7 @@ function mt:doEmmy(action) self:doEmmyVararg(action) elseif tp == 'emmyLanguage' then elseif tp == 'emmyArrayType' then + self:doEmmyArrayType(action) elseif tp == 'emmyTableType' then elseif tp == 'emmyFunctionType' then elseif tp == 'emmySee' then @@ -223,6 +224,19 @@ function mt:doEmmyVararg(action) end end +function mt:doEmmyArrayType(action) + ---@type emmyMgr + local emmyMgr = self.emmyMgr + self:instantSource(action) + action:set('emmy class', action[1]) + local type = emmyMgr:addArrayType(action) + self._emmy = type + if self.lsp then + self.lsp.global:markGet(self:getUri()) + end + return type +end + function mt:doEmmyIncomplete(action) self:instantSource(action) end diff --git a/server/src/vm/ipairs.lua b/server/src/vm/ipairs.lua new file mode 100644 index 00000000..e27b8584 --- /dev/null +++ b/server/src/vm/ipairs.lua @@ -0,0 +1,43 @@ +local mt = require 'vm.manager' + +---@param func function +function mt:callIpairs(func, values, source) + local tbl = values[1] + func:setReturn(2, tbl) +end + +---@param func function +function mt:callAtIpairs(func, values, source) + local tbl = values[1] + if tbl then + local emmy = tbl:getEmmy() + if emmy then + if emmy.type == 'emmy.arrayType' then + local value = self:createValue(emmy:getName(), source) + func:setReturn(2, value) + end + end + end +end + +---@param func function +function mt:callPairs(func, values, source) + local tbl = values[1] + func:setReturn(2, tbl) +end + +---@param func function +function mt:callNext(func, values, source) + local tbl = values[1] + if tbl then + local emmy = tbl:getEmmy() + if emmy then + if emmy.type == 'emmy.arrayType' then + local key = self:createValue('integer', self:getDefaultSource()) + local value = self:createValue(emmy:getName(), source) + func:setReturn(1, key) + func:setReturn(2, value) + end + end + end +end diff --git a/server/src/vm/library.lua b/server/src/vm/library.lua index e1bd335e..258118a7 100644 --- a/server/src/vm/library.lua +++ b/server/src/vm/library.lua @@ -43,6 +43,9 @@ function buildLibValue(lib) if lib.special == 'pairs' then func:setReturn(1, Special['next']) end + if lib.special == 'ipairs' then + func:setReturn(1, Special['@ipairs']) + end end elseif tp == 'string' then value = valueMgr.create('string', sourceMgr.dummy()) @@ -71,6 +74,10 @@ function buildLibValue(lib) if lib.special == 'next' then Special['next'] = value end + if lib.special == '@ipairs' then + Special['@ipairs'] = value + return nil + end return value end diff --git a/server/src/vm/local.lua b/server/src/vm/local.lua index 3591eab9..ad7d80e8 100644 --- a/server/src/vm/local.lua +++ b/server/src/vm/local.lua @@ -140,7 +140,10 @@ function mt:setEmmy(emmy) if not emmy then return end - if emmy.type ~= 'emmy.class' and emmy.type ~= 'emmy.type' then + if emmy.type ~= 'emmy.class' + and emmy.type ~= 'emmy.type' + and emmy.type ~= 'emmy.arrayType' + then return end if self.value then diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua index efbe50c4..d974cec0 100644 --- a/server/src/vm/value.lua +++ b/server/src/vm/value.lua @@ -184,7 +184,17 @@ function mt:getChild(index, source) parent = method end if not value and source then - value = create('any', source) + local emmy = self:getEmmy() + if emmy then + if emmy.type == 'emmy.arrayType' then + if type(index) == 'number' then + value = create(emmy:getName(), source) + end + end + end + if not value then + value = create('any', source) + end self:setChild(index, value) value.uri = self.uri end @@ -575,6 +585,10 @@ function mt:setEmmy(emmy) self:mergeValue(class:getValue()) end end) + elseif emmy.type == 'emmy.arrayType' then + ---@type EmmyArrayType + local EmmyArrayType = emmy + EmmyArrayType:setValue(self) else return end diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua index d057c1cd..fab500e5 100644 --- a/server/src/vm/vm.lua +++ b/server/src/vm/vm.lua @@ -14,6 +14,7 @@ local mt = require 'vm.manager' require 'vm.module' require 'vm.raw' require 'vm.pcall' +require 'vm.ipairs' require 'vm.emmy' -- TODO source测试 @@ -296,6 +297,14 @@ function mt:callLibrary(func, values, source, lib) self:callPcall(func, values, source) elseif lib.special == 'xpcall' then self:callXpcall(func, values, source) + elseif lib.special == 'ipairs' then + self:callIpairs(func, values, source) + elseif lib.special == '@ipairs' then + self:callAtIpairs(func, values, source) + elseif lib.special == 'pairs' then + self:callPairs(func, values, source) + elseif lib.special == 'next' then + self:callNext(func, values, source) end else -- 如果lib的参数中有function,则立即执行function diff --git a/server/test/hover/init.lua b/server/test/hover/init.lua index 5e46bf26..485b68a7 100644 --- a/server/test/hover/init.lua +++ b/server/test/hover/init.lua @@ -642,3 +642,52 @@ end [[ local x: *Class {} ]] + +TEST [[ +---@type string[] +local <?x?> +]] +[[ +local x: { + [*integer]: string, +} +]] + +TEST [[ +---@type string[] +local t +local <?x?> = t[1] +]] +[[ +local x: string +]] + +TEST [[ +---@type string[] +local t +for _, <?x?> in ipairs(t) do +end +]] +[[ +local x: string +]] + +TEST [[ +---@type string[] +local t +for _, <?x?> in pairs(t) do +end +]] +[[ +local x: string +]] + +TEST [[ +---@type string[] +local t +for <?k?>, v in pairs(t) do +end +]] +[[ +local k: integer +]] |