Skip to content

R (.r/.R) listed in CODE_EXTENSIONS but has no AST extractor — silently drops all R files with zero warning #1689

Description

@Sneakypeat

Summary

.r/.R is included in detect.py's CODE_EXTENSIONS set, so R files are classified as FileType.CODE and counted in the scan summary (e.g. found 24 code, ...). But extract.py's _DISPATCH dict — the table that maps extensions to an actual AST extractor function — has no .r/.R entry at all (it covers ~45 languages: Python, JS/TS, Go, Rust, Java, Ruby, C/C++, Swift, Kotlin, Scala, PHP, Lua, Zig, PowerShell, Elixir, Objective-C, Julia, Fortran, Vue, Svelte, Astro, Dart, Verilog, SQL, Pascal/Delphi, DragonFly BASIC, .NET project files, etc. — but not R).

Reproduction

Run graphify extract . on a project that's mostly .R scripts (e.g. an R/renv analysis project with ~17 .R files and a handful of .py helper scripts).

  • Scan step reports something like found 24 code, 0 docs, 1 papers, 0 images — the R files are counted as code.
  • AST extraction runs on all 24 "code" files.
  • The resulting graph.json only contains nodes/edges from the non-R files (in my case, 7 small Python scripts). All ~17 .R files contribute zero nodes and zero edges.
  • No warning, error, or log line indicates this. The CLI reports success (wrote graph.json: N nodes, M edges, K communities) as if the whole codebase was mapped.

Root cause

In extract.py:

def _get_extractor(path):
    ...
    return _DISPATCH.get(path.suffix)

For a .R file, _DISPATCH.get(".R") returns None (no key for .r or .R). The caller handles this by silently returning an empty result:

extractor = _get_extractor(path)
if extractor is None:
    return idx, {"nodes": [], "edges": []}

Meanwhile detect.py::classify_file lowercases the extension before checking CODE_EXTENSIONS (ext = path.suffix.lower()), so .R files do get classified as FileType.CODE and counted in scan stats — creating a mismatch between "files graphify says it found as code" and "files graphify can actually parse."

Impact

For any primarily-R codebase, graphify extract silently produces a graph that reflects none of the actual project code, with no indication to the user that anything was skipped. This is worse than an explicit "unsupported language" error, because the tool reports success and the user has no reason to suspect the graph is incomplete/misleading.

Suggested fix

Either:

  1. Add a real .r/.R extractor (tree-sitter has an R grammar — tree-sitter-r), consistent with how other languages are wired into _DISPATCH; or
  2. At minimum, when _get_extractor() returns None for a file that classify_file() counted as FileType.CODE, surface a warning (e.g. [graphify extract] WARNING: N code files have no AST extractor and were skipped: .R (17), ...) instead of silently returning empty results and reporting overall success.

Option 2 alone would have saved a lot of confused debugging — the CLI output gave no signal that anything was wrong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions