Skip to content

fix(registry): restrict same-module suffix resolution to self/namespace receivers#893

Open
sahil-mangla wants to merge 4 commits into
DeusData:mainfrom
sahil-mangla:main
Open

fix(registry): restrict same-module suffix resolution to self/namespace receivers#893
sahil-mangla wants to merge 4 commits into
DeusData:mainfrom
sahil-mangla:main

Conversation

@sahil-mangla

Copy link
Copy Markdown
Contributor

What does this PR do?

This PR fixes #876 false-positive recursion flags (unguarded_recursion, self_recursive, recursive) occurring on store wrappers, singleton delegations, and other method calls targeting unrelated objects that happen to share a name with a top-level function in the current module (e.g. _get_store().get(...) inside get(...) or _default.check(...) inside check(...)).

Root Cause

During call graph resolution in Strategy 2 (resolve_same_module in src/pipeline/registry.c), dotted/colon-separated callee names (like _default.check) were split into prefix (_default) and suffix (check). The resolver fell back to checking if the suffix exists as a top-level function in the caller's module (module_qn.check). If a local check function was defined, it matched and mistakenly resolved the call to it, generating a self-loop CALLS edge which flagged the function as recursive.

Solution

  • Introduced is_same_module_receiver to validate the receiver prefix. Suffix fallback checks in resolve_same_module are now restricted to:
    • Valid self-receivers: "self", "this", "cls", "@self".
    • Prefix matching the module/namespace name itself (or ending with .<prefix>).
  • Restricting this prevents unrelated receiver calls (like axios.get, _get_store().get, _default.check) from matching same-module top-level functions, eliminating spurious CALLS self-loops.
  • Added a regression test suite in tests/test_registry.c (resolve_same_module_only_on_self_receiver) to cover delegation, self, and namespace/module receiver pattern cases.

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)

@sahil-mangla sahil-mangla requested a review from DeusData as a code owner July 5, 2026 18:44
@DeusData DeusData added bug Something isn't working parsing/quality Graph extraction bugs, false positives, missing edges priority/normal Standard review queue; useful PR with ordinary maintainer urgency. labels Jul 7, 2026
@DeusData

DeusData commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Thanks for the focused #876 fix. Triage: parsing/quality bug, normal priority.

Review should verify the receiver restriction removes store/delegation false positives without regressing legitimate same-module self or namespace receiver calls. The small registry-focused diff is a good shape for this bug.

… receivers

Limit same-module suffix fallback in resolve_same_module to only fire if the receiver is a self-receiver or matches the module/namespace. Also reject matching dotted/colon-qualified callees targeting a Function to a different prefix in name lookup. This prevents false-positive recursion flags on store/delegation calls.

Signed-off-by: sahil-mangla <manglasahil2017@gmail.com>
Signed-off-by: sahil-mangla <manglasahil2017@gmail.com>
Java enums with methods (e.g. isWeekend/label in cp_enum_method_java)
have their method declarations inside enum_body_declarations, which is a
child of enum_body — not a direct child of enum_body itself.

find_class_body was returning the raw enum_body node (16 children:
enum_constant×7, commas, and the nested enum_body_declarations). As a
result, extract_class_methods iterated enum_constant/comma nodes and
never visited any method_declaration, so no Method nodes were created
and no CALLS edges resolved.

Fixes:
- find_class_body: if a body resolved via field-name lookup is enum_body,
  look for enum_body_declarations inside it and return that instead.
- find_class_body fallback loop: same unwrapping for the type-scan path.
- push_class_body_children: add enum_body and enum_body_declarations to
  the recognised body-container kinds so the walk_defs stack correctly
  scopes enum method children under the enum QN.

Tests: convergence_probe 47/47 passed (was 46/47, cp_enum_method_java
was the failing case).

Signed-off-by: sahil-mangla <manglasahil2017@gmail.com>
Wrap two if-conditions that exceeded the 100-column limit:

- Line 3506: break &&-condition before the parenthesised ObjC/Java
  language check so the line stays within 100 cols.
- Lines 5860-5861: split the combined enum_body / enum_body_declarations
  comparison onto separate continuation lines to satisfy the limit.

No logic change; formatting only.

Signed-off-by: sahil-mangla <manglasahil2017@gmail.com>
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/normal Standard review queue; useful PR with ordinary maintainer urgency.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recursion flags still false-positive on store/delegation calls after #599 (soil.get, _default.check)

2 participants