Skip to content

Enable minimal static analysis - #10329

Open
Toucan4Life wants to merge 3 commits into
PathOfBuildingCommunity:devfrom
Toucan4Life:enable-static-analysis
Open

Toucan4Life wants to merge 3 commits into
PathOfBuildingCommunity:devfrom
Toucan4Life:enable-static-analysis

Conversation

@Toucan4Life

@Toucan4Life Toucan4Life commented Sep 7, 2026

Copy link
Copy Markdown

Description of the problem being solved:

As a newcomer, it was very hard to follow which attribute is available on which type and which function are available. This PR goal is to enable an minimally useful static analysis.

I tried to type some of the module that were dynamically loaded like busted lfs and lzip among others, and tried to fix the most egregious errors that surfaced. To keep the PR small I changed the severity of some classes of errors to warning.

  • Add a LuaJIT-aware EmmyLua project configuration with support for the project's += syntax and LoadModule / PLoadModule loading model.
  • Analyze handwritten application and Busted test code by default, while excluding generated tree data, generated skill/cache data, stat descriptions, and exporter output.

A small number of non-annotation changes are included because static analysis exposed some issues :

  • Scope the dynamically injected updater progress callback locally and handle failed update/download file writes rather than continuing with a nil file handle.
  • Correct the SHA-1 module import shape used by the updater.
  • Fix missing or stale local values in calculation, breakdown, timeless-jewel repair, import, party, trade, and copy-to-clipboard paths.
  • Remove an obsolete aura-modifier consumer whose parser-side producer no longer exists.
  • Make test/build-generation setup explicitly require LuaFileSystem and fail clearly when a required fixture or output file cannot be opened.

Steps taken to verify a working solution:

  • Ran POB.
  • Ran the full default Busted suite: 584 successes, 0 failures, 0 errors.

Thanks to this PR, EmmyLua reports 0 errors, and its diagnostics are less noisy

@Toucan4Life

Copy link
Copy Markdown
Author

Hi @vaisest I was inspired by your PR and want to have full static analysis for the whole project .

This PR is to enable it and fix the errors reported by EmmyLua. I have another PR coming soon that will annotate all the file in the classes folder.

Do you know how can I get this one merged please? :)

@vaisest

vaisest commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

What errors (or warnings) does this fix? Most of these look like fixes for undefined globals which certainly makes sense. It would be a good idea to get rid of any existing errors so that there could be a CI action which checks for really obvious errors

I'm not sure how the maintainers feel about putting the emmylua config and types in git. I avoided that myself by just putting examples in CONTRIBUTING.md

@Toucan4Life
Toucan4Life force-pushed the enable-static-analysis branch from 9a59d86 to 2f89a6f Compare September 16, 2026 09:22
@Toucan4Life

Copy link
Copy Markdown
Author

I would prefer to leave it as is to ease the barrier to entry, but I let that decision up to the maintainers. In the meantime I removed it so it is in line with the CONTRIBUTING.md

Shamelessly used AI to do this summary :

The pre-fix version produced 716 EmmyLua errors. The committed version produced 0 EmmyLua errors. The table below contains the exact diagnostic messages emitted by the checker, grouped when the same message appeared multiple times.

