Skip to content

R: module$function() call syntax not resolved to CALLS edges #219

Closed

Description

@marcusyoung

Summary

In R code using the box module system, functions imported from other modules are called using $ accessor syntax — e.g., validation$validate_input(x). The call resolution pipeline does not resolve this pattern, so no CALLS edge is created between the calling function and validate_input. Call chains are silently truncated at module boundaries.

Expected behaviour

module$function() call syntax should be resolved to a CALLS edge where the target is the qualified name of the function in the source module, provided the source module can be identified from an IMPORTS edge (see companion issue on box::use() parsing).

Actual behaviour

No CALLS edge is created. trace_path on any function called via $ syntax shows zero callers, regardless of actual usage in the codebase.

Minimal example

# app/view/map_panel.R
box::use(
  app/logic/validation[validate_input]
)
 
map_server <- function(id) {
  shiny::moduleServer(id, function(input, output, session) {
    result <- validation$validate_input(input$track)  # not resolved
  })
}

trace_path on validation$validate_input (or app/logic/validation::validate_input) returns no callers. map_server does not appear in any call chain originating from validate_input.

Context

This pattern is ubiquitous in Rhino applications and in any R code using box. It is distinct from the standard package::function() namespace syntax (which uses :: and may already be handled). The $ accessor is specific to box's imported-alias calling convention.

Both issues are related: resolving the call target in this issue depends on knowing what module the alias refers to, which requires IMPORTS edge support from the companion issue.

Version

0.6.0 (Windows amd64)

Activity

  1. added
    bugSomething isn't working
    parsing/qualityGraph extraction bugs, false positives, missing edges
    on Apr 15, 2026
  2. DeusData commented on May 31, 2026

    @DeusData
    Owner

    Confirmed, and coupled to #218. module$function() accessor-call resolution depends on first having the box::use() IMPORTS edge (#218) to know which module module refers to. Once box imports are parsed, the call resolver needs a rule: <alias>$<fn>() → CALLS edge to <resolved-module>.<fn>. Both are queued together as the R box-module support work (kept open). 🙏

  3. DeusData commented on May 31, 2026

    @DeusData
    Owner

    Thanks — accepted feature-gap, paired with #218. R is tree-sitter-only, and the module$function() call form isn't yet resolved into CALLS edges (it needs the box::use import resolution from #218 to know what module binds to). Implementing #218 (box import edges) is the prerequisite; this issue tracks the call-resolution half on top of it. A representative public R/box repo would help me reproduce and validate. Thanks!

  4. marcusyoung commented on May 31, 2026

    @marcusyoung
    Author
  5. DeusData commented on May 31, 2026

    @DeusData
    Owner

    Fixed in commit 1a636f1 (same change as #218). R module$function() calls were dropped because the call-callee resolver didn't recognize R's extract_operator ($) as a call function node — so no CALLS edge was produced.

    extract_callee_from_fields now handles a function node of type extract_operator: it emits "<lhs>.<rhs>" (e.g. validation$validate_input(x) → callee validation.validate_input), consistent with how member/method calls are represented for other languages. Regression test extract_r_dollar_call_issue219 verifies the CALLS edge now exists.

    This composes with the box::use import work in #218, so a Rhino/box Shiny app's module calls now resolve. Ships next release — thanks!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingparsing/qualityGraph extraction bugs, false positives, missing edges

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions