ConceptioArchivearXiv CS
arXiv CSopen access

Supporting the Comprehension of Data Analysis Scripts

Unknown · 2026 · arxiv_cs
arXiv CS · Papers · License: Open Access · 2026
Open Source ↗Direct PDF ↓
softwarearchitecturesoftwareengineeringtesting
software engineering, software architecture, testing

arXiv:2604.15963v1 [cs.SE] 17 Apr 2026

Supporting the Comprehension of Data Analysis Scripts Florian Sihler

Oliver Gerstl

Lars Pfrenger

[email protected] Ulm University Germany

[email protected] Ulm University Germany

[email protected] Ulm University Germany

Julian Schubert

Matthias Tichy

[email protected] Ulm University Germany

[email protected] Ulm University Germany

Abstract

Program Comprehension, Static Analysis, Data Analysis, R

non-reproducible, non-executable, or simply difficult to comprehend [11, 17, 18, 21]. In previous work [19, 20], we presented flowR as a dataflow analysis framework and backward program slicer for the R programming language, which can help researchers understand and maintain R scripts. Building upon this, we now present a significant extension of flowR, by adding several features to its integration into common data analysis environments: (𝑖) support for various notebook formats, (𝑖𝑖) an overview of important analysis steps and script dependencies, (𝑖𝑖𝑖) impact slicing to understand how inputs affect the remaining analysis, (𝑖𝑣) reproducibility-oriented linting rules with quick-fixes, (𝑣) hover-over values to understand variable and data shapes at specific program points, (𝑣𝑖) responsive visualizations of, for example, the control-flow graph, and more. These techniques support researchers and reviewers in comprehending, maintaining, and reusing R scripts more effectively. Additionally, these features also support researchers during the script development process, for example, by providing near realtime linting feedback and quick-fixes directly in the code editor. FlowR’s integration also provides several features to support tool developers in building new analyses on top of flowR like the query API. Alongside its previously supported integrations into VS Code, as a server, REPL, and Docker image, flowR now also works in the browser (e.g., on vscode.dev) and in Positron. Moreover, it ships with an easy-to-use interface for custom analyses and debugging and a sophisticated online documentation, which is continuously updated to stay in sync with the latest flowR version. After providing a brief overview of important related work in Section 2, we present all newly supported features of flowR in Section 3 alongside explanations on how to extend flowR with new analyses in Section 4 and discuss the brief evaluation in Section 5. Finally, we conclude and outline future work in Section 6.

1

2

A lot of research relies on data analysis scripts to process, clean, and visualize data. However, recent studies show that these scripts are often hard to comprehend and maintain, hindering reproducibility and reuse, accompanied by a lack of tool support for handling such scripts. In this work, we focus on the R programming language, addressing this problem by presenting flowR as an extension for the common data analysis IDEs Positron and VS Code. Alongside a previously presented static backward program slicer, flowR provides an overview of data analysis scripts, interactive graph visualizations, linting, and inline value annotations to support data analysts. FlowR incrementally analyzes R projects by intertwining interprocedural data- and control-flow analyses to build a comprehensive dataflow graph, incorporating R’s dynamic and explorative features. Additionally, flowR offers a plugin system and interfaces, allowing the integration of further analyses, such as new linting rules or custom visualizations. Requiring an average of 576 ms to calculate the full dataflow graph of real-world projects, this enables near real-time feedback. The demonstration video is available at https:// youtu.be/hJzr-r-NmMg. For the full source code and extensive documentation, refer to https:// github.com/f lowranalysis/f lowr. To try the docker image, use docker run --rm -it eagleoutice/flowr.

CCS Concepts • Theory of computation → Program analysis; • Software and its engineering → General programming languages; Maintaining software.

Keywords

Introduction

Assume the role of a researcher who found an interesting study online that analyzes a dataset similar to their own. According to recent studies, chances are high that the accompanying scripts are either

This work is licensed under a Creative Commons Attribution 4.0 International License. Conference’17, Washington, DC, USA © 2026 Copyright held by the owner/author(s). ACM ISBN 978-x-xxxx-xxxx-x/YYYY/MM https://doi.org/10.1145/nnnnnnn.nnnnnnn

Related Work

There are various tools and approaches to support developers and researchers in understanding and analyzing their programs. Language servers [7], like the R Language Server [15], provide features such as code completion and go-to-definition functionalities. Analysis frameworks like SootUp [14] for Java or CodeQL [6] offer static analysis to efficiently analyze programs for potential issues or vulnerabilities while linters like lintr [10] for R, or ESLint [2] for JavaScript help identify and fix common issues based on rules. More focused on data science, recent works explore analysisspecific validity checks [4], verifying statistical reporting [16], or

Conference’17, July 2017, Washington, DC, USA

expressing and verifying statistical assumptions within the analysis code [22]. However, so far related work is mostly unconnected to the problems mentioned in executability and reproducibility studies [11, 21]. Moreover, these works do not focus on supporting comprehension, e.g., by incorporating the data science workflow as described by Wickham et al. [24]. With flowR, we fill this gap, as explained in more detail in Section 3.

3

New Features

This section presents the new features that flowR now supports to help R users comprehend, maintain, and develop R scripts more effectively, on top of the previously presented techniques [19]. Every feature is presented alongside its integration into the extension, focusing on the benefits for end-users. For the underlying techniques and how tool developers can build upon them, please refer to Section 4. By default, flowR uses a system-independent, treesitter based R parser and setup to analyze R code, which allows it to work in the browser or without any R installation present. However, flowR can also make use of the R installation on the user’s system. Figure 5 provides a simplified overview of flowR.

3.1

Notebook Support

Using flowR’s plugin system, we provide built-in support for popular notebook formats: Jupyter Notebooks, Quarto, and R Markdown. This support includes parsing these formats, extracting the R code from cells, and mapping analysis results to their respective locations in the notebooks. This allows a seamless integration of flowR’s features into notebook environments, which means that all subsequent and previously described features [19] work in notebooks (or projects that include notebooks) as well. Moreover, the information gained by these plugins are made available, allowing to easily build notebook-aware analyses on top of flowR (cf. Section 4). Users can also add support for custom notebook formats by implementing their own plugin.

3.2

Florian Sihler, Oliver Gerstl, Lars Pfrenger, Julian Schubert, and Matthias Tichy

3.3

Dependency Overview

To help researchers understand the structure of a given data analysis, we provide an automatically generated and updated overview of all script dependencies and outputs (cf. Figure 1 to the right). This overview categorizes important steps of the analysis, such as data loading and visualizations, alongside all used libraries and the Generated for the analysis from Fischer et al. [5] Figure 1: Dependency View produced outputs. Each item is automatically linked to its location in the project so a user can quickly navigate to it by clicking on the respective element. Additionally, users can directly inspect the corresponding backward slice (i.e., all code that influences the respective element [19]) or the impact of an element (Section 3.2) as shown by the context menu open in Figure 1. This makes it easy to answer questions such as “What are the visualizations produced by this script?” or “Which parts of the analysis depend on this input file?”. If an element is semantically connected to another one—for example, a plot function like abline in Figure 1 that draws to the same figure created by the plot functions—the view will group them automatically. This allows to see related parts together, even if they are separated in the code. The overview is highly configurable, e.g., by allowing to disable elements such as Outputs in Figure 1 or adding custom categories.

3.4

Linting Integration

flowR includes a set of ten different and highly configurable linting rules designed to identify common issues that hinder the executability and reproducibility of R scripts as exemplified in Figure 2.

Impact Slicing

Corresponding to the previously presented backward slicing [19], which allows users to understand which parts of the code influence a specific program point, we now also support forward or impact slicing. Given an element in the program, an impact slice contains all code that is influenced by this element (also called a “forward slice”). This feature helps users to understand how specific or multiple inputs affect the remaining analysis, for example, by showing all expressions that operate on a specific dataset. Similar to the drastic reductions we found with backward slices (to around 13.5 %, cf. [20]) the average forward slices on real-world sources reduces the project to just around 13 % of the original code, making it easier to comprehend the effects of specific inputs. Please note that in contrast to backward slicing, the forward slices presented by flowR are usually not executable, as they, by-design, omit other inputs that may be required for the data analysis. Moreover, combining backward and forward slicing (a process known as “chopping” [12]) allows to reduce the analysis to only the parts that connect specific inputs and outputs. This helps to answer questions like “How is the data from this CSV file processed to produce this plot?” more easily.

Generated for the analysis from Hamilton et al. [9]

