Skip to content

fix(php): add fallback for self:: static calls when enclosing_class_q… - #2164

Open
Carnival-z wants to merge 2 commits into
DeusData:mainfrom
Carnival-z:fix/php-self-static-fallback
Open

Carnival-z wants to merge 2 commits into
DeusData:mainfrom
Carnival-z:fix/php-self-static-fallback

Conversation

@Carnival-z

Copy link
Copy Markdown

…n is NULL

Problem:
PHP LSP's resolve_static_call() returns early when enclosing_class_qn is NULL, causing self::/static::/parent:: calls to fall back to low-confidence heuristic strategies (unique_name 0.75 or suffix_match 0.55) instead of high-confidence php_self_static (0.95).

Root Cause:
When process_class_decl doesn't populate enclosing_class_qn (e.g., complex method bodies with closures), resolve_static_call short-circuits without generating any LSP resolution, leaving pass_calls.c to use registry fallbacks.

Fix:
Add fallback logic to infer class_qn from enclosing_func_qn when handling self::/static:: scopes. Extract class QN by stripping the last .method segment from "Project.path.Class.method" → "Project.path.Class", then continue with normal method lookup and emit php_self_static strategy at 0.95 confidence.

Impact:

  • PHP only (no other languages affected)
  • Improves self:: call resolution from 0.55-0.75 → 0.95 confidence
  • Verified on iCMS v8.0.0: AdminAdmincp.do_index self::setContext/tableData/view

What does this PR do?

Checklist

  • Every commit is signed off (git commit -s) — required, CI rejects
    unsigned commits (DCO, see CONTRIBUTING.md)
  • Tests pass locally (make -f Makefile.cbm test)
  • Lint passes (make -f Makefile.cbm lint-ci)
  • New behavior is covered by a test (reproduce-first for bug fixes)

…n is NULL

Problem:
PHP LSP's resolve_static_call() returns early when enclosing_class_qn is NULL,
causing self::/static::/parent:: calls to fall back to low-confidence heuristic
strategies (unique_name 0.75 or suffix_match 0.55) instead of high-confidence
php_self_static (0.95).

Root Cause:
When process_class_decl doesn't populate enclosing_class_qn (e.g., complex
method bodies with closures), resolve_static_call short-circuits without
generating any LSP resolution, leaving pass_calls.c to use registry fallbacks.

Fix:
Add fallback logic to infer class_qn from enclosing_func_qn when handling
self::/static:: scopes. Extract class QN by stripping the last .method segment
from "Project.path.Class.method" → "Project.path.Class", then continue with
normal method lookup and emit php_self_static strategy at 0.95 confidence.

Impact:
- PHP only (no other languages affected)
- Improves self:: call resolution from 0.55-0.75 → 0.95 confidence
- Verified on iCMS v8.0.0: AdminAdmincp.do_index self::setContext/tableData/view

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
… strategies

Problem:
weak name-only matching (unique_name/suffix_match) can fabricate spurious
cross-language edges when no imports are present, e.g., Python builtin 'get'
matching every unrelated project 'get' function.

Change:
Add strict import requirement in resolve_name_lookup() - return empty result
when import_vals is NULL/empty, forcing reliance on high-confidence strategies
(import_map 0.95, same_module 0.90) only.

Trade-off:
- Eliminates false positive cross-language edges
- May miss legitimate same-language calls in import-sparse codebases
- Reduces noise in call graphs at the cost of coverage

Impact:
- unique_name: was 0.75 → 0.375 (degraded) → now rejected entirely
- suffix_match: was 0.55 (module distance) → now rejected entirely
- High-confidence strategies unaffected

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Thanks for opening this — it has been seen, and it is queued.

This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence.

Current review status: working through a backlog. 0.9.1-rc.1 is out, so the release freeze that held reviews is over — but it left a large queue of open pull requests behind it, and we are reading through them oldest-first. The background is in discussion #1144.

What that means for this PR, concretely:

  • It will not be closed for inactivity. No stale bot touches pull requests here.
  • It may still sit a while before a human reads it. That is on us, not on you.
  • Older PRs are read first, so a recent one is not being skipped — it is behind a queue.

Things that will genuinely speed it up whenever review does happen:

  • Keep it rebased on main — the tree is moving quickly right now, and a conflicting branch cannot be reviewed as the diff you intended.
  • Get CI green, or say which failures you believe are pre-existing.
  • Keep the change to one claim. Bundled features and refactors get split before they get merged, which costs you a round trip.
  • Every commit needs a sign-off (git commit -s) — CI enforces DCO.

If this fixes a bug, a reproduction we can run is worth more than a description of the symptom.

Thanks for contributing, and sorry in advance for the wait.

@DeusData DeusData added bug Something isn't working parsing/quality Graph extraction bugs, false positives, missing edges priority/high Needs near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker. labels Sep 19, 2026
@DeusData

Copy link
Copy Markdown
Owner

Thank you for the PHP investigation. The current diff also changes shared resolve_name_lookup behavior for callers without imports across languages, so this is broader than a PHP-only adjustment. Please separate that shared policy decision from the focused PHP correction and add the relevant PHP regression controls, including closure and parent:: behavior. That will let the concrete fix be reviewed without implicitly approving a cross-language binding change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working parsing/quality Graph extraction bugs, false positives, missing edges priority/high Needs near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants