Skip to content

Commit

Permalink
Merge pull request #2994 from findstr/master
Browse files Browse the repository at this point in the history
add setting`Lua.hint.awaitPropagate`
  • Loading branch information
sumneko authored Dec 20, 2024
2 parents 7f76050 + 4b13b1a commit 55aa1b9
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 18 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased
<!-- Add all new changes here. They will be moved under a version at release -->
* `FIX` Incorrect infer for function array annotation on tables [#2367](https://github.com/LuaLS/lua-language-server/issues/2367)
* `NEW` Setting: `Lua.hint.awaitPropagate`: When enabled, --@async propagates to the caller.

## 3.13.4
`2024-12-13`
Expand Down
3 changes: 3 additions & 0 deletions locale/en-us/setting.lua
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ config.hint.arrayIndex.Disable =
'Disable hints of array index.'
config.hint.await =
'If the called function is marked `---@async`, prompt `await` at the call.'
config.hint.awaitPropagate =
'Enable the propagation of `await`. When a function calls a function marked `---@async`,\z
it will be automatically marked as `---@async`.'
config.hint.semicolon =
'If there is no semicolon at the end of the statement, display a virtual semicolon.'
config.hint.semicolon.All =
Expand Down
3 changes: 3 additions & 0 deletions locale/ja-jp/setting.lua
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ config.hint.arrayIndex.Disable = -- TODO: need translate!
'Disable hints of array index.'
config.hint.await = -- TODO: need translate!
'If the called function is marked `---@async`, prompt `await` at the call.'
config.hint.awaitPropagate = -- TODO: need translate!
'Enable the propagation of `await`. When a function calls a function marked `---@async`,\z
it will be automatically marked as `---@async`.'
config.hint.semicolon = -- TODO: need translate!
'If there is no semicolon at the end of the statement, display a virtual semicolon.'
config.hint.semicolon.All = -- TODO: need translate!
Expand Down
3 changes: 3 additions & 0 deletions locale/pt-br/setting.lua
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ config.hint.arrayIndex.Disable = -- TODO: need translate!
'Disable hints of array index.'
config.hint.await = -- TODO: need translate!
'If the called function is marked `---@async`, prompt `await` at the call.'
config.hint.awaitPropagate = -- TODO: need translate!
'Enable the propagation of `await`. When a function calls a function marked `---@async`,\z
it will be automatically marked as `---@async`.'
config.hint.semicolon = -- TODO: need translate!
'If there is no semicolon at the end of the statement, display a virtual semicolon.'
config.hint.semicolon.All = -- TODO: need translate!
Expand Down
2 changes: 2 additions & 0 deletions locale/zh-cn/setting.lua
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ config.hint.arrayIndex.Disable =
'禁用数组索引提示。'
config.hint.await =
'如果调用的函数被标记为了 `---@async` ,则在调用处提示 `await` 。'
config.hint.awaitPropagate =
'启用 `await` 的传播, 当一个函数调用了一个`---@async`标记的函数时,会自动标记为`---@async`。'
config.hint.semicolon =
'若语句尾部没有分号,则显示虚拟分号。'
config.hint.semicolon.All =
Expand Down
2 changes: 2 additions & 0 deletions locale/zh-tw/setting.lua
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ config.hint.arrayIndex.Disable =
'停用陣列索引提示。'
config.hint.await =
'如果呼叫的函數被標記為了 `---@async`,則在呼叫處提示 `await`。'
config.hint.awaitPropagate =
'啟用 `await` 的傳播,當一個函數呼叫了一個 `---@async` 標記的函數時,會自動標記為 `---@async`。'
config.hint.semicolon =
'若陳述式尾部沒有分號,則顯示虛擬分號。'
config.hint.semicolon.All =
Expand Down
1 change: 1 addition & 0 deletions script/config/template.lua
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ local template = {
'Disable',
},
['Lua.hint.await'] = Type.Boolean >> true,
['Lua.hint.awaitPropagate'] = Type.Boolean >> false,
['Lua.hint.arrayIndex'] = Type.String >> 'Auto' << {
'Enable',
'Auto',
Expand Down
74 changes: 56 additions & 18 deletions script/vm/doc.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
local files = require 'files'
local guide = require 'parser.guide'
local files = require 'files'
local await = require 'await'
local guide = require 'parser.guide'
---@class vm
local vm = require 'vm.vm'
local config = require 'config'
local vm = require 'vm.vm'
local config = require 'config'

---@class parser.object
---@field package _castTargetHead? parser.object | vm.global | false
Expand Down Expand Up @@ -186,20 +187,53 @@ function vm.getDeprecated(value, deep)
end

---@param value parser.object
---@param propagate boolean
---@param deepLevel integer?
---@return boolean
local function isAsync(value)
local function isAsync(value, propagate, deepLevel)
if value.type == 'function' then
if not value.bindDocs then
return false
end
if value._async ~= nil then
if value._async ~= nil then --already calculated, directly return
return value._async
end
for _, doc in ipairs(value.bindDocs) do
if doc.type == 'doc.async' then
value._async = true
local asyncCache
if propagate then
asyncCache = vm.getCache 'async.propagate'
local result = asyncCache[value]
if result ~= nil then
return result
end
end
if value.bindDocs then --try parse the annotation
for _, doc in ipairs(value.bindDocs) do
if doc.type == 'doc.async' then
value._async = true
return true
end
end
end
if propagate then -- if enable async propagation, try check calling functions
if deepLevel and deepLevel > 50 then
return false
end
local isAsyncCall = vm.isAsyncCall
local callingAsync = guide.eachSourceType(value, 'call', function (source)
local parent = guide.getParentFunction(source)
if parent ~= value then
return nil
end
local nextLevel = (deepLevel or 1) + 1
local ok = isAsyncCall(source, nextLevel)
if ok then --if any calling function is async, directly return
return ok
end
--if not, try check the next calling function
return nil
end)
if callingAsync then
asyncCache[value] = true
return true
end
asyncCache[value] = false
end
value._async = false
return false
Expand All @@ -212,9 +246,12 @@ end

---@param value parser.object
---@param deep boolean?
---@param deepLevel integer?
---@return boolean
function vm.isAsync(value, deep)
if isAsync(value) then
function vm.isAsync(value, deep, deepLevel)
local uri = guide.getUri(value)
local propagate = config.get(uri, 'Lua.hint.awaitPropagate')
if isAsync(value, propagate, deepLevel) then
return true
end
if deep then
Expand All @@ -223,7 +260,7 @@ function vm.isAsync(value, deep)
return false
end
for _, def in ipairs(defs) do
if isAsync(def) then
if isAsync(def, propagate, deepLevel) then
return true
end
end
Expand Down Expand Up @@ -325,16 +362,17 @@ function vm.isLinkedCall(node, index)
end

---@param call parser.object
---@param deepLevel integer?
---@return boolean
function vm.isAsyncCall(call)
if vm.isAsync(call.node, true) then
function vm.isAsyncCall(call, deepLevel)
if vm.isAsync(call.node, true, deepLevel) then
return true
end
if not call.args then
return false
end
for i, arg in ipairs(call.args) do
if vm.isAsync(arg, true)
if vm.isAsync(arg, true, deepLevel)
and isLinkedCall(call.node, i) then
return true
end
Expand Down

0 comments on commit 55aa1b9

Please sign in to comment.