diff options
Diffstat (limited to 'script/core/diagnostics')
-rw-r--r-- | script/core/diagnostics/assign-type-mismatch.lua | 2 | ||||
-rw-r--r-- | script/core/diagnostics/cast-field-type.lua | 70 | ||||
-rw-r--r-- | script/core/diagnostics/cast-local-type.lua | 2 | ||||
-rw-r--r-- | script/core/diagnostics/init.lua | 13 |
4 files changed, 79 insertions, 8 deletions
diff --git a/script/core/diagnostics/assign-type-mismatch.lua b/script/core/diagnostics/assign-type-mismatch.lua index aae4cccb..89ae0a61 100644 --- a/script/core/diagnostics/assign-type-mismatch.lua +++ b/script/core/diagnostics/assign-type-mismatch.lua @@ -16,7 +16,7 @@ local checkTypes = { ---@async return function (uri, callback) - if not PREVIEW then + if not PREVIEW and not TEST then return end local state = files.getState(uri) diff --git a/script/core/diagnostics/cast-field-type.lua b/script/core/diagnostics/cast-field-type.lua new file mode 100644 index 00000000..24299649 --- /dev/null +++ b/script/core/diagnostics/cast-field-type.lua @@ -0,0 +1,70 @@ +local files = require 'files' +local lang = require 'language' +local guide = require 'parser.guide' +local vm = require 'vm' +local await = require 'await' + +---@async +return function (uri, callback) + if not PREVIEW and not TEST then + return + end + local state = files.getState(uri) + if not state then + return + end + + local fieldNodeCache = {} + + local function getParentField(parent, key) + if parent.type == 'getlocal' then + parent = parent.node + end + if not fieldNodeCache[parent] then + fieldNodeCache[parent] = {} + end + if fieldNodeCache[parent][key] then + return fieldNodeCache[parent][key] + end + local fieldNode = vm.createNode() + fieldNodeCache[parent][key] = fieldNode + for _, class in ipairs(vm.getDefs(parent)) do + if class.type == 'doc.class' then + vm.getClassFields(uri, vm.getGlobal('type', class.class[1]), key, false, function (def) + if def.type == 'doc.field' then + fieldNode:merge(vm.compileNode(def)) + end + end) + end + end + return fieldNode + end + + ---@async + guide.eachSourceTypes(state.ast, { 'setfield', 'setindex', 'setmethod', 'tablefield', 'tableindex' }, function (ref) + await.delay() + if not ref.value then + return + end + local key = guide.getKeyName(ref) + if not key then + return nil + end + local parent = ref.node + local fieldNode = getParentField(parent, key) + if not fieldNode or fieldNode:isEmpty() then + return + end + if vm.canCastType(uri, fieldNode, vm.compileNode(ref.value)) then + return + end + callback { + start = ref.start, + finish = ref.finish, + message = lang.script('DIAG_CAST_LOCAL_TYPE', { + def = vm.getInfer(fieldNode):view(uri), + ref = vm.getInfer(ref.value):view(uri), + }), + } + end) +end diff --git a/script/core/diagnostics/cast-local-type.lua b/script/core/diagnostics/cast-local-type.lua index 0a236084..dd3a37e8 100644 --- a/script/core/diagnostics/cast-local-type.lua +++ b/script/core/diagnostics/cast-local-type.lua @@ -6,7 +6,7 @@ local await = require 'await' ---@async return function (uri, callback) - if not PREVIEW then + if not PREVIEW and not TEST then return end local state = files.getState(uri) diff --git a/script/core/diagnostics/init.lua b/script/core/diagnostics/init.lua index 746052b0..efd23bf4 100644 --- a/script/core/diagnostics/init.lua +++ b/script/core/diagnostics/init.lua @@ -8,12 +8,13 @@ local util = require 'utility' -- 把耗时最长的诊断放到最后面 local diagSort = { ['redundant-value'] = 100, - ['not-yieldable'] = 101, - ['deprecated'] = 102, - ['undefined-field'] = 103, - ['redundant-parameter'] = 104, - ['cast-local-type'] = 105, - ['assign-type-mismatch'] = 106, + ['not-yieldable'] = 100, + ['deprecated'] = 100, + ['undefined-field'] = 110, + ['redundant-parameter'] = 110, + ['cast-local-type'] = 120, + ['cast-field-type'] = 120, + ['assign-type-mismatch'] = 120, } local diagList = {} |