diff options
-rw-r--r-- | script/core/diagnostics/undefined-field.lua | 2 | ||||
-rw-r--r-- | script/vm/def.lua | 39 |
2 files changed, 40 insertions, 1 deletions
diff --git a/script/core/diagnostics/undefined-field.lua b/script/core/diagnostics/undefined-field.lua index 4fd55966..ab5d4d54 100644 --- a/script/core/diagnostics/undefined-field.lua +++ b/script/core/diagnostics/undefined-field.lua @@ -21,7 +21,7 @@ return function (uri, callback) local function checkUndefinedField(src) await.delay() - if #vm.getDefs(src) > 0 then + if vm.hasDef(src) then return end local node = src.node diff --git a/script/vm/def.lua b/script/vm/def.lua index 5388a384..669d39c2 100644 --- a/script/vm/def.lua +++ b/script/vm/def.lua @@ -92,3 +92,42 @@ function vm.getDefs(source) return results end + +local HAS_DEF_ERR = {} -- the error object for comparing +local function checkHasDef(checkFunc, source, pushResult) + local _, err = pcall(checkFunc, source, pushResult) + return err == HAS_DEF_ERR +end + +---@param source parser.object +function vm.hasDef(source) + local mark = {} + local hasLocal + local function pushResult(src) + if src.type == 'local' then + if hasLocal then + return + end + hasLocal = true + if source.type ~= 'local' + and source.type ~= 'getlocal' + and source.type ~= 'setlocal' + and source.type ~= 'doc.cast.name' then + return + end + end + if not mark[src] then + mark[src] = true + if guide.isAssign(src) + or guide.isLiteral(src) then + -- break out on 1st result using error() with a unique error object + error(HAS_DEF_ERR) + end + end + end + + return checkHasDef(searchBySimple, source, pushResult) + or checkHasDef(searchByLocalID, source, pushResult) + or checkHasDef(vm.compileByNodeChain, source, pushResult) + or checkHasDef(searchByNode, source, pushResult) +end |