diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-01-29 11:26:20 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-01-29 11:26:20 +0800 |
commit | 0e99f6a8116f3cfb9e49cea1758d03b541024ff4 (patch) | |
tree | 9955f5e033d3e0c95cdfbb71b9aa10d9237dfae2 | |
parent | 2490ce5d8b5770370fb31619a8151b0211320385 (diff) | |
download | lua-language-server-0e99f6a8116f3cfb9e49cea1758d03b541024ff4.zip |
全局变量
-rw-r--r-- | server/src/core/global.lua | 77 | ||||
-rw-r--r-- | server/src/core/value.lua | 12 | ||||
-rw-r--r-- | server/src/core/vm.lua | 62 | ||||
-rw-r--r-- | server/src/service.lua | 27 | ||||
-rw-r--r-- | server/test/crossfile/definition.lua | 2 |
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', |