Unified: Introduce local variables and 'self' bindings - #22547
Merged
Conversation
We used the term declaration both for the identifier and the surrounding node declaring containing one or more such identifiers (possibly nested in a pattern). It led to code like `getADeclaration().getDeclaration()`. We now use the term "binding" for identifiers in binding position, and declarations as contexts that establish the binding position.
This moves a handful of predicates into a module, parameterised by the 'accessCand' predicate. There are no other changes to predicates, they are just moved. This is to allow further variable-lookups at a later stage.
This caused name clashes in other languages.
Now that StaticNameBinding also has a module called 'Public' we get conflicts when importing both. Adding a facade for importing both.
asgerf
force-pushed
the
unified/local-variables-and-self
branch
from
September 11, 2026 08:22
8906ed2 to
57c071f
Compare
asgerf
marked this pull request as ready for review
September 11, 2026 08:44
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved moderate issues affect top-level declaration classification and capture detection.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 1
New issues introduced by this change (1)
| Severity | Finding |
|---|---|
shared/namebinding/codeql/namebinding/LocalNameBinding.qll — Correct the LocalAccess spelling in the comment |
What changed in this PR
Introduces unified local-variable and implicit-self name binding, including capture tracking, and updates related consumers and tests.
Changes:
- Adds local-variable, access, capture, and implicit-qualifier APIs.
- Consolidates name-binding and enclosing-callable utilities.
- Updates diagnostics, definitions, tests, and debugging tools.
| File | Changes |
|---|---|
unified/ql/test/library-tests/static-name-binding/test.ql |
Updates static binding tests. |
unified/ql/test/library-tests/local-name-binding/test.swift |
Adds capture expectations. |
unified/ql/test/library-tests/local-name-binding/test.ql |
Tests variables, captures, and implicit qualifiers. |
unified/ql/test/library-tests/local-name-binding/self_access.swift |
Tests Swift self scenarios. |
unified/ql/test/library-tests/local-name-binding/class_scope.swift |
Tests implicit instance receivers. |
unified/ql/test/library-tests/definitions/test.ql |
Updates definition tests. |
unified/ql/src/diagnostic/StaticNameResolution.ql |
Uses unified bindings. |
unified/ql/src/diagnostic/FilesCoveredByModuleManifest.ql |
Updates binding usage. |
unified/ql/lib/utils/test/TestUtils.qll |
Updates test binding utilities. |
unified/ql/lib/utils/test/CommentUtil.qll |
Supports hyphenated expectation tags. |
unified/ql/lib/unified.qll |
Exports the unified binding facade. |
unified/ql/lib/ide-contextual-queries/definitions.ql |
Updates definition query types. |
unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll |
Renames APIs and resolves implicit receivers. |
unified/ql/lib/codeql/unified/internal/NameBindingPluginSwift.qll |
Adds Swift receiver metadata. |
unified/ql/lib/codeql/unified/internal/NameBindingPlugin.qll |
Adds a receiver plugin hook. |
unified/ql/lib/codeql/unified/internal/NameBinding.qll |
Re-exports binding implementations. |
unified/ql/lib/codeql/unified/internal/LocalNameBinding.qll |
Adds local-variable and capture modeling. |
unified/ql/lib/codeql/unified/internal/FacadeAst.qll |
Adds callable and class ancestry helpers. |
unified/ql/lib/codeql/unified/internal/dev/debugStaticNameBindingGraph.ql |
Migrates debug graph imports. |
unified/ql/lib/codeql/unified/internal/dev/debugLocalNameBindingGraph.ql |
Migrates debug graph imports. |
unified/ql/lib/codeql/unified/internal/ControlFlowGraph.qll |
Reuses the AST callable helper. |
unified/ql/lib/codeql/unified/internal/AstExtra.qll |
Updates local declaration classification. |
unified/ql/lib/codeql/unified/internal/AnalysisQuality.qll |
Migrates analysis types. |
unified/ql/lib/codeql/Definitions.qll |
Updates definition binding types. |
shared/namebinding/codeql/namebinding/LocalNameBinding.qll |
Adds extensible access resolution. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
hvitved
reviewed
Sep 11, 2026
hvitved
left a comment
Contributor
There was a problem hiding this comment.
Looks great, some (mostly minor) comments.
Contributor
Author
Rerun has been triggered: 4 restarted 🚀 |
Contributor
Author
|
@hvitved I pushed two more commits as I noticed |
hvitved
approved these changes
Sep 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Expands name binding with:
LocalVariablewith many of the usual predicates likegetDeclaringCallable()andisCaptured().LocalVariableAccessUnqualifiedMemberAccess.getImplicitQualifierVariablefor getting theLocalVariablecorresponding to the implicitselfaccess.AstNode.getEnclosingCallable()(moved out from CFG)Re-declarations of 'self' in Swift
There is a unique complication for Swift due to
[weak self]andguard let selfstatements, which re-introduce new variables calledself. I've decided to just treatselfas "just another variable" so this doesn't become a weird corner case, but something that "just works" because the extractor inserts the correct variable-declarations: