diff options
author | sumneko <sumneko@hotmail.com> | 2019-04-30 17:16:13 +0800 |
---|---|---|
committer | sumneko <sumneko@hotmail.com> | 2019-04-30 17:16:13 +0800 |
commit | e683d90bdb40ed07ad3f1b53ca94b0d299382c74 (patch) | |
tree | f6c7f1d8d7906ab6f962ce0660248f0ebf94ba75 /server | |
parent | cf97b3bf418d73894bb7849b6c02e40c753425bb (diff) | |
download | lua-language-server-e683d90bdb40ed07ad3f1b53ca94b0d299382c74.zip |
emmyTableType
Diffstat (limited to 'server')
-rw-r--r-- | server/src/core/hover/hover.lua | 41 | ||||
-rw-r--r-- | server/src/emmy/manager.lua | 6 | ||||
-rw-r--r-- | server/src/emmy/tableType.lua | 40 | ||||
-rw-r--r-- | server/src/parser/ast.lua | 13 | ||||
-rw-r--r-- | server/src/parser/grammar.lua | 2 | ||||
-rw-r--r-- | server/src/vm/emmy.lua | 15 | ||||
-rw-r--r-- | server/src/vm/ipairs.lua | 7 | ||||
-rw-r--r-- | server/src/vm/local.lua | 1 | ||||
-rw-r--r-- | server/src/vm/value.lua | 10 | ||||
-rw-r--r-- | server/test/hover/init.lua | 49 |
10 files changed, 159 insertions, 25 deletions
diff --git a/server/src/core/hover/hover.lua b/server/src/core/hover/hover.lua index 12d6fbe5..c0f62f24 100644 --- a/server/src/core/hover/hover.lua +++ b/server/src/core/hover/hover.lua @@ -71,23 +71,28 @@ local function findClass(value) end) end +local function formatKey(key) + local kType = type(key) + if kType == 'table' then + key = ('[*%s]'):format(key:getType()) + elseif math.type(key) == 'integer' then + key = ('[%03d]'):format(key) + elseif kType == 'string' then + if key:find '^%d' or key:find '[^%w_]' then + key = ('[%q]'):format(key) + end + elseif key == '' then + key = '[*any]' + else + key = ('[%s]'):format(key) + end + return key +end + local function unpackTable(value) local lines = {} value:eachChild(function (key, child) - local kType = type(key) - if kType == 'table' then - key = ('[*%s]'):format(key:getType()) - elseif math.type(key) == 'integer' then - key = ('[%03d]'):format(key) - elseif kType == 'string' then - if key:find '^%d' or key:find '[^%w_]' then - key = ('[%q]'):format(key) - end - elseif key == '' then - key = '[*any]' - else - key = ('[%s]'):format(key) - end + key = formatKey(key) local vType = type(child:getLiteral()) if vType == 'boolean' @@ -101,8 +106,12 @@ local function unpackTable(value) end end) local emmy = value:getEmmy() - if emmy and emmy.type == 'emmy.arrayType' then - lines[#lines+1] = ('[*integer]: %s'):format(emmy:getName()) + if emmy then + if emmy.type == 'emmy.arrayType' then + lines[#lines+1] = ('[*integer]: %s'):format(emmy:getName()) + elseif emmy.type == 'emmy.tableType' then + lines[#lines+1] = ('[*%s]: %s'):format(emmy:getKeyType():getType(), emmy:getValueType():getType()) + end end if #lines == 0 then return '{}' diff --git a/server/src/emmy/manager.lua b/server/src/emmy/manager.lua index 45fc1c3d..dad456a8 100644 --- a/server/src/emmy/manager.lua +++ b/server/src/emmy/manager.lua @@ -8,6 +8,7 @@ local newReturn = require 'emmy.return' local newField = require 'emmy.field' local newGeneric = require 'emmy.generic' local newArrayType = require 'emmy.arrayType' +local newTableType = require 'emmy.tableType' local mt = {} mt.__index = mt @@ -110,6 +111,11 @@ function mt:addArrayType(source) return typeObj end +function mt:addTableType(source, keyType, valueType) + local typeObj = newTableType(self, source, keyType, valueType) + return typeObj +end + function mt:addAlias(source, typeObj) local aliasName = source[1][1] local aliasObj = newAlias(self, source) diff --git a/server/src/emmy/tableType.lua b/server/src/emmy/tableType.lua new file mode 100644 index 00000000..3882cd61 --- /dev/null +++ b/server/src/emmy/tableType.lua @@ -0,0 +1,40 @@ +local listMgr = require 'vm.list' + +---@class EmmyTableType +local mt = {} +mt.__index = mt +mt.type = 'emmy.tableType' + +function mt:getType() + return 'table' +end + +function mt:getKeyType() + return self.keyType +end + +function mt:getValueType() + return self.valueType +end + +function mt:getSource() + return listMgr.get(self.source) +end + +function mt:setValue(value) + self.value = value +end + +function mt:getValue() + return self.value +end + +return function (manager, source, keyType, valueType) + local self = setmetatable({ + source = source.id, + keyType = keyType, + valueType = valueType, + _manager = manager, + }, mt) + return self +end diff --git a/server/src/parser/ast.lua b/server/src/parser/ast.lua index 72c441ca..bf8f5dab 100644 --- a/server/src/parser/ast.lua +++ b/server/src/parser/ast.lua @@ -1168,11 +1168,14 @@ local Defs = { typeName.type = 'emmyArrayType' return typeName end, - EmmyTableType = function (typeName, keyType, valueType) - typeName.type = 'emmyTableType' - typeName[2] = keyType - typeName[3] = valueType - return typeName + EmmyTableType = function (start, keyType, valueType, finish) + return { + type = 'emmyTableType', + start = start, + finish = finish - 1, + [1] = keyType, + [2] = valueType, + } end, EmmyFunctionType = function (...) local result = { diff --git a/server/src/parser/grammar.lua b/server/src/parser/grammar.lua index 2cbc6d34..28e3eb28 100644 --- a/server/src/parser/grammar.lua +++ b/server/src/parser/grammar.lua @@ -577,7 +577,7 @@ EmmyLanguage <- MustEmmyName EmmyArrayType <- (MustEmmyName '[]') -> EmmyArrayType -EmmyTableType <- (MustEmmyName '<' %s* EmmyType %s* ',' %s* EmmyType %s* '>') +EmmyTableType <- ({} 'table' Cut '<' %s* EmmyType %s* ',' %s* EmmyType %s* '>' {}) -> EmmyTableType EmmyFunctionType<- ('fun' Cut %s* EmmyFunctionArgs? %s* EmmyFunctionRtn?) diff --git a/server/src/vm/emmy.lua b/server/src/vm/emmy.lua index cf6d7026..a66738e5 100644 --- a/server/src/vm/emmy.lua +++ b/server/src/vm/emmy.lua @@ -29,6 +29,7 @@ function mt:doEmmy(action) elseif tp == 'emmyArrayType' then self:doEmmyArrayType(action) elseif tp == 'emmyTableType' then + self:doEmmyTableType(action) elseif tp == 'emmyFunctionType' then elseif tp == 'emmySee' then elseif tp == 'emmyIncomplete' then @@ -237,6 +238,20 @@ function mt:doEmmyArrayType(action) return type end +function mt:doEmmyTableType(action) + ---@type emmyMgr + local emmyMgr = self.emmyMgr + self:instantSource(action) + local keyType = self:buildEmmyType(action[1]) + local valueType = self:buildEmmyType(action[2]) + local type = emmyMgr:addTableType(action, keyType, valueType) + 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 index e27b8584..b8d821ef 100644 --- a/server/src/vm/ipairs.lua +++ b/server/src/vm/ipairs.lua @@ -33,10 +33,15 @@ function mt:callNext(func, values, source) local emmy = tbl:getEmmy() if emmy then if emmy.type == 'emmy.arrayType' then - local key = self:createValue('integer', self:getDefaultSource()) + local key = self:createValue('integer', source) local value = self:createValue(emmy:getName(), source) func:setReturn(1, key) func:setReturn(2, value) + elseif emmy.type == 'emmy.tableType' then + local key = self:createValue(emmy:getKeyType():getType(), source) + local value = self:createValue(emmy:getValueType():getType(), source) + func:setReturn(1, key) + func:setReturn(2, value) end end end diff --git a/server/src/vm/local.lua b/server/src/vm/local.lua index ad7d80e8..ce47414a 100644 --- a/server/src/vm/local.lua +++ b/server/src/vm/local.lua @@ -143,6 +143,7 @@ function mt:setEmmy(emmy) if emmy.type ~= 'emmy.class' and emmy.type ~= 'emmy.type' and emmy.type ~= 'emmy.arrayType' + and emmy.type ~= 'emmy.tableType' then return end diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua index d974cec0..6cfaec4b 100644 --- a/server/src/vm/value.lua +++ b/server/src/vm/value.lua @@ -190,6 +190,8 @@ function mt:getChild(index, source) if type(index) == 'number' then value = create(emmy:getName(), source) end + elseif emmy.type == 'emmy.tableType' then + value = create(emmy:getValueType():getType(), source) end end if not value then @@ -587,8 +589,12 @@ function mt:setEmmy(emmy) end) elseif emmy.type == 'emmy.arrayType' then ---@type EmmyArrayType - local EmmyArrayType = emmy - EmmyArrayType:setValue(self) + local emmyArrayType = emmy + emmyArrayType:setValue(self) + elseif emmy.type == 'emmy.tableType' then + ---@type EmmyTableType + local emmyTableType = emmy + emmyTableType:setValue(self) else return end diff --git a/server/test/hover/init.lua b/server/test/hover/init.lua index 485b68a7..685ee507 100644 --- a/server/test/hover/init.lua +++ b/server/test/hover/init.lua @@ -691,3 +691,52 @@ end [[ local k: integer ]] + +TEST [[ +---@type table<ClassA, ClassB> +local <?x?> +]] +[[ +local x: { + [*ClassA]: ClassB, +} +]] + +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 +]] |