Figure 2: Excerpt of linting results These rules check for various issues such as (1) absolute paths which are usually not portable to different systems, (2) invalid file paths indicating missing or misplaced inputs, (3) accessing non-existent columns in data frames hinting at wrong or incomplete data processing, or (4) using a random number source without initializing it with a fixed seed, as indicators for non-executable or non-reproducible code. Many of these rules also provide quick-fixes that automatically resolve the identified issues, e.g., by replacing absolute paths with relative ones based on the project’s root directory or by setting a fixed seed for random number generators. These quick-fixes also support and respect R’s dynamic features like relative directory changes and path constructions [20]. The linting results are presented in a dedicated view within the extension, allowing users to quickly navigate to and fix issues in their code or try to automatically resolve them using the provided quick-fixes. The presented

Supporting the Comprehension of Data Analysis Scripts

Conference’17, July 2017, Washington, DC, USA

linting results can be silenced individually and linting rules can be configured extensively to fit the user’s needs. Additionally, using the API, tool developers can easily extend the linter with new rules or update existing ones.

especially the simplified control-flow graph are helpful to provide an overview of a program’s structure and possible execution paths. Moreover, they also serve as the underlying structures for all other analyses (cf. Section 4)

3.5

4

Hover-Over Value Provider

To help users understand the # ... <- " id " values of variables and data xcoln Value: "id" <- a % >% shapes at specific program mutate ( level = score ^ 2 ) % >% left_join (b , b y=coln) % >% points, flowR provides value select( - age ) information in the code editor. Returns a data frame with 4 rows, and When hovering over a variknown columns: foo, score, level, id. able or expression in the code Figure 3: Hover-over values editor, a tooltip appears showing the computed value or data shape at that point in the program as exemplified in Figure 3. These values are also used internally by other analyses, e.g., to determine whether a column access could fail due to a missing column in a data frame or whether a given piece of code is dead because its condition is set to be constantly FALSE [20]. While the idea follows the approach of various teaching tools and debuggers, which usually indicate the concrete values of variables [8, 13], we also provide abstracted descriptions that, for example, summarize the shape of data frames even if the concrete values are not known statically. Providing these values also helps while writing new analyses in R, as they provide quick feedback on the expected values of variables without needing to run the code (or even converting it to an executable form). All these values are computed using flowR’s interprocedural static analysis and fixpoint solver and are available throughout the analysis process (cf. Section 4).

3.6

Responsive Graph Views

FlowR provides a various graphs and views to help users understand the code but also to support tool developers in building new analyses: (𝑖) a normalized AST, (𝑖𝑖) dataflow graph (DFG), (𝑖𝑖𝑖) call graph (CG), and (𝑖𝑣) control flow graph (CFG). All of these can be directly visualized using mermaid.live and shown within the editor. Figure 4 below exemplifies the presentation of a simplified CFG: x <- 0 while ( x < 20) { x <- x + 1 }

x <- 0 x < 20

x <- x + 1

Figure 4: Example Code and the Compact CFG These views automatically respond to content changes and selections in the code editor. For example, by only showing the relevant parts of the graph for the currently selected code. Additionally, these views provide various configurations to adapt the presentation of the graphs to the user’s needs, e.g., by allowing to toggle between a compact and detailed view of the CFG or automatically removing dead code from the graphs. In general, these views can be opened on demand with the command palette of the editor, e.g., using the command “flowR: Show Dataflow Graph”. While the inspection of a dataflow graph or the normalized AST may be only interesting for tool developers [23], the call graph and

Extending flowR

Besides the extension with its new features as presented in Section 3, flowR offers a TCP and WebSocket server interface [19] as well as a read-eval-print loop (REPL) directly accessible from the Docker image: docker run --rm -it eagleoutice/flowr. Moreover, flowR is available as an R and an npm package, the latter of which we use in the extension presented in this work. FlowR is mostly implemented in TypeScript with parts in R. In this section, we present flowR’s core pipeline architecture (Section 4.1) and the project analyzer (Section 4.2) from a tool developer’s perspective. For the underlying techniques, please refer to our previous work [20] and the extensive documentation.

4.1

Pipeline Architecture

For each R source to be analyzed, flowR follows a multi-step analysis pipeline which can be freely configured and extended, but in general consists of three main steps: (1) Parsing, to obtain the abstract syntax tree (AST). (2) Normalization, to transform the AST into a normalized and version-independent representation of the R code. (3) Data- and Control-flow analysis, to compute the dataflow graph alongside the control-flow based on the normalized AST. To parse and normalize the source, flowR provides two back-ends: (𝑖) a tree-sitter based parser using a specialized R grammar without any external dependencies, and (𝑖𝑖) an R based parser using R’s built-in parse function but requiring R to be installed on the system. Both back-ends produce the same normalized AST representation which then serves as the input for the subsequent interprocedural data- and control-flow analysis. Using the unique identifiers of every node in the normalized AST, all subsequent analyses can then relate their results back to the original source code. Based on the dataflow graph produced by the last step, various static analyses can be performed, e.g., slicing, call graph generation, or value resolution. These analyses then directly contribute to the features presented in Section 3. To add new or replace existing steps, users can simply implement the IPipelineStep interface, combine them with other steps, and pass the created pipeline to the PipelineExecutor.

