summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-01-29 11:26:20 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-01-29 11:26:20 +0800
commit0e99f6a8116f3cfb9e49cea1758d03b541024ff4 (patch)
tree9955f5e033d3e0c95cdfbb71b9aa10d9237dfae2
parent2490ce5d8b5770370fb31619a8151b0211320385 (diff)
downloadlua-language-server-0e99f6a8116f3cfb9e49cea1758d03b541024ff4.zip
全局变量
-rw-r--r--server/src/core/global.lua77
-rw-r--r--server/src/core/value.lua12
-rw-r--r--server/src/core/vm.lua62
-rw-r--r--server/src/service.lua27
-rw-r--r--server/test/crossfile/definition.lua2
5 files changed, 100 insertions, 80 deletions
diff --git a/server/src/core/global.lua b/server/src/core/global.lua
index 655bc1c4..ac1170a7 100644
--- a/server/src/core/global.lua
+++ b/server/src/core/global.lua
@@ -1,71 +1,50 @@
local mt = {}
mt.__index = mt
-function mt:clearGlobal(uri)
- self.get[uri] = nil
- self.set[uri] = nil
+function mt:compileVM(uri)
+ if not self.set[uri] and not self.get[uri] then
+ return
+ end
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
+function mt:markSet(uri)
+ self.set[uri] = true
end
-function mt:markGet(uri, k)
- local gets = self.get[uri]
- if not gets then
- gets = {}
- self.get[uri] = gets
- end
- gets[k] = true
+function mt:markGet(uri)
+ self.get[uri] = true
end
-function mt:compileVM(uri, vm)
- local seted = {}
- local fixed = {}
- for _, data in ipairs(vm.results.globals) do
- local key = data.global.key
- fixed[key] = true
- if data.type == 'global' then
- seted[key] = true
- self:markSet(uri, key, data.global)
- end
- end
- for k in next, vm.env.child do
- self:markGet(uri, k)
+function mt:clearGlobal(uri)
+ self.get[uri] = nil
+ if not self.set[uri] then
+ return
end
-
- local needReCompile = {}
- for otherUri, gets in pairs(self.get) do
- for key in pairs(fixed) do
- if gets[key] ~= nil then
- needReCompile[#needReCompile+1] = otherUri
- goto CONTINUE
- end
- end
- ::CONTINUE::
+ self.set[uri] = nil
+ local globalValue = self.lsp.globalValue
+ if not globalValue then
+ return
end
-
- return needReCompile
+ globalValue:removeUri(uri)
end
-function mt:getGlobal(key)
- for _, sets in pairs(self.set) do
- local v = sets[key]
- if v ~= nil then
- return v
+function mt:getAllUris()
+ local uris = {}
+ for uri in pairs(self.set) do
+ uris[#uris+1] = uri
+ end
+ for uri in pairs(self.get) do
+ if not self.set[uri] then
+ uris[#uris+1] = uri
end
end
- return nil
+ return uris
end
-return function ()
+return function (lsp)
return setmetatable({
get = {},
set = {},
+ lsp = lsp,
}, mt)
end
diff --git a/server/src/core/value.lua b/server/src/core/value.lua
index 1d8ed567..adc92ddd 100644
--- a/server/src/core/value.lua
+++ b/server/src/core/value.lua
@@ -163,6 +163,18 @@ function mt:eachField(callback)
return nil
end
+function mt:removeUri(uri)
+ if not self._child then
+ return
+ end
+ self._child[uri] = nil
+ self:eachField(function (field)
+ if field.value then
+ field.value:removeUri(uri)
+ end
+ end)
+end
+
function mt:getDeclarat()
local declarat = self:eachInfo(function (info)
if info.type == 'local' then
diff --git a/server/src/core/vm.lua b/server/src/core/vm.lua
index 69aa4a43..11461c31 100644
--- a/server/src/core/vm.lua
+++ b/server/src/core/vm.lua
@@ -710,9 +710,47 @@ function mt:getName(name, source)
source.uri = self.uri
local ENV = self.scope.locals._ENV
local ENVValue = self:getValue(ENV)
- local global = ENVValue:getField(name, source) or ENVValue:createField(name, source)
- global.parent = ENV
- return global
+ local global = ENVValue:getField(name, source)
+ if global then
+ global.parent = ENV
+ if self.lsp and self:isGlobal(global) then
+ self.lsp.global:markGet(self.uri)
+ end
+ return global
+ else
+ global = ENVValue:createField(name, source)
+ global.parent = ENV
+ if self.lsp and self:isGlobal(global) then
+ self.lsp.global:markGet(self.uri)
+ end
+ return global
+ end
+end
+
+function mt:setName(name, source, value)
+ source.uri = self.uri
+ local loc = self.scope.locals[name]
+ if loc then
+ self:setValue(loc, value, source)
+ return
+ end
+ local ENV = self.scope.locals._ENV
+ local ENVValue = self:getValue(ENV)
+ local global = ENVValue:getField(name, source)
+ if global then
+ global.parent = ENV
+ if self.lsp and self:isGlobal(global) then
+ self.lsp.global:markSet(self.uri)
+ end
+ self:setValue(global, value, source)
+ else
+ global = ENVValue:createField(name, source)
+ global.parent = ENV
+ if self.lsp and self:isGlobal(global) then
+ self.lsp.global:markSet(self.uri)
+ end
+ self:setValue(global, value, source)
+ end
end
function mt:getIndex(obj)
@@ -1144,24 +1182,17 @@ function mt:doSet(action)
self:forList(action[1], function (key)
local value = table.remove(values, 1)
if key.type == 'name' then
- local var = self:getName(key[1], key)
- self:setValue(var, value, key)
- if self:isGlobal(var) then
- self.results.globals[#self.results.globals+1] = {
- type = 'global',
- global = var,
- }
- end
+ self:setName(key[1], key, value)
elseif key.type == 'simple' then
local field = self:getSimple(key, 'field')
self:setValue(field, value, key[#key])
+ if not self.lsp then
+ return
+ end
local var = field
repeat
if self:isGlobal(var) then
- self.results.globals[#self.results.globals+1] = {
- type = 'field',
- global = var,
- }
+ self.lsp.global:markSet(self.uri)
break
end
var = var.parent
@@ -1389,7 +1420,6 @@ local function compile(ast, lsp, uri)
sources= {},
strings= {},
indexs = {},
- globals= {},
main = nil,
},
lsp = lsp,
diff --git a/server/src/service.lua b/server/src/service.lua
index f1110a23..d218f3f8 100644
--- a/server/src/service.lua
+++ b/server/src/service.lua
@@ -279,19 +279,18 @@ function mt:_compileChain(obj, compiled)
end
end
-function mt:_compileGlobal(obj, compiled)
- local needReCompile = self._global:compileVM(obj.uri, obj.vm)
- for _, uri in ipairs(needReCompile) do
+function mt:_compileGlobal(compiled)
+ local uris = self.global:getAllUris()
+ for _, uri in ipairs(uris) do
self:needCompile(uri, compiled)
end
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
+function mt:_clearGlobal(uri, compiled)
+ self.global:clearGlobal(uri)
+ local uris = self.global:getAllUris()
+ for _, uri in ipairs(uris) do
+ self:needCompile(uri, compiled)
end
end
@@ -300,7 +299,8 @@ function mt:compileVM(uri)
if not obj then
return nil
end
- if not self._needCompile[uri] then
+ local compiled = self._needCompile[uri]
+ if not compiled then
return nil
end
@@ -309,11 +309,10 @@ function mt:compileVM(uri)
local version = obj.version
obj.astCost = os.clock() - clock
self:_clearChainNode(obj, uri)
- --self._global:clearGlobal(uri)
+ self:_clearGlobal(uri, compiled)
local clock = os.clock()
local vm = core.vm(ast, self, uri)
- local compiled
if version ~= obj.version then
return nil
end
@@ -337,7 +336,7 @@ function mt:compileVM(uri)
end
self:_compileChain(obj, compiled)
- --self:_compileGlobal(obj, compiled)
+ self:_compileGlobal(compiled)
return obj
end
@@ -551,7 +550,7 @@ return function ()
_needDiagnostics = {},
_clock = -100,
_version = 0,
- _global = core.global(),
}, mt)
+ session.global = core.global(session)
return session
end
diff --git a/server/test/crossfile/definition.lua b/server/test/crossfile/definition.lua
index 07548b77..458154bc 100644
--- a/server/test/crossfile/definition.lua
+++ b/server/test/crossfile/definition.lua
@@ -182,7 +182,7 @@ TEST {
]]
}
}
-do return end
+
TEST {
{
path = 'a.lua',