fix(members): credit interface-typed property dispatch through implementers (#1863)#1889
Merged
Merged
Conversation
…enters (#1863) A method reached through a property whose declared type is an interface, on a class that implements that interface (deps.greeter.greet() where Deps.greeter: GreeterPort and GreeterAdapter implements GreeterPort), was false-flagged as unused-class-member. The #1785 typed-property hop resolves the terminal to the interface, but the terminal credit only handled classes (export_is_class_with_members gates out interfaces), so it never reached the interface-to-implementer propagation that already covers the direct-parameter case (useIt(g: GreeterPort) { g.greet() }). propagate_typed_property_accesses now routes an interface terminal to its canonical export key so the later propagate_interface_member_accesses pass carries the member to every implementing class, making the property-hop terminal behave exactly like the direct-parameter case. Additive and false-negative-only: a terminal that is not an interface with implementers credits nothing, so it can only suppress a false positive, never create one. No CACHE_VERSION bump (analyze-only; reads existing type_member_types facts and class_heritage.implements). Closes #1863
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.
unused-class-membersfalse-flagged a method reached through a property whose declared type is an interface, on a class that implements that interface (ports-and-adapters / hexagonal DI):useIt(deps: Deps) { deps.greeter.greet() }whereDeps.greeter: GreeterPortandclass GreeterAdapter implements GreeterPort. The interface dispatch already worked through a direct parameter or variable; this closes the remaining gap where the receiver is reached via an interface property hop.The #1785 typed-property hop resolves the terminal to interface
GreeterPort, but the terminal credit only handled classes (export_is_class_with_membersgates out interfaces), so it never reached the interface-to-implementer propagation that already covers the direct-parameter case.propagate_typed_property_accessesnow routes an interface terminal to its canonical export key so the laterpropagate_interface_member_accessespass carries the member to every implementing class.Additive and false-negative-only (can only suppress a false positive, never create one). Analyze-only, so no
CACHE_VERSIONbump. A genuinely-unused method on the implementing class still reports.Third in the #1785 / #1788 / #1858 cluster. Thanks @lukeramsden for the clean minimal reduction.
Closes #1863