diff options
author | Sewbacca <sebastian.kalus@kolabnow.com> | 2023-07-17 14:34:49 +0200 |
---|---|---|
committer | Sewbacca <sebastian.kalus@kolabnow.com> | 2023-07-17 14:34:49 +0200 |
commit | 393f3e844d5164116de8bd739fc06d76bd03439f (patch) | |
tree | 2e1b514bdc38885623781089fba3ef327c76f39a /script | |
parent | 62068c0709d2fd131607940852b0d938b43794b4 (diff) | |
download | lua-language-server-393f3e844d5164116de8bd739fc06d76bd03439f.zip |
Extracted undefined global check
Diffstat (limited to 'script')
-rw-r--r-- | script/core/code-action.lua | 17 | ||||
-rw-r--r-- | script/core/diagnostics/undefined-global.lua | 47 | ||||
-rw-r--r-- | script/vm/global.lua | 28 | ||||
-rw-r--r-- | script/vm/node.lua | 1 |
4 files changed, 47 insertions, 46 deletions
diff --git a/script/core/code-action.lua b/script/core/code-action.lua index b37b478e..7f59f493 100644 --- a/script/core/code-action.lua +++ b/script/core/code-action.lua @@ -8,6 +8,7 @@ local autoreq = require 'core.completion.auto-require' local rpath = require 'workspace.require-path' local furi = require 'file-uri' local undefined = require 'core.diagnostics.undefined-global' +local vm = require 'vm' ---@param uri uri ---@param row integer @@ -695,14 +696,7 @@ local function checkMissingRequire(results, uri, start, finish) return end - local potentialGlobals = {} - guide.eachSourceBetween(state.ast, start, finish, function (source) - if source.type == 'getglobal' then - potentialGlobals[#potentialGlobals+1] = { name = source[1], endpos = source.finish } - end - end) - - local function addPotentialRequires(global, endpos) + local function addRequires(global, endpos) autoreq.check(state, global, endpos, function(moduleFile, stemname, targetSource) local visiblePaths = rpath.getVisiblePath(uri, furi.decode(moduleFile)) if not visiblePaths or #visiblePaths == 0 then return end @@ -728,9 +722,8 @@ local function checkMissingRequire(results, uri, start, finish) end) end - undefined(uri, function(foundUndefined) - if foundUndefined.start <= start and start <= foundUndefined.finish and foundUndefined.start <= finish and finish <= foundUndefined.finish then - addPotentialRequires(foundUndefined.undefinedGlobal, foundUndefined.finish) + guide.eachSourceBetween(state.ast, start, finish, function (source)if vm.isUndefinedGlobal(source) then + addRequires(source[1], source.finish) end end) end @@ -747,7 +740,7 @@ return function (uri, start, finish, diagnostics) checkSwapParams(results, uri, start, finish) --checkExtractAsFunction(results, uri, start, finish) checkJsonToLua(results, uri, start, finish) - checkMissingRequire(results, uri, start, finish, diagnostics) + checkMissingRequire(results, uri, start, finish) return results end diff --git a/script/core/diagnostics/undefined-global.lua b/script/core/diagnostics/undefined-global.lua index 87501277..d9d94959 100644 --- a/script/core/diagnostics/undefined-global.lua +++ b/script/core/diagnostics/undefined-global.lua @@ -20,42 +20,21 @@ return function (uri, callback) return end - local dglobals = util.arrayToHash(config.get(uri, 'Lua.diagnostics.globals')) - local rspecial = config.get(uri, 'Lua.runtime.special') - local cache = {} - -- 遍历全局变量,检查所有没有 set 模式的全局变量 guide.eachSourceType(state.ast, 'getglobal', function (src) ---@async - local key = src[1] - if not key then - return - end - if dglobals[key] then - return - end - if rspecial[key] then - return - end - local node = src.node - if node.tag ~= '_ENV' then - return - end - if cache[key] == nil then - await.delay() - cache[key] = vm.hasGlobalSets(uri, 'variable', key) - end - if cache[key] then - return - end - local message = lang.script('DIAG_UNDEF_GLOBAL', key) - if requireLike[key:lower()] then - message = ('%s(%s)'):format(message, lang.script('DIAG_REQUIRE_LIKE', key)) + if vm.isUndefinedGlobal(src) then + local key = src[1] + local message = lang.script('DIAG_UNDEF_GLOBAL', key) + if requireLike[key:lower()] then + message = ('%s(%s)'):format(message, lang.script('DIAG_REQUIRE_LIKE', key)) + end + + callback { + start = src.start, + finish = src.finish, + message = message, + undefinedGlobal = src[1] + } end - callback { - start = src.start, - finish = src.finish, - message = message, - undefinedGlobal = src[1] - } end) end diff --git a/script/vm/global.lua b/script/vm/global.lua index c1b5f320..687d53c8 100644 --- a/script/vm/global.lua +++ b/script/vm/global.lua @@ -1,6 +1,7 @@ local util = require 'utility' local scope = require 'workspace.scope' local guide = require 'parser.guide' +local config = require 'config' ---@class vm local vm = require 'vm.vm' @@ -518,6 +519,33 @@ function vm.hasGlobalSets(suri, cate, name) return true end +---@param src parser.object +local function checkIsUndefinedGlobal(src) + local key = src[1] + + local uri = guide.getUri(src) + local dglobals = util.arrayToHash(config.get(uri, 'Lua.diagnostics.globals')) + local rspecial = config.get(uri, 'Lua.runtime.special') + + local node = src.node + return src.type == 'getglobal' and key and not ( + dglobals[key] or + rspecial[key] or + node.tag ~= '_ENV' or + vm.hasGlobalSets(uri, 'variable', key) + ) +end + +---@param src parser.object +---@return boolean +function vm.isUndefinedGlobal(src) + local node = vm.compileNode(src) + if node._undefined_global == nil then + node._undefined_global = checkIsUndefinedGlobal(src) + end + return node._undefined_global +end + ---@param source parser.object function compileObject(source) if source._globalNode ~= nil then diff --git a/script/vm/node.lua b/script/vm/node.lua index 0ffd8c70..90ae839d 100644 --- a/script/vm/node.lua +++ b/script/vm/node.lua @@ -15,6 +15,7 @@ vm.nodeCache = setmetatable({}, util.MODE_K) ---@field [integer] vm.node.object ---@field [vm.node.object] true ---@field fields? table<vm.node|string, vm.node> +---@field _undefined_global boolean? local mt = {} mt.__index = mt mt.id = 0 |