LuaLS / LuaLS/lua-language-server

Request: Limit "Fields cannot be injected" to exact classes

未关闭
#3,361 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

主要语言
Lua
星标
4.4k
派生
442
PR 合并指标
30 天内没有已合并 PR

描述

How are you using the lua-language-server?

NeoVim

Which OS are you using?

Windows

What is the issue affecting?

Annotations

Expected Behaviour

The docs say:

Marking the class as (exact) means fields cannot be injected after the definition.

So when I use @class, I expect to not get any injection warnings unless I use (exact). I see this came up before in #2710, so I'd add: I should be able to get a warning for injections in exact classes while silencing warnings in non-exact classes.

Actual Behaviour

Any time I add a field outside of the constructor (and sometimes even ones that are defined in my class constructor), I get this warning:

Fields cannot be injected into the reference of ClassX for field_y. To do so, use ---@class for instance_z.

The @class annotation makes lua too strict. I'm using lua because I want to be able to inject fields.

Using annotations has multiple effects:

  1. It improves completion.
  2. It improves symbol lookups like goto definition.
  3. It does type checking.

But it's not great that adding annotations to get 1+2 results in tons of warnings from 3.

I understand that people may not want to add (exact) all over their codebase, but I don't want to add ---@field [any] any to all of mine.

I'd propose a change to diagnostic flags to allow independently controlling these two cases:

  • inject-field: suppress inject field diagnostic for non-exact classes.
  • inject-field-exact: suppress inject field diagnostic for exact classes.
Reproduction steps

Using neovim and installed luals with Mason. Version: pkg:github/luals/lua-language-server@3.17.1

-- Stripped-down version of https://github.com/rxi/classic/blob/master/classic.lua with an annotation added to be close to real-world class usage.
--
-- classic
--
-- Copyright (c) 2014, rxi
--
-- This module is free software; you can redistribute it and/or modify it under
-- the terms of the MIT license. See LICENSE for details.

--- @class Object
local Object = {}
Object.__index = Object

function Object:new()
end

function Object:extend()
  local cls = {}
  for k, v in pairs(self) do
    if k:find("__") == 1 then
      cls[k] = v
    end
  end
  cls.__index = cls
  cls.super = self
  setmetatable(cls, self)
  return cls
end

function Object:__call(...)
  local obj = setmetatable({}, self)
  obj:new(...)
  return obj
end

-- /end classic



--- @class Item : Object
local Item = Object:extend()

function Item:new(id, category)
	self.id = id
	self.category = category
	self.count = 0
end

function Item:Print()
	print("Item", self.id, self.category, self.count)
end

--- @param item Item
function FlagDebugItem(item)
	item:Print()  -- with the annotation, this completes. Yay!
	item.is_cheater = true  -- Warning :( "Fields cannot be injected into the reference of `Item` for `is_cheater`."
end

If I configure luals to add inject-field to the Lua.diagnostics.disable list, then the warning goes away. But the warning doesn't come back when I make Item an exact class with this annotation: --- @class (exact) Item : Object

Workaround: Add a fake field of any type:

--- @class Item : Object
--- @field [any] any
local Item = Object:extend()
Additional Notes

No response

Log File
[WARN][2026-02-23 11:41:41] ...lsp/handlers.lua:564	"More than 100000 files have been scanned. The current scanned directory is `D:\\code\\project\\br`. Please see the [FAQ](https://luals.github.io/wiki/faq/#how-can-i-improve-startup-speeds) to see how you can include fewer files. It is also possible that your [configuration is incorrect](https://luals.github.io/wiki/faq#why-is-the-server-scanning-the-wrong-folder)."
[WARN][2026-02-23 14:32:31] .../lua/vim/lsp.lua:52	"method textDocument/typeDefinition is not supported by any of the servers registered for the current buffer"
[START][2026-02-23 15:29:24] LSP logging initiated
[ERROR][2026-02-23 15:29:24] ...m/lsp/client.lua:620	"LSP[lua_ls]"	"Cannot find request with id 125 whilst attempting to cancel"

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先使用 LuaLS 3.17.1 运行提供的 NeoVim 复现,并比较 @class@class (exact)。然后跟踪 inject-field 诊断的应用方式;完成的标准是,非精确类和精确类可以按提议独立控制,同时文档中所述的补全和查找行为仍然可用。

由索引模型根据 Issue 内容生成。

评估

技术栈
lua
领域
devtools
Issue 类型
功能
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
38/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。