4.2

Project Analyzer

The project analyzer is the main API of flowR’s analysis pipeline and it orchestrates the complete analysis process. The underlying architecture is depicted in Figure 5, the pipeline as explained in Section 4.1 is highlighted in red. Given an R project, flowR first discovers, loads, and prepares all relevant files using its plugin system including build specifications if present and then analyzes the contained R sources using the configured pipeline. Plugins. Plugins are automatically applied during the analysis process to provide support for (𝑖) discovering files in a project, (𝑖𝑖) loading and parsing specific file types, (𝑖𝑖𝑖) enriching the context

Conference’17, July 2017, Washington, DC, USA

Florian Sihler, Oliver Gerstl, Lars Pfrenger, Julian Schubert, and Matthias Tichy Most of these edges are “on demand”!

Inspectable Context

“flowR Project API” Plugin Defs.

analysis.R data.Rda helper.R renv.lock research.Rproj

A

Type Info

Project Context

A’

Plugins

Abstract Domains 1

... ...

1

2 4 3

...

2

files, dependencies, . . .

î

3

4

Fixpoint Solver

Abstract Values

semantic visitor

“flowR Core”

ü

Control-flow Info

Config R-Shell

Controlfl. Analysis Normalized AST

(enrich)

...

Project

Linter Results

Dataflow Info

Tree-sitter “Engines”

Query API

Decorator

Slicing

Dataflow Analysis

Query Results

Linter Sliced Program

Criterion, Direction, . . .

The FlowrAnalyzerBuilder class serves as the main entry point to configure and construct analyses with as well as on-top of flowR. The resulting FlowrAnalyzer orchestrates the complete analysis process, providing methods such as dataflow or query to calculate the results on-demand and provide full access to all components indicated to the left. During the analysis, plugins provide support for various filetypes, modify the project discovery process, and enrich the analysis with additional information. The context can be inspected to retrieve additional information about the current analysis state (see Section 4).

For brevity, we omit other requests

Figure 5: A simplified view of flowR’s processes and results. All important steps are hyperlinked to their documentation. of a project, and (𝑖𝑣) identifying the optimal loading order of files. New plugins can be created by building on the FlowrAnalyzerPlugin base class or one of its specializations. Analysis Example. With the project analyzer API, obtaining the dataflow graph of a project looks like this: const analyzer = await new FlowrAnalyzerBuilder () . setEngine ( ' tree-sitter ') . build () ; analyzer . addRequest ( ' file :/// path / to / project ') ; const df = await analyzer . dataflow () ;

The builder automatically registers a set of default plugins which provide support for notebooks as presented in Section 3.1 and other file types commonly found in R projects. To inspect a project, flowR provides its query API. With it, we can obtain the value of a variable using queries like the resolve value query. This query is used by the the hover-over value provider as presented in Section 3.5. As a quick example, the following code uses the dependencies query which is also used to provide the dependency overview presented in Section 3.3 to list all libraries used in the analyzed project: const q = await analyzer . query ([ { type : ' dependencies ' } ]) ; for ( const lib of q . dependencies . library ) { console . log ( lib . value , lib . derivedVersion ) ; }

The project API is type-safe, including the results of the queries, which allows for an easier exploration using autocompletion.

any multithreading and caching is disabled to reflect a bottom line for flowR’s cold-start performance. On average, we require 115 ms to parse and normalize a project using the tree-sitter back-end (cf. Section 4.1). Based on the normalized AST, we build the dataflow graph in ≈ 525 ms on average, resulting in a total analysis time of ≈ 640 ms per project. Please note that these numbers are biased by outliers, with a median total time of just 251 ms.1 The average dataflow graph contains 1,733 vertices and 3,738 edges, with a median size of 213 kB [20]. All other capabilities presented in Section 3 only require 10 ms to 100 ms with minor outliers in specific linting rules like the access validation of data frames. By parallelizing these analyses in practice, executing queries lazily and caching, flowR can provide near real-time feedback, with an average of around a second for the complete analysis of a project including the subsequent analyses.

6

Conclusion

