summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/core/global.lua61
-rw-r--r--server/src/core/init.lua1
-rw-r--r--server/src/core/vm.lua14
-rw-r--r--server/src/service.lua20
4 files changed, 93 insertions, 3 deletions
diff --git a/server/src/core/global.lua b/server/src/core/global.lua
new file mode 100644
index 00000000..8aa801de
--- /dev/null
+++ b/server/src/core/global.lua
@@ -0,0 +1,61 @@
+local mt = {}
+mt.__index = mt
+
+function mt:clearGlobal(uri)
+ self.get[uri] = nil
+ self.set[uri] = nil
+end
+
+function mt:markSet(uri, k, v)
+ local sets = self.set[uri]
+ if not sets then
+ sets = {}
+ self.set[uri] = sets
+ end
+ sets[k] = v
+end
+
+function mt:markGet(uri, k)
+ local gets = self.get[uri]
+ if not gets then
+ gets = {}
+ self.get[uri] = gets
+ end
+ gets[k] = true
+end
+
+function mt:compileVM(uri, vm)
+ self:clearGlobal(uri)
+ for k, v in next, vm.env.child do
+ local get, set
+ for _, info in ipairs(v) do
+ if info.type == 'get' then
+ get = true
+ elseif info.type == 'set' then
+ set = true
+ end
+ end
+ if set then
+ self:markSet(uri, k, v)
+ elseif get then
+ self:markGet(uri, k)
+ end
+ end
+end
+
+function mt:getGlobal(key)
+ for _, sets in pairs(self.set) do
+ local v = sets[key]
+ if v ~= nil then
+ return v
+ end
+ end
+ return nil
+end
+
+return function ()
+ return setmetatable({
+ get = {},
+ set = {},
+ }, mt)
+end
diff --git a/server/src/core/init.lua b/server/src/core/init.lua
index 31a7c1b1..68898814 100644
--- a/server/src/core/init.lua
+++ b/server/src/core/init.lua
@@ -10,6 +10,7 @@ local api = {
completion = require 'core.completion',
signature = require 'core.signature',
documentSymbol = require 'core.document_symbol',
+ global = require 'core.global',
vm = require 'core.vm',
}
diff --git a/server/src/core/vm.lua b/server/src/core/vm.lua
index 99e92fe5..b69d928d 100644
--- a/server/src/core/vm.lua
+++ b/server/src/core/vm.lua
@@ -377,8 +377,17 @@ end
function mt:getField(pValue, name, source)
local field = (pValue.child and pValue.child[name])
- or self:createField(pValue, name, source)
-
+ if not field and pValue.ENV then
+ if self.lsp then
+ local g = self.lsp:getGlobal(name)
+ if g then
+ field = readOnly(g)
+ end
+ end
+ end
+ if not field then
+ field = self:createField(pValue, name, source)
+ end
return field
end
@@ -1471,6 +1480,7 @@ function mt:createEnvironment()
local g = self:getField(envValue, '_G')
local gValue = self:getValue(g)
gValue.child = envValue.child
+ self.env = envValue
end
local function compile(ast, lsp, uri)
diff --git a/server/src/service.lua b/server/src/service.lua
index 1d15fb0a..f15c351e 100644
--- a/server/src/service.lua
+++ b/server/src/service.lua
@@ -4,7 +4,7 @@ local thread = require 'bee.thread'
local async = require 'async'
local rpc = require 'rpc'
local parser = require 'parser'
-local core = require 'core'
+local core = require 'core'
local lang = require 'language'
local ErrorCodes = {
@@ -121,6 +121,7 @@ function mt:saveText(uri, version, text)
self._file[uri] = {
version = version,
text = text,
+ uri = uri,
}
self:needCompile(uri)
end
@@ -171,6 +172,8 @@ function mt:removeText(uri)
self._file[uri] = nil
-- 删除文件后,清除该文件的诊断
self:clearDiagnostics(uri)
+ -- 清除全局变量
+ self._global:clearGlobal(uri)
end
function mt:reCompile()
@@ -259,6 +262,19 @@ function mt:_compileChain(obj, compiled)
end
end
+function mt:_compileGlobal(obj, compiled)
+ self._global:compileVM(obj.uri, obj.vm)
+end
+
+function mt:getGlobal(key)
+ local tp = type(key)
+ if tp == 'string' or tp == 'number' or tp == 'boolean' then
+ return self._global:getGlobal(key)
+ else
+ return nil
+ end
+end
+
function mt:compileVM(uri)
local obj = self._file[uri]
if not obj then
@@ -289,6 +305,7 @@ function mt:compileVM(uri)
end
self:_compileChain(obj, compiled)
+ self:_compileGlobal(obj, compiled)
return obj
end
@@ -474,6 +491,7 @@ return function ()
_needDiagnostics = {},
_clock = -100,
_version = 0,
+ _global = core.global(),
}, mt)
return session
end