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:
- 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
- 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.
Summary
.r/.Ris included indetect.py'sCODE_EXTENSIONSset, so R files are classified asFileType.CODEand counted in the scan summary (e.g.found 24 code, ...). Butextract.py's_DISPATCHdict — the table that maps extensions to an actual AST extractor function — has no.r/.Rentry 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.Rscripts (e.g. an R/renv analysis project with ~17.Rfiles and a handful of.pyhelper scripts).found 24 code, 0 docs, 1 papers, 0 images— the R files are counted as code.graph.jsononly contains nodes/edges from the non-R files (in my case, 7 small Python scripts). All ~17.Rfiles contribute zero nodes and zero edges.wrote graph.json: N nodes, M edges, K communities) as if the whole codebase was mapped.Root cause
In
extract.py:For a
.Rfile,_DISPATCH.get(".R")returnsNone(no key for.ror.R). The caller handles this by silently returning an empty result:Meanwhile
detect.py::classify_filelowercases the extension before checkingCODE_EXTENSIONS(ext = path.suffix.lower()), so.Rfiles do get classified asFileType.CODEand 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 extractsilently 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:
.r/.Rextractor (tree-sitter has an R grammar —tree-sitter-r), consistent with how other languages are wired into_DISPATCH; or_get_extractor()returnsNonefor a file thatclassify_file()counted asFileType.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.