In this work, we presented a significant extension to flowR, a sophisticated program analysis framework for the R programming language. As an important next step, we plan to evaluate the usability and usefulness of flowR’s new features in a user study with researchers from data science domains.

Acknowledgments This work was supported by the German Research Foundation (DFG): 504226141.

References 5

Evaluation

We evaluate the performance of flowR’s dataflow analysis following the ACM SIGPLAN [3] and SIGSOFT Empirical Standards [1] using a dataset of 4,230 real-world R scripts provided as supplements to publications (cf. [20, Section 7]). Analyzing each project, we measure the time required to build the inter-procedural dataflow graph as well as the size of the resulting graph. For the analysis,

[1] 2022. ACM SIGSOFT Empirical Standards. https:// www2.sigsoft.org/Empirical Standards/ docs/?standard=RepositoryMining [2] 2026. Find and fix problems in your JavaScript code - ESLint - Pluggable JavaScript Linter — eslint.org. https:// eslint.org/ . [3] E. D. Berger, S. M. Blackburn, M. Hauswirth, and M. Hicks. 2018. SIGPLAN Empirical Evaluation Checklist. https:// raw.githubusercontent.com/ SI GPLAN/ empirical-evaluation/master/ checklist/ checklist.pdf 1 Using a Linux PC with a 5 GHz Intel i9-9900K CPU and sufficient memory.

Supporting the Comprehension of Data Analysis Scripts

