aboutsummaryrefslogtreecommitdiff
path: root/scripts/gen_lsp.lua
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/gen_lsp.lua')
-rw-r--r--scripts/gen_lsp.lua126
1 files changed, 118 insertions, 8 deletions
diff --git a/scripts/gen_lsp.lua b/scripts/gen_lsp.lua
index 9fbcc1c15e..943e88896b 100644
--- a/scripts/gen_lsp.lua
+++ b/scripts/gen_lsp.lua
@@ -24,7 +24,17 @@ local function tofile(fname, text)
end
end
----@param opt gen_lsp._opt
+--- The LSP protocol JSON data (it's partial, non-exhaustive).
+--- https://raw.githubusercontent.com/microsoft/language-server-protocol/gh-pages/_specifications/lsp/3.18/metaModel/metaModel.schema.json
+--- @class vim._gen_lsp.Protocol
+--- @field requests vim._gen_lsp.Request[]
+--- @field notifications vim._gen_lsp.Notification[]
+--- @field structures vim._gen_lsp.Structure[]
+--- @field enumerations vim._gen_lsp.Enumeration[]
+--- @field typeAliases vim._gen_lsp.TypeAlias[]
+
+---@param opt vim._gen_lsp.opt
+---@return vim._gen_lsp.Protocol
local function read_json(opt)
local uri = 'https://raw.githubusercontent.com/microsoft/language-server-protocol/gh-pages/_specifications/lsp/'
.. opt.version
@@ -46,6 +56,7 @@ local function name(s)
return s:gsub('^%$', 'dollar'):gsub('/', '_')
end
+---@param protocol vim._gen_lsp.Protocol
local function gen_methods(protocol)
local output = {
'-- Generated by gen_lsp.lua, keep at end of file.',
@@ -56,6 +67,32 @@ local function gen_methods(protocol)
}
local indent = (' '):rep(2)
+ --- @class vim._gen_lsp.Request
+ --- @field deprecated? string
+ --- @field documentation? string
+ --- @field messageDirection string
+ --- @field method string
+ --- @field params? any
+ --- @field proposed? boolean
+ --- @field registrationMethod? string
+ --- @field registrationOptions? any
+ --- @field since? string
+
+ --- @class vim._gen_lsp.Notification
+ --- @field deprecated? string
+ --- @field documentation? string
+ --- @field errorData? any
+ --- @field messageDirection string
+ --- @field method string
+ --- @field params? any[]
+ --- @field partialResult? any
+ --- @field proposed? boolean
+ --- @field registrationMethod? string
+ --- @field registrationOptions? any
+ --- @field result any
+ --- @field since? string
+
+ ---@type (vim._gen_lsp.Request|vim._gen_lsp.Notification)[]
local all = vim.list_extend(protocol.requests, protocol.notifications)
table.sort(all, function(a, b)
return name(a.method) < name(b.method)
@@ -106,14 +143,15 @@ return protocol
vim.cmd.write()
end
----@class gen_lsp._opt
+---@class vim._gen_lsp.opt
---@field output_file string
---@field version string
---@field methods boolean
----@param opt gen_lsp._opt
+---@param opt vim._gen_lsp.opt
function M.gen(opt)
- local protocol = read_json(opt) --- @type table
+ --- @type vim._gen_lsp.Protocol
+ local protocol = read_json(opt)
if opt.methods then
gen_methods(protocol)
@@ -144,6 +182,7 @@ function M.gen(opt)
local anonymous_num = 0
+ ---@type string[]
local anonym_classes = {}
local simple_types = {
@@ -154,32 +193,65 @@ function M.gen(opt)
'decimal',
}
+ --- @class vim._gen_lsp.Type
+ --- @field kind string a common field for all Types.
+ --- @field name? string for ReferenceType, BaseType
+ --- @field element? any for ArrayType
+ --- @field items? vim._gen_lsp.Type[] for OrType, AndType
+ --- @field key? vim._gen_lsp.Type for MapType
+ --- @field value? string|vim._gen_lsp.Type for StringLiteralType, MapType, StructureLiteralType
+
+ ---@param type vim._gen_lsp.Type
+ ---@return string
local function parse_type(type)
+ -- ReferenceType | BaseType
if type.kind == 'reference' or type.kind == 'base' then
if vim.tbl_contains(simple_types, type.name) then
return type.name
end
return 'lsp.' .. type.name
+
+ -- ArrayType
elseif type.kind == 'array' then
return parse_type(type.element) .. '[]'
+
+ -- OrType
elseif type.kind == 'or' then
local val = ''
for _, item in ipairs(type.items) do
- val = val .. parse_type(item) .. '|'
+ val = val .. parse_type(item) .. '|' --[[ @as string ]]
end
val = val:sub(0, -2)
return val
+
+ -- StringLiteralType
elseif type.kind == 'stringLiteral' then
return '"' .. type.value .. '"'
+
+ -- MapType
elseif type.kind == 'map' then
- return 'table<' .. parse_type(type.key) .. ', ' .. parse_type(type.value) .. '>'
+ local key = assert(type.key)
+ local value = type.value --[[ @as vim._gen_lsp.Type ]]
+ return 'table<' .. parse_type(key) .. ', ' .. parse_type(value) .. '>'
+
+ -- StructureLiteralType
elseif type.kind == 'literal' then
-- can I use ---@param disabled? {reason: string}
-- use | to continue the inline class to be able to add docs
-- https://github.com/LuaLS/lua-language-server/issues/2128
anonymous_num = anonymous_num + 1
local anonym = { '---@class anonym' .. anonymous_num }
- for _, field in ipairs(type.value.properties) do
+
+ --- @class vim._gen_lsp.StructureLiteral translated to anonymous @class.
+ --- @field deprecated? string
+ --- @field description? string
+ --- @field properties vim._gen_lsp.Property[]
+ --- @field proposed? boolean
+ --- @field since? string
+
+ ---@type vim._gen_lsp.StructureLiteral
+ local structural_literal = assert(type.value) --[[ @as vim._gen_lsp.StructureLiteral ]]
+ for _, field in ipairs(structural_literal.properties) do
if field.documentation then
field.documentation = field.documentation:gsub('\n', '\n---')
anonym[#anonym + 1] = '---' .. field.documentation
@@ -195,6 +267,8 @@ function M.gen(opt)
anonym_classes[#anonym_classes + 1] = line
end
return 'anonym' .. anonymous_num
+
+ -- TupleType
elseif type.kind == 'tuple' then
local tuple = '{ '
for i, value in ipairs(type.items) do
@@ -204,10 +278,20 @@ function M.gen(opt)
tuple = tuple:sub(0, -3)
return tuple .. ' }'
end
- vim.print(type)
+
+ vim.print('WARNING: Unknown type ', type)
return ''
end
+ --- @class vim._gen_lsp.Structure translated to @class
+ --- @field deprecated? string
+ --- @field documentation? string
+ --- @field extends? { kind: string, name: string }[]
+ --- @field mixins? { kind: string, name: string }[]
+ --- @field name string
+ --- @field properties? vim._gen_lsp.Property[] members, translated to @field
+ --- @field proposed? boolean
+ --- @field since? string
for _, structure in ipairs(protocol.structures) do
if structure.documentation then
structure.documentation = structure.documentation:gsub('\n', '\n---')
@@ -225,6 +309,15 @@ function M.gen(opt)
else
output[#output + 1] = '---@class lsp.' .. structure.name
end
+
+ --- @class vim._gen_lsp.Property translated to @field
+ --- @field deprecated? string
+ --- @field documentation? string
+ --- @field name string
+ --- @field optional? boolean
+ --- @field proposed? boolean
+ --- @field since? string
+ --- @field type { kind: string, name: string }
for _, field in ipairs(structure.properties or {}) do
if field.documentation then
field.documentation = field.documentation:gsub('\n', '\n---')
@@ -239,6 +332,14 @@ function M.gen(opt)
output[#output + 1] = ''
end
+ --- @class vim._gen_lsp.Enumeration translated to @enum
+ --- @field deprecated string?
+ --- @field documentation string?
+ --- @field name string?
+ --- @field proposed boolean?
+ --- @field since string?
+ --- @field suportsCustomValues boolean?
+ --- @field values { name: string, value: string, documentation?: string, since?: string }[]
for _, enum in ipairs(protocol.enumerations) do
if enum.documentation then
enum.documentation = enum.documentation:gsub('\n', '\n---')
@@ -256,6 +357,13 @@ function M.gen(opt)
output[#output + 1] = ''
end
+ --- @class vim._gen_lsp.TypeAlias translated to @alias
+ --- @field deprecated? string?
+ --- @field documentation? string
+ --- @field name string
+ --- @field proposed? boolean
+ --- @field since? string
+ --- @field type vim._gen_lsp.Type
for _, alias in ipairs(protocol.typeAliases) do
if alias.documentation then
alias.documentation = alias.documentation:gsub('\n', '\n---')
@@ -274,6 +382,7 @@ function M.gen(opt)
output[#output + 1] = ''
end
+ -- anonymous classes
for _, line in ipairs(anonym_classes) do
output[#output + 1] = line
end
@@ -281,6 +390,7 @@ function M.gen(opt)
tofile(opt.output_file, table.concat(output, '\n'))
end
+---@type vim._gen_lsp.opt
local opt = {
output_file = 'runtime/lua/vim/lsp/_meta/protocol.lua',
version = DEFAULT_LSP_VERSION,