perf(lsp): update semantic tokens algorithm for parsing modifiers (#21383)

Instead of testing for every possible modifier type, only test bits up
to the highest set in the token array. Saves many bit ops and
comparisons when there are no modifiers or when the highest set bit is a
lower bit than the highest possible in the legend on average.

Can be further simplified when non-luaJIT gets the full bit module (see #21222)
This commit is contained in:
jdrouhard 2022-12-12 11:42:37 -06:00 committed by GitHub
parent d40d34aaa5
commit 3869a2e0cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 37 deletions

View File

@ -55,22 +55,22 @@ end
---@private
---@return string[]
local function modifiers_from_number(x, modifiers_table)
---@private
local function _get_bit(n, k)
--TODO(jdrouhard): remove once `bit` module is available for non-LuaJIT
if _G.bit then
return _G.bit.band(_G.bit.rshift(n, k), 1)
else
return math.floor((n / math.pow(2, k)) % 2)
end
end
local modifiers = {}
for i = 0, #modifiers_table - 1 do
local b = _get_bit(x, i)
if b == 1 then
modifiers[#modifiers + 1] = modifiers_table[i + 1]
local idx = 1
while x > 0 do
if _G.bit then
if _G.bit.band(x, 1) == 1 then
modifiers[#modifiers + 1] = modifiers_table[idx]
end
x = _G.bit.rshift(x, 1)
else
--TODO(jdrouhard): remove this branch once `bit` module is available for non-LuaJIT (#21222)
if x % 2 == 1 then
modifiers[#modifiers + 1] = modifiers_table[idx]
end
x = math.floor(x / 2)
end
idx = idx + 1
end
return modifiers

View File

@ -459,29 +459,6 @@ describe('semantic token highlighting', function()
{1:~ }|
|
]] }
exec_lua([[
vim.lsp.semantic_tokens.start(bufnr, client_id)
]])
screen:expect { grid = [[
#include <iostream> |
|
int main() |
{ |
int x; |
#ifdef __cplusplus |
std::cout << x << "\n"; |
#else |
printf("%d\n", x); |
#endif |
} |
^} |
{1:~ }|
{1:~ }|
{1:~ }|
|
]], unchanged = true }
end)
it('does not send delta requests if not supported by server', function()