[4] Greta Dolcetti, Agostino Cortesi, Caterina Urban, and Enea Zaffanella. 2024. Towards a High Level Linter for Data Science. In Proceedings of the 10th ACM SIGPLAN International Workshop on Numerical and Symbolic Abstract Domains, NSAD 2024, Pasadena, CA, USA, 22 October 2024, Vincenzo Arceri and Michele Pasqua (Eds.). ACM, 18–25. doi:10.1145/ 3689609.3689996 [5] Stefan Fischer, Callum Duffield, Amanda Davidson, Rhiannon Bolton, Jane Hurst, and Paula Stockley. 2022. Data for: Fitness costs of female competition linked to resource defence and relatedness of competitors. doi:10.5061/ DRYAD.J0ZPC86H 1 [6] GitHub. 2026. CodeQL. https:// codeql.github.com/ [7] Nadeeshaan Gunasinghe and Nipuna Marcus. 2021. Language server protocol and implementation. Springer. [8] Nakshatra Gupta, Ashutosh Rajput, and Sridhar Chimalakonda. 2022. COSPEX: A Program Comprehension Tool for Novice Programmers. In 44th IEEE/ACM International Conference on Software Engineering: Companion Proceedings, ICSE Companion 2022, Pittsburgh, PA, USA, May 22-24, 2022. ACM/IEEE, 41–45. doi:10 .1145/ 3510454.3516842 [9] Sara Hamilton, Vienna Saccomanno, Walter Heady, Alyssa-Lois Gehman, Steve Lonhart, Rodrigo Beas-Luna, Fiona Francis, Lynn Lee, Laura Rogers-Bennett, Anne Salomon, and Sarah Gravem. 2021. Disease-driven mass mortality event leads to widespread extirpation and variable recovery potential of a marine predator across the eastern Pacific. doi:10.5281/ ZENODO.5116546 [10] Jim Hester, Florent Angly, Michael Chirico, Russ Hyde, Ren Kun, Indrajeet Patil, and Alexander Rosenstock. 2025. Static Code Analysis for R. Journal of Open Source Software 10, 108 (2025), 7240. doi:10.21105/joss.07240 [11] Md. Anaytul Islam, Muhammad Asaduzzaman, and Shaowei Wang. 2024. On the Executability of R Markdown Files. In 21st IEEE/ACM International Conference on Mining Software Repositories, MSR 2024, Lisbon, Portugal, April 15-16, 2024, Diomidis Spinellis, Alberto Bacchelli, and Eleni Constantinou (Eds.). ACM, 254– 264. doi:10.1145/ 3643991.3644931 [12] Daniel Jackson and Eugene J. Rollins. 1994. A New Model of Program Dependences for Reverse Engineering. In Proceedings of the Second ACM SIGSOFT Symposium on Foundations of Software Engineering, SIGSOFT 1994, New Orleans, Louisiana, USA, December 6-9, 1994, David S. Wile (Ed.). ACM, 2–10. doi:10.1145/ 193173.195281 [13] Hyeonsu B. Kang and Philip J. Guo. 2017. Omnicode: A Novice-Oriented Live Programming Environment with Always-On Run-Time Value Visualizations. In Proceedings of the 30th Annual ACM Symposium on User Interface Software and Technology, UIST 2017, Quebec City, QC, Canada, October 22 - 25, 2017, Krzysztof Gajos, Jennifer Mankoff, and Chris Harrison (Eds.). ACM, 737–745. doi:10.1145/ 3126594.3126632 [14] Kadiray Karakaya, Stefan Schott, Jonas Klauke, Eric Bodden, Markus Schmidt, Linghui Luo, and Dongjie He. 2024. SootUp: A Redesign of the Soot Static Analysis Framework. In TACAS 2024, Luxembourg City, Luxembourg, April 6-11, 2024, Proceedings, Part I (Lecture Notes in Computer Science, Vol. 14570). Springer, 229–247. doi:10.1007/ 978-3-031-57246-3_13 [15] Randy Lai. 2023. languageserver: Language Server Protocol. doi:10.32614/CRAN. package.languageserver R package version 0.3.16. [16] Michèle B. Nuijten and Joshua R. Polanin. 2020. “statcheck”: Automatically detect statistical reporting inconsistencies to increase reproducibility of meta-analyses. Research Synthesis Methods 11, 5 (2020), 574–579. doi:10.1002/ jrsm.1408 [17] Lorraine Saju, Tobias Holtdirk, Meetkumar Pravinbhai Mangroliya, and Arnim Bleier. 2025. Computational Reproducibility of R Code Supplements on OSF. ICWSM, US. doi:10.36190/2025.49 [18] Florian Sihler, Lukas Pietzschmann, Raphael Straub, Matthias Tichy, Andor Diera, and Abdelhalim Hafedh Dahou. 2024. On the Anatomy of Real-World R Code for Static Analysis. In 21st IEEE/ACM International Conference on Mining Software Repositories, MSR 2024, Lisbon, Portugal, April 15-16, 2024, Diomidis Spinellis, Alberto Bacchelli, and Eleni Constantinou (Eds.). ACM, 619–630. doi:10.1145/ 36 43991.3644911 [19] Florian Sihler and Matthias Tichy. 2024. flowR: A Static Program Slicer for R. In Proceedings of the 39th IEEE/ACM International Conference on Automated Software Engineering, ASE 2024, Sacramento, CA, USA, October 27 - November 1, 2024, Vladimir Filkov, Baishakhi Ray, and Minghui Zhou (Eds.). ACM, 2390–2393. doi:10.1145/ 3691620.3695359 [20] Florian Sihler and Matthias Tichy. 2025. Statically Analyzing the Dataflow of R Programs, In OOPSLA ’25. Proceedings of the ACM on Programming Languages 9, OOPSLA2, 1034–1062. doi:10.1145/ 3763087 [21] Ana Trisovic, Matthew K. Lau, Thomas Pasquier, and Mercè Crosas. 2022. A Large-Scale Study on Research Code Quality and Execution. 9, 1 (2022), 60. Issue 1. doi:10.1038/ s41597-022-01143-6 [22] Alexi Turcotte and Zheyuan Wu. 2025. Expressing and Checking Statistical Assumptions. Proc. ACM Softw. Eng. 2, FSE (2025), 2735–2758. doi:10.1145/ 3729391 [23] Tobias Weck and Matthias Tichy. 2016. Visualizing Data-Flows in Functional Programs. In IEEE 23rd International Conference on Software Analysis, Evolution, and Reengineering, SANER 2016, Suita, Osaka, Japan, March 14-18, 2016 - Volume 1. IEEE Computer Society, 293–303. doi:10.1109/ SANER.2016.82 [24] Hadley Wickham, Garrett Grolemund, et al. 2017. R for data science. Vol. 2. O’Reilly Sebastopol.

Conference’17, July 2017, Washington, DC, USA

A

Demonstration Walkthrough

This appendix contains the walkthrough of our demonstration video. For the required information on the tool, please refer to Section B. The walkthrough is organized chronologically alongside the different parts in the video.

A.1

The VS Code Extension

