Skip to content

Unified: Add folder-based fallback for static name resolution - #22370

Open
asgerf wants to merge 11 commits into
github:mainfrom
asgerf:unified/folder-fallback
Open

Unified: Add folder-based fallback for static name resolution#22370
asgerf wants to merge 11 commits into
github:mainfrom
asgerf:unified/folder-fallback

Conversation

@asgerf

@asgerf asgerf commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Static name resolution relies on Package.swift manifests to indicate how files are linked up. However, it seems only about 50% of real-world projects use such manifest files. In the absence of a known manifest file, we had no way of linking up names across files.

This PR adds a generic fallback mechanism for files that are not covered by a known manifest. An unqualified name X, appearing in a file without a known manifest, may now resolve to any (exported) top-level declaration X. If multiple such declarations exist, we prioritise the one "closest" in the file hierarchy, meaning the one with the lowest common ancestor in the folder tree.

If two definitions are tied for being closest, none is resolved as the target. Some more real-world examples of this would help motivate what to do here.

Evaluation

The PR also adds meta and metric queries for measuring the success rate of static name binding (first commit). I wanted to make sure the meta queries and metric query stay in sync, so they now share code through AnalysisQuality.qll.

Note that the percentage of statically resolvable names is currently not very useful because 100% is not an attainable number due to dependencies not being extracted. A lower number is not necessarily bad, because MaD models can still be evaluated by stepping through the name-binding graph directly. With that said, resolution rate, averaged over all projects, increases from 31% to 37%. An increase is always good, though it doesn't count as a "success rate".

See the DCA report for more concrete stats.

@asgerf
asgerf force-pushed the unified/folder-fallback branch from 01d2ec1 to 60dd3ba Compare August 18, 2026 08:10
@asgerf asgerf added the no-change-note-required This PR does not need a change note label Aug 18, 2026
@asgerf
asgerf force-pushed the unified/folder-fallback branch 4 times, most recently from 26940cf to 252d8cd Compare August 20, 2026 07:46
asgerf added 6 commits August 20, 2026 13:22
The spurious result is offered by the folder-based heuristic, but would have been blocked by proper shadowing support.
Inheritance and access to nested classes is one of the reasons not to apply the heuristic as a "fixup" after the recursive layer, because when a base class is resolved through the folder heuristic, access to nested members still need to be resolved through the standard logic.
@asgerf
asgerf force-pushed the unified/folder-fallback branch from 252d8cd to b6741aa Compare August 20, 2026 11:23
}

module EntityReportStats<EntityStatsSig Input> {
private import Input
Comment thread unified/ql/src/diagnostic/FilesCoveredByModuleManifest.ql Fixed
Comment thread unified/ql/src/diagnostic/StaticNameResolution.ql Fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds folder-based fallback name resolution for Swift files without package manifests, plus analysis-quality telemetry.

Changes:

  • Adds folder-proximity-based static name binding.
  • Adds resolution and manifest-coverage diagnostics.
  • Adds tests for unique and ambiguous cross-file names.
Show a summary per file
File Description
unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll Implements folder-based name resolution.
unified/ql/lib/codeql/unified/internal/AnalysisQuality.qll Defines reusable quality statistics.
shared/util/codeql/util/ReportStats.qll Adds entity-based statistics reporting.
unified/ql/src/diagnostic/StaticNameResolution.ql Reports resolved static names.
unified/ql/src/diagnostic/FilesCoveredByModuleManifest.ql Reports manifest-covered files.
unified/ql/src/diagnostic/ExtractorInformation.ql Exposes statistics as telemetry.
unified/ql/test/library-tests/static-name-binding/unqualified-access.swift Records a heuristic false positive.
unified/ql/test/library-tests/static-name-binding/not-a-package/SiblingFiles/Use.swift Tests sibling-file resolution and ambiguity.
unified/ql/test/library-tests/static-name-binding/not-a-package/SiblingFiles/Def1.swift Adds sibling declarations.
unified/ql/test/library-tests/static-name-binding/not-a-package/SiblingFiles/Def2.swift Adds competing sibling declarations.
unified/ql/test/library-tests/static-name-binding/not-a-package/SiblingFiles/SubFolder1/Def.swift Adds nested declarations.
unified/ql/test/library-tests/static-name-binding/not-a-package/SiblingFiles/SubFolder2/Def.swift Adds competing nested declarations.
unified/ql/test/library-tests/static-name-binding/not-a-package/Main/Runner.swift Tests proximity in the Main tree.
unified/ql/test/library-tests/static-name-binding/not-a-package/Main/Util/Util.swift Tests nested Main resolution.
unified/ql/test/library-tests/static-name-binding/not-a-package/Main/Drivers/Driver.swift Defines Main-specific targets.
unified/ql/test/library-tests/static-name-binding/not-a-package/Mock/Runner.swift Tests proximity in the Mock tree.
unified/ql/test/library-tests/static-name-binding/not-a-package/Mock/Util/Util.swift Tests nested Mock resolution.
unified/ql/test/library-tests/static-name-binding/not-a-package/Mock/Drivers/Driver.swift Defines Mock-specific targets.

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 18/18 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll Outdated
Comment thread unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll
@asgerf

asgerf commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

@asgerf
asgerf marked this pull request as ready for review August 20, 2026 14:20
@asgerf
asgerf requested review from a team as code owners August 20, 2026 14:20
@asgerf
asgerf requested a review from hvitved August 20, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants