Skip to content

Class methods trigger a missing required field error #3175

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
CWood-sdf opened this issue May 6, 2025 · 4 comments
Open

Class methods trigger a missing required field error #3175

CWood-sdf opened this issue May 6, 2025 · 4 comments

Comments

@CWood-sdf
Copy link

How are you using the lua-language-server?

NeoVim

Which OS are you using?

Linux

What is the issue affecting?

Type Checking, Annotations

Expected Behaviour

When I create a class with a class annotation:

---@class (exact) Foo
---@field g number
local Class = {
}

then add a method:

function Class:thing()

end

I would like to be able to initialize a class in a way that I get an error if I am missing a field (and not a method). The way I do that (correct me if this is not the proper way) is with the following code:

-- a function of some type
---@param g number
---@return Foo
local function constructor(g)
    -- type annotation so that i get a missing-fields diagnostic if i forget
    -- g or another field
    ---@type Foo
    local ret = {
        g = g,
    }
    -- setmetatable so ret has all the methods
    setmetatable(ret, { __index = Class })
    return ret
end

This used to work and I would get missing fields diagnostics for the problem. Then this changed after the 3.13.2 release. The problem is that now, along with any missing fields warnings for the fields I defined, I also get a missing-fields diagnostic for all methods as well. In the above example, I get a missing fields warning for thing. I bisected and this behavior was introduced in bbffd42.

Actual Behaviour

What is currently happening is that I get missing-fields diagnostics for both missing fields and missing methods. I would like to only get diagnostics for missing fields, and not methods, as those are defined by the setmetatable function

Reproduction steps

Create a file with the below contents:

local M = {}
---@class (exact) Foo
---@field g number
local Class = {
}

function Class:thing()

end

---@return Foo
function M.makeFoo()
    ---@type Foo
    local ret = {
        g = 0
    }
    setmetatable(ret, { __index = Class })

    return ret
end

return M

Open it in your editor of choice. When the lsp attaches, there will be a diagnostic on the local ret line (line 14) with the text: "Missing required fields in type Foo: thing"

Additional Notes

No response

Log File

This is the log file I have from neovim

[START][2025-05-06 00:55:21] LSP logging initiated
[INFO][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:597 "Starting RPC client" { cmd = { "/home/christopher-wood/fun/lua-language-server/bin/lua-language-server" }, extra = { cwd = "/home/christopher-wood/projects/lualsbug" } }
[TRACE][2025-05-06 00:55:21] ...m/lsp/client.lua:546 "LSP[lua_ls]" "init_params" { capabilities = { general = { positionEncodings = { "utf-8", "utf-16", "utf-32" } }, textDocument = { callHierarchy = { dynamicRegistration = false }, codeAction = { codeActionLiteralSupport = { codeActionKind = { valueSet = { "", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" } } }, dataSupport = true, dynamicRegistration = true, isPreferredSupport = true, resolveSupport = { properties = { "edit", "command" } } }, codeLens = { dynamicRegistration = false, resolveSupport = { properties = { "command" } } }, completion = { completionItem = { commitCharactersSupport = false, deprecatedSupport = true, documentationFormat = { "markdown", "plaintext" }, preselectSupport = false, resolveSupport = { properties = { "additionalTextEdits", "command" } }, snippetSupport = true, tagSupport = { valueSet = { 1 } } }, completionItemKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 } }, completionList = { itemDefaults = { "editRange", "insertTextFormat", "insertTextMode", "data" } }, contextSupport = true, dynamicRegistration = false }, declaration = { linkSupport = true }, definition = { dynamicRegistration = true, linkSupport = true }, diagnostic = { dynamicRegistration = false }, documentHighlight = { dynamicRegistration = false }, documentSymbol = { dynamicRegistration = false, hierarchicalDocumentSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, foldingRange = { dynamicRegistration = false, foldingRange = { collapsedText = true }, lineFoldingOnly = true }, formatting = { dynamicRegistration = true }, hover = { contentFormat = { "markdown", "plaintext" }, dynamicRegistration = true }, implementation = { linkSupport = true }, inlayHint = { dynamicRegistration = true, resolveSupport = { properties = { "textEdits", "tooltip", "location", "command" } } }, publishDiagnostics = { dataSupport = true, relatedInformation = true, tagSupport = { valueSet = { 1, 2 } } }, rangeFormatting = { dynamicRegistration = true, rangesSupport = true }, references = { dynamicRegistration = false }, rename = { dynamicRegistration = true, prepareSupport = true }, semanticTokens = { augmentsSyntaxTokens = true, dynamicRegistration = false, formats = { "relative" }, multilineTokenSupport = false, overlappingTokenSupport = true, requests = { full = { delta = true }, range = false }, serverCancelSupport = false, tokenModifiers = { "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary" }, tokenTypes = { "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" } }, signatureHelp = { dynamicRegistration = false, signatureInformation = { activeParameterSupport = true, documentationFormat = { "markdown", "plaintext" }, parameterInformation = { labelOffsetSupport = true } } }, synchronization = { didSave = true, dynamicRegistration = false, willSave = true, willSaveWaitUntil = true }, typeDefinition = { linkSupport = true } }, window = { showDocument = { support = true }, showMessage = { messageActionItem = { additionalPropertiesSupport = true } }, workDoneProgress = true }, workspace = { applyEdit = true, configuration = true, didChangeConfiguration = { dynamicRegistration = false }, didChangeWatchedFiles = { dynamicRegistration = false, relativePatternSupport = true }, inlayHint = { refreshSupport = true }, semanticTokens = { refreshSupport = true }, symbol = { dynamicRegistration = false, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, workspaceEdit = { resourceOperations = { "rename", "create", "delete" } }, workspaceFolders = true } }, clientInfo = { name = "Neovim", version = "0.12.0-dev+gac8ae1596c" }, initializationOptions = vim.empty_dict(), processId = 1837179, rootPath = "/home/christopher-wood/projects/lualsbug", rootUri = "file:///home/christopher-wood/projects/lualsbug", trace = "off", workDoneToken = "1", workspaceFolders = { { name = "/home/christopher-wood/projects/lualsbug", uri = "file:///home/christopher-wood/projects/lualsbug" } } }
[DEBUG][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 1, jsonrpc = "2.0", method = "initialize", params = { capabilities = { general = { positionEncodings = { "utf-8", "utf-16", "utf-32" } }, textDocument = { callHierarchy = { dynamicRegistration = false }, codeAction = { codeActionLiteralSupport = { codeActionKind = { valueSet = { "", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" } } }, dataSupport = true, dynamicRegistration = true, isPreferredSupport = true, resolveSupport = { properties = { "edit", "command" } } }, codeLens = { dynamicRegistration = false, resolveSupport = { properties = { "command" } } }, completion = { completionItem = { commitCharactersSupport = false, deprecatedSupport = true, documentationFormat = { "markdown", "plaintext" }, preselectSupport = false, resolveSupport = { properties = { "additionalTextEdits", "command" } }, snippetSupport = true, tagSupport = { valueSet = { 1 } } }, completionItemKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 } }, completionList = { itemDefaults = { "editRange", "insertTextFormat", "insertTextMode", "data" } }, contextSupport = true, dynamicRegistration = false }, declaration = { linkSupport = true }, definition = { dynamicRegistration = true, linkSupport = true }, diagnostic = { dynamicRegistration = false }, documentHighlight = { dynamicRegistration = false }, documentSymbol = { dynamicRegistration = false, hierarchicalDocumentSymbolSupport = true, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, foldingRange = { dynamicRegistration = false, foldingRange = { collapsedText = true }, lineFoldingOnly = true }, formatting = { dynamicRegistration = true }, hover = { contentFormat = { "markdown", "plaintext" }, dynamicRegistration = true }, implementation = { linkSupport = true }, inlayHint = { dynamicRegistration = true, resolveSupport = { properties = { "textEdits", "tooltip", "location", "command" } } }, publishDiagnostics = { dataSupport = true, relatedInformation = true, tagSupport = { valueSet = { 1, 2 } } }, rangeFormatting = { dynamicRegistration = true, rangesSupport = true }, references = { dynamicRegistration = false }, rename = { dynamicRegistration = true, prepareSupport = true }, semanticTokens = { augmentsSyntaxTokens = true, dynamicRegistration = false, formats = { "relative" }, multilineTokenSupport = false, overlappingTokenSupport = true, requests = { full = { delta = true }, range = false }, serverCancelSupport = false, tokenModifiers = { "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary" }, tokenTypes = { "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" } }, signatureHelp = { dynamicRegistration = false, signatureInformation = { activeParameterSupport = true, documentationFormat = { "markdown", "plaintext" }, parameterInformation = { labelOffsetSupport = true } } }, synchronization = { didSave = true, dynamicRegistration = false, willSave = true, willSaveWaitUntil = true }, typeDefinition = { linkSupport = true } }, window = { showDocument = { support = true }, showMessage = { messageActionItem = { additionalPropertiesSupport = true } }, workDoneProgress = true }, workspace = { applyEdit = true, configuration = true, didChangeConfiguration = { dynamicRegistration = false }, didChangeWatchedFiles = { dynamicRegistration = false, relativePatternSupport = true }, inlayHint = { refreshSupport = true }, semanticTokens = { refreshSupport = true }, symbol = { dynamicRegistration = false, symbolKind = { valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } } }, workspaceEdit = { resourceOperations = { "rename", "create", "delete" } }, workspaceFolders = true } }, clientInfo = { name = "Neovim", version = "0.12.0-dev+gac8ae1596c" }, initializationOptions = vim.empty_dict(), processId = 1837179, rootPath = "/home/christopher-wood/projects/lualsbug", rootUri = "file:///home/christopher-wood/projects/lualsbug", trace = "off", workDoneToken = "1", workspaceFolders = { { name = "/home/christopher-wood/projects/lualsbug", uri = "file:///home/christopher-wood/projects/lualsbug" } } } }
[DEBUG][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/hello", params = { "world" } }
[TRACE][2025-05-06 00:55:21] ...m/lsp/client.lua:1092 "notification" "$/hello" { "world" }
[DEBUG][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "window/logMessage", params = { message = "Log path: file:///home/christopher-wood/fun/lua-language-server/log/file_home_christopher-wood_projects_lualsbug.log", type = 4 } }
[TRACE][2025-05-06 00:55:21] ...m/lsp/client.lua:1092 "notification" "window/logMessage" { message = "Log path: file:///home/christopher-wood/fun/lua-language-server/log/file_home_christopher-wood_projects_lualsbug.log", type = 4 }
[TRACE][2025-05-06 00:55:21] ...lsp/handlers.lua:656 "default_handler" "window/logMessage" { ctx = '{\n client_id = 1,\n method = "window/logMessage"\n}', result = { message = "Log path: file:///home/christopher-wood/fun/lua-language-server/log/file_home_christopher-wood_projects_lualsbug.log", type = 4 } }
[INFO][2025-05-06 00:55:21] ...lsp/handlers.lua:566 "Log path: file:///home/christopher-wood/fun/lua-language-server/log/file_home_christopher-wood_projects_lualsbug.log"
[DEBUG][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 1, jsonrpc = "2.0", result = { capabilities = { codeActionProvider = { codeActionKinds = { "", "quickfix", "refactor.rewrite", "refactor.extract" }, resolveProvider = false }, codeLensProvider = { resolveProvider = true }, colorProvider = true, completionProvider = { resolveProvider = true, triggerCharacters = { "\t", "\n", ".", ":", "(", "'", '"', "[", ",", "#", "", "@", "|", "=", "-", "{", " ", "+", "?" } }, definitionProvider = true, documentFormattingProvider = true, documentHighlightProvider = true, documentOnTypeFormattingProvider = { firstTriggerCharacter = "\n" }, documentRangeFormattingProvider = true, documentSymbolProvider = true, executeCommandProvider = { commands = { "lua.removeSpace", "lua.solve", "lua.jsonToLua", "lua.setConfig", "lua.getConfig", "lua.autoRequire" } }, foldingRangeProvider = true, hoverProvider = true, implementationProvider = true, inlayHintProvider = { resolveProvider = true }, offsetEncoding = "utf-16", referencesProvider = true, renameProvider = { prepareProvider = true }, semanticTokensProvider = { full = true, legend = { tokenModifiers = { "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary", "global" }, tokenTypes = { "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" } }, range = true }, signatureHelpProvider = { triggerCharacters = { "(", "," } }, textDocumentSync = { change = 2, openClose = true, save = { includeText = false } }, typeDefinitionProvider = true, workspace = { fileOperations = { didRename = { filters = { { pattern = { glob = "/home/christopher-wood/projects/lualsbug/**", options = { ignoreCase = true } } } } } }, workspaceFolders = { changeNotifications = true, supported = true } }, workspaceSymbolProvider = true }, serverInfo = { name = "sumneko.lua", version = "3.14.0" } } }
[DEBUG][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:216 "rpc.send" { jsonrpc = "2.0", method = "initialized", params = vim.empty_dict() }
[DEBUG][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:216 "rpc.send" { jsonrpc = "2.0", method = "workspace/didChangeConfiguration", params = { settings = { Lua = { hint = { enable = true }, misc = { parameters = { "--dbgport=11428", "--develop=true", "--dbgwait=true" } } } } } }
[DEBUG][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:216 "rpc.send" { jsonrpc = "2.0", method = "textDocument/didOpen", params = { textDocument = { languageId = "lua", text = "local M = {}\n---@Class (exact) Foo\n---@field g number\nlocal Class = {\n}\n\nfunction Class:thing()\n\nend\n\n---@return Foo\nfunction M.makeFoo()\n ---@type Foo\n local ret = {\n g = 0\n }\n setmetatable(ret, { __index = Class })\n\n return ret\nend\n\nreturn M\n", uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua", version = 0 } } }
[INFO][2025-05-06 00:55:21] ...m/lsp/client.lua:585 "LSP[lua_ls]" "server_capabilities" { server_capabilities = { codeActionProvider = { codeActionKinds = { "", "quickfix", "refactor.rewrite", "refactor.extract" }, resolveProvider = false }, codeLensProvider = { resolveProvider = true }, colorProvider = true, completionProvider = { resolveProvider = true, triggerCharacters = { "\t", "\n", ".", ":", "(", "'", '"', "[", ",", "#", "
", "@", "|", "=", "-", "{", " ", "+", "?" } }, definitionProvider = true, documentFormattingProvider = true, documentHighlightProvider = true, documentOnTypeFormattingProvider = { firstTriggerCharacter = "\n" }, documentRangeFormattingProvider = true, documentSymbolProvider = true, executeCommandProvider = { commands = { "lua.removeSpace", "lua.solve", "lua.jsonToLua", "lua.setConfig", "lua.getConfig", "lua.autoRequire" } }, foldingRangeProvider = true, hoverProvider = true, implementationProvider = true, inlayHintProvider = { resolveProvider = true }, offsetEncoding = "utf-16", referencesProvider = true, renameProvider = { prepareProvider = true }, semanticTokensProvider = { full = true, legend = { tokenModifiers = { "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary", "global" }, tokenTypes = { "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" } }, range = true }, signatureHelpProvider = { triggerCharacters = { "(", "," } }, textDocumentSync = { change = 2, openClose = true, save = { includeText = false } }, typeDefinitionProvider = true, workspace = { fileOperations = { didRename = { filters = { { pattern = { glob = "/home/christopher-wood/projects/lualsbug/**", options = { ignoreCase = true } } } } } }, workspaceFolders = { changeNotifications = true, supported = true } }, workspaceSymbolProvider = true } }
[DEBUG][2025-05-06 00:55:21] ...m/lsp/client.lua:680 "LSP[lua_ls]" "client.request" 1 "textDocument/semanticTokens/full" { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } <function 1> 1
[DEBUG][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 2, jsonrpc = "2.0", method = "textDocument/semanticTokens/full", params = { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } }
[DEBUG][2025-05-06 00:55:21] .../vim/lsp/rpc.lua:216 "rpc.send" { jsonrpc = "2.0", method = "workspace/didChangeConfiguration", params = { settings = { Lua = {} } } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 1, jsonrpc = "2.0", method = "workspace/configuration", params = { items = { { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "Lua" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.associations" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.exclude" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.semanticHighlighting.enabled" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.acceptSuggestionOnEnter" } } } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 2, jsonrpc = "2.0", method = "workspace/configuration", params = { items = { { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "Lua" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.associations" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.exclude" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.semanticHighlighting.enabled" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.acceptSuggestionOnEnter" } } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/configuration" { items = { { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "Lua" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.associations" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.exclude" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.semanticHighlighting.enabled" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.acceptSuggestionOnEnter" } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/configuration"
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = { { hint = { enable = true }, misc = { parameters = { "--dbgport=11428", "--develop=true", "--dbgwait=true" } }, runtime = { path = { "?.lua", "?/init.lua" }, pathStrict = true, version = "LuaJIT" }, workspace = { checkThirdParty = false, ignoreDir = { "/lua" }, library = { "/home/christopher-wood/.local/share/bob/nightly/share/nvim/runtime/lua", "/home/christopher-wood/.local/share/nvim/lazy/luvit-meta/library" } } }, vim.NIL, vim.NIL, vim.NIL, vim.NIL }, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 1, jsonrpc = "2.0", result = { { hint = { enable = true }, misc = { parameters = { "--dbgport=11428", "--develop=true", "--dbgwait=true" } }, runtime = { path = { "?.lua", "?/init.lua" }, pathStrict = true, version = "LuaJIT" }, workspace = { checkThirdParty = false, ignoreDir = { "/lua" }, library = { "/home/christopher-wood/.local/share/bob/nightly/share/nvim/runtime/lua", "/home/christopher-wood/.local/share/nvim/lazy/luvit-meta/library" } } }, vim.NIL, vim.NIL, vim.NIL, vim.NIL } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/configuration" { items = { { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "Lua" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.associations" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.exclude" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.semanticHighlighting.enabled" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.acceptSuggestionOnEnter" } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/configuration"
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = { { hint = { enable = true }, misc = { parameters = { "--dbgport=11428", "--develop=true", "--dbgwait=true" } }, runtime = { path = { "?.lua", "?/init.lua" }, pathStrict = true, version = "LuaJIT" }, workspace = { checkThirdParty = false, ignoreDir = { "/lua" }, library = { "/home/christopher-wood/.local/share/bob/nightly/share/nvim/runtime/lua", "/home/christopher-wood/.local/share/nvim/lazy/luvit-meta/library" } } }, vim.NIL, vim.NIL, vim.NIL, vim.NIL }, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 2, jsonrpc = "2.0", result = { { hint = { enable = true }, misc = { parameters = { "--dbgport=11428", "--develop=true", "--dbgwait=true" } }, runtime = { path = { "?.lua", "?/init.lua" }, pathStrict = true, version = "LuaJIT" }, workspace = { checkThirdParty = false, ignoreDir = { "/lua" }, library = { "/home/christopher-wood/.local/share/bob/nightly/share/nvim/runtime/lua", "/home/christopher-wood/.local/share/nvim/lazy/luvit-meta/library" } } }, vim.NIL, vim.NIL, vim.NIL, vim.NIL } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 3, jsonrpc = "2.0", method = "workspace/configuration", params = { items = { { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "Lua" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.associations" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.exclude" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.semanticHighlighting.enabled" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.acceptSuggestionOnEnter" } } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/configuration" { items = { { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "Lua" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.associations" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "files.exclude" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.semanticHighlighting.enabled" }, { scopeUri = "file:///home/christopher-wood/projects/lualsbug", section = "editor.acceptSuggestionOnEnter" } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/configuration"
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = { { hint = { enable = true }, misc = { parameters = { "--dbgport=11428", "--develop=true", "--dbgwait=true" } }, runtime = { path = { "?.lua", "?/init.lua" }, pathStrict = true, version = "LuaJIT" }, workspace = { checkThirdParty = false, ignoreDir = { "/lua" }, library = { "/home/christopher-wood/.local/share/bob/nightly/share/nvim/runtime/lua", "/home/christopher-wood/.local/share/nvim/lazy/luvit-meta/library" } } }, vim.NIL, vim.NIL, vim.NIL, vim.NIL }, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 3, jsonrpc = "2.0", result = { { hint = { enable = true }, misc = { parameters = { "--dbgport=11428", "--develop=true", "--dbgwait=true" } }, runtime = { path = { "?.lua", "?/init.lua" }, pathStrict = true, version = "LuaJIT" }, workspace = { checkThirdParty = false, ignoreDir = { "/lua" }, library = { "/home/christopher-wood/.local/share/bob/nightly/share/nvim/runtime/lua", "/home/christopher-wood/.local/share/nvim/lazy/luvit-meta/library" } } }, vim.NIL, vim.NIL, vim.NIL, vim.NIL } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 4, jsonrpc = "2.0", method = "workspace/configuration", params = { items = { { section = "Lua" }, { section = "files.associations" }, { section = "files.exclude" }, { section = "editor.semanticHighlighting.enabled" }, { section = "editor.acceptSuggestionOnEnter" } } } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 5, jsonrpc = "2.0", method = "workspace/configuration", params = { items = { { section = "Lua" }, { section = "files.associations" }, { section = "files.exclude" }, { section = "editor.semanticHighlighting.enabled" }, { section = "editor.acceptSuggestionOnEnter" } } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/configuration" { items = { { section = "Lua" }, { section = "files.associations" }, { section = "files.exclude" }, { section = "editor.semanticHighlighting.enabled" }, { section = "editor.acceptSuggestionOnEnter" } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/configuration"
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = {}, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 4, jsonrpc = "2.0", result = {} }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/configuration" { items = { { section = "Lua" }, { section = "files.associations" }, { section = "files.exclude" }, { section = "editor.semanticHighlighting.enabled" }, { section = "editor.acceptSuggestionOnEnter" } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/configuration"
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = {}, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 5, jsonrpc = "2.0", result = {} }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 6, jsonrpc = "2.0", method = "workspace/configuration", params = { items = { { section = "Lua" }, { section = "files.associations" }, { section = "files.exclude" }, { section = "editor.semanticHighlighting.enabled" }, { section = "editor.acceptSuggestionOnEnter" } } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/configuration" { items = { { section = "Lua" }, { section = "files.associations" }, { section = "files.exclude" }, { section = "editor.semanticHighlighting.enabled" }, { section = "editor.acceptSuggestionOnEnter" } } }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/configuration"
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = {}, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 6, jsonrpc = "2.0", result = {} }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 7, jsonrpc = "2.0", method = "workspace/semanticTokens/refresh" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 8, jsonrpc = "2.0", method = "workspace/inlayHint/refresh" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 9, jsonrpc = "2.0", method = "workspace/semanticTokens/refresh" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 10, jsonrpc = "2.0", method = "workspace/inlayHint/refresh" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 11, jsonrpc = "2.0", method = "workspace/semanticTokens/refresh" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 12, jsonrpc = "2.0", method = "workspace/inlayHint/refresh" }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/semanticTokens/refresh" nil
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/semanticTokens/refresh"
[TRACE][2025-05-06 00:55:22] ...lsp/handlers.lua:656 "default_handler" "workspace/semanticTokens/refresh" { ctx = '{\n client_id = 1,\n method = "workspace/semanticTokens/refresh"\n}' }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { jsonrpc = "2.0", method = "$/cancelRequest", params = { id = 2 } }
[DEBUG][2025-05-06 00:55:22] ...m/lsp/client.lua:680 "LSP[lua_ls]" "client.request" 1 "textDocument/semanticTokens/full" { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } <function 1> 1
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 3, jsonrpc = "2.0", method = "textDocument/semanticTokens/full", params = { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 7, jsonrpc = "2.0", result = vim.NIL }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/inlayHint/refresh" nil
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/inlayHint/refresh"
[TRACE][2025-05-06 00:55:22] ...lsp/handlers.lua:656 "default_handler" "workspace/inlayHint/refresh" { ctx = '{\n client_id = 1,\n method = "workspace/inlayHint/refresh"\n}' }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 8, jsonrpc = "2.0", result = vim.NIL }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/semanticTokens/refresh" nil
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/semanticTokens/refresh"
[TRACE][2025-05-06 00:55:22] ...lsp/handlers.lua:656 "default_handler" "workspace/semanticTokens/refresh" { ctx = '{\n client_id = 1,\n method = "workspace/semanticTokens/refresh"\n}' }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { jsonrpc = "2.0", method = "$/cancelRequest", params = { id = 3 } }
[DEBUG][2025-05-06 00:55:22] ...m/lsp/client.lua:680 "LSP[lua_ls]" "client.request" 1 "textDocument/semanticTokens/full" { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } <function 1> 1
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 4, jsonrpc = "2.0", method = "textDocument/semanticTokens/full", params = { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 9, jsonrpc = "2.0", result = vim.NIL }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/inlayHint/refresh" nil
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/inlayHint/refresh"
[TRACE][2025-05-06 00:55:22] ...lsp/handlers.lua:656 "default_handler" "workspace/inlayHint/refresh" { ctx = '{\n client_id = 1,\n method = "workspace/inlayHint/refresh"\n}' }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 10, jsonrpc = "2.0", result = vim.NIL }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/semanticTokens/refresh" nil
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/semanticTokens/refresh"
[TRACE][2025-05-06 00:55:22] ...lsp/handlers.lua:656 "default_handler" "workspace/semanticTokens/refresh" { ctx = '{\n client_id = 1,\n method = "workspace/semanticTokens/refresh"\n}' }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { jsonrpc = "2.0", method = "$/cancelRequest", params = { id = 4 } }
[DEBUG][2025-05-06 00:55:22] ...m/lsp/client.lua:680 "LSP[lua_ls]" "client.request" 1 "textDocument/semanticTokens/full" { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } <function 1> 1
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 5, jsonrpc = "2.0", method = "textDocument/semanticTokens/full", params = { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 11, jsonrpc = "2.0", result = vim.NIL }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/inlayHint/refresh" nil
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/inlayHint/refresh"
[TRACE][2025-05-06 00:55:22] ...lsp/handlers.lua:656 "default_handler" "workspace/inlayHint/refresh" { ctx = '{\n client_id = 1,\n method = "workspace/inlayHint/refresh"\n}' }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 12, jsonrpc = "2.0", result = vim.NIL }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 13, jsonrpc = "2.0", method = "workspace/semanticTokens/refresh" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 14, jsonrpc = "2.0", method = "workspace/inlayHint/refresh" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { error = { code = -32800, message = "Request cancelled." }, id = 2, jsonrpc = "2.0" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:393 "Received cancellation ack" { error = { code = -32800, message = "Request cancelled." }, id = 2, jsonrpc = "2.0" }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/semanticTokens/refresh" nil
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/semanticTokens/refresh"
[TRACE][2025-05-06 00:55:22] ...lsp/handlers.lua:656 "default_handler" "workspace/semanticTokens/refresh" { ctx = '{\n client_id = 1,\n method = "workspace/semanticTokens/refresh"\n}' }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { jsonrpc = "2.0", method = "$/cancelRequest", params = { id = 5 } }
[DEBUG][2025-05-06 00:55:22] ...m/lsp/client.lua:680 "LSP[lua_ls]" "client.request" 1 "textDocument/semanticTokens/full" { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } <function 1> 1
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 6, jsonrpc = "2.0", method = "textDocument/semanticTokens/full", params = { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 13, jsonrpc = "2.0", result = vim.NIL }
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1108 "server_request" "workspace/inlayHint/refresh" nil
[TRACE][2025-05-06 00:55:22] ...m/lsp/client.lua:1111 "server_request: found handler for" "workspace/inlayHint/refresh"
[TRACE][2025-05-06 00:55:22] ...lsp/handlers.lua:656 "default_handler" "workspace/inlayHint/refresh" { ctx = '{\n client_id = 1,\n method = "workspace/inlayHint/refresh"\n}' }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 14, jsonrpc = "2.0", result = vim.NIL }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { error = { code = -32800, message = "Request cancelled." }, id = 5, jsonrpc = "2.0" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:393 "Received cancellation ack" { error = { code = -32800, message = "Request cancelled." }, id = 5, jsonrpc = "2.0" }
[DEBUG][2025-05-06 00:55:22] ...m/lsp/client.lua:680 "LSP[lua_ls]" "client.request" 1 "textDocument/formatting" { options = { insertSpaces = true, tabSize = 4 }, textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } <function 1> 1
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 7, jsonrpc = "2.0", method = "textDocument/formatting", params = { options = { insertSpaces = true, tabSize = 4 }, textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 7, jsonrpc = "2.0" }
[DEBUG][2025-05-06 00:55:22] .../vim/lsp/rpc.lua:216 "rpc.send" { jsonrpc = "2.0", method = "textDocument/didSave", params = { textDocument = { uri = "file:///home/christopher-wood/projects/lualsbug/thing.lua" } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 15, jsonrpc = "2.0", method = "window/workDoneProgress/create", params = { token = 2 } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { cancellable = false, kind = "begin", message = "130/260", percentage = 49, title = "Loading workspace" } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1108 "server_request" "window/workDoneProgress/create" { token = 2 }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1111 "server_request: found handler for" "window/workDoneProgress/create"
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "window/workDoneProgress/create" { ctx = '{\n client_id = 1,\n method = "window/workDoneProgress/create"\n}', result = { token = 2 } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:346 "server_request: callback result" { result = vim.NIL, status = true }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:216 "rpc.send" { id = 15, jsonrpc = "2.0", result = vim.NIL }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { cancellable = false, kind = "begin", message = "130/260", percentage = 49, title = "Loading workspace" } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { cancellable = false, kind = "begin", message = "130/260", percentage = 49, title = "Loading workspace" } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "141/260", percentage = 54 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "141/260", percentage = 54 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "141/260", percentage = 54 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "168/260", percentage = 64 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "168/260", percentage = 64 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "168/260", percentage = 64 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "180/260", percentage = 69 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "180/260", percentage = 69 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "180/260", percentage = 69 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "183/260", percentage = 70 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "183/260", percentage = 70 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "183/260", percentage = 70 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "193/260", percentage = 73 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "193/260", percentage = 73 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "193/260", percentage = 73 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "203/260", percentage = 77 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "203/260", percentage = 77 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "203/260", percentage = 77 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "209/260", percentage = 80 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "209/260", percentage = 80 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "209/260", percentage = 80 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "218/260", percentage = 83 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "218/260", percentage = 83 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "218/260", percentage = 83 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "227/260", percentage = 87 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "227/260", percentage = 87 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "227/260", percentage = 87 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "237/260", percentage = 91 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "237/260", percentage = 91 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "237/260", percentage = 91 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "report", message = "252/260", percentage = 96 } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "report", message = "252/260", percentage = 96 } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "report", message = "252/260", percentage = 96 } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { jsonrpc = "2.0", method = "$/progress", params = { token = 2, value = { kind = "end" } } }
[TRACE][2025-05-06 00:55:23] ...m/lsp/client.lua:1092 "notification" "$/progress" { token = 2, value = { kind = "end" } }
[TRACE][2025-05-06 00:55:23] ...lsp/handlers.lua:656 "default_handler" "$/progress" { ctx = '{\n client_id = 1,\n method = "$/progress"\n}', result = { token = 2, value = { kind = "end" } } }
[DEBUG][2025-05-06 00:55:23] .../vim/lsp/rpc.lua:330 "rpc.receive" { id = 6, jsonrpc = "2.0", result = { data = { 0, 6, 1, 8, 1, 1, 0, 3, 17, 0, 0, 3, 6, 15, 256, 0, 7, 7, 22, 0, 0, 8, 3, 2, 1, 1, 0, 3, 17, 0, 0, 3, 6, 15, 256, 0, 7, 1, 9, 1, 0, 2, 6, 1, 0, 1, 6, 5, 2, 0, 3, 9, 5, 2, 0, 0, 6, 5, 13, 1, 4, 0, 3, 17, 0, 0, 3, 7, 15, 256, 0, 8, 3, 1, 0, 1, 9, 1, 8, 0, 0, 2, 7, 13, 0, 1, 4, 3, 17, 0, 0, 3, 5, 15, 256, 0, 6, 3, 1, 0, 1, 10, 3, 8, 1, 1, 8, 1, 9, 0, 2, 4, 12, 12, 512, 0, 13, 3, 8, 0, 0, 7, 7, 9, 0, 0, 10, 5, 2, 0, 2, 11, 3, 8, 0, 3, 7, 1, 8, 0 } } }

@CppCXY
Copy link
Collaborator

CppCXY commented May 6, 2025

I suggest you define the data type:

---@class MyClass.Data
---@field g integer

local M = {}

---@class MyClass : MyClass.Data
local Class = {
}

function Class:thing()

end

---@return MyClass
function M.makeFoo()
    ---@type MyClass.Data
    local ret = {
        g = 0
    }
    setmetatable(ret, { __index = Class })

    return ret
end

return M

@tomlau10
Copy link
Contributor

tomlau10 commented May 6, 2025

Background Information

Looking at bbffd42 from your bisected result, it comes from PR #2970.
I have some impression on that PR, because it broke the partial class feature.
And later I wrote another PR #3024 to patch it up 🤔 .

PR#2970 fixes the missing field check in which it cannot check for inherited fields.
The original code only iterates over def.fields, which will be all those @field of a @class, so it cannot detect inherited fields.
Take the following as an example:

---@class Parent
---@field p string

---@class Child: Parent
---@field c integer

---@type Child
local child = {}    -- only warns for `c` but not `p`

Further Investigation

In that PR, it changed to use vm.getFields().
Though it can include the inherited fields, but the side effect is that it will include all other defined function / methods of that class as well, which is undesired 😕

From the wiki, it clearly states that this warning is:

Triggered when an instance of a class is missing a required @field.
https://luals.github.io/wiki/diagnostics/#missing-fields

=> only @field should be checked, but not methods or functions, or other fields which are defined with t.field = x style.

Simple fix?

By printing the field.type inside the forloop here:

for _, field in ipairs(fields) do
if not field.optional
and not vm.compileNode(field):isNullable() then

  • I found that for @field objects, they have the type doc.field
  • while for other objects, they have something like setfield / setmethod

💡 So a simple fix would be to check field.type == 'doc.field' in the filter condition in that forloop 🤔

                 for _, field in ipairs(fields) do
                     if  not field.optional
+                    and field.type == 'doc.field'
                     and not vm.compileNode(field):isNullable() then

With this suggested fix, no more undesired missing field warning:

---@class Bar
---@field h string

---@class Foo: Bar
---@field g number
local Class = {}

function Class:thing() end

function Class.func() end

Class.x = 1

-- a function of some type
---@param g number
---@return Foo
local function constructor(g)
    -- type annotation so that i get a missing-fields diagnostic if i forget
    -- g or another field
    ---@type Foo
    local ret = { --> Missing required fields in type `Foo`: `h`
        g = g,
    }
    -- setmetatable so ret has all the methods
    setmetatable(ret, { __index = Class })
    return ret
end

=> in this example only h is reported, which is expected


You may consider open a PR for it after more testing 👀

@CWood-sdf
Copy link
Author

I suggest you define the data type:

---@Class MyClass.Data
---@field g integer

local M = {}

---@Class MyClass : MyClass.Data
local Class = {
}

function Class:thing()

end

---@return MyClass
function M.makeFoo()
---@type MyClass.Data
local ret = {
g = 0
}
setmetatable(ret, { __index = Class })

return ret

end

return M

I would rather avoid doing this as it requires a non-insignificant amount of rewriting of stuff. If I could avoid that and just use the old behavior and send in a PR like @tomlau10 suggested, that would be amazing. However, if it is unlikely that the described PR would be accepted, I would be fine with rewriting to use the suggested pattern

@tomlau10
Copy link
Contributor

tomlau10 commented May 7, 2025

However, if it is unlikely that the described PR would be accepted

I believe the current behavior is actually a bug, so a fix PR will be welcomed 😄 as long as it passes all exiting tests (or any additional tests that you would like to add) .

According to my experience, PR merge cycle is around 2-4 weeks. while the release cycle would be around once a month (unless there are critical bugs).
So be reminded that your fix might not be released soon enough.


PS: I am just a contributor, not maintainer of this project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants