Fix lua lint warnings reported by emmylua

The largest source was compat.lua returning the setmetatable call
directly, which made emmylua infer the module type from the metatable
rather than the LibCompat class, hiding every field from consumers.

The remaining fixes are nil guards on gui element and character
accesses, type annotations for research_sync's script data and
player_auth's rcon arguments, casts where the api's read/write union
types are wider than the values at runtime, and scoped diagnostic
disables for the vendored json.lua and the version fallback code that
touches apis removed from the current typedefs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
bbassieandClaude Fable 5 committed 2026-08-27 22:25:24 +00:00
1 parent 59cd193b65
commit a25f8c8611
8 files changed
+43 -19

No files matched your search

+3
View File
@@ -1,3 +1,6 @@
--- Undefined fields are expected, the typedefs only cover the latest version
--- @diagnostic disable: undefined-field
local function send_json(channel, data)
data = helpers and helpers.table_to_json(data) or game.table_to_json(data)
print("\f$ipc:" .. channel .. "?j" .. data)
+5 -2
View File
@@ -10,7 +10,8 @@ Implementation Guidelines
local lib_json = require("json")
--- @diagnostic disable: deprecated
--- Undefined fields are expected, the typedefs only cover the latest version
--- @diagnostic disable: deprecated, undefined-field
--- @class LibCompat
--- @field script_data table
@@ -238,4 +239,6 @@ set_script_data()
compat.on_init = set_script_data --- @package
compat.on_load = set_script_data --- @package
return setmetatable(compat, compat_mt)
-- Not returned directly because that would infer the metatable type rather than LibCompat
setmetatable(compat, compat_mt)
return compat
+3
View File
@@ -22,6 +22,9 @@
-- SOFTWARE.
--
--- Vendored file, the forward declared recursion is not worth annotating
--- @diagnostic disable: need-check-nil
local json = { _version = "0.1.2" }
-------------------------------------------------------------------------------
@@ -21,9 +21,10 @@ return function(player, record)
player.driving = true
-- Teleport to safe location if unable to enter vehicle
if not player.driving and player.controller_type == defines.controllers.character then
local character = player.character
if not player.driving and character and player.controller_type == defines.controllers.character then
local safe_position = record.vehicle.surface.find_non_colliding_position(
player.character.name, player.position, 32, 1/8
character.name, player.position, 32, 1/8
)
if safe_position then
player.teleport(safe_position, player.surface)
+10 -9
View File
@@ -207,14 +207,14 @@ end
--- @return QuickBarSlotEncoded
local function serialize_filter(filter)
if filter.quality == "normal" and filter.comparator == "=" then
return filter.name
return filter.name --[[@as string]]
end
return {
t = "f",
n = filter.name,
q = filter.quality,
c = filter.comparator,
n = filter.name --[[@as string]],
q = filter.quality --[[@as string]],
c = filter.comparator --[[@as string]],
}
end
@@ -234,7 +234,7 @@ function serialize.serialize_quick_bar_slot(slot)
if v2_0_quick_bar_api then
-- 2.0 gives us an item filter which supports quality
--- @cast slot ItemFilter
--- @cast slot -QuickBarSlot, -LuaItemPrototype
return serialize_filter(slot)
end
@@ -267,7 +267,7 @@ function serialize.deserialize_quick_bar_slot(entry)
quality = entry.q,
comparator = entry.c,
},
}
} --[[@as QuickBarSlot]]
end
print("Warning: Unsupported serialized quick bar slot type '" .. tostring(entry.t) .. "'")
@@ -292,7 +292,7 @@ function serialize.deserialize_quick_bar_slot(entry)
-- Return a string (member of ItemPrototypeIdentification)
-- Pre 2.0 this was the only method of encoding used
return entry
return entry --[[@as string]]
end
--- @param player LuaPlayer
@@ -709,7 +709,8 @@ local function ensure_character(player)
local surface = player.surface
if v2_space_platform and surface.platform then
local planet_surface = find_planet_surface(surface.platform)
player.teleport(player.force.get_spawn_position(planet_surface), planet_surface)
local force = player.force --[[@as LuaForce]]
player.teleport(force.get_spawn_position(planet_surface), planet_surface)
end
-- Create and return the character
@@ -721,7 +722,7 @@ local function ensure_character(player)
player.surface.name, tostring(player.connected), tostring(player.driving)
))
end
return player.character
return assert(player.character)
end
--- @class FailedDeserializationPlayerData
+8 -5
View File
@@ -132,6 +132,7 @@ function auth.add_commands()
end
if event.parameter then
--- @type string[]
local args = {}
for w in string.gmatch(event.parameter, "[^ ]+") do
args[#args + 1] = w
@@ -149,7 +150,7 @@ function auth.add_commands()
end
local player_name, url, code = table.unpack(args)
local player = game.players[player_name]
local player = game.get_player(player_name)
if not player then
rcon.print("Player " .. player_name .. " does not exist")
return
@@ -159,7 +160,7 @@ function auth.add_commands()
elseif command == "code_set" then
local player_name = args[1]
local player = game.players[player_name]
local player = game.get_player(player_name)
if not player then
rcon.print("Player " .. player_name .. " does not exist")
return
@@ -171,7 +172,7 @@ function auth.add_commands()
elseif command == "error" then
local player_name = table.remove(args, 1)
local player = game.players[player_name]
local player = game.get_player(player_name)
if not player then
rcon.print("Player " .. player_name .. " does not exist")
return
@@ -192,10 +193,12 @@ auth.events[defines.events.on_gui_click] = function(event)
end
if event.element.name == "player_auth_dialog_close_button" then
event.element.parent.parent.destroy()
local parent = assert(event.element.parent)
assert(parent.parent).destroy()
elseif event.element.name == "player_auth_verify_code_button" then
local verify_code = event.element.parent.player_auth_verify_code_input.text
local parent = assert(event.element.parent)
local verify_code = assert(parent.player_auth_verify_code_input).text
local player_name = game.players[event.player_index].name
clusterio_api.send_json("player_auth", {
type = "set_verify_code",
+10 -1
View File
@@ -30,8 +30,17 @@ local function set_technology_progress(tech, progress)
end
end
--- @class ResearchSyncTechnology
--- @field level uint
--- @field researched boolean?
--- @field progress double?
--- @class ResearchSyncData
--- @field technologies table<string, ResearchSyncTechnology>
--- @field ignore_research_finished boolean
--- @param no_early_return boolean?
--- @return table
--- @return ResearchSyncData
local function get_script_data(no_early_return)
local research_sync = compat.script_data.research_sync
if research_sync and not no_early_return then
@@ -32,6 +32,7 @@ function statistics_exporter.export()
for _, force in pairs(game.forces) do
local flow_statistics = {}
for _, statName in pairs(statistics) do
--- @type LuaFlowStatistics
local stat = v2_stats and force["get_" .. statName](surface.index) or force[statName]
flow_statistics[statName] = {
input = stat.input_counts,