summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
authorSewbacca <sebastian.kalus@kolabnow.com>2023-07-17 14:34:49 +0200
committerSewbacca <sebastian.kalus@kolabnow.com>2023-07-17 14:34:49 +0200
commit393f3e844d5164116de8bd739fc06d76bd03439f (patch)
tree2e1b514bdc38885623781089fba3ef327c76f39a /script
parent62068c0709d2fd131607940852b0d938b43794b4 (diff)
downloadlua-language-server-393f3e844d5164116de8bd739fc06d76bd03439f.zip
Extracted undefined global check
Diffstat (limited to 'script')
-rw-r--r--script/core/code-action.lua17
-rw-r--r--script/core/diagnostics/undefined-global.lua47
-rw-r--r--script/vm/global.lua28
-rw-r--r--script/vm/node.lua1
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