summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
Diffstat (limited to 'script')
-rw-r--r--script/await.lua7
-rw-r--r--script/client.lua1
-rw-r--r--script/config/config.lua1
-rw-r--r--script/config/loader.lua1
-rw-r--r--script/core/code-action.lua40
-rw-r--r--script/core/command/autoRequire.lua2
-rw-r--r--script/core/command/jsonToLua.lua1
-rw-r--r--script/core/command/removeSpace.lua1
-rw-r--r--script/core/command/solve.lua1
-rw-r--r--script/core/completion.lua27
-rw-r--r--script/core/diagnostics/await-in-sync.lua26
-rw-r--r--script/core/diagnostics/deprecated.lua2
-rw-r--r--script/core/diagnostics/init.lua1
-rw-r--r--script/core/diagnostics/redundant-value.lua2
-rw-r--r--script/core/diagnostics/type-check.lua29
-rw-r--r--script/core/diagnostics/undefined-field.lua1
-rw-r--r--script/core/diagnostics/undefined-global.lua2
-rw-r--r--script/core/diagnostics/unused-function.lua3
-rw-r--r--script/core/document-symbol.lua5
-rw-r--r--script/core/folding.lua3
-rw-r--r--script/core/generic.lua2
-rw-r--r--script/core/hint.lua40
-rw-r--r--script/core/hover/init.lua8
-rw-r--r--script/core/hover/label.lua14
-rw-r--r--script/core/hover/table.lua1
-rw-r--r--script/core/semantic-tokens.lua2
-rw-r--r--script/core/signature.lua3
-rw-r--r--script/core/workspace-symbol.lua1
-rw-r--r--script/encoder/init.lua22
-rw-r--r--script/files.lua2
-rw-r--r--script/fs-utility.lua18
-rw-r--r--script/library.lua7
-rw-r--r--script/parser/luadoc.lua29
-rw-r--r--script/plugin.lua3
-rw-r--r--script/proto/define.lua2
-rw-r--r--script/proto/proto.lua4
-rw-r--r--script/provider/diagnostic.lua27
-rw-r--r--script/provider/provider.lua58
-rw-r--r--script/pub/pub.lua1
-rw-r--r--script/service/telemetry.lua2
-rw-r--r--script/utility.lua18
-rw-r--r--script/vm/getDocs.lua37
-rw-r--r--script/workspace/workspace.lua15
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