Skip to content

Commit 4b13b1a

Browse files
committed
add settingLua.hint.awaitPropagate
This option is disabled by default. When disabled, it has no impact on performance. When enabled, --@async propagates to the caller.
1 parent 7f76050 commit 4b13b1a

File tree

8 files changed

+71
-18
lines changed

8 files changed

+71
-18
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44
<!-- Add all new changes here. They will be moved under a version at release -->
55
* `FIX` Incorrect infer for function array annotation on tables [#2367](https://github.com/LuaLS/lua-language-server/issues/2367)
6+
* `NEW` Setting: `Lua.hint.awaitPropagate`: When enabled, --@async propagates to the caller.
67

78
## 3.13.4
89
`2024-12-13`

locale/en-us/setting.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ config.hint.arrayIndex.Disable =
256256
'Disable hints of array index.'
257257
config.hint.await =
258258
'If the called function is marked `---@async`, prompt `await` at the call.'
259+
config.hint.awaitPropagate =
260+
'Enable the propagation of `await`. When a function calls a function marked `---@async`,\z
261+
it will be automatically marked as `---@async`.'
259262
config.hint.semicolon =
260263
'If there is no semicolon at the end of the statement, display a virtual semicolon.'
261264
config.hint.semicolon.All =

locale/ja-jp/setting.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ config.hint.arrayIndex.Disable = -- TODO: need translate!
256256
'Disable hints of array index.'
257257
config.hint.await = -- TODO: need translate!
258258
'If the called function is marked `---@async`, prompt `await` at the call.'
259+
config.hint.awaitPropagate = -- TODO: need translate!
260+
'Enable the propagation of `await`. When a function calls a function marked `---@async`,\z
261+
it will be automatically marked as `---@async`.'
259262
config.hint.semicolon = -- TODO: need translate!
260263
'If there is no semicolon at the end of the statement, display a virtual semicolon.'
261264
config.hint.semicolon.All = -- TODO: need translate!

locale/pt-br/setting.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ config.hint.arrayIndex.Disable = -- TODO: need translate!
256256
'Disable hints of array index.'
257257
config.hint.await = -- TODO: need translate!
258258
'If the called function is marked `---@async`, prompt `await` at the call.'
259+
config.hint.awaitPropagate = -- TODO: need translate!
260+
'Enable the propagation of `await`. When a function calls a function marked `---@async`,\z
261+
it will be automatically marked as `---@async`.'
259262
config.hint.semicolon = -- TODO: need translate!
260263
'If there is no semicolon at the end of the statement, display a virtual semicolon.'
261264
config.hint.semicolon.All = -- TODO: need translate!

locale/zh-cn/setting.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ config.hint.arrayIndex.Disable =
255255
'禁用数组索引提示。'
256256
config.hint.await =
257257
'如果调用的函数被标记为了 `---@async` ,则在调用处提示 `await` 。'
258+
config.hint.awaitPropagate =
259+
'启用 `await` 的传播, 当一个函数调用了一个`---@async`标记的函数时,会自动标记为`---@async`。'
258260
config.hint.semicolon =
259261
'若语句尾部没有分号,则显示虚拟分号。'
260262
config.hint.semicolon.All =

locale/zh-tw/setting.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ config.hint.arrayIndex.Disable =
255255
'停用陣列索引提示。'
256256
config.hint.await =
257257
'如果呼叫的函數被標記為了 `---@async`,則在呼叫處提示 `await`。'
258+
config.hint.awaitPropagate =
259+
'啟用 `await` 的傳播,當一個函數呼叫了一個 `---@async` 標記的函數時,會自動標記為 `---@async`。'
258260
config.hint.semicolon =
259261
'若陳述式尾部沒有分號,則顯示虛擬分號。'
260262
config.hint.semicolon.All =

script/config/template.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ local template = {
369369
'Disable',
370370
},
371371
['Lua.hint.await'] = Type.Boolean >> true,
372+
['Lua.hint.awaitPropagate'] = Type.Boolean >> false,
372373
['Lua.hint.arrayIndex'] = Type.String >> 'Auto' << {
373374
'Enable',
374375
'Auto',

script/vm/doc.lua

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
local files = require 'files'
2-
local guide = require 'parser.guide'
1+
local files = require 'files'
2+
local await = require 'await'
3+
local guide = require 'parser.guide'
34
---@class vm
4-
local vm = require 'vm.vm'
5-
local config = require 'config'
5+
local vm = require 'vm.vm'
6+
local config = require 'config'
67

78
---@class parser.object
89
---@field package _castTargetHead? parser.object | vm.global | false
@@ -186,20 +187,53 @@ function vm.getDeprecated(value, deep)
186187
end
187188

188189
---@param value parser.object
190+
---@param propagate boolean
191+
---@param deepLevel integer?
189192
---@return boolean
190-
local function isAsync(value)
193+
local function isAsync(value, propagate, deepLevel)
191194
if value.type == 'function' then
192-
if not value.bindDocs then
193-
return false
194-
end
195-
if value._async ~= nil then
195+
if value._async ~= nil then --already calculated, directly return
196196
return value._async
197197
end
198-
for _, doc in ipairs(value.bindDocs) do
199-
if doc.type == 'doc.async' then
200-
value._async = true
198+
local asyncCache
199+
if propagate then
200+
asyncCache = vm.getCache 'async.propagate'
201+
local result = asyncCache[value]
202+
if result ~= nil then
203+
return result
204+
end
205+
end
206+
if value.bindDocs then --try parse the annotation
207+
for _, doc in ipairs(value.bindDocs) do
208+
if doc.type == 'doc.async' then
209+
value._async = true
210+
return true
211+
end
212+
end
213+
end
214+
if propagate then -- if enable async propagation, try check calling functions
215+
if deepLevel and deepLevel > 50 then
216+
return false
217+
end
218+
local isAsyncCall = vm.isAsyncCall
219+
local callingAsync = guide.eachSourceType(value, 'call', function (source)
220+
local parent = guide.getParentFunction(source)
221+
if parent ~= value then
222+
return nil
223+
end
224+
local nextLevel = (deepLevel or 1) + 1
225+
local ok = isAsyncCall(source, nextLevel)
226+
if ok then --if any calling function is async, directly return
227+
return ok
228+
end
229+
--if not, try check the next calling function
230+
return nil
231+
end)
232+
if callingAsync then
233+
asyncCache[value] = true
201234
return true
202235
end
236+
asyncCache[value] = false
203237
end
204238
value._async = false
205239
return false
@@ -212,9 +246,12 @@ end
212246

213247
---@param value parser.object
214248
---@param deep boolean?
249+
---@param deepLevel integer?
215250
---@return boolean
216-
function vm.isAsync(value, deep)
217-
if isAsync(value) then
251+
function vm.isAsync(value, deep, deepLevel)
252+
local uri = guide.getUri(value)
253+
local propagate = config.get(uri, 'Lua.hint.awaitPropagate')
254+
if isAsync(value, propagate, deepLevel) then
218255
return true
219256
end
220257
if deep then
@@ -223,7 +260,7 @@ function vm.isAsync(value, deep)
223260
return false
224261
end
225262
for _, def in ipairs(defs) do
226-
if isAsync(def) then
263+
if isAsync(def, propagate, deepLevel) then
227264
return true
228265
end
229266
end
@@ -325,16 +362,17 @@ function vm.isLinkedCall(node, index)
325362
end
326363

327364
---@param call parser.object
365+
---@param deepLevel integer?
328366
---@return boolean
329-
function vm.isAsyncCall(call)
330-
if vm.isAsync(call.node, true) then
367+
function vm.isAsyncCall(call, deepLevel)
368+
if vm.isAsync(call.node, true, deepLevel) then
331369
return true
332370
end
333371
if not call.args then
334372
return false
335373
end
336374
for i, arg in ipairs(call.args) do
337-
if vm.isAsync(arg, true)
375+
if vm.isAsync(arg, true, deepLevel)
338376
and isLinkedCall(call.node, i) then
339377
return true
340378
end

0 commit comments

Comments
 (0)