The extension is readily available on the VS Code Marketplace and can be installed like any other extension. For example, by searching for “R Code Analyzer (flowR)” in the extensions tab of VS Code and clicking Install. This should also work in the browser on vscode.dev, even though the web-version of VS Code has some limitations on certain browsers so we recommend using Google Chrome. With the default configuration, flowR and all of the following steps work out of the box. Additionally, explanations of the respective features alongside GIFs that explain how to access them in the extension are part of the extension’s README. To have a concrete example to test whether the extension is working correctly, we use the following synthetic example script: library ( ggp lot 2) da ta <- read . csv ("/ data / data . csv ") min_age <- 42 b y_age <- da ta |> dplyr :: filter ( age >= min_age ) ggplot (b y_age , aes (x= age , y=m)) + geom_count () The Dependency View (Section 3.3, GIF). After installing the flowR extension, the sidebar features a new icon of a flower: clicking it opens the dependency view, which, whenever an R project is opened, shows an overview of the dependencies as presented in Section 3.3. Alternatively, the command “Focus on Dependencies View” can be used to open the view. The view updates automatically, by default based on the size of the project either on every change or in a fixed interval. Clicking on the entries navigates to the respective position in the code where the dependency is introduced. To inspect the backward slice [19] and the impact slice (Section 3.2) of the respective dependency, the context menu can be accessed by right clicking on an entry (also shown in Figure 1). Using the example code introduced above, the dependency view shows two loaded libraries: (1) ggplot2 in line 1, loaded with the library function (2) dplyr in line 6, loaded with the :: operator Additionally, it shows one imported dataset with the “read.csv” function in line 3 and a single visualization created with ggplot in line 8 with one linked function call to geom_count (as it draws to the same plot). Impact Slicing (Section 3.2). By right clicking on an entry in the dependency view, the context menu allows to inspect the impact slice of the respective dependency. For example, the impact slice of the dataset imported in line 3 includes all lines of the script but the library import and the assignment to min_age, as all other

Conference’17, July 2017, Washington, DC, USA

expressions depend on the data. Alternatively, an impact slice can be produced for any expression in the code by right clicking on the element and using the “Show Influence. . . ” and “Toggle Influence. . . ” commands in the context menu. Any active highlighting can be cleared with the “flowR: Clear Current Slice Presentation” command or the shortcut Alt+C. Please note that currently, flowR does not (sensibly) support forward slicing on library imports, because flowR does not ship with the known export signatures of all R packages yet [20]. Accessing the Linter (Section 3.4). While the linter is enabled by default, running in the background with similar update strategies as the dependency view, it can also be triggered manually using the command “flowR: Code Quality Analysis (Linter)”. Spotted problems are highlighted directly in the code editor (if VS Code is not configured otherwise) and also appear in the Problems tab. For the example code, the linter spots only one issue: the hardcoded path in the read.csv call. However, playing around with the code, e.g., by adding an unused variable or calling a deprecated function such as filter_all should automatically trigger new linter warnings. For an unused assignment like x <- 2, the linter also provides a quick-fix which removes the expression.2 Hover-Over Value Provider (Section 3.5, GIF). By hovering over either occurrence of min_age in the example code, flowR shows a hover-over tooltip with the inferred value [42L, 42L] as an interval to indicate that the variable holds the integer value 42. Without knowing the contents of the csv file, flowR cannot infer sensible shapes for the data frames data and by_age (also due to R’s semantics based on whether age is a column in the data frame or not). However, if you supply a csv file with (at least) the columns age and m at the requested path, flowR can infer more precise shapes for the data frames and, consequently, also for the visualization. Accessing Graph-Views (Section 3.6, GIF). All graph-views can be accessed via the command palette. For example, by searching for “flowR: Show Dataflow Graph” and selecting the command. This opens a new tab in VS Code showing the dataflow graph alongside a toolbar at the bottom of the view that allows to configure and fine-tune the graph visualization.3 While the configuration options differ between the graph views (e.g., control-flow graphs can be shown with various simplifications selected or not), they all share common options such as automatically reducing the graph to only show or highlight currently selected elements in the code editor. Additionally, every graph view shows links to the corresponding documentation and to the underlying mermaid graph in the upper right corner. Notebook Support (Section 3.1). All of the aforementioned features also work in R notebooks, as explained in Section 3.1. However, you have to make sure that VS Code also labels the file as an R notebook or R code in general, as flowR does not activate if, for example, VS Code thinks the file is a plain text file. Moreover, please note, 2 By default, the linter probably does not suggest a quick-fix for the absolute path as if

you just paste the code into VS Code without opening a regular project, flowR has no notion of the project root directory. 3 Please note, that for large projects detailed views such as the dataflow graph might take some time to load and render due to our reliance on mermaid.live. If the extension rejects the graph for being too large, you can try to increase the default value of vscode-flowr.style.mermaidMaxTextLength in the extension settings.

