Swift: computed-property reads create caller edges#1176
Open
nftmago wants to merge 1 commit into
Open
Conversation
Reading a Swift computed property (`obj.isReady`, `Store.canPublish`) runs its getter — behaviourally a call — but the paren-free syntax parsed as neither a call_expression (the call extractor) nor a capitalized Type.member value-read (the static-member pass). So a heavily-used gate property showed "No callers found", silently hiding real dependencies from callers / callees / impact / blast-radius. This is the frontier the docs call out for a Swift codebase (the crypto gates isWellFormed / canPublishBundle). - New internal-only referenceKind `property_read`, emitted by the Swift body walker for every navigation_expression value-read (instance and static receivers). Resolution maps it to a `calls` edge. - matchPropertyRead: strict, mirrors matchFunctionRef — binds to computed-`property` targets ONLY, same language family, same-file then a unique same-directory match, else drop. Swift stored properties extract as field/constant/variable (never `property`) and stdlib members aren't in the graph, so reads of `arr.count` / stored fields / Type.CONST / enum values resolve to nothing and drop — no new noise. A wrong "call" edge is worse than none. - The same-directory tier handles symlinked/mirrored source trees (a test target re-exposing app files) that put a second same-named property in a distant dir. Scoped to Swift end to end (extractor language check + sameLanguageFamily in the matcher), so no other language's resolution changes. Verified: full vitest suite green (2121 passed; the lone intermittent mcp-daemon timeout is pre-existing flake, passes in isolation). New test asserts a computed gate lists its readers while a same-shaped stored field does not. On the Auris crypto codebase, `callers isWellFormed` now returns receiveMessage and `callers canPublishBundle` returns registerSelf (both were "No callers found").
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.
Problem
Reading a Swift computed property —
enc.header.isWellFormed,Store.canPublishBundle— runs its getter, so it is behaviourally a call. But the paren-free syntax parsed as neither acall_expression(the call extractor) nor a capitalizedType.membervalue-read (the static-member pass). So a heavily-used gate property showed "No callers found", silently hiding real dependencies fromcallers/callees/impact/ blast-radius. On a real Swift codebase these are exactly the security choke points (a crypto header'sisWellFormed, an identity store'scanPublishBundle).Fix
property_readreference kind (sibling offunction_ref), emitted by the Swift body walker for everynavigation_expressionvalue-read (instance and static receivers). Resolution maps it to acallsedge.matchPropertyRead: strict, modelled onmatchFunctionRef— binds to computed-propertytargets only, same language family, same-file then a unique same-directory match, else drop. Swift stored properties extract asfield/constant/variable(neverproperty) and stdlib members aren't in the graph, soarr.count, stored-field reads,Type.CONST, and enum values resolve to nothing and drop — no new noise. A wrong "call" edge is worse than none.Scoped to Swift end-to-end (extractor language check +
sameLanguageFamilyin the matcher), so no other language's resolution changes. The eval harness has no Swift coverage, so this is neither exercised nor regressed by it; validated via the unit suite (which has Swift resolution tests) plus a real codebase.Tests
New resolution test: a computed-property gate lists both its readers as callers, while a same-shaped stored field of the same struct produces no bogus caller edge. Full suite green (2121 passed).