From c233a9ab066f57cfbd3d63a1ed47972c2b2d5af5 Mon Sep 17 00:00:00 2001 From: bbassie <17990055+bbassie@users.noreply.github.com> Date: Thu, 6 Aug 2026 21:16:40 +0000 Subject: [PATCH] Defer need-check-nil and clean up stale suppressions emmylua deserialises an unknown diagnostic code to a catch all that matches no checker, so every `invisible`, `nil-check` and `global-element` suppression was silently doing nothing. Renamed to the emmylua codes. `name-style-check` has no equivalent and is dropped, it was already disabled under luals. The `get_tile` suppressions referenced an api typedef bug from 2024 which no longer reproduces. need-check-nil is deferred rather than disabled on merit: a third of the 407 findings come from MapPosition and BoundingBox being aliased as `struct|[double, double]`, so every `entity.position.x` reads as possibly nil. The rest need per site knowledge of runtime invariants. Co-Authored-By: Claude Opus 5 (1M context) --- .emmyrc.json | 2 ++ exp_commands/module/commands/rcon.lua | 2 -- exp_commands/module/commands/sudo.lua | 2 +- exp_groups/module/globals.lua | 2 +- exp_gui/module/control.lua | 6 +++--- exp_gui/module/toolbar.lua | 2 +- exp_legacy/module/modules/gui/_role_updates.lua | 2 +- exp_roles/module/globals.lua | 2 +- exp_scenario/module/commands/roles.lua | 2 +- exp_scenario/module/control/degrading_tiles.lua | 2 -- exp_scenario/module/control/spawn_area.lua | 2 -- exp_scenario/module/gui/debug/expcore_gui_view.lua | 14 +++++++------- .../module/gui/debug/redmew_global_view.lua | 2 +- 13 files changed, 19 insertions(+), 23 deletions(-) diff --git a/.emmyrc.json b/.emmyrc.json index c103023e..62b2e74a 100644 --- a/.emmyrc.json +++ b/.emmyrc.json @@ -18,6 +18,7 @@ }, "$comment-disable": "Carried over from the luals config, which had these as editor only rather than checked in ci", "$comment-unnecessary-if": "Disabled by the config fmtk generates for itself, the api union types make it unreliable", + "$comment-need-check-nil": "To be enabled once the backlog is cleared, a third of it is MapPosition and BoundingBox being aliased as struct|[double, double]", "diagnostics": { "globals": [ "__DebugAdapter", "__Profiler" ], "disable": [ @@ -26,6 +27,7 @@ "invert-if", "missing-parameter", "missing-return-value", + "need-check-nil", "param-type-mismatch", "preferred-local-alias", "redefined-local", diff --git a/exp_commands/module/commands/rcon.lua b/exp_commands/module/commands/rcon.lua index cedab49e..77da68f6 100644 --- a/exp_commands/module/commands/rcon.lua +++ b/exp_commands/module/commands/rcon.lua @@ -21,12 +21,10 @@ setmetatable(rcon_static, { __index = _G }) setmetatable(rcon_env, { __index = rcon_static }) --- Some common static values which can be added now ---- @diagnostic disable: name-style-check rcon_static.Async = Async rcon_static.ExpUtil = ExpUtil rcon_static.Commands = Commands rcon_static.print = Commands.print ---- @diagnostic enable: name-style-check --- Some common callback values which are useful when a player uses the command --- @alias ExpCommand.RconDynamic fun(player: LuaPlayer?): any diff --git a/exp_commands/module/commands/sudo.lua b/exp_commands/module/commands/sudo.lua index c56ef29d..33fb9e3c 100644 --- a/exp_commands/module/commands/sudo.lua +++ b/exp_commands/module/commands/sudo.lua @@ -19,7 +19,7 @@ Commands.new("_sudo", { "exp-commands_sudo.description" }) --- @cast command ExpCommand --- @cast parameter string - --- @diagnostic disable-next-line: invisible + --- @diagnostic disable-next-line: access-invisible return Commands._event_handler{ name = command.name, tick = game.tick, diff --git a/exp_groups/module/globals.lua b/exp_groups/module/globals.lua index ce036c21..27ecdb31 100644 --- a/exp_groups/module/globals.lua +++ b/exp_groups/module/globals.lua @@ -5,7 +5,7 @@ Therefore, we advise that this should be the only file in your module to expose Typically this would be your control file as shown in the example below ]] ---- @diagnostic disable: global-element +--- @diagnostic disable: global-in-non-module -- Access using `/sc exp_groups.foo()` exp_groups = require("modules/exp_groups/control") diff --git a/exp_gui/module/control.lua b/exp_gui/module/control.lua index 6fdd5727..56cf2dd3 100644 --- a/exp_gui/module/control.lua +++ b/exp_gui/module/control.lua @@ -188,9 +188,9 @@ function Gui._ensure_consistency(event) -- This check isn't needed, but allows the toolbar file to be deleted without modifying any lib code if Gui.toolbar then - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible Gui.toolbar._create_elements(player) - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible Gui.toolbar._ensure_consistency(player) end end @@ -211,7 +211,7 @@ local function on_gui_opened(event) if visible then event.element = element - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible define:raise_event(event) end end diff --git a/exp_gui/module/toolbar.lua b/exp_gui/module/toolbar.lua index 22a478af..69cc68ff 100644 --- a/exp_gui/module/toolbar.lua +++ b/exp_gui/module/toolbar.lua @@ -29,7 +29,7 @@ Toolbar.on_gui_button_toggled = script.generate_event_name() --- @class _ExpElement._prototype --- @field on_button_toggled ExpElement.OnEventAdder ---- @diagnostic disable-next-line: invisible, inject-field +--- @diagnostic disable-next-line: access-invisible, inject-field function ExpElement._prototype.on_button_toggled(self, handler) return self:on_event(Toolbar.on_gui_button_toggled, handler) end diff --git a/exp_legacy/module/modules/gui/_role_updates.lua b/exp_legacy/module/modules/gui/_role_updates.lua index 75273b57..ac171b49 100644 --- a/exp_legacy/module/modules/gui/_role_updates.lua +++ b/exp_legacy/module/modules/gui/_role_updates.lua @@ -2,6 +2,6 @@ local Gui = require("modules/exp_gui") local Roles = require("modules.exp_legacy.expcore.roles") local Event = require("modules/exp_legacy/utils/event") ---- @diagnostic disable invisible +--- @diagnostic disable: access-invisible Event.add(Roles.events.on_role_assigned, Gui._ensure_consistency) Event.add(Roles.events.on_role_unassigned, Gui._ensure_consistency) diff --git a/exp_roles/module/globals.lua b/exp_roles/module/globals.lua index 10d74063..2a982c2e 100644 --- a/exp_roles/module/globals.lua +++ b/exp_roles/module/globals.lua @@ -4,7 +4,7 @@ However, sometimes you need globals, for example to access functions within rcon Therefore, we advise that this should be the only file in your module to expose globals ]] ---- @diagnostic disable: global-element +--- @diagnostic disable: global-in-non-module -- Access using `/sc exp_roles.foo()` exp_roles = require("modules/exp_roles/control") diff --git a/exp_scenario/module/commands/roles.lua b/exp_scenario/module/commands/roles.lua index 7adbb3a1..eb2ec833 100644 --- a/exp_scenario/module/commands/roles.lua +++ b/exp_scenario/module/commands/roles.lua @@ -55,7 +55,7 @@ Commands.new("get-roles", { "exp-commands_roles.description-get" }) end local last = #roles_formatted - --- @diagnostic disable-next-line nil-check + --- @diagnostic disable-next-line: need-check-nil roles_formatted[last] = roles_formatted[last][2] return Commands.status.success(response) diff --git a/exp_scenario/module/control/degrading_tiles.lua b/exp_scenario/module/control/degrading_tiles.lua index ad16dbfd..b83090a1 100644 --- a/exp_scenario/module/control/degrading_tiles.lua +++ b/exp_scenario/module/control/degrading_tiles.lua @@ -18,7 +18,6 @@ end --- @param surface LuaSurface --- @param position MapPosition local function degrade_tile(surface, position) - --- @diagnostic disable-next-line Incorrect Api Type: https://forums.factorio.com/viewtopic.php?f=233&t=109145&p=593761&hilit=get_tile#p593761 local tile = surface.get_tile(position) local tile_name = tile.name local degrade_tile_name = config.degrade_order[tile_name] @@ -61,7 +60,6 @@ end --- @param position MapPosition --- @return number? local function get_tile_strength(surface, position) - --- @diagnostic disable-next-line Incorrect Api Type: https://forums.factorio.com/viewtopic.php?f=233&t=109145&p=593761&hilit=get_tile#p593761 local tile = surface.get_tile(position) local tile_name = tile.name local strength = config.strengths[tile_name] diff --git a/exp_scenario/module/control/spawn_area.lua b/exp_scenario/module/control/spawn_area.lua index 4810585c..cceb15fa 100644 --- a/exp_scenario/module/control/spawn_area.lua +++ b/exp_scenario/module/control/spawn_area.lua @@ -164,7 +164,6 @@ local function clear_spawn_area(surface, offset) local get_tile = surface.get_tile -- Make sure a non water tile is used for filling - --- @diagnostic disable-next-line Incorrect Api Type: https://forums.factorio.com/viewtopic.php?f=233&t=109145&p=593761&hilit=get_tile#p593761 local starting_tile = get_tile(offset) local fill_tile = starting_tile.collides_with("player") and "landfill" or starting_tile.name local fill_radius = config.spawn_area.landfill_radius @@ -185,7 +184,6 @@ local function clear_spawn_area(surface, offset) if dst < tile_radius_sqr then -- If it is inside the decon radius always set the tile tiles_to_make[#tiles_to_make + 1] = { name = decon_tile, position = pos } - --- @diagnostic disable-next-line Incorrect Api Type: https://forums.factorio.com/viewtopic.php?f=233&t=109145&p=593761&hilit=get_tile#p593761 elseif dst < fill_radius_sqr and get_tile(pos).collides_with("player") then -- If it is inside the fill radius only set the tile if it is water tiles_to_make[#tiles_to_make + 1] = { name = fill_tile, position = pos } diff --git a/exp_scenario/module/gui/debug/expcore_gui_view.lua b/exp_scenario/module/gui/debug/expcore_gui_view.lua index 4fd18849..399656de 100644 --- a/exp_scenario/module/gui/debug/expcore_gui_view.lua +++ b/exp_scenario/module/gui/debug/expcore_gui_view.lua @@ -27,7 +27,7 @@ function Public.show(container) local left_panel_style = left_panel.style left_panel_style.width = 300 - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible for element_name in pairs(ExpElement._elements) do local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = element_name } Gui.set_data(header, element_name) @@ -92,18 +92,18 @@ Gui.on_click( input_text_box.text = concat{ "ExpElement._elements[\"", element_name, "\"]" } input_text_box.style.font_color = Color.black - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible local define = ExpElement._elements[element_name] local content = dump({ - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible debug = define._debug, - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible has_handlers = define._has_handlers, - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible track_elements = define._track_elements, - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible elements = ExpIter._scopes[element_name], - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible data = ExpData._scopes[element_name]._raw, }) or "nil" right_panel.text = content diff --git a/exp_scenario/module/gui/debug/redmew_global_view.lua b/exp_scenario/module/gui/debug/redmew_global_view.lua index 8e387479..de43f1ac 100644 --- a/exp_scenario/module/gui/debug/redmew_global_view.lua +++ b/exp_scenario/module/gui/debug/redmew_global_view.lua @@ -24,7 +24,7 @@ function Public.show(container) local left_panel_style = left_panel.style left_panel_style.width = 300 - --- @diagnostic disable-next-line invisible + --- @diagnostic disable-next-line: access-invisible for token_id in pairs(Storage._registered) do local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = token_id } Gui.set_data(header, token_id)