- The paper presents flowR, a state-of-the-art tool that enhances comprehension and reproducibility of R data analysis scripts using modular static analysis and IDE integration.
- The methodology leverages tree-sitter parsing, AST normalization, and interprocedural dataflow and control-flow analysis to perform effective slicing, linting, and visualization.
- The results demonstrate significant code reduction and near real-time analysis feedback, supporting practical improvements in research code reuse and reproducibility.
Supporting Data Analysis Script Comprehension: The flowR Extension for R
Motivation and Problem Context
Within computational science and applied data analysis, scriptsโespecially in Rโare central to the creation, transformation, and visualization of data. However, empirical research repeatedly demonstrates that such scripts typically lack structural clarity and reproducibility, with reproducibility barriers including missing or invalid file paths, undeclared or outdated dependencies, and ambiguity in data provenance. The lack of dedicated tool support for script comprehension is a direct hindrance to methodical code reuse and reliable research reproduction. FlowR is presented as a comprehensive extension targeting these deficits, focusing on enhancing not only post hoc comprehension but also the developmental workflow of R scripts via integration with standard IDEs such as VS Code and Positron (2604.15963).
Architecture and Analysis Pipeline
FlowR adopts a modular, pipeline-based static analysis strategy. For each R source artifact, it applies:
- Parsing: Using both a tree-sitter grammar for system-agnostic syntax extraction and a fallback to Rโs native parser for maximal compatibility.
- Normalization: Converting the raw AST to a canonical, version-robust normalized AST. This facilitates robust downstream analysis despite the idiosyncratic dynamism of R.
- Interprocedural Dataflow and Control-flow Analysis: Construction of an explicit dataflow graph (DFG) and control-flow graph (CFG), supporting accurate dependence tracking across standard and highly dynamic R constructs.
Through these representations, all core analysesโslicing, value propagation, call hierarchy inferenceโare performed. Notably, the framework provides a robust plugin architecture enabling injection of new analyses, file-type support, and post-processing stages.
Key Features
Notebook Support
The extension natively supports major notebook formats (Jupyter, Quarto, R Markdown), augmenting code cell extraction, provenance tracking, and position mapping. Analysis results are correctly referenced in the hybrid code/text environments prevalent in modern data science workflows.
Slicing Capabilities
Both backward and forward program slicing are supported:
- Backward slicing isolates all ancestor code statements affecting a designated value or computation, reducing code size to โ13.5% of the original on realistic datasets.
- Impact slicing (forward slicing) highlights all program elements transitively influenced by a particular inputโa complementary view critical for understanding propagation of assumptions and data through pipelines. The average forward slice reduces code to โ13% of the corpus.
- Chopping (intersection of forward and backward slices) facilitates precise pathways mapping from inputs to outputs, e.g., elucidating data paths from file load to visualization.
Dependency Overview
A project-level, interactive dependency graph is generated, automatically identifying major pipeline stages (data loading, transformation, visualization) and explicit library imports. Navigation is facilitated by linking each overview node directly to its source code reference. Semantic grouping increases expressiveness; e.g., plot modifications (such as layered ggplot2 calls) are recognized as associated with a single figure output.
Linting and Quick-Fixes
FlowR features ten configurable linter rules targeting typical reproducibility failures:
- Non-portable or absolute file paths
- Input/output path validity assertions
- Runtime-deterministic behaviors (unseeded RNG usage)
- Invalid column/index accesses
All lints support IDE-native quick-fixes where possible, e.g., re-mapping absolute paths relative to the project root or injecting set.seed statements automatically. The rules are extendable via API and can be selectively silenced and highly customized.
Statically Computed Value Annotations
A prominent feature is the hover-over value provider: at each variable or subexpression, hover actions in the IDE surface statically inferred values, data frame shapes, and abstract domains. This information is synthesized via interprocedural fixpoint iteration, and the abstraction design supports summarization of large or undefined datasets (e.g., set or interval domains for uncertain values).
Responsive Graph Views
The extension provides immediate visualization of the current normalized AST, CFG, DFG, and call graph, using mermaid-live for rapid rendering. The visualizations are tightly coupled to the active editor region, supporting both compact and detailed graph exploration, structural filtering (e.g., removal of statically unreachable code), and present analysis state in nearly real time. This functionality further serves as an extensibility interface for developers aiming to construct custom analyses on top of canonical code graphs.
Project Analyzer API and Extensibility
The main Project Analyzer interface exposes both imperative (invoke-dataflow, slicing, etc.) and declarative (query API) entry points. The extension supports interaction via TypeScript, R, TCP/WebSocket, or Docker-based REPL environments. Developers can introduce novel analysis plugins, file type handlers, or visualization extensions by subclassing pipeline or plugin base classes. Concrete extension scenarios include new notebook cell types, nonstandard dependency formats, or task-specific static analyses.
On a curated set of 4230 real-world R projects, flowR achieves:
- Mean full dataflow graph construction time โ 576 ms/project; includes parsing (mean 115 ms), normalization, and interprocedural analysis (mean 525 ms).
- Typical DFG size โ 1733 nodes/3738 edges, median graph serialization size 213 kB.
- Median total analysis time โ 251 ms/project.
All secondary analyses (slicing, linting, value inference) are performant (10โ100 ms typical, barring known worst-case behaviors such as complex data frame access validation). Through lazy evaluation, parallelization, and caching, the interactive experience achieves near real-time feedback across all use cases.
Empirical and Theoretical Implications
Practically, flowR bridges the gap between research code as-written and its comprehensible, reusable, and auditable counterpart. It operationalizes static analysis ideas (as in SootUp [DBLP:conf/tacas/KarakayaSKBSLH24], CodeQL, and domain-specific approaches [DBLP:conf/nsad/DolcettiCUZ24]) for the R language, overcoming language-specific challenges such as runtime metaprogramming, nonstandard evaluation, and fluid typing. The plugin and extension architecture aligns with current trends towards modular, language server-driven code analysis.
For empirical software engineering, flowR provides tooling for the systematic study of scientific code. The slicing results quantitatively confirm dramatic codebase reducibility for comprehension tasks and the efficacy of purely static, non-executive analysis in highly dynamic languages [DBLP:conf/msr/SihlerPSTDD24]. The static value annotation is informative for dependently-typed or formal verification approaches in statistical code, potentially stimulating further work on hybrid static-dynamic provenance and error checking.
Prospective Extensions
The paper identifies ongoing work in user studies to empirically validate the effect of flowR on end-user (i.e., researcher) productivity and understanding. Future directions logically include:
- Registry-driven annotation of library exports to further enhance forward slicing for imported libraries and dynamic dependencies.
- Dynamic analysis integration (hybrid slicing) for more complete runtime behavior characterization in the presence of polymorphic or runtime-dependent code.
- Deep semantic integration with statistical analysis workflows to verify assumptions, pipeline validity, and effect propagation [DBLP:journals/pacmse/TurcotteW25].
Conclusion
FlowR constitutes a state-of-the-art, extensible program analysis environment tailored for R data analysis scripts, combining static interprocedural analysis, slicing, dependency mapping, linting, and value annotation within familiar IDE workflows. Its performance and integration profile facilitate near real-time, context-aware feedback, supporting both software engineering research and scientific code authors. It sets a concrete baseline for subsequent empirical work on improving research code clarity and reproducibility (2604.15963).