summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorsumneko <sumneko@hotmail.com>2019-04-18 11:42:45 +0800
committersumneko <sumneko@hotmail.com>2019-04-18 11:42:45 +0800
commit04c3ce15f1515b11e43e4630888e323c6372b409 (patch)
treecfd2659fdaac0499416f8bf1406641f35edd6cb2 /server
parent1c0416baecc6db9720beb18d5abfc3b7ef33ffbe (diff)
downloadlua-language-server-04c3ce15f1515b11e43e4630888e323c6372b409.zip
emmy.class
Diffstat (limited to 'server')
-rw-r--r--server/src/emmy/class.lua16
-rw-r--r--server/src/emmy/init.lua1
-rw-r--r--server/src/emmy/manager.lua62
-rw-r--r--server/src/service.lua6
-rw-r--r--server/src/vm/emmy.lua16
-rw-r--r--server/src/vm/local.lua16
-rw-r--r--server/src/vm/value.lua25
-rw-r--r--server/src/vm/vm.lua36
8 files changed, 170 insertions, 8 deletions
diff --git a/server/src/emmy/class.lua b/server/src/emmy/class.lua
new file mode 100644
index 00000000..69d731ee
--- /dev/null
+++ b/server/src/emmy/class.lua
@@ -0,0 +1,16 @@
+local mt = {}
+mt.__index = mt
+mt.type = 'emmy.class'
+
+function mt:getType()
+ return self._name
+end
+
+return function (class, parent)
+ local self = setmetatable({
+ name = class[1],
+ source = class.id,
+ parent = parent and parent.id,
+ })
+ return self
+end
diff --git a/server/src/emmy/init.lua b/server/src/emmy/init.lua
new file mode 100644
index 00000000..769c9e05
--- /dev/null
+++ b/server/src/emmy/init.lua
@@ -0,0 +1 @@
+return require 'vm.emmy.emmy'
diff --git a/server/src/emmy/manager.lua b/server/src/emmy/manager.lua
new file mode 100644
index 00000000..5f83c9d1
--- /dev/null
+++ b/server/src/emmy/manager.lua
@@ -0,0 +1,62 @@
+local listMgr = require 'vm.list'
+local newClass = require 'emmy.class'
+
+local mt = {}
+mt.__index = mt
+mt.__name = 'emmyMgr'
+
+function mt:flushClass(name)
+ local list = self._class[name]
+ if not list then
+ return
+ end
+ local version = listMgr.getVersion()
+ if version == list.version then
+ return
+ end
+ for srcId in pairs(list) do
+ if not listMgr.get(srcId) then
+ list[srcId] = nil
+ end
+ end
+ if not next(list) then
+ self._class[name] = nil
+ return
+ end
+ list.version = version
+end
+
+function mt:eachClass(name, callback)
+ self:flushClass(name)
+ local list = self._class[name]
+ if not list then
+ return
+ end
+ for _, class in pairs(list) do
+ callback(class)
+ end
+end
+
+function mt:addClass(class, parent)
+ local className = class[1]
+ local list = self._class[className]
+ local version = listMgr.getVersion()
+ if not list then
+ list = {
+ version = version,
+ }
+ self._class[className] = list
+ end
+ list[class.id] = newClass(class, parent)
+ self:flushClass(className)
+end
+
+function mt:remove()
+end
+
+return function ()
+ local self = setmetatable({
+ _class = {},
+ }, mt)
+ return self
+end
diff --git a/server/src/service.lua b/server/src/service.lua
index 0a1b27aa..ea3c4488 100644
--- a/server/src/service.lua
+++ b/server/src/service.lua
@@ -14,6 +14,7 @@ local valueMgr = require 'vm.value'
local chainMgr = require 'vm.chain'
local functionMgr= require 'vm.function'
local listMgr = require 'vm.list'
+local emmyMgr = require 'emmy.manager'
local config = require 'config'
local ErrorCodes = {
@@ -270,6 +271,9 @@ function mt:reCompile()
if self.chain then
self.chain:remove()
end
+ if self.emmy then
+ self.emmy:remove()
+ end
for _, obj in pairs(listMgr.list) do
if obj.type == 'source' or obj.type == 'function' then
@@ -279,6 +283,7 @@ function mt:reCompile()
self.global = core.global(self)
self.chain = chainMgr()
+ self.emmy = emmyMgr()
self.globalValue = nil
self._needCompile = {}
@@ -859,5 +864,6 @@ return function ()
}, mt)
session.global = core.global(session)
session.chain = chainMgr()
+ session.emmy = emmyMgr()
return session
end
diff --git a/server/src/vm/emmy.lua b/server/src/vm/emmy.lua
new file mode 100644
index 00000000..a9899477
--- /dev/null
+++ b/server/src/vm/emmy.lua
@@ -0,0 +1,16 @@
+local mt = require 'vm.manager'
+
+function mt:doEmmyClass(action)
+ if not self.lsp then
+ return
+ end
+ local emmyMgr = self.lsp.emmyMgr
+ local class = action[1]
+ local parent = action[2]
+ self:instantSource(class)
+ if parent then
+ self:instantSource(parent)
+ end
+ local emmyClass = emmyMgr:addClass(class, parent)
+ self.emmy = emmyClass
+end
diff --git a/server/src/vm/local.lua b/server/src/vm/local.lua
index 0da5112f..e75ed149 100644
--- a/server/src/vm/local.lua
+++ b/server/src/vm/local.lua
@@ -19,6 +19,9 @@ function mt:setValue(value)
else
self.value = value
end
+ if self._emmy then
+ self.value:setEmmy(self._emmy)
+ end
return value
end
@@ -126,6 +129,19 @@ function mt:getSource()
return listMgr.get(self.source)
end
+function mt:setEmmy(emmy)
+ if not emmy then
+ return
+ end
+ if emmy.type ~= 'emmy.class' and emmy.type ~= 'emmy.type' then
+ return
+ end
+ self._emmy = emmy
+ if self.value then
+ self.value:setEmmy(emmy)
+ end
+end
+
local function create(name, source, value)
if not value then
error('Local must has a value')
diff --git a/server/src/vm/value.lua b/server/src/vm/value.lua
index 2a1c14d1..3b3a8c01 100644
--- a/server/src/vm/value.lua
+++ b/server/src/vm/value.lua
@@ -76,6 +76,9 @@ function mt:setType(tp, rate)
end
function mt:getType()
+ if self:getEmmy() then
+ return self:getEmmy():getType()
+ end
if not self._type then
return 'nil'
end
@@ -515,6 +518,28 @@ function mt:isGlobal()
return self._global
end
+function mt:setEmmy(emmy)
+ if not emmy then
+ return
+ end
+ if emmy.type ~= 'emmy.class' and emmy.type ~= 'emmy.type' then
+ return
+ end
+ self._emmy = emmy
+end
+
+function mt:getEmmy()
+ if not self._emmy then
+ return nil
+ end
+ local source = self._emmy.source
+ if not listMgr.get(source) then
+ self._emmy = nil
+ return nil
+ end
+ return self._emmy
+end
+
return {
create = create,
watch = Watch,
diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua
index ead87fda..3bacfc6c 100644
--- a/server/src/vm/vm.lua
+++ b/server/src/vm/vm.lua
@@ -13,6 +13,7 @@ local mt = require 'vm.manager'
require 'vm.module'
require 'vm.raw'
require 'vm.pcall'
+require 'vm.emmy'
-- TODO source测试
--rawset(_G, 'CachedSource', setmetatable({}, { __mode = 'kv' }))
@@ -849,6 +850,7 @@ function mt:doLocal(action)
end
self:createLocal(key[1], key, value)
end)
+ self.emmy = nil
end
function mt:doIf(action)
@@ -1036,6 +1038,20 @@ function mt:doAction(action)
self:doFunction(action)
elseif tp == 'localfunction' then
self:doLocalFunction(action)
+ elseif tp == 'emmyClass' then
+ self:doEmmyClass(action)
+ elseif tp == 'emmyType' then
+ elseif tp == 'emmyAlias' then
+ elseif tp == 'emmyParam' then
+ elseif tp == 'emmyReturn' then
+ elseif tp == 'emmyField' then
+ elseif tp == 'emmyGeneric' then
+ elseif tp == 'emmyVararg' then
+ elseif tp == 'emmyLanguage' then
+ elseif tp == 'emmyArrayType' then
+ elseif tp == 'emmyTableType' then
+ elseif tp == 'emmyFunctionType' then
+ elseif tp == 'emmySee' then
else
self:getExp(action)
action:set('as action', true)
@@ -1143,16 +1159,18 @@ end
function mt:createLocal(key, source, value)
local loc = self:bindLocal(source)
+ if not value then
+ value = self:createValue('nil', source)
+ end
if loc then
+ loc:setValue(value)
+ loc:setEmmy(self.emmy)
self:saveLocal(key, loc)
return loc
end
- if not value then
- value = self:createValue('nil', source)
- end
-
loc = localMgr.create(key, source, value)
+ loc:setEmmy(self.emmy)
self:saveLocal(key, loc)
self:bindLocal(source, loc, 'local')
value:addInfo('local', source)
@@ -1161,13 +1179,14 @@ end
function mt:createUpvalue(key, source, value)
local loc = self:bindLocal(source)
- if loc then
- return loc
- end
-
if not value then
value = self:createValue('nil', source)
end
+ if loc then
+ loc:setValue(value)
+ self:saveUpvalue(key, loc)
+ return loc
+ end
loc = localMgr.create(key, source, value)
self:saveUpvalue(key, loc)
@@ -1257,6 +1276,7 @@ return function (ast, lsp, uri)
sources = {},
main = nil,
env = nil,
+ emmy = nil,
lsp = lsp,
uri = uri or '',
}, mt)