Count Exact EmmyLua diagnostic Locations / affected files
546 undefined global variable: it Test files under spec/System/; repeated at each it(...) declaration
75 undefined global variable: describe Test files under spec/System/; repeated at each describe(...) declaration
31 undefined global variable: before_each Test files under spec/System/
11 undefined global variable: after_each Test files under spec/System/
10 undefined global variable: teardown Test files under spec/System/
4 undefined global variable: lfs [spec/GenerateBuilds.lua](/home/theo/Documents/Source/pob/spec/GenerateBuilds.lua):3,6; [spec/System/TestBuilds_spec.lua](/home/theo/Documents/Source/pob/spec/System/TestBuilds_spec.lua):3,6
4 undefined global variable: skillCfg [src/Modules/CalcBreakdown.lua](/home/theo/Documents/Source/pob/src/Modules/CalcBreakdown.lua):212,232; [src/Modules/CalcPerform.lua](/home/theo/Documents/Source/pob/src/Modules/CalcPerform.lua):915
2 undefined global variable: cfg [src/Modules/CalcOffence.lua](/home/theo/Documents/Source/pob/src/Modules/CalcOffence.lua):2506,2507
2 undefined global variable: dotCfg [src/Modules/CalcOffence.lua](/home/theo/Documents/Source/pob/src/Modules/CalcOffence.lua):3527,3538
2 undefined global variable: fileName [src/Classes/PartyTab.lua](/home/theo/Documents/Source/pob/src/Classes/PartyTab.lua):198,201
2 undefined global variable: nullValue [src/Classes/ModDB.lua](/home/theo/Documents/Source/pob/src/Classes/ModDB.lua):262; [src/Classes/ModList.lua](/home/theo/Documents/Source/pob/src/Classes/ModList.lua):207
2 undefined global variable: scriptPath [src/Modules/DataLegionLookUpTableHelper.lua](/home/theo/Documents/Source/pob/src/Modules/DataLegionLookUpTableHelper.lua):136,144
2 undefined global variable: UpdateProgress [src/UpdateCheck.lua](/home/theo/Documents/Source/pob/src/UpdateCheck.lua):222,223
1 annotation-usage-error: \@Generic T` can't be used here` [src/Classes/Control.lua](/home/theo/Documents/Source/pob/src/Classes/Control.lua):68
1 doc-syntax-error: expect name or ... [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):117
1 undefined global variable: affectedByAura [src/Modules/CalcPerform.lua](/home/theo/Documents/Source/pob/src/Modules/CalcPerform.lua):3464
1 undefined global variable: aura [src/Classes/PartyTab.lua](/home/theo/Documents/Source/pob/src/Classes/PartyTab.lua):919
1 undefined global variable: expose [spec/System/TestBuilds_spec.lua](/home/theo/Documents/Source/pob/spec/System/TestBuilds_spec.lua):18
1 undefined global variable: gameId [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: grantedEffectId [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: i [src/Classes/TradeQueryGenerator.lua](/home/theo/Documents/Source/pob/src/Classes/TradeQueryGenerator.lua):333
1 undefined global variable: item [src/Classes/NotableDBControl.lua](/home/theo/Documents/Source/pob/src/Classes/NotableDBControl.lua):293
1 undefined global variable: modSource [src/Modules/CalcDefence.lua](/home/theo/Documents/Source/pob/src/Modules/CalcDefence.lua):1606
1 undefined global variable: nan [spec/TestBuilds/3.13/Dual Savior.lua](/home/theo/Documents/Source/pob/spec/TestBuilds/3.13/Dual%20Savior.lua):1064
1 undefined global variable: name [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: naturalMaxLevel [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: pending [spec/System/TestRadiusJewelStatDiff_spec.lua](/home/theo/Documents/Source/pob/spec/System/TestRadiusJewelStatDiff_spec.lua):561
1 undefined global variable: reqDex [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: reqInt [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: reqStr [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: secondaryGrantedEffectId [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: sessionID [src/Classes/ImportTab.lua](/home/theo/Documents/Source/pob/src/Classes/ImportTab.lua):973
1 undefined global variable: stat [src/Classes/TradeQuery.lua](/home/theo/Documents/Source/pob/src/Classes/TradeQuery.lua):737
1 undefined global variable: tagString [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: vaalGem [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131
1 undefined global variable: variantId [src/Modules/Data.lua](/home/theo/Documents/Source/pob/src/Modules/Data.lua):1131

What the commit fixed

The 716 errors fall into these groups:

  • 673 undefined-global errors
    • 673 = test-framework globals, missing locals, and undeclared variables.
  • 1 annotation syntax error
    • Invalid @generic T usage.
  • 1 documentation syntax error
    • Invalid TransformFunc declaration.
  • 41 additional test-framework/global errors
    • describe, it, before_each, after_each, teardown, expose, and pending.

The fixes were:

  • Added [types/busted.lua](/home/theo/Documents/Source/pob/types/busted.lua) for Busted globals.
  • Added [types/lfs.lua](/home/theo/Documents/Source/pob/types/lfs.lua) for LuaFileSystem.
  • Replaced accidental globals with locals.
  • Added missing local variables and EmmyLua annotations.
  • Corrected invalid LuaDoc syntax.
  • Replaced the invalid nan token with 0 / 0.
  • Removed or corrected references to undefined variables such as cfg, dotCfg, skillCfg, nullValue, scriptPath, and UpdateProgress.

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

Successfully merging this pull request may close these issues.

2 participants