From 0bc67627a4409a08e34be0b44cba928cdacf8192 Mon Sep 17 00:00:00 2001 From: sumneko Date: Sun, 28 Apr 2019 20:09:43 +0800 Subject: emmy.field --- server/src/emmy/class.lua | 17 +++++++++++++++++ server/src/emmy/field.lua | 40 ++++++++++++++++++++++++++++++++++++++++ server/src/emmy/manager.lua | 8 ++++++++ server/src/vm/emmy.lua | 36 ++++++++++++++++++++++++++++++------ server/src/vm/value.lua | 5 +++++ server/test/completion/init.lua | 18 ++++++++++++++++++ server/test/definition/emmy.lua | 8 ++++++++ 7 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 server/src/emmy/field.lua (limited to 'server') diff --git a/server/src/emmy/class.lua b/server/src/emmy/class.lua index 84854fc5..a7417210 100644 --- a/server/src/emmy/class.lua +++ b/server/src/emmy/class.lua @@ -33,6 +33,23 @@ function mt:eachChild(callback) end) end +function mt:addField(field) + if not self._fields then + self._fields = {} + end + self._fields[#self._fields+1] = field +end + +function mt:eachField(callback) + if not self._fields then + return + end + ---@param field EmmyField + for _, field in ipairs(self._fields) do + callback(field) + end +end + return function (manager, source) local self = setmetatable({ name = source[1][1], diff --git a/server/src/emmy/field.lua b/server/src/emmy/field.lua new file mode 100644 index 00000000..d7dfbe98 --- /dev/null +++ b/server/src/emmy/field.lua @@ -0,0 +1,40 @@ +local listMgr = require 'vm.list' + +---@class EmmyField +local mt = {} +mt.__index = mt +mt.type = 'emmy.field' + +function mt:getName() + return self.name +end + +function mt:getSource() + return listMgr.get(self.source) +end + +function mt:bindType(type) + if type then + self._bindType = type + else + return self._bindType + end +end + +function mt:bindValue(value) + if value then + self._bindValue = value + else + return self._bindValue + end +end + +return function (manager, source) + local self = setmetatable({ + name = source[2][1], + source = source.id, + visible = source[1], + _manager = manager, + }, mt) + return self +end diff --git a/server/src/emmy/manager.lua b/server/src/emmy/manager.lua index e0b60304..7875e322 100644 --- a/server/src/emmy/manager.lua +++ b/server/src/emmy/manager.lua @@ -5,6 +5,7 @@ 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 mt = {} mt.__index = mt @@ -118,6 +119,13 @@ function mt:addReturn(source, typeObj) return returnObj end +function mt:addField(source, typeObj, value) + local fieldObj = newField(self, source) + fieldObj:bindType(typeObj) + fieldObj:bindValue(value) + return fieldObj +end + function mt:remove() end diff --git a/server/src/vm/emmy.lua b/server/src/vm/emmy.lua index 34312831..6c93a116 100644 --- a/server/src/vm/emmy.lua +++ b/server/src/vm/emmy.lua @@ -19,6 +19,7 @@ function mt:doEmmy(action) elseif tp == 'emmyReturn' then self:doEmmyReturn(action) elseif tp == 'emmyField' then + self:doEmmyField(action) elseif tp == 'emmyGeneric' then elseif tp == 'emmyVararg' then elseif tp == 'emmyLanguage' then @@ -83,7 +84,7 @@ function mt:doEmmyClass(action) end end -function mt:doEmmyType(action) +function mt:buildEmmyType(action) ---@type emmyMgr local emmyMgr = self.emmyMgr self:instantSource(action) @@ -92,6 +93,11 @@ function mt:doEmmyType(action) obj:set('emmy class', obj[1]) end local type = emmyMgr:addType(action) + return type +end + +function mt:doEmmyType(action) + local type = self:buildEmmyType(action) self._emmy = type if self.lsp then self.lsp.global:markGet(self:getUri()) @@ -104,10 +110,11 @@ function mt:doEmmyAlias(action) local emmyMgr = self.emmyMgr self:instantSource(action) self:instantSource(action[1]) - local type = self:doEmmyType(action[2]) + local type = self:buildEmmyType(action[2]) local alias = emmyMgr:addAlias(action, type) action:set('emmy.alias', alias) action[1]:set('emmy class', alias:getName()) + self._emmy = type if self.lsp then self.lsp.global:markSet(self:getUri()) end @@ -118,10 +125,9 @@ function mt:doEmmyParam(action) local emmyMgr = self.emmyMgr self:instantSource(action) self:instantSource(action[1]) - local type = self:doEmmyType(action[2]) + local type = self:buildEmmyType(action[2]) local param = emmyMgr:addParam(action, type) action:set('emmy.param', param) - self._emmy = nil self:addEmmyParam(param) end @@ -129,13 +135,31 @@ function mt:doEmmyReturn(action) ---@type emmyMgr local emmyMgr = self.emmyMgr self:instantSource(action) - local type = self:doEmmyType(action[1]) + local type = self:buildEmmyType(action[1]) local rtn = emmyMgr:addReturn(action, type) action:set('emmy.return', rtn) - self._emmy = nil self:addEmmyReturn(rtn) end +function mt:doEmmyField(action) + ---@type emmyMgr + local emmyMgr = self.emmyMgr + self:instantSource(action) + self:instantSource(action[2]) + local type = self:buildEmmyType(action[3]) + local value = self:createValue('nil', action[2]) + local field = emmyMgr:addField(action, type, value) + value:setEmmy(type) + action:set('emmy.field', field) + + local class = self._emmy + if not self._emmy or self._emmy.type ~= 'emmy.class' then + return + end + class:addField(field) + action:set('target class', class) +end + function mt:doEmmyIncomplete(action) self:instantSource(action) end diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua index 9f9b6b7c..e924f642 100644 --- a/server/src/vm/value.lua +++ b/server/src/vm/value.lua @@ -546,6 +546,11 @@ function mt:setEmmy(emmy) value:mergeValue(self) end end) + emmyClass:eachField(function (field) + local name = field:getName() + local value = field:bindValue() + self:setChild(name, value, field:getSource()[2]) + end) elseif emmy.type == 'emmy.type' then ---@type EmmyType local emmyType = emmy diff --git a/server/test/completion/init.lua b/server/test/completion/init.lua index 9d8477f7..7d0d1d04 100644 --- a/server/test/completion/init.lua +++ b/server/test/completion/init.lua @@ -1010,3 +1010,21 @@ end kind = CompletionItemKind.Keyword, } } + +TEST [[ +---@class Class +---@field name string +---@field id integer +local mt = {} +mt.$ +]] +{ + { + label = 'id', + kind = CompletionItemKind.Field, + }, + { + label = 'name', + kind = CompletionItemKind.Field, + }, +} diff --git a/server/test/definition/emmy.lua b/server/test/definition/emmy.lua index 7b5110c7..937f1d70 100644 --- a/server/test/definition/emmy.lua +++ b/server/test/definition/emmy.lua @@ -71,3 +71,11 @@ TEST [[ ---@class ---@param a ]] + +TEST [[ +---@class Class +---@field string +---@field id integer +local mt = {} +mt. +]] -- cgit v1.2.3