[Types] LLM env layer (emmylua config, type stubs, manual fixes) - #7447
[Types] LLM env layer (emmylua config, type stubs, manual fixes)#7447keithharvey wants to merge 4 commits into
Conversation
51586e5 to
dcc143b
Compare
Integration Test Results14 tests 6 ✅ 3s ⏱️ Results for commit 673a85b. ♻️ This comment has been updated with latest results. |
dcc143b to
c3c76f2
Compare
deb455c to
d4149b0
Compare
0bef3c4 to
e0cf2e6
Compare
4c977b7 to
9c18293
Compare
56c26df to
7626dc3
Compare
479ab0e to
9fb60f6
Compare
a2f416e to
629787d
Compare
ea02d03 to
0935307
Compare
keithharvey
left a comment
There was a problem hiding this comment.
Rationale for each env-layer decision, per file — every undefined-global suppression justified inline below. (Comments requested off-source so the code stays terse.)
| "spec/?.lua", "spec/?/init.lua", | ||
| }, ";") | ||
| }, ";"), | ||
| helper = "spec/spec_helper.lua", |
There was a problem hiding this comment.
spec_helper installs the Spring/SpringShared/SpringSynced/SpringUnsynced shims that unit-def loading (Builders.Spring:WithRealUnitDefs) relies on. Previously only the _all and coverage tasks set helper, so the default task (just bar::units) silently swallowed ~20 unit-def load failures per run — any spring-split unit def touching SpringShared.GetModOptions() nil-dereffed at require time.
| "widgetHandler", | ||
| "actionHandler", | ||
| "gadgetHandler", | ||
| "CALLIN_MAP", |
There was a problem hiding this comment.
CALLIN_MAP is a real global in the LuaRules environment: luarules/gadgets.lua does VFS.Include(HANDLER_DIR .. "callins.lua"), which resolves to the engine base content's LuaGadgets/callins.lua (CALLIN_MAP = {} at top level). The analyzer can't see engine base content, so it's declared here. (An earlier revision of this branch suppressed it at the use site with a "likely dead code" TODO — wrong: gadgetHandler:RegisterGlobal is called by live gadgets and would crash if CALLIN_MAP were nil.)
| -- This file includes common functionality that should be available globally | ||
|
|
||
| -- shim for engines without RecoilEngine LuaSpringContext::SetupAliases | ||
| SpringShared = SpringShared or Spring |
There was a problem hiding this comment.
Backwards-compat shim for the Spring API type split. The RecoilEngine PR (LuaSpringContext::SetupAliases) creates these globals in every Lua sandbox; engines without that commit only expose Spring. This lets the spring-split codemod output run on both. Once the engine PR reaches mainline this is a harmless no-op (or Spring never fires).
| -- Icon Generator Config File | ||
| -- | ||
| -- info/scheme/faction are injected into this include's fenv by the caller | ||
| ---@diagnostic disable: undefined-global |
There was a problem hiding this comment.
File-level suppression: this config is VFS.Included by the icon-generator gadget, which injects info, scheme, and faction into the include's environment as template parameters. The analyzer can't follow fenv injection, so every read of those three looks undefined. Scoped to this file only.
A refactor of how these globals are DI'd and accessed is probably the answer here, but outside the scope of this PR.
| @@ -1,3 +1,6 @@ | |||
| -- decompiled BOS: bare globals are per-unit script state | |||
| ---@diagnostic disable: undefined-global | |||
There was a problem hiding this comment.
File-level suppression: this is the only .lua unit script in scripts/Units/ (everything else is .bos/.cob), decompiled from BOS. Unit scripts run one environment per unit instance, and the decompiled code uses dozens of bare globals as per-unit mutable state (bMoving, bAiming, rightArm, animSpeed, …) alongside framework-injected ones (unitID). Declaring them in .emmyrc.json would leak them workspace-wide; a file-scoped disable is the correct blast radius.
| local encodeString | ||
| local isArray | ||
| local isEncodable | ||
| local null -- assigned below |
There was a problem hiding this comment.
null was used by encode/decode before its function null() definition, resolving to a global at runtime (worked by accident: assignment ran before first call). Forward-declared as a local; function null() now assigns the upvalue.
| -- Get lava config for map. | ||
| -- mapConfig has preference over gameConfig, unless game sets 'overrideMap' | ||
| local gameConfig, mapConfig | ||
| local mapNameNoVersion = mapName and trimMapVersion(mapName) or mapName |
There was a problem hiding this comment.
Hoisted out of the if mapName block because the MAP_CONFIG_PATH log below reads it even when mapName == nil (previously a nil-global read on that path).
|
|
||
| --- Integration-test DSL that the `dbg_test_runner` widget injects into each | ||
| --- test file's env, plus extras from `common/testing/test_extra_utils.lua`. | ||
| ---@class Test |
There was a problem hiding this comment.
@meta stub for the integration-test DSL that dbg_test_runner injects into each test file's environment via setfenv (plus the flat-merged assertion/util globals from common/testing/). @meta keeps it analysis-only — nothing here exists as a runtime global outside test files. Named IntegrationTests.lua (not Test.lua after the class) to make the file's scope obvious when browsing types/.
| - name: Install emmylua_check | ||
| env: | ||
| # keep in lockstep with BAR-Devtools docker/dev.Containerfile EMMYLUA_VERSION | ||
| EMMYLUA_VERSION: 0.22.0 |
There was a problem hiding this comment.
Pinned to the same version as the BAR-Devtools dev container (docker/dev.Containerfile, ARG EMMYLUA_VERSION) so editor results match CI. Bump both together.
Reviewer note: these comments were all ported from looooong comments that used to live in the code, but full disclosure: these were ported here and improved by fable. This PR seems legit and surgical to me. Most of the emmylua globals exceptions we add are hanky VFS file loading and probably something we should refactor, but this PR is not the time.
|
|
||
| local raptorStartBoxTexture = "LuaUI/Images/rapt-tileable_v002_small.tga" | ||
|
|
||
| local noRushTime = 0 -- was a bare read that always resolved nil; 0 matches runtime behavior |
There was a problem hiding this comment.
noRushTime is only ever a local in gfx_norush_timer_gl4.lua; these widgets have always read it as a bare identifier at the shader-uniform call site, i.e. nil → 0 at runtime (master behavior, pre-dating this branch). Declaring = 0 locally matches runtime exactly and lets the analyzer check the reference instead of suppressing it.
…ixes Human-curated environment that, together with the LLM type-triage pass (fmt-llm), drives emmylua_check to zero on the migrated tree. Per-change rationale lives in PR beyond-all-reason#7447 review comments. - .emmyrc.json globals + diagnostics; types/* stubs; busted mock; CI gate - forward-decl / assertEqual declarations; reverted orphaned kikito loader - rationale-comment strip; types/IntegrationTests rename - deterministic pins for type-triage leftovers the LLM mishandles on big files (multi_attack opts, HighlightUnit forward-decl, ripairs suppress, gui_pip gameFrame use-before-declare) - json.lua forward-decl tidy (relocate null, drop dead decode_scan*) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
IsDevModeCached (upstream beyond-all-reason#6918) references `utilities` inside its own table constructor, where the local is not yet in scope — Lua resolves those reads as GLOBALS, so the first real call would index nil. Dormant today only because nothing calls it. Forward-declare the local so the closure captures it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0.22.0's analyzer resolves a local inside its own table constructor, so constructor-self-reference globals — a real dormant-crash class (see the springFunctions.lua fix) — passed CI silently. 0.24.0 catches them; the whole workspace surfaces exactly the four occurrences of that one bug, fixed in the previous commit, so the stricter gate lands green. Also tracks the upstream release asset rename (arm64 -> aarch64). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
gui_flowui.lua: Draw.Button uses `opaque` — Draw.Element's 17th parameter, which Button never had; the global read was always nil. Pinned false (behavior-identical) until upstream decides whether Button should expose an opaque mode. snd_notifications.lua: `customNotifications` is persisted by GetConfigData but never declared or assigned anywhere. Declared nil so the round-trip is explicit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Superseded by #8397 — recreated as a same-repo PR (head on beyond-all-reason instead of the fork) so the fmt → mig → fmt-llm-source → fmt-llm chain can use GitHub's native stacked pull requests. Branch content is identical; review history stays readable here. |
Warning
Superseded — this PR was an earlier mint of the stack. The type-error cleanup
now lands via the current stack tip
fmt-llm#8398.This slice's current counterpart is #8397.
Kept closed for review history; nothing here merges.
Part of BAR type-error cleanup. Human-curated env layer that prepares the codebase for the LLM type-fix pass.
This branch carries:
.emmyrc.jsonglobals and analyzer configtypes/*stubs for vendored/generated declarationsThe fix recipes the subsequent LLM pass (#8235) uses are catalogued in
SKILL.md— same rulebook that guides the subagents.Branch Topology
All branches in the BAR type-error cleanup stack — see Bulk Migrations for the migration log and how to run
just bar::migrate::stylua-cleanup. Regenerated deterministically byjust bar::migrate::stylua-cleanup-generate. Generated 2026-07-22 19:34:36 UTC.Leaves — each isolates one transform's diff vs
fmt:styluabar-lua-codemod bracket-to-dotbar-lua-codemod rename-aliasesbar-lua-codemod detach-bar-modules<hand curated><hand curated>Rollups — composite branches stacking the leaves and (for
fmt-llm) the env + LLM layers:master