diff options
Diffstat (limited to 'script')
-rw-r--r-- | script/core/completion/completion.lua | 7 | ||||
-rw-r--r-- | script/core/diagnostics/cast-type-mismatch.lua | 45 | ||||
-rw-r--r-- | script/core/diagnostics/unknown-cast-variable.lua | 32 | ||||
-rw-r--r-- | script/files.lua | 4 | ||||
-rw-r--r-- | script/fs-utility.lua | 2 | ||||
-rw-r--r-- | script/parser/guide.lua | 4 | ||||
-rw-r--r-- | script/parser/luadoc.lua | 3 | ||||
-rw-r--r-- | script/proto/define.lua | 4 | ||||
-rw-r--r-- | script/provider/markdown.lua | 2 | ||||
-rw-r--r-- | script/vm/function.lua | 22 | ||||
-rw-r--r-- | script/vm/type.lua | 5 |
11 files changed, 120 insertions, 10 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index 165dbac5..52ec7a18 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -1103,7 +1103,7 @@ local function tryLabelInString(label, source) if not state or not state.ast then return label end - if not matchKey(source[1], state.ast[1]) then + if not matchKey(source[1], state.ast[1]--[[@as string]]) then return nil end return util.viewString(state.ast[1], source[2]) @@ -1242,6 +1242,9 @@ local function tryIndex(state, position, results) return end local word = parent.next and parent.next.index and parent.next.index[1] + if not word then + return + end checkField(state, word, position, position, parent, oop, results) end @@ -1426,6 +1429,7 @@ local function tryCallArg(state, position, results) if src.type == 'doc.type.string' or src.type == 'doc.type.integer' or src.type == 'doc.type.boolean' then + ---@cast src parser.object enums[#enums+1] = { label = vm.viewObject(src, state.uri), description = src.comment, @@ -1439,6 +1443,7 @@ local function tryCallArg(state, position, results) } end if src.type == 'doc.type.function' then + ---@cast src parser.object local insertText = buildInsertDocFunction(src) local description if src.comment then diff --git a/script/core/diagnostics/cast-type-mismatch.lua b/script/core/diagnostics/cast-type-mismatch.lua new file mode 100644 index 00000000..ecee6a84 --- /dev/null +++ b/script/core/diagnostics/cast-type-mismatch.lua @@ -0,0 +1,45 @@ +local files = require 'files' +local guide = require 'parser.guide' +local lang = require 'language' +local vm = require 'vm' +local await = require 'await' + +---@async +return function (uri, callback) + local state = files.getState(uri) + if not state then + return + end + + if not state.ast.docs then + return + end + + for _, doc in ipairs(state.ast.docs) do + if doc.type == 'doc.cast' then + await.delay() + local defs = vm.getDefs(doc.loc) + local loc = defs[1] + if loc then + local defNode = vm.compileNode(loc) + if defNode:getData 'hasDefined' then + for _, cast in ipairs(doc.casts) do + if not cast.mode and cast.extends then + local refNode = vm.compileNode(cast.extends) + if not vm.canCastType(uri, defNode, refNode) then + callback { + start = cast.extends.start, + finish = cast.extends.finish, + message = lang.script('DIAG_UNKNOWN_CAST_VARIABLE', { + def = vm.getInfer(defNode):view(uri), + ref = vm.getInfer(refNode):view(uri), + }) + } + end + end + end + end + end + end + end +end diff --git a/script/core/diagnostics/unknown-cast-variable.lua b/script/core/diagnostics/unknown-cast-variable.lua new file mode 100644 index 00000000..cfa25ed8 --- /dev/null +++ b/script/core/diagnostics/unknown-cast-variable.lua @@ -0,0 +1,32 @@ +local files = require 'files' +local guide = require 'parser.guide' +local lang = require 'language' +local vm = require 'vm' +local await = require 'await' + +---@async +return function (uri, callback) + local state = files.getState(uri) + if not state then + return + end + + if not state.ast.docs then + return + end + + for _, doc in ipairs(state.ast.docs) do + if doc.type == 'doc.cast' then + await.delay() + local defs = vm.getDefs(doc.loc) + local loc = defs[1] + if not loc then + callback { + start = doc.loc.start, + finish = doc.loc.finish, + message = lang.script('DIAG_UNKNOWN_CAST_VARIABLE', doc[1]) + } + end + end + end +end diff --git a/script/files.lua b/script/files.lua index 252a6ee5..d0225f45 100644 --- a/script/files.lua +++ b/script/files.lua @@ -14,6 +14,9 @@ local progress = require "progress" local encoder = require 'encoder' local scope = require 'workspace.scope' +---@class file +---@field content string + ---@class files local m = {} @@ -23,6 +26,7 @@ m.assocVersion = -1 function m.reset() m.openMap = {} + ---@type table<string, file> m.fileMap = {} m.dllMap = {} m.visible = {} diff --git a/script/fs-utility.lua b/script/fs-utility.lua index 08aae98a..cca65521 100644 --- a/script/fs-utility.lua +++ b/script/fs-utility.lua @@ -40,7 +40,7 @@ function m.loadFile(path, keepBom) end --- 写入文件 ----@param path string +---@param path any ---@param content string function m.saveFile(path, content) if type(path) ~= 'string' then diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 3f68ccd2..7a9cb875 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -478,7 +478,9 @@ function m.getLocal(source, name, pos) if not block then return nil end - if block.start <= pos and block.finish >= pos then + if block.start <= pos + and block.finish >= pos + and blockTypes[block.type] then break end block = block.parent diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index 420e78cd..c4f40ac4 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -1661,6 +1661,9 @@ return function (state) end end + ast.docs.start = ast.start + ast.docs.finish = ast.finish + if #ast.docs == 0 then return end diff --git a/script/proto/define.lua b/script/proto/define.lua index 45fbba9e..30ef621e 100644 --- a/script/proto/define.lua +++ b/script/proto/define.lua @@ -62,6 +62,8 @@ m.DiagnosticDefaultSeverity = { ['doc-field-no-class'] = 'Warning', ['duplicate-doc-field'] = 'Warning', ['unknown-diag-code'] = 'Warning', + ['unknown-cast-variable'] = 'Warning', + ['cast-type-mismatch'] = 'Warning', ['codestyle-check'] = 'Warning', ['spell-check'] = 'Information', @@ -126,6 +128,8 @@ m.DiagnosticDefaultNeededFileStatus = { ['doc-field-no-class'] = 'Any', ['duplicate-doc-field'] = 'Any', ['unknown-diag-code'] = 'Any', + ['unknown-cast-variable'] = 'Any', + ['cast-type-mismatch'] = 'Any', ['codestyle-check'] = 'None', ['spell-check'] = 'None', diff --git a/script/provider/markdown.lua b/script/provider/markdown.lua index 6b007713..f2f7f777 100644 --- a/script/provider/markdown.lua +++ b/script/provider/markdown.lua @@ -10,7 +10,7 @@ function mt:__tostring() end ---@param language string ----@param text string|markdown +---@param text? string|markdown function mt:add(language, text) if not text then return self diff --git a/script/vm/function.lua b/script/vm/function.lua index 2a169bd6..e8fadb38 100644 --- a/script/vm/function.lua +++ b/script/vm/function.lua @@ -75,14 +75,15 @@ function vm.countParamsOfNode(node) end ---@param func parser.object +---@param mark? table ---@return integer min ---@return integer max -function vm.countReturnsOfFunction(func) +function vm.countReturnsOfFunction(func, mark) if func.type == 'function' then local min, max if func.returns then for _, ret in ipairs(func.returns) do - local rmin, rmax = vm.countList(ret) + local rmin, rmax = vm.countList(ret, mark) if not min or rmin < min then min = rmin end @@ -126,14 +127,15 @@ function vm.countReturnsOfFunction(func) end ---@param func parser.object +---@param mark? table ---@return integer min ---@return integer max -function vm.countReturnsOfCall(func, args) +function vm.countReturnsOfCall(func, args, mark) local funcs = vm.getMatchedFunctions(func, args) local min local max for _, f in ipairs(funcs) do - local rmin, rmax = vm.countReturnsOfFunction(f) + local rmin, rmax = vm.countReturnsOfFunction(f, mark) if not min or rmin < min then min = rmin end @@ -145,9 +147,10 @@ function vm.countReturnsOfCall(func, args) end ---@param list parser.object[]? +---@param mark? table ---@return integer min ---@return integer max -function vm.countList(list) +function vm.countList(list, mark) if not list then return 0, 0 end @@ -160,7 +163,14 @@ function vm.countList(list) return #list - 1, math.huge end if lastArg.type == 'call' then - local rmin, rmax = vm.countReturnsOfCall(lastArg.node, lastArg.args) + if not mark then + mark = {} + end + if mark[lastArg] then + return #list - 1, math.huge + end + mark[lastArg] = true + local rmin, rmax = vm.countReturnsOfCall(lastArg.node, lastArg.args, mark) return #list - 1 + rmin, #list - 1 + rmax end return #list, #list diff --git a/script/vm/type.lua b/script/vm/type.lua index fa78f735..208f21ed 100644 --- a/script/vm/type.lua +++ b/script/vm/type.lua @@ -130,6 +130,11 @@ function vm.isSubType(uri, child, parent, mark) end end end + if set.type == 'doc.alias' and set.extends then + if vm.isSubType(uri, vm.compileNode(set.extends), parent, mark) then + return true + end + end end end end |