Skip to content

Callers

callers

Caller/usage analysis via tree-sitter call-site detection.

Parses call-sites from tree-sitter AST to answer "who calls this function?" — traversing call nodes to find every function/method invocation across a package.

Example

from axm_ast.core.callers import find_callers results = find_callers(pkg, "greet") for r in results: ... print(f"{r.module}:{r.line} — {r.call_expression}")

extract_calls(mod, module_name=None)

Extract all function/method call-sites from a module.

Traverses the tree-sitter AST to find every call node and extracts the called symbol name, location, and context.

Parameters:

Name Type Description Default
mod ModuleInfo

Parsed module info (with path to source).

required
module_name str | None

Dotted module name for CallSite.module.

None

Returns:

Type Description
list[CallSite]

List of CallSite objects for each call in the module.

Source code in packages/axm-ast/src/axm_ast/core/callers.py
def extract_calls(
    mod: ModuleInfo,
    module_name: str | None = None,
) -> list[CallSite]:
    """Extract all function/method call-sites from a module.

    Traverses the tree-sitter AST to find every ``call`` node
    and extracts the called symbol name, location, and context.

    Args:
        mod: Parsed module info (with path to source).
        module_name: Dotted module name for CallSite.module.

    Returns:
        List of CallSite objects for each call in the module.
    """
    source = mod.path.read_text(encoding="utf-8")
    tree = parse_source(source)
    mod_name = module_name or mod.path.stem

    calls: list[CallSite] = []
    _visit_calls(tree.root_node, mod_name, source, calls)
    return calls

extract_references(mod)

Extract symbol names used as references (not direct calls).

Detects identifiers that appear as: - Dict values: {"key": my_func} - List elements: [func_a, func_b] - Tuple elements: (func_a, func_b) - Set elements: {func_a, func_b} - Keyword arguments: DataLoader(collate_fn=my_func) - Default parameters: def foo(callback=my_func)

This catches dynamic dispatch patterns where functions are stored in data structures, passed as keyword arguments, or used as default parameter values.

Parameters:

Name Type Description Default
mod ModuleInfo

Parsed module info (with path to source).

required

Returns:

Type Description
set[str]

Set of symbol names referenced in non-call positions.

Source code in packages/axm-ast/src/axm_ast/core/callers.py
def extract_references(mod: ModuleInfo) -> set[str]:
    """Extract symbol names used as references (not direct calls).

    Detects identifiers that appear as:
    - Dict values: ``{"key": my_func}``
    - List elements: ``[func_a, func_b]``
    - Tuple elements: ``(func_a, func_b)``
    - Set elements: ``{func_a, func_b}``
    - Keyword arguments: ``DataLoader(collate_fn=my_func)``
    - Default parameters: ``def foo(callback=my_func)``

    This catches dynamic dispatch patterns where functions are stored
    in data structures, passed as keyword arguments, or used as default
    parameter values.

    Args:
        mod: Parsed module info (with path to source).

    Returns:
        Set of symbol names referenced in non-call positions.
    """
    source = mod.path.read_text(encoding="utf-8")
    tree = parse_source(source)
    refs: set[str] = set()
    _visit_references(tree.root_node, refs)
    return refs

find_callers(pkg, symbol)

Find all call-sites of a given symbol across a package.

Searches every module in the package for calls matching the given symbol name. Uses cached call-sites when available to avoid re-parsing files on repeated queries.

Parameters:

Name Type Description Default
pkg PackageInfo

Analyzed package info.

required
symbol str

Name of the function/method to search for.

required

Returns:

Type Description
list[CallSite]

List of CallSite objects where the symbol is called.

Example

results = find_callers(pkg, "greet") results[0].module 'cli'

Source code in packages/axm-ast/src/axm_ast/core/callers.py
def find_callers(
    pkg: PackageInfo,
    symbol: str,
) -> list[CallSite]:
    """Find all call-sites of a given symbol across a package.

    Searches every module in the package for calls matching
    the given symbol name.  Uses cached call-sites when available
    to avoid re-parsing files on repeated queries.

    Args:
        pkg: Analyzed package info.
        symbol: Name of the function/method to search for.

    Returns:
        List of CallSite objects where the symbol is called.

    Example:
        >>> results = find_callers(pkg, "greet")
        >>> results[0].module
        'cli'
    """
    from axm_ast.core.cache import get_calls

    # Use cached call-sites when possible
    try:
        calls_by_module = get_calls(pkg.root)
    except (ValueError, OSError):
        # Fallback for programmatic PackageInfo without a real root
        calls_by_module = None

    all_calls: list[CallSite] = []

    if calls_by_module is not None:
        for mod_calls in calls_by_module.values():
            for call in mod_calls:
                if call.symbol == symbol:
                    all_calls.append(call)
    else:
        for mod in pkg.modules:
            mod_name = module_dotted_name(mod.path, pkg.root)
            calls = extract_calls(mod, module_name=mod_name)
            for call in calls:
                if call.symbol == symbol:
                    all_calls.append(call)

    return all_calls

find_callers_workspace(ws, symbol)

Find all call-sites of a symbol across a workspace.

Searches every package in the workspace for calls matching the given symbol name. Module names are prefixed with pkg_name:: for disambiguation.

Parameters:

Name Type Description Default
ws WorkspaceInfo

Analyzed workspace info.

required
symbol str

Name of the function/method to search for.

required

Returns:

Type Description
list[CallSite]

List of CallSite objects where the symbol is called.

Example

results = find_callers_workspace(ws, "ToolResult") results[0].module 'axm_mcp::server'

Source code in packages/axm-ast/src/axm_ast/core/callers.py
def find_callers_workspace(
    ws: WorkspaceInfo,
    symbol: str,
) -> list[CallSite]:
    """Find all call-sites of a symbol across a workspace.

    Searches every package in the workspace for calls matching
    the given symbol name. Module names are prefixed with
    ``pkg_name::`` for disambiguation.

    Args:
        ws: Analyzed workspace info.
        symbol: Name of the function/method to search for.

    Returns:
        List of CallSite objects where the symbol is called.

    Example:
        >>> results = find_callers_workspace(ws, "ToolResult")
        >>> results[0].module
        'axm_mcp::server'
    """
    all_calls: list[CallSite] = []

    for pkg in ws.packages:
        callers = find_callers(pkg, symbol)
        for call in callers:
            # Prefix with package name for cross-package disambiguation
            call.module = f"{pkg.name}::{call.module}"
            all_calls.append(call)

    return all_calls