summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorsumneko <sumneko@hotmail.com>2019-04-28 20:09:43 +0800
committersumneko <sumneko@hotmail.com>2019-04-28 20:09:43 +0800
commit0bc67627a4409a08e34be0b44cba928cdacf8192 (patch)
treea78bf45ded637b3a6424653745895b6c327cb578 /server
parentb4ed749782ba58140c8d7878e4b27ec6b3d2fffb (diff)
downloadlua-language-server-0bc67627a4409a08e34be0b44cba928cdacf8192.zip
emmy.field
Diffstat (limited to 'server')
-rw-r--r--server/src/emmy/class.lua17
-rw-r--r--server/src/emmy/field.lua40
-rw-r--r--server/src/emmy/manager.lua8
-rw-r--r--server/src/vm/emmy.lua36
-rw-r--r--server/src/vm/value.lua5
-rw-r--r--server/test/completion/init.lua18
-rw-r--r--server/test/definition/emmy.lua8
7 files changed, 126 insertions, 6 deletions
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 <!Class!>
---@param a <?Class?>
]]
+
+TEST [[
+---@class Class
+---@field <!name!> string
+---@field id integer
+local mt = {}
+mt.<?name?>
+]]