-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
fix(php): consolidated PHP support — member-call resolution, use-import handling, node identity, cross-language isolation, query seeding (#1682, #2615) #2617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
filipechagas
wants to merge
68
commits into
Graphify-Labs:v8
Choose a base branch
from
lawnstarter:consolidated/php-support-1682
base: v8
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
68 commits
Select commit
Hold shift + click to select a range
43cd7a2
feat(php): resolve $this->prop->method() to the property's declared t…
filipechagas ae95261
feat(php): resolve (new Service())->method() with FQN corroboration (#3)
filipechagas a707b42
feat(php): resolve typed locals and typed params with scope poisoning…
filipechagas 6d33de1
fix(extract): skip language-tagged raw calls in the Swift, Python and…
filipechagas 4f17dd8
feat(php): refuse interface-typed receivers, even under short-name co…
filipechagas f567a36
Merge branch 'feat/php-member-calls-1682-t6': mixed-corpus lang-tag h…
filipechagas 2e68ec6
fix(extract): language-scope the PHP and ObjC receiver type indexes (#8)
filipechagas 5de8f76
feat(php): refuse enum- and trait-typed receivers alongside interface…
filipechagas 0cb78af
fix(php): poison receiver types rebound by `global` and `static` stat…
filipechagas 8d051c6
fix(php): keep the interface refusal across incremental rebuilds (#11)
filipechagas 49b665e
fix(php): corroborate an inline-`new` FQN against the declared namesp…
filipechagas c2c3e89
Merge branch 'feat/php-member-calls-1682-t6': interface refusal acros…
filipechagas 85bb8df
fix(php): carry enum and trait names across incremental rebuilds too …
filipechagas db7c8f8
chore: bump to 0.9.34; changelog and docs for #1682 (#2/#3/#4/#5/#6/#…
filipechagas 102ae79
Merge pull request #17 from lawnstarter/feat/php-member-calls-1682
filipechagas cf49aff
fix(php): emit indirect_call for first-class callables (#15)
filipechagas f310fb5
fix(php): refuse the same-file bare-name edge for union/intersection …
filipechagas fe25b51
fix(php): recognize PHP 8.2 DNF property and promoted-param types (#9)
filipechagas f8c58e6
feat(php): capture use FQN/alias/kind metadata on imports edges (#19)
filipechagas 6e91dbd
Merge pull request #25 from lawnstarter/fix/php-union-intersection-9
filipechagas fbda3ec
fix(extract): scope member-call resolvers to the sources they own (#10)
filipechagas d97e37d
Merge branch 'v8' into fix/php-fcc-indirect-call-15
filipechagas 2a9f9fe
Merge pull request #27 from lawnstarter/fix/php-fcc-indirect-call-15
filipechagas e147764
Merge branch 'v8' into fix/member-call-lang-scoping-10
filipechagas ee3a411
Merge pull request #28 from lawnstarter/fix/member-call-lang-scoping-10
filipechagas d40d006
Merge remote-tracking branch 'origin/v8' into feat/php-use-import-cap…
filipechagas e188ff6
Merge pull request #29 from lawnstarter/feat/php-use-import-capture-19
filipechagas 45f7de1
fix(php): stop group-form `use function`/`use const` from claiming cl…
filipechagas 7006988
Merge pull request #30 from lawnstarter/fix/php-group-use-kind-26
filipechagas 68a3274
feat(extract): keep written qualified PHP receiver types (#20)
filipechagas 64da0eb
Merge remote-tracking branch 'origin/v8' into feat/php-qualified-rece…
filipechagas e713e02
Merge pull request #31 from lawnstarter/feat/php-qualified-receiver-t…
filipechagas 3e148ef
fix(php): refuse a member call whose receiver type the file claims (#21)
filipechagas cec9cdd
Merge pull request #32 from lawnstarter/feat/php-name-resolver-21
filipechagas 49c25ff
fix(extract): scope the last four receiver-type indexes to their own …
filipechagas 10cdee2
fix(extract): keep stem-named import edges alive across a same-stem s…
filipechagas d724156
Merge pull request #34 from lawnstarter/fix/cross-language-isolation-…
filipechagas bf0a92c
feat(extract): bind claimed PHP receiver types to their declared FQNs…
filipechagas 520e58f
feat(extract): persist PHP declared FQNs for incremental-rebuild pari…
filipechagas 5517334
Merge pull request #35 from lawnstarter/feat/php-positive-alias-bindi…
filipechagas 725d082
Merge upstream/v8 (v0.9.34) into chore/sync-upstream-v8
filipechagas ff970bb
Merge pull request #36 from lawnstarter/chore/sync-upstream-v8
filipechagas 87a7398
feat(serve): demote relational-intent terms from the seed guarantee (…
filipechagas cebf231
feat(serve): skip the seed guarantee for already-covered terms (#41)
filipechagas 4e8ff46
feat(serve): relax a starving heuristic context filter (#42)
filipechagas 635db73
fix(serve): judge covered-term coverage on the seed label, never its …
filipechagas ebe7b67
Merge feat/seeding-fix-37-c3: heuristic-filter starvation fallback (#42)
filipechagas 457b31e
chore: bump to 0.9.36; changelog for the query seeding fix (#40/#41/#…
filipechagas 2033c46
Merge pull request #44 from lawnstarter/feat/seeding-fix-37
filipechagas be80845
Merge upstream/v8 (v0.9.35) into chore/sync-upstream-0935
filipechagas acf29e1
fix(serve): only the top-ranked seed may declare a term covered (#37)
filipechagas a9adfc6
Merge pull request #45 from lawnstarter/chore/sync-upstream-0935
filipechagas 075038e
fix(engine): refuse relative-scope names as PHP scoped-call callees (…
filipechagas 313a168
fix(serve): find_node_ambiguity must not collapse sourceless rivals i…
filipechagas 9c4db41
fix(extract): PHP interface/trait/enum declarations mint canonical no…
filipechagas 258d8e3
fix(resolution): resolve imports edges from their own target_fqn meta…
filipechagas 293d57e
fix(extract): bind PHP receiver type from ctor-body assignment of a t…
filipechagas 1606462
chore: bump to 0.9.38; changelog for the stub-shadow + call-edge fixe…
filipechagas 18c17d8
Merge pull request #51 from lawnstarter/fix/stub-shadowing-46
filipechagas 9069df5
fix(extract): PHP function-call sites never bare-match method or clas…
filipechagas 630072e
fix(serve): scored endpoint resolution prefers sourced nodes over sou…
filipechagas 26f7b03
fix(extract): lift the redundant _php_non_class_types receiver refusa…
filipechagas ec4d97e
chore: bump to 0.9.39; changelog for the call-resolution + endpoint-s…
filipechagas 93657ef
Merge pull request #57 from lawnstarter/fix/resolution-gaps-52-53-54
filipechagas 5e9d95c
Merge upstream/v8 (v0.9.37) into chore/sync-upstream-0937
filipechagas 4492f9f
Merge upstream/v8 (v0.9.39) into chore/sync-upstream-0939
filipechagas a79ebe0
chore: consolidate CHANGELOG under 0.9.40 for the single upstream PR …
filipechagas b69dab8
Merge upstream 'v8' (v0.9.40) into consolidated/php-support-1682
filipechagas File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -102,6 +102,22 @@ def _prefer_file_node( | |
| return None | ||
|
|
||
|
|
||
| def _is_sourced(graph: nx.Graph, node_id: str) -> bool: | ||
| return bool(str(graph.nodes[node_id].get("source_file") or "")) | ||
|
|
||
|
|
||
| def _prefer_sourced_node(graph: nx.Graph, node_ids: list[str]) -> str | None: | ||
| """Return the one node with a source file among label rivals, else None. | ||
|
|
||
| Mirrors serve's `_find_node_tiers` exact-tier rule (#49): a sourceless node is | ||
| an unresolved-reference placeholder, so a real declaration sharing its label is | ||
| the answer rather than a tie. Without this, `explain` resolved the sourced node | ||
| while `affected` refused with "No unique node match" — #46's symptom. | ||
| """ | ||
| sourced = [node_id for node_id in node_ids if _is_sourced(graph, node_id)] | ||
| return sourced[0] if len(sourced) == 1 else None | ||
|
|
||
|
|
||
| def resolve_seed(graph: nx.Graph, query: str) -> str | None: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
18 callers depend on it (afferent coupling). Grounded coupling-delta finding (deterministic), not an LLM guess. |
||
| # A trailing path separator must not change a source-file match — serve's | ||
| # _find_node tokenizes the path (which drops it), so strip it here for parity | ||
|
|
@@ -115,8 +131,17 @@ def resolve_seed(graph: nx.Graph, query: str) -> str | None: | |
| for node_id, data in graph.nodes(data=True) | ||
| if _normalize_label(str(data.get("label", ""))) == query_lower | ||
| ] | ||
| if len(exact_label_matches) == 1: | ||
| if len(exact_label_matches) == 1 and _is_sourced(graph, exact_label_matches[0]): | ||
| return exact_label_matches[0] | ||
| if exact_label_matches: | ||
| sourced = _prefer_sourced_node(graph, exact_label_matches) | ||
| if sourced is not None: | ||
| return sourced | ||
| # A lone match that is a sourceless stub is NOT yet an answer: the real | ||
| # declaration may carry a decorated label ("handle()") that only the | ||
| # bare-name pass below reaches, and serve's exact tier — which matches | ||
| # both forms — would prefer it (#49). That pass is a superset of this | ||
| # one, so a stub with no sourced rival still resolves there. | ||
| # Callable labels are decorated ("name()"), so a bare "name" query falls | ||
| # through exact matching and then ties with any "name*" sibling in the | ||
| # contains pass. Match on the undecorated name before giving up. | ||
|
|
@@ -128,6 +153,10 @@ def resolve_seed(graph: nx.Graph, query: str) -> str | None: | |
| ] | ||
| if len(bare_name_matches) == 1: | ||
| return bare_name_matches[0] | ||
| if bare_name_matches: | ||
| sourced = _prefer_sourced_node(graph, bare_name_matches) | ||
| if sourced is not None: | ||
| return sourced | ||
| exact_source_matches = [ | ||
| str(node_id) | ||
| for node_id, data in graph.nodes(data=True) | ||
|
|
||
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
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resolve_seed()18 callers depend on it (afferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.