Florian Sihler, Oliver Gerstl, Lars Pfrenger, Julian Schubert, and Matthias Tichy

that currently, flowR offers no support for the non-trivial execution model of R notebooks, i.e., the analysis assumes that all code cells are executed in order from top to bottom without skipping or reexecuting cells [20]. Configuration Options. Searching for vscode-flowr in the settings (or using the settings icon shown in the title bar of the dependency view) opens the configuration options of the extension. These allow, among others, to configure the update strategies of the analyses, enable/disable specific analyses, and to configure advanced options such as the port used to communicate with the flowR server.

A.2

Using flowR in Positron and the Browser

Using flowR’s Open VSX package in Positron changes nothing compared to the VS Code extension, providing all features in a similar manner. Yet, the default configuration of the IDEs might differ, so it may be that linter results are not shown automatically because the corresponding tab is hidden by default. In vscode.dev, flowR’s extension also works similarly and out of the box, although some configuration options (like switching to an installed R interpreter) are disabled due to the limitations of the browser environment.

A.3

Working with the Docker Image

FlowR’s read-eval-print loop (REPL) is the main way to use the docker image and explore flowR’s features as well as running analyses of real-world projects in an isolated environment. The REPL provides a plethora of commands — all starting with a colon — to interact with flowR’s analysis capabilities. Additionally, the REPL provides auto-completion, a command history, summarized outputs, and REPL-specific configurations. An example REPL session is shown in Figure 6 below. $ docker run -- rm - it eagleoutice / flowr flowR repl using flowR v 2 .8 .6 , R grammar v 1 4 . . . use :help to get a list of available commands. R> :dataflowascii x <- 2 c < 2 >c - - - - - - - - - - 0 <1 >0 | < - | v < 0 >v | 2 | c - - -c - -| x | - - - 0 ---0 v---v Edges : 2 → 1 : reads , argument 2 → 0 : returns , argument 0 → 1 : defined - by 0 → 2 : defined - by R> :quit

Figure 6: Example REPL Session Please note that while the REPL can access the file system using the file:// prefix, the corresponding directories have to be mounted into the docker container (this is also exemplified in the video). Besides the REPL, the docker image also supports starting a TCP server using the --server flag, as well as a websocket server by additionally passing the --ws flag. Consult the Interface wiki page for more information on how to interact with the server instance.

A.4

Programming with the flowR API

All important components of flowR’s API are explained in the wiki pages including code-examples and automatically updated

Supporting the Comprehension of Data Analysis Scripts

hyperlinks into the source code. In the demonstration video, we construct a brief example in which we use the query API to infer the data frame shape of the first argument of all print function calls in a given project: const analyzer = await new FlowrAnalyzerBuilder () . setEngine ( ' tree-sitter ') . build () ; analyzer . addRequest ( ' file :// ' + folder ) ; const df = await analyzer . dataflow () ; const calls = df . graph . verticesOfType ( VertexType . FunctionCall ) . filter (([ , v ]) = > v . name === ' print ') ; for ( const [ , v ] of calls ) { const firstArg = v . args [ 0 ]; if ( firstArg !== EmptyArgument ) { const criterion : SingleSlicingCriterion = `$$ { firstArg . nodeId } `; const shape = await analyzer . query ([{ type : ' df-shape ' , criterion }]) console . log ( shape [ " df-shape " ]. domains

Conference’17, July 2017, Washington, DC, USA

}

}

)

. get ( criterion ) ?. toString ()

To ease the usage of the API, we already have sample repositories like flowr-analysis/sample-analyzer-project-query that can be used as a starting point for building new analyses on top of flowR.

B

Tool Information

As stated in the paper, flowR is available as an extension for VS Code and Positron, as a Docker image, and as an npm and R package. We distribute the source code alongside its extensive documentation under a GPL-3.0 license on GitHub: https:// github.com/f lowr analysis/f lowr. With a test-suite of more then 7,700 tests, continuous integration, and various benchmarks and evaluation on large real-world datasets (e.g, [18, 20]), we consider flowR to be mature. Regarding users we note around 1,500 installations of the newest version of our extensions and around 5,000 pulls of the Docker image. The documentation is available at https:// github.com/f lowr-an alysis/f lowr/wiki with a rendered version of the in-source documentation at https:// flowr-analysis.github.io/f lowr/doc/index.html.

Related documents

Record · ID 31336 · SHA-256 d5f3b8af3a9bb10a
Conceptio Open Knowledge Archive — every document is proof-bundled with source, license, and retrieval metadata.