diff options
Diffstat (limited to 'script')
43 files changed, 370 insertions, 102 deletions
diff --git a/script/await.lua b/script/await.lua index e92af272..cea5667b 100644 --- a/script/await.lua +++ b/script/await.lua @@ -25,7 +25,7 @@ local function setID(id, co, callback) end --- 设置错误处理器 ----@param errHandle function {comment = '当有错误发生时,会以错误堆栈为参数调用该函数'} +---@param errHandle function # 当有错误发生时,会以错误堆栈为参数调用该函数 function m.setErrorHandle(errHandle) m.errorHandle = errHandle end @@ -66,6 +66,7 @@ function m.call(callback, ...) end --- 创建一个任务,并挂起当前线程,当任务完成后再延续当前线程/若任务被关闭,则返回nil +---@async function m.await(callback, ...) if not coroutine.isyieldable() then return callback(...) @@ -109,6 +110,7 @@ end --- 休眠一段时间 ---@param time number +---@async function m.sleep(time) if not coroutine.isyieldable() then if m.errorHandle then @@ -128,6 +130,7 @@ end --- 等待直到唤醒 ---@param callback function +---@async function m.wait(callback, ...) if not coroutine.isyieldable() then return @@ -148,6 +151,7 @@ function m.wait(callback, ...) end --- 延迟 +---@async function m.delay() if not m._enable then return @@ -174,6 +178,7 @@ function m.delay() end --- stop then close +---@async function m.stop() if not coroutine.isyieldable() then return diff --git a/script/client.lua b/script/client.lua index 93ac38b3..4d338016 100644 --- a/script/client.lua +++ b/script/client.lua @@ -88,6 +88,7 @@ end ---@param titles string[] ---@return string action ---@return integer index +---@async function m.awaitRequestMessage(type, message, titles) proto.notify('window/logMessage', { type = define.MessageType[type] or 3, diff --git a/script/config/config.lua b/script/config/config.lua index 8661e0d0..c2eec880 100644 --- a/script/config/config.lua +++ b/script/config/config.lua @@ -199,6 +199,7 @@ local Template = { ['Lua.hint.paramType'] = Type.Boolean >> true, ['Lua.hint.setType'] = Type.Boolean >> false, ['Lua.hint.paramName'] = Type.String >> 'All', + ['Lua.hint.await'] = Type.Boolean >> true, ['Lua.window.statusBar'] = Type.Boolean >> true, ['Lua.window.progressBar'] = Type.Boolean >> true, ['Lua.telemetry.enable'] = Type.Or(Type.Boolean >> false, Type.Nil), diff --git a/script/config/loader.lua b/script/config/loader.lua index 03fe9456..03588634 100644 --- a/script/config/loader.lua +++ b/script/config/loader.lua @@ -63,6 +63,7 @@ function m.loadLocalConfig(filename) end end +---@async function m.loadClientConfig() local configs = proto.awaitRequest('workspace/configuration', { items = { diff --git a/script/core/code-action.lua b/script/core/code-action.lua index 8256107e..ad048c48 100644 --- a/script/core/code-action.lua +++ b/script/core/code-action.lua @@ -308,6 +308,44 @@ local function solveTrailingSpace(uri, diag, results) } end +local function solveAwaitInSync(uri, diag, results) + local state = files.getState(uri) + if not state then + return + end + local start, finish = converter.unpackRange(uri, diag.range) + local parentFunction + guide.eachSourceType(state.ast, 'function', function (source) + if source.start > finish + or source.finish < start then + return + end + if not parentFunction or parentFunction.start < source.start then + parentFunction = source + end + end) + if not parentFunction then + return + end + local row = guide.rowColOf(parentFunction.start) + local pos = guide.positionOf(row, 0) + results[#results+1] = { + title = lang.script.ACTION_MARK_ASYNC, + kind = 'quickfix', + edit = { + changes = { + [uri] = { + { + start = pos, + finish = pos, + newText = '---@async\n', + } + } + } + }, + } +end + local function solveDiagnostic(uri, diag, start, results) if diag.source == lang.script.DIAG_SYNTAX_CHECK then solveSyntax(uri, diag, results) @@ -326,6 +364,8 @@ local function solveDiagnostic(uri, diag, start, results) solveAmbiguity1(uri, diag, results) elseif diag.code == 'trailing-space' then solveTrailingSpace(uri, diag, results) + elseif diag.code == 'await-in-sync' then + solveAwaitInSync(uri, diag, results) end disableDiagnostic(uri, diag.code, start, results) end diff --git a/script/core/command/autoRequire.lua b/script/core/command/autoRequire.lua index ca8826d7..30bd13a1 100644 --- a/script/core/command/autoRequire.lua +++ b/script/core/command/autoRequire.lua @@ -63,6 +63,7 @@ local function findInsertRow(uri) return row or 0, fmt end +---@async local function askAutoRequire(visiblePaths) local selects = {} local nameMap = {} @@ -125,6 +126,7 @@ local function applyAutoRequire(uri, row, name, result, fmt) }) end +---@async return function (data) local uri = data.uri local target = data.target diff --git a/script/core/command/jsonToLua.lua b/script/core/command/jsonToLua.lua index 6aecee2c..d29ad608 100644 --- a/script/core/command/jsonToLua.lua +++ b/script/core/command/jsonToLua.lua @@ -7,6 +7,7 @@ local lang = require 'language' local converter = require 'proto.converter' local guide = require 'parser.guide' +---@async return function (data) local state = files.getState(data.uri) local text = files.getText(data.uri) diff --git a/script/core/command/removeSpace.lua b/script/core/command/removeSpace.lua index 3021d4a4..aa565f7f 100644 --- a/script/core/command/removeSpace.lua +++ b/script/core/command/removeSpace.lua @@ -12,6 +12,7 @@ local function isInString(ast, offset) end) or false end +---@async return function (data) local uri = data.uri local text = files.getText(uri) diff --git a/script/core/command/solve.lua b/script/core/command/solve.lua index 9428d065..19148092 100644 --- a/script/core/command/solve.lua +++ b/script/core/command/solve.lua @@ -27,6 +27,7 @@ local literalMap = { ['table'] = true, } +---@async return function (data) local uri = data.uri local text = files.getText(uri) diff --git a/script/core/completion.lua b/script/core/completion.lua index 8b31614d..e30c9c91 100644 --- a/script/core/completion.lua +++ b/script/core/completion.lua @@ -20,6 +20,7 @@ local lookBackward = require 'core.look-backward' local guide = require 'parser.guide' local infer = require 'core.infer' local noder = require 'core.noder' +local await = require 'await' local DiagnosticModes = { 'disable-next-line', @@ -202,6 +203,7 @@ local function getSnip(source) end end +---@async local function buildDesc(source) if source.type == 'dummy' then return @@ -228,7 +230,7 @@ local function buildFunction(results, source, value, oop, data) title = 'trigger signature', command = 'editor.action.triggerParameterHints', } - snipData.id = stack(function () + snipData.id = stack(function () ---@async return { detail = buildDetail(source), description = buildDesc(source), @@ -291,7 +293,7 @@ local function checkLocal(state, word, position, results) match = name, insertText = name, kind = define.CompletionItemKind.Function, - id = stack(function () + id = stack(function () ---@async return { detail = buildDetail(source), description = buildDesc(source), @@ -304,7 +306,7 @@ local function checkLocal(state, word, position, results) results[#results+1] = { label = name, kind = define.CompletionItemKind.Variable, - id = stack(function () + id = stack(function () ---@async return { detail = buildDetail(source), description = buildDesc(source), @@ -369,7 +371,7 @@ local function checkModule(state, word, position, results) }, }, }, - id = stack(function () + id = stack(function () ---@async local md = markdown() md:add('md', lang.script('COMPLETION_IMPORT_FROM', ('[%s](%s)'):format( workspace.getRelativePath(uri), @@ -470,7 +472,7 @@ local function checkFieldThen(name, src, word, startPos, position, parent, oop, match = name:match '^[^(]+', insertText = name:match '^[^(]+', deprecated = vm.isDeprecated(src) or nil, - id = stack(function () + id = stack(function () ---@async return { detail = buildDetail(src), description = buildDesc(src), @@ -503,7 +505,7 @@ local function checkFieldThen(name, src, word, startPos, position, parent, oop, deprecated = vm.isDeprecated(src) or nil, textEdit = textEdit, additionalTextEdits = additionalTextEdits, - id = stack(function () + id = stack(function () ---@async return { detail = buildDetail(src), description = buildDesc(src), @@ -512,6 +514,7 @@ local function checkFieldThen(name, src, word, startPos, position, parent, oop, } end +---@async local function checkFieldOfRefs(refs, state, word, startPos, position, parent, oop, results, locals, isGlobal) local fields = {} local funcs = {} @@ -571,16 +574,19 @@ local function checkFieldOfRefs(refs, state, word, startPos, position, parent, o for name, src in util.sortPairs(fields) do if src then checkFieldThen(name, src, word, startPos, position, parent, oop, results) + await.delay() end end end +---@async local function checkGlobal(state, word, startPos, position, parent, oop, results) local locals = guide.getVisibleLocals(state.ast, position) local globals = vm.getGlobalSets '*' checkFieldOfRefs(globals, state, word, startPos, position, parent, oop, results, locals, 'global') end +---@async local function checkField(state, word, start, position, parent, oop, results) if parent.tag == '_ENV' or parent.special == '_G' then local globals = vm.getGlobalSets '*' @@ -1202,6 +1208,7 @@ local function trySpecial(state, text, position, results) checkEqualEnum(state, text, position, results) end +---@async local function tryIndex(state, text, position, results) local parent, oop = findParentInStringIndex(state, text, position) if not parent then @@ -1211,6 +1218,7 @@ local function tryIndex(state, text, position, results) checkField(state, word, position, position, parent, oop, results) end +---@async local function tryWord(state, text, position, triggerCharacter, results) local offset = guide.positionToOffset(state, position) local finish = lookBackward.skipSpace(text, offset) @@ -1266,6 +1274,7 @@ local function tryWord(state, text, position, triggerCharacter, results) end end +---@async local function trySymbol(state, text, position, results) local symbol, start = lookBackward.findSymbol(text, guide.positionToOffset(state, position)) if not symbol then @@ -1484,7 +1493,7 @@ local function checkTableLiteralField(state, text, position, tbl, fields, result label = guide.getKeyName(field), kind = define.CompletionItemKind.Property, insertText = ('%s = $0'):format(guide.getKeyName(field)), - id = stack(function () + id = stack(function () ---@async return { detail = buildDetail(field), description = buildDesc(field), @@ -1619,6 +1628,7 @@ local function tryLuaDocCate(word, results) 'see', 'diagnostic', 'module', + 'async', } do if matchKey(word, docType) then results[#results+1] = { @@ -2058,6 +2068,7 @@ local function clearCache() cache.results = nil end +---@async local function completion(uri, position, triggerCharacter) tracy.ZoneBeginN 'completion cache' local results = getCache(uri, position) @@ -2065,12 +2076,14 @@ local function completion(uri, position, triggerCharacter) if results then return results end + await.delay() tracy.ZoneBeginN 'completion #1' local state = files.getState(uri) local text = files.getText(uri) results = {} clearStack() tracy.ZoneEnd() + await.delay() tracy.ZoneBeginN 'completion #2' if state then if getComment(state, position) then diff --git a/script/core/diagnostics/await-in-sync.lua b/script/core/diagnostics/await-in-sync.lua new file mode 100644 index 00000000..5fb6467d --- /dev/null +++ b/script/core/diagnostics/await-in-sync.lua @@ -0,0 +1,26 @@ +local files = require 'files' +local guide = require 'parser.guide' +local vm = require 'vm' +local lang = require 'language' + +return function (uri, callback) + local state = files.getState(uri) + if not state then + return + end + + guide.eachSourceType(state.ast, 'call', function (source) + local currentFunc = guide.getParentFunction(source) + if currentFunc and vm.isAsync(currentFunc) then + return + end + if not vm.isAsync(source.node, true) then + return + end + callback { + start = source.node.start, + finish = source.node.finish, + message = lang.script('DIAG_AWAIT_IN_SYNC'), + } + end) +end diff --git a/script/core/diagnostics/deprecated.lua b/script/core/diagnostics/deprecated.lua index 0aeac9e9..7cd9e00f 100644 --- a/script/core/diagnostics/deprecated.lua +++ b/script/core/diagnostics/deprecated.lua @@ -16,7 +16,7 @@ return function (uri, callback) local cache = {} - guide.eachSourceTypes(ast.ast, types, function (src) + guide.eachSourceTypes(ast.ast, types, function (src) ---@async if src.type == 'getglobal' then local key = src[1] if not key then diff --git a/script/core/diagnostics/init.lua b/script/core/diagnostics/init.lua index 63a1bcf0..4950900b 100644 --- a/script/core/diagnostics/init.lua +++ b/script/core/diagnostics/init.lua @@ -64,6 +64,7 @@ local function check(uri, name, results) end end +---@async return function (uri, response) local ast = files.getState(uri) if not ast then diff --git a/script/core/diagnostics/redundant-value.lua b/script/core/diagnostics/redundant-value.lua index 4c913330..edead570 100644 --- a/script/core/diagnostics/redundant-value.lua +++ b/script/core/diagnostics/redundant-value.lua @@ -10,7 +10,7 @@ return function (uri, callback) return end - guide.eachSource(state.ast, function (src) + guide.eachSource(state.ast, function (src) ---@async await.delay() if src.redundant then callback { diff --git a/script/core/diagnostics/type-check.lua b/script/core/diagnostics/type-check.lua index 11678b38..3fa5050c 100644 --- a/script/core/diagnostics/type-check.lua +++ b/script/core/diagnostics/type-check.lua @@ -23,6 +23,9 @@ local typeNameMap = { } local function isTable(name) + if type(name) ~= 'string' then + return + end if tableMap[name] ---table<K: number, V: string> table or tableMap[name:sub(1, 5)] @@ -84,7 +87,8 @@ local function compatibleType(param, args) if param[1] and param[1]:sub(1,1) == '"' then return true end - elseif isTable(v.type or v[1]) and isTable(param[1] or param.type) then + elseif (isTable(v.type) or isTable(v[1])) + and (isTable(param[1]) or isTable(param.type)) then return true end end @@ -114,14 +118,16 @@ end local function addFatherClass(infers) for k in pairs(infers) do - local docDefs = vm.getDocDefines(k) - for _, doc in ipairs(docDefs) do - if doc.parent - and doc.parent.type == 'doc.class' - and doc.parent.extends then - for _, tp in ipairs(doc.parent.extends) do - if tp.type == 'doc.extends.name' then - infers[tp[1]] = true + if type(k) == 'string' then + local docDefs = vm.getDocDefines(k) + for _, doc in ipairs(docDefs) do + if doc.parent + and doc.parent.type == 'doc.class' + and doc.parent.extends then + for _, tp in ipairs(doc.parent.extends) do + if tp.type == 'doc.extends.name' then + infers[tp[1]] = true + end end end end @@ -238,9 +244,6 @@ local function getInfoFromDefs(defs) and isClassOralias(v.type) then plusAlias[#plusAlias+1] = v end - if not v[1] or not v.type then - log.warn('type-check: if not v[1] or not v.type') - end end plusAlias[#plusAlias+1] = types[i] end @@ -414,7 +417,7 @@ return function (uri, callback) if not ast then return end - guide.eachSourceType(ast.ast, 'call', function (source) + guide.eachSourceType(ast.ast, 'call', function (source) ---@async if not source.args then return end diff --git a/script/core/diagnostics/undefined-field.lua b/script/core/diagnostics/undefined-field.lua index ff02728f..66b1f8c5 100644 --- a/script/core/diagnostics/undefined-field.lua +++ b/script/core/diagnostics/undefined-field.lua @@ -26,6 +26,7 @@ return function (uri, callback) local cache = {} + ---@async local function checkUndefinedField(src) local id = noder.getID(src) if not id then diff --git a/script/core/diagnostics/undefined-global.lua b/script/core/diagnostics/undefined-global.lua index 14754c16..640f521b 100644 --- a/script/core/diagnostics/undefined-global.lua +++ b/script/core/diagnostics/undefined-global.lua @@ -21,7 +21,7 @@ return function (uri, callback) end -- 遍历全局变量,检查所有没有 set 模式的全局变量 - guide.eachSourceType(ast.ast, 'getglobal', function (src) + guide.eachSourceType(ast.ast, 'getglobal', function (src) ---@async local key = src[1] if not key then return diff --git a/script/core/diagnostics/unused-function.lua b/script/core/diagnostics/unused-function.lua index 8f6ccaac..ada4a23d 100644 --- a/script/core/diagnostics/unused-function.lua +++ b/script/core/diagnostics/unused-function.lua @@ -25,6 +25,7 @@ return function (uri, callback) end local cache = {} + ---@async local function checkFunction(source) if cache[source] ~= nil then return cache[source] @@ -81,7 +82,7 @@ return function (uri, callback) end -- 只检查局部函数 - guide.eachSourceType(ast.ast, 'function', function (source) + guide.eachSourceType(ast.ast, 'function', function (source) ---@async checkFunction(source) end) end diff --git a/script/core/document-symbol.lua b/script/core/document-symbol.lua index cfabedab..00299867 100644 --- a/script/core/document-symbol.lua +++ b/script/core/document-symbol.lua @@ -219,6 +219,7 @@ local function buildAnonymousFunction(source, text, used, symbols) } end +---@async local function buildSource(source, text, used, symbols) if source.type == 'local' or source.type == 'setlocal' @@ -243,7 +244,7 @@ local function makeSymbol(uri) local symbols = {} local used = {} - guide.eachSource(ast.ast, function (source) + guide.eachSource(ast.ast, function (source) ---@async buildSource(source, text, used, symbols) end) @@ -279,6 +280,7 @@ local function packChild(symbols) return root end +---@async local function packSymbols(symbols) await.delay() table.sort(symbols, function (a, b) @@ -291,6 +293,7 @@ local function packSymbols(symbols) return packChild(symbols) end +---@async return function (uri) local symbols = makeSymbol(uri) if not symbols then diff --git a/script/core/folding.lua b/script/core/folding.lua index bd3ba5f3..2cf06d46 100644 --- a/script/core/folding.lua +++ b/script/core/folding.lua @@ -145,6 +145,7 @@ local Care = { end, } +---@async return function (uri) local state = files.getState(uri) local text = files.getText(uri) @@ -154,7 +155,7 @@ return function (uri) local regions = {} local status = {} - guide.eachSource(state.ast, function (source) + guide.eachSource(state.ast, function (source) ---@async local tp = source.type if Care[tp] then await.delay() diff --git a/script/core/generic.lua b/script/core/generic.lua index 92e97362..b383ee5d 100644 --- a/script/core/generic.lua +++ b/script/core/generic.lua @@ -7,7 +7,7 @@ local noder = require "core.noder" ---@field proto parser.guide.object ---@field parent parser.guide.object ----@class generic.closure +---@class generic.closure: parser.guide.object ---@field type string ---@field proto parser.guide.object ---@field upvalues table<string, generic.value[]> diff --git a/script/core/hint.lua b/script/core/hint.lua index 62d2f7bf..e094fc51 100644 --- a/script/core/hint.lua +++ b/script/core/hint.lua @@ -7,12 +7,12 @@ local await = require 'await' local define = require 'proto.define' local function typeHint(uri, results, start, finish) - local ast = files.getState(uri) - if not ast then + local state = files.getState(uri) + if not state then return end local mark = {} - guide.eachSourceBetween(ast.ast, start, finish, function (source) + guide.eachSourceBetween(state.ast, start, finish, function (source) ---@async if source.type ~= 'local' and source.type ~= 'setglobal' and source.type ~= 'tablefield' @@ -101,12 +101,12 @@ local function paramName(uri, results, start, finish) if not paramConfig or paramConfig == 'None' then return end - local ast = files.getState(uri) - if not ast then + local state = files.getState(uri) + if not state then return end local mark = {} - guide.eachSourceBetween(ast.ast, start, finish, function (source) + guide.eachSourceBetween(state.ast, start, finish, function (source) ---@async if source.type ~= 'call' then return end @@ -158,9 +158,37 @@ local function paramName(uri, results, start, finish) end) end +local function awaitHint(uri, results, start, finish) + local awaitConfig = config.get 'Lua.hint.await' + if not awaitConfig then + return + end + local state = files.getState(uri) + if not state then + return + end + guide.eachSourceBetween(state.ast, start, finish, function (source) ---@async + if source.type ~= 'call' then + return + end + await.delay() + local node = source.node + if not vm.isAsync(node, true) then + return + end + results[#results+1] = { + text = 'await ', + offset = node.start, + kind = define.InlayHintKind.Other, + where = 'left', + } + end) +end + return function (uri, start, finish) local results = {} typeHint(uri, results, start, finish) + awaitHint(uri, results, start, finish) paramName(uri, results, start, finish) return results end diff --git a/script/core/hover/init.lua b/script/core/hover/init.lua index 784ef75d..7d99a006 100644 --- a/script/core/hover/init.lua +++ b/script/core/hover/init.lua @@ -7,12 +7,14 @@ local findSource = require 'core.find-source' local markdown = require 'provider.markdown' local infer = require 'core.infer' +---@async local function getHover(source) local md = markdown() local defMark = {} local labelMark = {} local descMark = {} + ---@async local function addHover(def, checkLable) if defMark[def] then return @@ -37,12 +39,17 @@ local function getHover(source) end if infer.searchAndViewInfers(source) == 'function' then + local hasFunc for _, def in ipairs(vm.getDefs(source)) do if def.type == 'function' or def.type == 'doc.type.function' then + hasFunc = true addHover(def, true) end end + if not hasFunc then + addHover(source, true) + end else addHover(source, true) for _, def in ipairs(vm.getDefs(source)) do @@ -74,6 +81,7 @@ local accept = { ['doc.module'] = true, } +---@async local function getHoverByUri(uri, position) local ast = files.getState(uri) if not ast then diff --git a/script/core/hover/label.lua b/script/core/hover/label.lua index 8906d54d..0bb4fe89 100644 --- a/script/core/hover/label.lua +++ b/script/core/hover/label.lua @@ -16,7 +16,11 @@ local function asFunction(source, oop) local arg = buildArg(source, oop) local rtn = buildReturn(source) local lines = {} - lines[1] = ('%s %s(%s)'):format(oop and 'method' or 'function', name or '', arg) + lines[1] = ('%s%s %s(%s)'):format( + vm.isAsync(source) and 'async ' or '', + oop and 'method' or 'function', + name or '', arg + ) lines[2] = rtn return table.concat(lines, '\n') end @@ -44,6 +48,7 @@ local function asDocTypeName(source) end end +---@async local function asValue(source, title) local name = buildName(source, false) or '' local type = infer.searchAndViewInfers(source) @@ -59,6 +64,9 @@ local function asValue(source, title) local pack = {} pack[#pack+1] = title pack[#pack+1] = name .. ':' + if vm.isAsync(source, true) then + pack[#pack+1] = 'async' + end if cont and ( type == 'table' or type == 'any' @@ -76,10 +84,12 @@ local function asValue(source, title) return table.concat(pack, ' ') end +---@async local function asLocal(source) return asValue(source, 'local') end +---@async local function asGlobal(source) return asValue(source, 'global') end @@ -111,6 +121,7 @@ local function isGlobalField(source) end end +---@async local function asField(source) if isGlobalField(source) then return asGlobal(source) @@ -175,6 +186,7 @@ local function asNumber(source) return formatNumber(num) end +---@async return function (source, oop) if source.type == 'function' then return asFunction(source, oop) diff --git a/script/core/hover/table.lua b/script/core/hover/table.lua index 68a04b40..285d5c02 100644 --- a/script/core/hover/table.lua +++ b/script/core/hover/table.lua @@ -134,6 +134,7 @@ local function getOptionalMap(fields) return optionals end +---@async return function (source) local maxFields = config.get 'Lua.hover.previewFields' if maxFields <= 0 then diff --git a/script/core/semantic-tokens.lua b/script/core/semantic-tokens.lua index dc0649d1..aef28aa6 100644 --- a/script/core/semantic-tokens.lua +++ b/script/core/semantic-tokens.lua @@ -381,7 +381,7 @@ return function (uri, start, finish) end local results = {} - guide.eachSourceBetween(state.ast, start, finish, function (source) + guide.eachSourceBetween(state.ast, start, finish, function (source) ---@async local method = Care[source.type] if not method then return diff --git a/script/core/signature.lua b/script/core/signature.lua index 007a3787..57483718 100644 --- a/script/core/signature.lua +++ b/script/core/signature.lua @@ -39,6 +39,7 @@ local function findNearCall(uri, ast, pos) return nearCall end +---@async local function makeOneSignature(source, oop, index) local label = hoverLabel(source, oop) -- 去掉返回值 @@ -77,6 +78,7 @@ local function makeOneSignature(source, oop, index) } end +---@async local function makeSignatures(text, call, pos) local node = call.node local oop = node.type == 'method' @@ -136,6 +138,7 @@ local function makeSignatures(text, call, pos) return signs end +---@async return function (uri, pos) local state = files.getState(uri) if not state then diff --git a/script/core/workspace-symbol.lua b/script/core/workspace-symbol.lua index 265a8d92..5fb4a741 100644 --- a/script/core/workspace-symbol.lua +++ b/script/core/workspace-symbol.lua @@ -57,6 +57,7 @@ local function searchFile(uri, key, results) end) end +---@async return function (key) local results = {} diff --git a/script/encoder/init.lua b/script/encoder/init.lua index f33f5a1d..d7753c1f 100644 --- a/script/encoder/init.lua +++ b/script/encoder/init.lua @@ -4,6 +4,8 @@ local utf16be = require 'encoder.utf16be' ---@alias encoder.encoding '"utf8"'|'"utf16"'|'"utf16le"'|'"utf16be"' +---@alias encoder.bom '"no"'|'"yes"'|'"auto"' + local m = {} ---@param encoding encoder.encoding @@ -63,9 +65,13 @@ end ---@param encoding encoder.encoding ---@param text string +---@param bom encoder.bom ---@return string -function m.encode(encoding, text) +function m.encode(encoding, text, bom) if encoding == 'utf8' then + if bom == 'yes' then + text = '\xEF\xBB\xBF' .. text + end return text end if encoding == 'ansi' then @@ -73,10 +79,20 @@ function m.encode(encoding, text) end if encoding == 'utf16' or encoding == 'utf16le' then - return utf16le.encode(text) + text = utf16le.encode(text) + if bom == 'yes' + or bom == 'auto' then + text = '\xFF\xFE' .. text + end + return text end if encoding == 'utf16be' then - return utf16be.encode(text) + text = utf16be.encode(text) + if bom == 'yes' + or bom == 'auto' then + text = '\xFE\xFF' .. text + end + return text end log.error('Unsupport encode encoding:', encoding) return text diff --git a/script/files.lua b/script/files.lua index 29a66d48..9b22ea41 100644 --- a/script/files.lua +++ b/script/files.lua @@ -124,7 +124,7 @@ function m.setText(uri, text, isTrust) if not text then return end - if #text > 1024 * 1024 * 100 then + if #text > 1024 * 1024 * 10 then local client = require 'client' client.showMessage('Warning', lang.script('WORKSPACE_SKIP_HUGE_FILE', uri)) return diff --git a/script/fs-utility.lua b/script/fs-utility.lua index f4e55716..a0fdc02f 100644 --- a/script/fs-utility.lua +++ b/script/fs-utility.lua @@ -16,7 +16,7 @@ _ENV = nil local m = {} --- 读取文件 ---@param path string -function m.loadFile(path) +function m.loadFile(path, keepBom) if type(path) ~= 'string' then ---@diagnostic disable-next-line: undefined-field path = path:string() @@ -25,12 +25,18 @@ function m.loadFile(path) if not f then return nil, e end - if f:read(3) ~= '\xEF\xBB\xBF' then - f:seek("set") - end - local buf = f:read 'a' + local text = f:read 'a' f:close() - return buf + if not keepBom then + if text:sub(1, 3) == '\xEF\xBB\xBF' then + return text:sub(4) + end + if text:sub(1, 2) == '\xFF\xFE' + or text:sub(1, 2) == '\xFE\xFF' then + return text:sub(3) + end + end + return text end --- 写入文件 diff --git a/script/library.lua b/script/library.lua index 0911750e..81242a91 100644 --- a/script/library.lua +++ b/script/library.lua @@ -236,7 +236,7 @@ local function initBuiltIn() local metaDoc = compileSingleMetaDoc(fsu.loadFile(libPath), metaLang, status) if metaDoc then local outPath = metaPath / libName - encoder.encode(encoding, metaDoc) + metaDoc = encoder.encode(encoding, metaDoc, 'auto') out:saveFile(libName, metaDoc) m.metaPaths[#m.metaPaths+1] = outPath:string() end @@ -341,6 +341,7 @@ local function apply3rd(cfg, onlyMemory) end local hasAsked +---@async local function askFor3rd(cfg) hasAsked = true local yes1 = lang.script.WINDOW_APPLY_WHIT_SETTING @@ -395,7 +396,7 @@ local function check3rdByWords(text, configs) if hasAsked then return end - await.call(function () + await.call(function () ---@async for _, cfg in ipairs(configs) do if cfg.words then for _, word in ipairs(cfg.words) do @@ -419,7 +420,7 @@ local function check3rdByFileName(uri, configs) if not path then return end - await.call(function () + await.call(function () ---@async for _, cfg in ipairs(configs) do if cfg.files then for _, filename in ipairs(cfg.files) do diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index e21e7c19..6f7593c1 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -10,9 +10,8 @@ local Parser = re.compile([[ Main <- (Token / Sp)* Sp <- %s+ X16 <- [a-fA-F0-9] -Word <- [a-zA-Z0-9_] Token <- Integer / Name / String / Symbol -Name <- ({} {[a-zA-Z_0-9] [a-zA-Z0-9_.*-]*} {}) +Name <- ({} {%name} {}) -> Name Integer <- ({} {[0-9]+} !'.' {}) -> Integer @@ -45,7 +44,7 @@ EChar <- 'a' -> ea / ('z' (%nl / %s)*) -> '' / ('x' {X16 X16}) -> Char16 / ([0-9] [0-9]? [0-9]?) -> Char10 - / ('u{' {Word*} '}') -> CharUtf8 + / ('u{' {X16*} '}') -> CharUtf8 Symbol <- ({} { [:|,<>()?+#`{}] / '[]' @@ -63,6 +62,7 @@ Symbol <- ({} { er = '\r', et = '\t', ev = '\v', + name = (m.R('az', 'AZ', '09', '\x80\xff') + m.S('_')) * (m.R('az', 'AZ', '__', '09', '\x80\xff') + m.S('_.*-'))^0, Char10 = function (char) char = tonumber(char) if not char or char < 0 or char > 255 then @@ -492,6 +492,19 @@ local function parseTypeUnitLiteralTable() end local function parseTypeUnit(parent, content) + if content == 'async' then + local tp, cont = peekToken() + if tp == 'name' then + if cont == 'fun' then + nextToken() + local func = parseTypeUnit(parent, cont) + if func then + func.async = true + return func + end + end + end + end local result if content == 'fun' then result = parseTypeUnitFunction() @@ -1098,6 +1111,14 @@ local function parseModule() return result end +local function parseAsync() + return { + type = 'doc.async', + start = getFinish(), + finish = getFinish(), + } +end + local function convertTokens() local tp, text = nextToken() if not tp then @@ -1141,6 +1162,8 @@ local function convertTokens() return parseDiagnostic() elseif text == 'module' then return parseModule() + elseif text == 'async' then + return parseAsync() end end diff --git a/script/plugin.lua b/script/plugin.lua index 26e99d53..f56dc9f9 100644 --- a/script/plugin.lua +++ b/script/plugin.lua @@ -50,6 +50,7 @@ local function resetFiles() end end +---@async local function checkTrustLoad() local filePath = LOGPATH .. '/trusted' local trusted = util.loadFile(filePath) @@ -79,7 +80,7 @@ function m.init() return end m.hasInited = true - await.call(function () + await.call(function () ---@async local ws = require 'workspace' m.interface = {} diff --git a/script/proto/define.lua b/script/proto/define.lua index 713857af..2409f972 100644 --- a/script/proto/define.lua +++ b/script/proto/define.lua @@ -44,6 +44,7 @@ m.DiagnosticDefaultSeverity = { ['no-implicit-any'] = 'Information', ['deprecated'] = 'Warning', ['different-requires'] = 'Warning', + ['await-in-sync'] = 'Warning', ['type-check'] = 'Warning', ['duplicate-doc-class'] = 'Warning', @@ -98,6 +99,7 @@ m.DiagnosticDefaultNeededFileStatus = { ['no-implicit-any'] = 'None', ['deprecated'] = 'Opened', ['different-requires'] = 'Any', + ['await-in-sync'] = 'None', ['type-check'] = 'None', ['duplicate-doc-class'] = 'Any', diff --git a/script/proto/proto.lua b/script/proto/proto.lua index e380f54f..d54c902f 100644 --- a/script/proto/proto.lua +++ b/script/proto/proto.lua @@ -68,6 +68,7 @@ function m.notify(name, params) io.write(buf) end +---@async function m.awaitRequest(name, params) local id = reqCounter() local buf = jsonrpc.encode { @@ -120,7 +121,7 @@ function m.doMethod(proto) if proto.id then m.holdon[proto.id] = proto end - await.call(function () + await.call(function () ---@async --log.debug('Start method:', method) if proto.id then await.setID('proto:' .. proto.id) @@ -146,6 +147,7 @@ function m.doMethod(proto) end end ok, res = xpcall(abil, log.error, proto.params) + await.delay() end) end diff --git a/script/provider/diagnostic.lua b/script/provider/diagnostic.lua index 492b3048..34bb10d4 100644 --- a/script/provider/diagnostic.lua +++ b/script/provider/diagnostic.lua @@ -152,11 +152,13 @@ function m.syntaxErrors(uri, ast) local results = {} - for _, err in ipairs(ast.errs) do - if not config.get 'Lua.diagnostics.disable'[err.type:lower():gsub('_', '-')] then - results[#results+1] = buildSyntaxError(uri, err) + pcall(function () + for _, err in ipairs(ast.errs) do + if not config.get 'Lua.diagnostics.disable'[err.type:lower():gsub('_', '-')] then + results[#results+1] = buildSyntaxError(uri, err) + end end - end + end) return results end @@ -180,6 +182,7 @@ function m.diagnostics(uri, diags) end) end +---@async function m.doDiagnostic(uri) if not config.get 'Lua.diagnostics.enable' then return @@ -265,15 +268,16 @@ function m.refresh(uri) return end await.close('diag:' .. uri) - await.call(function () + await.call(function () ---@async await.delay() if uri then - m.doDiagnostic(uri) + xpcall(m.doDiagnostic, log.error, uri) end m.diagnosticsAll() end, 'files.version') end +---@async local function askForDisable() if m.dontAskedForDisable then return @@ -332,7 +336,7 @@ function m.diagnosticsAll(force) return end await.close 'diagnosticsAll' - await.call(function () + await.call(function () ---@async await.sleep(delay) m.diagnosticsAllClock = os.clock() local clock = os.clock() @@ -347,7 +351,7 @@ function m.diagnosticsAll(force) for i, uri in ipairs(uris) do bar:setMessage(('%d/%d'):format(i, #uris)) bar:setPercentage(i / #uris * 100) - m.doDiagnostic(uri) + xpcall(m.doDiagnostic, log.error, uri) await.delay() if cancelled then log.debug('Break workspace diagnostics') @@ -375,6 +379,7 @@ function m.checkStepResult() end end +---@async function m.checkWorkspaceDiag() if not await.hasID 'diagnosticsAll' then return @@ -400,7 +405,7 @@ function m.checkWorkspaceDiag() return false end -files.watch(function (ev, uri) +files.watch(function (ev, uri) ---@async if ev == 'remove' then m.clear(uri) m.refresh(uri) @@ -410,7 +415,7 @@ files.watch(function (ev, uri) end elseif ev == 'open' then if ws.isReady() then - m.doDiagnostic(uri) + xpcall(m.doDiagnostic, log.error, uri) end elseif ev == 'close' then if files.isLibrary(uri) @@ -420,7 +425,7 @@ files.watch(function (ev, uri) end end) -await.watch(function (ev, co) +await.watch(function (ev, co) ---@async if ev == 'delay' then if m.checkStepResult then m.checkStepResult() diff --git a/script/provider/provider.lua b/script/provider/provider.lua index ac16c4e3..811dc4e0 100644 --- a/script/provider/provider.lua +++ b/script/provider/provider.lua @@ -16,6 +16,7 @@ local cfgLoader = require 'config.loader' local converter = require 'proto.converter' local filewatch = require 'filewatch' +---@async local function updateConfig() local new if CONFIGPATH then @@ -43,7 +44,7 @@ local function updateConfig() log.debug('loaded config dump:', util.dump(new)) end -filewatch.event(function (changes) +filewatch.event(function (changes) ---@async local configPath = workspace.getAbsolutePath(CONFIGPATH or '.luarc.json') if not configPath then return @@ -68,7 +69,7 @@ proto.on('initialize', function (params) } end) -proto.on('initialized', function (params) +proto.on('initialized', function (params) ---@async files.init() local _ <close> = progress.create(lang.script.WINDOW_INITIALIZING, 0.5) updateConfig() @@ -102,14 +103,14 @@ proto.on('shutdown', function () return true end) -proto.on('workspace/didChangeConfiguration', function () +proto.on('workspace/didChangeConfiguration', function () ---@async if CONFIGPATH then return end updateConfig() end) -proto.on('workspace/didCreateFiles', function (params) +proto.on('workspace/didCreateFiles', function (params) ---@async log.debug('workspace/didCreateFiles', util.dump(params)) for _, file in ipairs(params.files) do if workspace.isValidLuaUri(file.uri) then @@ -130,7 +131,7 @@ proto.on('workspace/didDeleteFiles', function (params) end end) -proto.on('workspace/didRenameFiles', function (params) +proto.on('workspace/didRenameFiles', function (params) ---@async log.debug('workspace/didRenameFiles', util.dump(params)) for _, file in ipairs(params.files) do local text = files.getOriginText(file.oldUri) @@ -157,7 +158,7 @@ proto.on('workspace/didRenameFiles', function (params) end end) -proto.on('textDocument/didOpen', function (params) +proto.on('textDocument/didOpen', function (params) ---@async workspace.awaitReady() local doc = params.textDocument local uri = doc.uri @@ -177,7 +178,7 @@ proto.on('textDocument/didClose', function (params) end end) -proto.on('textDocument/didChange', function (params) +proto.on('textDocument/didChange', function (params) ---@async workspace.awaitReady() local doc = params.textDocument local changes = params.contentChanges @@ -187,7 +188,7 @@ proto.on('textDocument/didChange', function (params) files.setText(uri, text, true) end) -proto.on('textDocument/hover', function (params) +proto.on('textDocument/hover', function (params) ---@async local doc = params.textDocument local uri = doc.uri if not workspace.isReady() then @@ -218,7 +219,7 @@ proto.on('textDocument/hover', function (params) } end) -proto.on('textDocument/definition', function (params) +proto.on('textDocument/definition', function (params) ---@async workspace.awaitReady() local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_DEFINITION, 0.5) local core = require 'core.definition' @@ -253,7 +254,7 @@ proto.on('textDocument/definition', function (params) return response end) -proto.on('textDocument/typeDefinition', function (params) +proto.on('textDocument/typeDefinition', function (params) ---@async workspace.awaitReady() local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_DEFINITION, 0.5) local core = require 'core.type-definition' @@ -288,7 +289,7 @@ proto.on('textDocument/typeDefinition', function (params) return response end) -proto.on('textDocument/references', function (params) +proto.on('textDocument/references', function (params) ---@async workspace.awaitReady() local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_REFERENCE, 0.5) local core = require 'core.reference' @@ -332,7 +333,7 @@ proto.on('textDocument/documentHighlight', function (params) return response end) -proto.on('textDocument/rename', function (params) +proto.on('textDocument/rename', function (params) ---@async workspace.awaitReady() local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_RENAME, 0.5) local core = require 'core.rename' @@ -376,7 +377,7 @@ proto.on('textDocument/prepareRename', function (params) } end) -proto.on('textDocument/completion', function (params) +proto.on('textDocument/completion', function (params) ---@async local uri = params.textDocument.uri if not workspace.isReady() then local count, max = workspace.getLoadProcess() @@ -408,7 +409,7 @@ proto.on('textDocument/completion', function (params) return end end - await.setPriority(1000) + --await.setPriority(1000) local clock = os.clock() local pos = converter.unpackPosition(uri, params.position) local result = core.completion(uri, pos, triggerCharacter) @@ -522,7 +523,7 @@ proto.on('completionItem/resolve', function (item) return item end) -proto.on('textDocument/signatureHelp', function (params) +proto.on('textDocument/signatureHelp', function (params) ---@async if not config.get 'Lua.signatureHelp.enable' then return nil end @@ -564,7 +565,7 @@ proto.on('textDocument/signatureHelp', function (params) } end) -proto.on('textDocument/documentSymbol', function (params) +proto.on('textDocument/documentSymbol', function (params) ---@async workspace.awaitReady() local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SYMBOL, 0.5) local core = require 'core.document-symbol' @@ -575,6 +576,7 @@ proto.on('textDocument/documentSymbol', function (params) return nil end + ---@async local function convert(symbol) await.delay() symbol.range = converter.packRange( @@ -636,7 +638,7 @@ proto.on('textDocument/codeAction', function (params) return results end) -proto.on('workspace/executeCommand', function (params) +proto.on('workspace/executeCommand', function (params) ---@async local command = params.command:gsub(':.+', '') if command == 'lua.removeSpace' then local core = require 'core.command.removeSpace' @@ -656,7 +658,7 @@ proto.on('workspace/executeCommand', function (params) end end) -proto.on('workspace/symbol', function (params) +proto.on('workspace/symbol', function (params) ---@async workspace.awaitReady() local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_WS_SYMBOL, 0.5) local core = require 'core.workspace-symbol' @@ -685,7 +687,7 @@ proto.on('workspace/symbol', function (params) return symbols end) -proto.on('textDocument/semanticTokens/full', function (params) +proto.on('textDocument/semanticTokens/full', function (params) ---@async local uri = params.textDocument.uri workspace.awaitReady() local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SEMANTIC_FULL, 0.5) @@ -696,7 +698,7 @@ proto.on('textDocument/semanticTokens/full', function (params) } end) -proto.on('textDocument/semanticTokens/range', function (params) +proto.on('textDocument/semanticTokens/range', function (params) ---@async local uri = params.textDocument.uri workspace.awaitReady() local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_SEMANTIC_RANGE, 0.5) @@ -716,7 +718,7 @@ proto.on('textDocument/semanticTokens/range', function (params) } end) -proto.on('textDocument/foldingRange', function (params) +proto.on('textDocument/foldingRange', function (params) ---@async local core = require 'core.folding' local uri = params.textDocument.uri if not files.exists(uri) then @@ -750,7 +752,7 @@ proto.on('window/workDoneProgress/cancel', function (params) progress.cancel(params.token) end) -proto.on('$/didChangeVisibleRanges', function (params) +proto.on('$/didChangeVisibleRanges', function (params) ---@async local uri = params.uri await.close('visible:' .. uri) await.setID('visible:' .. uri) @@ -758,7 +760,7 @@ proto.on('$/didChangeVisibleRanges', function (params) files.setVisibles(uri, params.ranges) end) -proto.on('$/status/click', function () +proto.on('$/status/click', function () ---@async -- TODO: translate local titleDiagnostic = '进行工作区诊断' local result = client.awaitRequestMessage('Info', 'xxx', { @@ -773,7 +775,7 @@ proto.on('$/status/click', function () end end) -proto.on('textDocument/onTypeFormatting', function (params) +proto.on('textDocument/onTypeFormatting', function (params) ---@async workspace.awaitReady() local _ <close> = progress.create(lang.script.WINDOW_PROCESSING_TYPE_FORMATTING, 0.5) local ch = params.ch @@ -805,7 +807,7 @@ proto.on('$/cancelRequest', function (params) proto.close(params.id, define.ErrorCodes.RequestCancelled) end) -proto.on('$/requestHint', function (params) +proto.on('$/requestHint', function (params) ---@async local core = require 'core.hint' if not config.get 'Lua.hint.enable' then return @@ -827,10 +829,14 @@ end) -- Hint do + ---@async local function updateHint(uri) if not config.get 'Lua.hint.enable' then return end + await.close 'updateHint' + await.setID 'updateHint' + await.delay() workspace.awaitReady() local visibles = files.getVisibles(uri) if not visibles then @@ -860,7 +866,7 @@ do files.watch(function (ev, uri) if ev == 'update' or ev == 'updateVisible' then - await.call(function () + await.call(function () ---@async updateHint(uri) end) end diff --git a/script/pub/pub.lua b/script/pub/pub.lua index ba57e5cb..fd780477 100644 --- a/script/pub/pub.lua +++ b/script/pub/pub.lua @@ -104,6 +104,7 @@ end ---@parma name string ---@param params any ---@return any +---@async function m.awaitTask(name, params) local info = { id = counter(), diff --git a/script/service/telemetry.lua b/script/service/telemetry.lua index 1ab3fdbe..dac72f3f 100644 --- a/script/service/telemetry.lua +++ b/script/service/telemetry.lua @@ -111,7 +111,7 @@ function m.updateConfig() end m.hasShowedMessage = true - await.call(function () + await.call(function () ---@async local enableTitle = lang.script.WINDOW_TELEMETRY_ENABLE local disableTitle = lang.script.WINDOW_TELEMETRY_DISABLE local item = proto.awaitRequest('window/showMessageRequest', { diff --git a/script/utility.lua b/script/utility.lua index 8d377708..b5eb4095 100644 --- a/script/utility.lua +++ b/script/utility.lua @@ -275,17 +275,23 @@ end --- 读取文件 ---@param path string -function m.loadFile(path) +function m.loadFile(path, keepBom) local f, e = ioOpen(path, 'rb') if not f then return nil, e end - if f:read(3) ~= '\xEF\xBB\xBF' then - f:seek("set") - end - local buf = f:read 'a' + local text = f:read 'a' f:close() - return buf + if not keepBom then + if text:sub(1, 3) == '\xEF\xBB\xBF' then + return text:sub(4) + end + if text:sub(1, 2) == '\xFF\xFE' + or text:sub(1, 2) == '\xFE\xFF' then + return text:sub(3) + end + end + return text end --- 写入文件 diff --git a/script/vm/getDocs.lua b/script/vm/getDocs.lua index 2fb2bda9..ed2299ec 100644 --- a/script/vm/getDocs.lua +++ b/script/vm/getDocs.lua @@ -163,6 +163,26 @@ local function isDeprecated(value) return false end +local function isAsync(value) + if value.type == 'function' then + if not value.bindDocs then + return false + end + if value._async ~= nil then + return value._async + end + for _, doc in ipairs(value.bindDocs) do + if doc.type == 'doc.async' then + value._async = true + return true + end + end + value._async = false + return false + end + return value.async == true +end + function vm.isDeprecated(value, deep) if deep then local defs = vm.getDefs(value) @@ -180,6 +200,23 @@ function vm.isDeprecated(value, deep) end end +function vm.isAsync(value, deep) + if deep then + local defs = vm.getDefs(value) + if #defs == 0 then + return false + end + for _, def in ipairs(defs) do + if isAsync(def) then + return true + end + end + return false + else + return isAsync(value) + end +end + local function makeDiagRange(uri, doc, results) local names if doc.names then diff --git a/script/workspace/workspace.lua b/script/workspace/workspace.lua index 726bec09..de534a96 100644 --- a/script/workspace/workspace.lua +++ b/script/workspace/workspace.lua @@ -74,6 +74,7 @@ local globInteferFace = { } --- 创建排除文件匹配器 +---@async function m.getNativeMatcher() if not m.path then return nil @@ -177,6 +178,7 @@ function m.getLibraryMatchers() end --- 文件是否被忽略 +---@async function m.isIgnored(uri) local path = m.getRelativePath(uri) local ignore = m.getNativeMatcher() @@ -186,6 +188,7 @@ function m.isIgnored(uri) return ignore(path) end +---@async function m.isValidLuaUri(uri) if not files.isLua(uri) then return false @@ -198,7 +201,7 @@ function m.isValidLuaUri(uri) end local function loadFileFactory(root, progressData, isLibrary) - return function (path) + return function (path) ---@async local uri = furi.encode(path) if files.isLua(uri) then if not isLibrary and progressData.preload >= config.get 'Lua.workspace.maxPreload' then @@ -279,6 +282,7 @@ local function loadFileFactory(root, progressData, isLibrary) end end +---@async function m.awaitLoadFile(uri) local progressBar <close> = progress.create(lang.script.WORKSPACE_LOADING) local progressData = { @@ -299,6 +303,7 @@ function m.awaitLoadFile(uri) end --- 预读工作区内所有文件 +---@async function m.awaitPreload() local diagnostic = require 'provider.diagnostic' await.close 'preload' @@ -347,7 +352,7 @@ function m.awaitPreload() if isLoadingFiles then return end - await.call(function () + await.call(function () ---@async isLoadingFiles = true while true do local loader = table.remove(progressData.loaders) @@ -563,6 +568,7 @@ function m.init() m.reload() end +---@async function m.awaitReload() m.ready = false m.hasHitMaxPreload = false @@ -580,6 +586,7 @@ function m.awaitReload() end ---等待工作目录加载完成 +---@async function m.awaitReady() if m.isReady() then return @@ -597,7 +604,7 @@ function m.getLoadProcess() return m.fileLoaded, m.fileFound end -files.watch(function (ev, uri) +files.watch(function (ev, uri) ---@async if ev == 'close' and m.isIgnored(uri) and not files.isLibrary(uri) then @@ -615,7 +622,7 @@ config.watch(function (key, value, oldValue) end end) -fw.event(function (changes) +fw.event(function (changes) ---@async m.awaitReady() for _, change in ipairs(changes) do local path = change.path |