-
Notifications
You must be signed in to change notification settings - Fork 13
Capabilities
Generated from 'doc-capabilities.ts' on 2026-09-03, 22:43:54 UTC (v2.15.8, R v4.5.0), please do not edit directly.
Each capability has an id that can be used to link to it (use the link symbol to get a direct link to the capability). The internal id is also mentioned in the capability description. This id can be used to reference the capability in a labeled test within flowR. Besides, we use colored bullets like this:
| 🟩 | flowR is capable of handling this feature fully |
| 🔶 | flowR is capable of handling this feature partially |
| 🔴 | flowR is not capable of handling this feature |
☁️ This could be a feature diagram... ☁️
Note
The capabilities are a qualitative measure of the features that flowR can handle. Statements like "flowR can fully handle 50/80 capabilities" are discouraged as the capabilities may have a vastly different granularity. Please prefer using a statement like "flowR has only partial support for feature 'XY'" (or simply reference this document) within the flowR sources.
-
Names and Identifiers 🔗
The recognition of syntactical and non-syntactical names, including their resolutions to corresponding definitions. (internal ID:names-and-identifiers)Consider the following R code:
"f" <- function(x) { get("x") } `y x` <- 2 print(`y x` + f(3))
Identifiers of interest are:
- The symbols
x(name-normal),f(name-quoted), and`y x`(name-escaped). - The function calls
<-,function,{,get,+, andprint(function-calls, all given with name-normal). Especially{is identified as a grouping of the function-definitions' body. - The quoted name created by a function call
get(name-created).
Besides the parameter
x, which is resolved in its lexicographic-scope, the other identifiers are resolved in the global-scope.Loadingflowchart LR 10["`**function** (L. 1) *RFunctionDefinition*`"] subgraph "flow-10" ["function(x) #123; get(#34;x#34;) #125; (L. 1)"] 1["`**x** (L. 1) *RSymbol*`"] 6(["`**#34;x#34;** (L. 1) *RString*`"]) 8[["`base#58;#58;**get** (L. 1) *RFunctionCall*`"]] built-in:get["`Built-In: get`"] style built-in:get stroke:gray,fill:gray,stroke-width:2px,opacity:.8; 9[["`base#58;#58;**#123;** *RExpressionList*`"]] built-in:_["`Built-In: #123;`"] style built-in:_ stroke:gray,fill:gray,stroke-width:2px,opacity:.8; end 0["`**#34;f#34;** (L. 1) *RString*`"] 11[["`base#58;#58;**#60;#45;** (L. 1) *RBinaryOp*`"]] built-in:_-["`Built-In: #60;#45;`"] style built-in:_- stroke:gray,fill:gray,stroke-width:2px,opacity:.8; 13{{"`**2** (L. 2) *RNumber*`"}} 12["`**#96;y x#96;** (L. 2) *RSymbol*`"] 14[["`base#58;#58;**#60;#45;** (L. 2) *RBinaryOp*`"]] 16(["`**#96;y x#96;** (L. 3) *RSymbol*`"]) 18{{"`**3** (L. 3) *RNumber*`"}} 20[["`**f** (L. 3) *RFunctionCall*`"]] 21[["`base#58;#58;**#43;** (L. 3) *RBinaryOp*`"]] built-in:_["`Built-In: #43;`"] style built-in:_ stroke:gray,fill:gray,stroke-width:2px,opacity:.8; 23[["`base#58;#58;**print** (L. 3) *RFunctionCall*`"]] built-in:print["`Built-In: print`"] style built-in:print stroke:gray,fill:gray,stroke-width:2px,opacity:.8; 1 -->|"def-by-on-call"| 18 6 -->|"reads"| 1 8 -->|"reads, returns, arg"| 6 8 -.->|"reads, calls"| built-in:get linkStyle 3 stroke:gray; 9 -->|"returns, arg"| 8 9 -.->|"reads, calls"| built-in:_ linkStyle 5 stroke:gray; 10 -.-|function| flow-10 0 -->|"defined-by, flow"| 11 0 -->|"defined-by"| 10 11 -->|"reads, arg"| 10 11 -->|"returns, arg"| 0 11 -.->|"reads, calls"| built-in:_- linkStyle 11 stroke:gray; 12 -->|"defined-by, flow"| 14 12 -->|"defined-by"| 13 14 -->|"reads, arg"| 13 14 -->|"returns, arg"| 12 14 -.->|"reads, calls"| built-in:_- linkStyle 16 stroke:gray; 16 -->|"reads"| 12 18 -->|"def-on-call"| 1 20 -->|"reads, arg"| 18 20 -->|"reads"| 0 20 -->|"returns"| 8 20 -->|"calls"| 10 21 -->|"reads, arg"| 16 21 -->|"reads, arg"| 20 21 -.->|"reads, calls"| built-in:_ linkStyle 25 stroke:gray; 23 -->|"reads, returns, arg"| 21 23 -.->|"reads, calls"| built-in:print linkStyle 27 stroke:gray;R Code of the (simplified) Dataflow Graph
The analysis required 2.2 ms (including parse and normalize, using the tree-sitter engine) within the generation environment. No signature database is mounted for these generated graphs, so
library()calls attach no package exports; base-R names are still qualified via the generated base-package store (e.g.acfasstats::acf). We encountered unknown side effects (with ids: 23 (linked)) during the analysis."f" <- function(x) { get("x") } `y x` <- 2 print(`y x` + f(3))
23 children (7 fully, 15 partially, 1 not supported)
-
Form 🔗
(internal ID:form)4 children (3 fully, 1 partially, 0 not supported)
-
Normal 🔗 (959 tests, slice: 339, resolve: 1, desugar-tree-sitter: 65, desugar-shell: 66, dataflow: 277, and backed with output: 63)
🟩 Recognize symbol uses likea,plot, ... (i.e., "normal variables or function calls").
See Advanced R/Bindings and R Definition/Identifiers for more info. (internal ID:name-normal) -
Quoted 🔗 (19 tests, slice: 16, desugar: 3, and backed with output: 6)
🟩 Recognize"a",'plot', ... In general, R allows to envelop names in quotations to allow for special characters such as spaces in variable names. However, this only works in the context of definitions. To access these names as variables, one has to either use function such asgetor escape the name with backticks.
See Advanced R/Non-Syntactic Names for more info. (internal ID:name-quoted) -
Escaped 🔗 (19 tests, slice: 11, dataflow: 8, and backed with output: 1)
🟩 Recognize`a`,`plot`, ...
See Advanced R/Non-Syntactic Names for more info. (internal ID:name-escaped) -
Created 🔗 (33 tests, slice: 19, dataflow: 14)
🔶 Recognize functions which resolve strings as identifiers, such asget, ...
See flowr#633 for more info. (internal ID:name-created)
-
Normal 🔗 (959 tests, slice: 339, resolve: 1, desugar-tree-sitter: 65, desugar-shell: 66, dataflow: 277, and backed with output: 63)
-
Resolution 🔗 (29 tests, dataflow: 1, call-graph: 28)
(internal ID:resolution)19 children (4 fully, 14 partially, 1 not supported)
-
Global Scope 🔗 (19 tests, slice: 8, and backed with output: 4)
🟩 For example, tracking a big table of current identifier bindings (internal ID:global-scope) -
Lexicographic Scope 🔗 (38 tests, slice: 14, dataflow: 11, and backed with output: 4)
🟩 For example, support function definition scopes (internal ID:lexicographic-scope) -
Closures 🔗 (33 tests, slice: 23, dataflow: 10, and backed with output: 4)
🔶 Handling function factories and friends. Currently, we do not have enough tests to be sure. (internal ID:closures) -
Dynamic Environment Resolution 🔗 (77 tests, slice: 17, dataflow: 60)
🔶 For example, usingnew.envand friends. Supportsnew.env/new.environment/rlang::new_environment,assign/get/localwithenvir=, dollar-sign access (e$x),attach,with/within, and env-variable aliasing (alias <- e). Static parent-argument resolution (parent = e,parent = emptyenv()) is supported. (internal ID:dynamic-environment-resolution)6 children (0 fully, 6 partially, 0 not supported)
-
Environment in Conditionals 🔗 (6 tests, slice: 1, dataflow: 5)
🔶 Tracking environment assignments and reads across if-then-else branches. flowR propagates envState through branch merging, but cross-branch name resolution inside the env is not guaranteed. (internal ID:environment-in-conditionals) -
Environment in Loops 🔗 (4 tests, dataflow: 4)
🔶 Tracking environment assignments inside loop constructs (for, while, repeat). The env variable is correctly attributed in each iteration body, but dynamic key generation (e.g.,paste0) prevents static name resolution. (internal ID:environment-in-loops) -
Environment Parent 🔗 (6 tests, slice: 1, dataflow: 5)
🔶 Specifying a parent for a newly-created environment (new.env(parent = e),new.env(parent = emptyenv())). Tracked-env-variable parents andemptyenv()/NULLare resolved statically; dynamic or unknown parents fall back to the default (parent.frame()). (internal ID:environment-parent) -
Environment Alias 🔗 (9 tests, slice: 2, dataflow: 7)
🔶 Aliasing a tracked environment variable (alias <- e). TheenvStatesnapshot at assignment time is propagated, so assigns made BEFORE the alias are visible through it. Assigns made AFTER the alias to the original variable are not reflected. (internal ID:environment-alias) -
With / Within 🔗 (8 tests, slice: 5, dataflow: 3)
🔶 Evaluating an expression inside a named environment withwith(data, expr)orwithin(data, expr). Whendatais a tracked env variable, reads of names defined in that env resolve correctly. Writes insideexprare ephemeral (not persisted back to the env). (internal ID:environment-with) -
Dynamic Variable Removal 🔗 (19 tests, dataflow: 19, and backed with output: 2)
🔶 Support forrm(list=..., envir=sys.frame(N))removing variables from a specific call frame. Currently handles negative and zero offsets from within depth-1 functions. (internal ID:dynamic-variable-removal)
-
Environment in Conditionals 🔗 (6 tests, slice: 1, dataflow: 5)
-
Environment Sharing 🔗 (27 tests, slice: 7, dataflow: 20)
🔴 Handling side-effects by environments which are not copied when modified (internal ID:environment-sharing) -
Search Type 🔗 (4 tests, slice: 2)
🟩 Separating the resolution for functions and symbols. (internal ID:search-type) -
Search Path 🔗 (85 tests, dataflow: 85)
🔶 Handling R's search path as explained in Advanced R. Attached packages andattached environments are placed below.GlobalEnv(so global bindings shadow package exports, matching R), attaching inside/through function calls propagates to the caller, and re-attaching is a no-op. Not yet handled: dynamicsearch/fn_envmanipulation. (internal ID:search-path) -
Namespaces 🔗 (11 tests, slice: 1, dataflow: 10)
🔶 Handling R's namespaces as explained in Advanced R (internal ID:namespaces) -
Accessing Exported Names 🔗 (7 tests, slice: 3, desugar: 4)
🔶 Resolving calls with::to their origin. Accessing external files is allowed, although the name of packages etc. is not resolved correctly. (internal ID:accessing-exported-names) -
Accessing Internal Names 🔗
🔶 Similar to::but for internal names. (internal ID:accessing-internal-names) -
Library Loading 🔗 (87 tests, slice: 1, dataflow: 86)
🔶 Resolve libraries identified withlibrary,require,attachNamespace, ... and attach them to the search path (internal ID:library-loading) -
Dynamic Scope Changes 🔗 (1 test, dataflow: 1)
🔶 Manually changing scopes likelocal(internal ID:dynamic-scope-changes) -
Anonymous Bindings 🔗 (3 tests, dataflow: 1, call-graph: 2)
🟩 Support forRecall(internal ID:anonymous-bindings)
-
- The symbols
-
Expressions 🔗
(internal ID:expressions)71 children (49 fully, 16 partially, 6 not supported)
-
Function Calls 🔗 (726 tests, slice: 313, resolve: 1, desugar: 106, dataflow: 274, call-graph: 31, and backed with output: 55)
(internal ID:function-calls)65 children (43 fully, 16 partially, 6 not supported)
-
Grouping 🔗 (146 tests, slice: 22, desugar: 111, dataflow: 13, and backed with output: 12)
🟩 Recognize groups done with(,{, ... (more precisely, their default mapping to the primitive implementations). (internal ID:grouping) -
Normal Call 🔗 (223 tests, slice: 180, desugar-tree-sitter: 22, desugar-shell: 23, dataflow: 20, and backed with output: 47)
🟩 Recognize and resolve calls likef(x),foo::bar(x, y), ... (internal ID:call-normal)7 children (5 fully, 2 partially, 0 not supported)
-
Unnamed Arguments 🔗 (282 tests, slice: 220, desugar: 3, dataflow: 59, and backed with output: 42)
🟩 Recognize and resolve calls likef(3),foo::bar(3, c(1,2)), ... (internal ID:unnamed-arguments) -
Empty Arguments 🔗 (7 tests, slice: 4, desugar: 1, dataflow: 2)
🟩 Essentially a special form of an unnamed argument as infoo::bar(3, ,42), ... (internal ID:empty-arguments) -
Named Arguments 🔗 (55 tests, slice: 37, desugar-tree-sitter: 3, desugar-shell: 4, dataflow: 14, and backed with output: 13)
🟩 Recognize and resolve calls likef(x = 3),foo::bar(x = 3, y = 4), ... (internal ID:named-arguments) -
String Arguments 🔗 (9 tests, desugar: 9)
🟩 Recognize and resolve calls likef('x' = 3),foo::bar('x' = 3, "y" = 4), ... (internal ID:string-arguments) -
Resolve Arguments 🔗 (98 tests, slice: 33, dataflow: 37, call-graph: 28)
🟩 Correctly bind arguments (includingpmatch). Currently, we do not have a correct implementation forpmatch. Furthermore, more tests would be nice. (internal ID:resolve-arguments) -
Side-Effects in Argument 🔗 (2 tests, slice: 1, dataflow: 1)
🔶 Handle side-effects of arguments (e.g.,f(x <- 3),f(x = y <- 3), ...). We have not enough tests to be sure (internal ID:side-effects-in-argument) -
Side-Effects in Function Call 🔗 (23 tests, slice: 14, dataflow: 9, and backed with output: 5)
🔶 Handle side-effects of function calls (e.g.,setXTo(3), ...) for example achieved with the super assignment. We need more tests and handlings. Furthermore, we do not detect side effects with external files, network, logging, etc. (internal ID:side-effects-in-function-call)
-
Unnamed Arguments 🔗 (282 tests, slice: 220, desugar: 3, dataflow: 59, and backed with output: 42)
-
Recursion 🔗 (4 tests, call-graph: 4)
🟩 Recognize and resolve recursive calls likef(3)inside the definition off, ... (internal ID:recursion) -
Anonymous Calls 🔗 (9 tests, slice: 3, desugar: 2, dataflow: 4)
🟩 Recognize and resolve calls like(function(x) x)(3),factory(0)(), ... (internal ID:call-anonymous) -
Infix Calls 🔗 (618 tests, slice: 312, desugar: 103, dataflow: 203, and backed with output: 55)
🟩 Recognize and resolve calls likex + y,x %>% f(y), ... (internal ID:infix-calls) -
Redefinition of Built-In Functions/primitives 🔗 (12 tests, slice: 12, and backed with output: 1)
🔶 Handle cases likeprint <- function(x) x,`for` <- function(a,b,c) a, ... Currently, we can not handle all of them there are no tests. Still wip as part of desugaring (internal ID:redefinition-of-built-in-functions-primitives) -
Functions with global side effects 🔗 (54 tests, slice: 30, dataflow: 24, and backed with output: 2)
🔶 Support functions likesetwdwhich have an impact on the subsequent program. (internal ID:functions-with-global-side-effects) -
Working Directory 🔗 (15 tests, resolve: 15, dataflow: 15)
🔶 Track the effective working directory acrosssetwd(control-flow- and location-sensitive) to resolve relative file paths. Interprocedural, sourced, and loop cases are treated as unbounded rather than guessed. (internal ID:working-directory) -
Index Access 🔗
(internal ID:index-access)7 children (7 fully, 0 partially, 0 not supported)
-
Single Bracket Access 🔗 (35 tests, slice: 17, desugar: 9, dataflow: 9, and backed with output: 2)
🟩 Detect calls likex[i],x[i, ,b],x[3][y], ... This does not include the real separation of cells, which is handled extra. (internal ID:single-bracket-access) -
Double Bracket Access 🔗 (43 tests, slice: 37, desugar: 4, dataflow: 2)
🟩 Detect calls likex[[i]],x[[i, b]], ... Similar to single bracket. (internal ID:double-bracket-access) -
Dollar Access 🔗 (24 tests, slice: 9, desugar: 2, dataflow: 13)
🟩 Detect calls likex$y,x$"y",x$y$z, ... (internal ID:dollar-access) -
Slot Access 🔗 (2 tests, desugar: 1, dataflow: 1)
🟩 Detect calls likex@y,x@y@z, ... (internal ID:slot-access) -
Access with Argument-Names 🔗 (3 tests, slice: 2, desugar: 1)
🟩 Detect calls likex[i = 3],x[[i=]], ... (internal ID:access-with-argument-names) -
Access with Empty 🔗 (4 tests, desugar: 4)
🟩 Detect calls likex[],x[2,,42], ... (internal ID:access-with-empty) -
Subsetting (Multiple Indices) 🔗 (4 tests, slice: 4)
🟩 Detect calls likex[i > 3],x[c(1,3)], ... (internal ID:subsetting-multiple)
-
Single Bracket Access 🔗 (35 tests, slice: 17, desugar: 9, dataflow: 9, and backed with output: 2)
-
Operators 🔗 (4 tests, dataflow: 4)
(internal ID:operators)15 children (11 fully, 3 partially, 1 not supported)
-
Unary Operator 🔗 (14 tests, desugar: 7, dataflow: 7)
🟩 Recognize and resolve calls like+3,-3, ... (internal ID:unary-operator) -
Binary Operator 🔗 (621 tests, slice: 310, desugar: 103, dataflow: 208, and backed with output: 55)
🟩 Recognize and resolve calls like3 + 4,3 * 4, ... (internal ID:binary-operator)13 children (9 fully, 3 partially, 1 not supported)
-
Special Operator 🔗 (14 tests, slice: 11, desugar: 1, dataflow: 2)
🟩 Recognize and resolve calls like3 %in% 4,3 %*% 4, ... (internal ID:special-operator) -
Model Formula 🔗 (14 tests, slice: 4, desugar: 7, dataflow: 3, and backed with output: 4)
🔶 Recognize and resolve calls likey ~ x,y ~ x + z, ... including their implicit redefinitions of some functions. Currently, we do not handle their redefinition and only treat model formulas as normal binary operators (internal ID:model-formula) -
Assignments and Bindings 🔗 (7 tests, slice: 7, and backed with output: 4)
(internal ID:assignments-and-bindings)11 children (8 fully, 2 partially, 1 not supported)
-
Local Left Assignment 🔗 (433 tests, slice: 311, desugar: 8, dataflow: 114, and backed with output: 59)
🟩 Handlex <- 3,x$y <- 3, ... (internal ID:local-left-assignment) -
Local Right Assignment 🔗 (19 tests, slice: 6, desugar: 6, dataflow: 7)
🟩 Handle3 -> x,3 -> x$y, ... (internal ID:local-right-assignment) -
Local Equal Assignment 🔗 (23 tests, slice: 5, desugar: 6, dataflow: 12)
🟩 Handlex = 3,x$y := 3, ... (internal ID:local-equal-assignment) -
Local Table Assignment 🔗 (12 tests, slice: 4, desugar: 5, dataflow: 3)
🟩 Handlex[,a:=3,], ... (internal ID:local-table-assignment) -
Super Left Assignment 🔗 (45 tests, slice: 17, desugar: 6, dataflow: 22, and backed with output: 5)
🟩 Handlex <<- 42,x$y <<- 42, ... (internal ID:super-left-assignment) -
Super Right Assignment 🔗 (10 tests, desugar: 6, dataflow: 4)
🟩 Handle42 ->> x,42 ->> x$y, ... (internal ID:super-right-assignment) -
Return Value of Assignments 🔗 (26 tests, slice: 8, dataflow: 18)
🟩 Handlex <- 3returning3, e.g., inx <- y <- 3(internal ID:return-value-of-assignments) -
Assignment Functions 🔗 (505 tests, slice: 317, desugar: 33, dataflow: 155, and backed with output: 59)
🔶 Handleassign(x, 3),delayedAssign(x, 3), ... Currently we can not handle all of them and tests are rare. (internal ID:assignment-functions) -
Range Assignment 🔗 (2 tests, slice: 2)
🟩 Handlex[1:3] <- 3,x$y[1:3] <- 3, ... (internal ID:range-assignment) -
Replacement Functions 🔗 (14 tests, slice: 9, dataflow: 5, and backed with output: 4)
🔶 Handlex[i] <- 3,x$y <- 3, ... as`[<-`(x, 3), ... Currently work in progress as part of the desugaring but still untested. (internal ID:replacement-functions) -
Locked Bindings 🔗
🔴 HandlelockBinding(x, 3), ... (internal ID:locked-bindings)
-
Local Left Assignment 🔗 (433 tests, slice: 311, desugar: 8, dataflow: 114, and backed with output: 59)
-
-
-
Control-Flow 🔗 (16 tests, slice: 13, dataflow: 3, and backed with output: 8)
(internal ID:control-flow)9 children (8 fully, 1 partially, 0 not supported)
-
if 🔗 (152 tests, slice: 32, desugar: 52, dataflow: 68, and backed with output: 5)
🟩 Handleif (x) y else z,if (x) y, ... (internal ID:if) -
for loop 🔗 (52 tests, slice: 31, desugar: 2, dataflow: 19, and backed with output: 5)
🟩 Handlefor (i in 1:3) print(i), ... (internal ID:for-loop) -
while loop 🔗 (46 tests, slice: 25, desugar: 4, dataflow: 17, and backed with output: 1)
🟩 Handlewhile (x) b, ... (internal ID:while-loop) -
repeat loop 🔗 (26 tests, slice: 14, desugar: 2, dataflow: 10)
🟩 Handlerepeat {b; if (x) break}, ... (internal ID:repeat-loop) -
break 🔗 (15 tests, slice: 6, desugar: 2, dataflow: 7)
🟩 Handlebreak(includingbreak()) ... (internal ID:break) -
next 🔗 (8 tests, slice: 3, desugar: 2, dataflow: 3)
🟩 Handlenext(includingnext()) ... (internal ID:next) -
switch 🔗 (1 test, slice: 1)
🟩 Handleswitch(3, "a", "b", "c"), ... (internal ID:switch) -
return 🔗 (41 tests, slice: 36, dataflow: 5)
🟩 Handlereturn(3), ... in function definitions (internal ID:return) -
Exceptions and Errors 🔗 (75 tests, slice: 8, dataflow: 60, controlflow: 6, call-graph: 1, and backed with output: 8)
🔶 Handletry,stop, ... (internal ID:exceptions-and-errors)
-
if 🔗 (152 tests, slice: 32, desugar: 52, dataflow: 68, and backed with output: 5)
-
Function Definitions 🔗 (61 tests, slice: 19, dataflow: 12, call-graph: 30, and backed with output: 1)
(internal ID:function-definitions)7 children (6 fully, 1 partially, 0 not supported)
-
Normal 🔗 (176 tests, slice: 122, desugar: 12, dataflow: 41, and backed with output: 45)
🟩 Handlefunction() 3, ... (internal ID:normal-definition) -
Formals 🔗
(internal ID:formals)4 children (3 fully, 1 partially, 0 not supported)
-
Named 🔗 (85 tests, slice: 56, desugar: 7, dataflow: 22, and backed with output: 14)
🟩 Handlefunction(x) x, ... (internal ID:formals-named) -
Default 🔗 (28 tests, slice: 19, desugar: 2, dataflow: 7, and backed with output: 8)
🟩 Handlefunction(x = 3) x, ... (internal ID:formals-default) -
Dot-Dot-Dot 🔗 (11 tests, slice: 3, desugar: 3, dataflow: 5)
🟩 Handlefunction(...) 3, ... (internal ID:formals-dot-dot-dot) -
Promises 🔗 (10 tests, slice: 3, dataflow: 7)
🔶 Handlefunction(x = y) { y <- 3; x },function(x = { x <- 3; x}) { x * x }, ... A default argument resolves in the function's own environment and an argument passed in resolves in the caller's, both as R does it. We do not model when a promise is forced: adelayedAssigned expression is linked to every binding it may be forced against, which never misses the one that feeds it but may name others as well. What forcing does is not modelled either, so the writes a promise performs when it is forced (delayedAssign("x", { x <- 99; 2 }), where readingxyields2and leavesxat99) do not reach the reads that follow. (internal ID:formals-promises)
-
Named 🔗 (85 tests, slice: 56, desugar: 7, dataflow: 22, and backed with output: 14)
-
Implicit Return 🔗 (185 tests, slice: 136, dataflow: 49, and backed with output: 36)
🟩 Handle the return offunction() 3, ... (internal ID:implicit-return) -
Lambda Syntax 🔗 (7 tests, slice: 2, dataflow: 5)
🟩 Support\(x) x, ... (internal ID:lambda-syntax)
-
-
Important Built-Ins 🔗
(internal ID:important-built-ins)12 children (1 fully, 6 partially, 5 not supported)
-
Non-Strict Logical Operators 🔗 (29 tests, desugar: 20, dataflow: 9)
🟩 Handle&&,||, ... (internal ID:non-strict-logical-operators) -
Pipe and Pipe-Bind 🔗 (19 tests, slice: 2, desugar: 2, dataflow: 15)
🔶 Handle the new (4.1) pipe and pipe-bind syntax:|>, and=>.; Similarly support the other pipe binds (internal ID:pipe-and-pipe-bind) -
Sequencing 🔗 (2 tests, slice: 2, and backed with output: 1)
🔴 Handle:,seq, ... by gathering value information using abstract interpretation. (internal ID:built-in-sequencing) -
Internal and Primitive Functions 🔗 (1 test, slice: 1)
🔶 Handle.Internal,.Primitive, ... In general we can not handle them as they refer to non-R code. We currently do not support them when used with the function. (internal ID:built-in-internal-and-primitive-functions) -
Options 🔗
🔴 Handleoptions,getOption, ... Currently, we do not support the function at all. (internal ID:built-in-options) -
Help 🔗 (3 tests, desugar: 2, dataflow: 1)
🔶 Handlehelp,?, ... We do not support the function in a sensible way but just ignore it (although this does not happen resolved). (internal ID:built-in-help) -
Reflection / "Computing on the Language" 🔗 (10 tests, dataflow: 10)
(internal ID:reflection-"computing-on-the-language")6 children (0 fully, 3 partially, 3 not supported)
-
Get Function Structure 🔗
🔴 Handlebody,formals,environmentto access the respective parts of a function. We do not support the functions at all. (internal ID:get-function-structure) -
Modify Function Structure 🔗
🔴 Handlebody<-,formals<-,environment<-to modify the respective parts of a function. We do not support the functions at all. (internal ID:modify-function-structure) -
Quoting 🔗 (26 tests, slice: 1, dataflow: 25)
🔶 Handlequote,substitute,bquote, ... A quoted argument is marked as non-standard evaluation as a whole, so nothing within it counts as read. We model the escapes back to standard evaluation that a quoting function offers: rlang's!!/!!!(inexpr,quo,enquo, ... and in data-masking arguments) andbquote's.(). Basequote/substitutehave no such escape, andsubstitutedoes not reach the caller's expression when used on a function argument. (internal ID:built-in-quoting) -
Evaluation 🔗 (51 tests, slice: 14, dataflow: 37)
🔶 Handleeval,evalq,eval.parent, ...evalof a string we can resolve is analyzed as if it were written in its place. A language object reaches theevalthat forces it even across assignments, branches, loop iterations, and function calls, and its names resolve in the scope evaluating it, as R does.eval(expr, envir)runs elsewhere, so we mark the call as an unknown side effect instead of guessing.evalqquotes its first argument and we do not follow it into the given environment. (internal ID:built-in-evaluation) -
String Templates 🔗
🔶 Handleglue::glue("{x}"),cli::cli_alert_info("{.val {x}}"),stringr::str_glue/str_interp, ... The{...}of a template carries R code that runs where the call is, so we analyze it as if it were written there: it reads, it writes, and its side effects land in the calling scope. Doubled delimiters escape,.open/.closeare honored when they are literal, and cli markup ({.cls ...}) contributes only the interpolations nested in it. A template aimed at another scope (.envir,.con,glue_data) is marked as an unknown side effect instead. (internal ID:string-templates) -
Parsing 🔗
🔴 Handleparse,deparse, ... We handle them as unknown function calls, but not specifically besides that. (internal ID:built-in-parsing)
-
Get Function Structure 🔗
-
-
-
Literal Values 🔗
(internal ID:literal-values)6 children (6 fully, 0 partially, 0 not supported)
-
Numbers 🔗 (684 tests, slice: 313, desugar-tree-sitter: 199, desugar-shell: 207, dataflow: 164, and backed with output: 66)
🟩 Recognize numbers like3,3.14,NA, float-hex, ... (internal ID:numbers) -
Strings 🔗 (143 tests, slice: 72, desugar: 45, dataflow: 26, and backed with output: 24)
🟩 Recognize strings like"a",'b', ... (internal ID:strings)1 child (1 fully, 0 partially, 0 not supported)
-
Raw Strings 🔗 (7 tests, desugar: 7)
🟩 Recognize raw strings liker"(a)", ... (internal ID:raw-strings)
-
Raw Strings 🔗 (7 tests, desugar: 7)
-
Logical 🔗 (116 tests, slice: 22, desugar: 56, dataflow: 38, and backed with output: 2)
🟩 Recognize the logicalsTRUEandFALSE, ... (internal ID:logical) -
NULL 🔗 (2 tests, slice: 1, dataflow: 1)
🟩 RecognizeNULL(internal ID:null) -
Inf and NaN 🔗 (3 tests, slice: 1, dataflow: 2)
🟩 RecognizeInfandNaN(internal ID:inf-and-nan)
-
-
-
Non-Standard Evaluations/Semantics 🔗
(internal ID:non-standard-evaluations-semantics)7 children (1 fully, 2 partially, 4 not supported)
-
Data Masking 🔗 (10 tests, dataflow: 10)
🔶 Handlesubset(d, col > 1), dplyr verbs,ggplot2::aes, data.table:=, ... In a masked argument, a name the caller binds is read as that variable and any other name is taken to come from the data. Which names a data frame actually offers is unknown to us, so a column shadowing a variable of the same name still resolves to the variable. rlang's!!/!!!and its:=name-value pair are recognised;[on adata.tabledoes not mask itsj/byyet. (internal ID:data-masking) -
Recycling 🔗
🔴 Handle recycling of vectors as explained in Advanced R. We do not support recycling. (internal ID:recycling) -
Vectorized Operator or Functions 🔗
🔴 Handle vectorized operations as explained in Advanced R. We do not support vectorized operations. (internal ID:vectorized-operator-or-functions) -
Hooks 🔗 (15 tests, dataflow: 12, call-graph: 3)
🔶 Handle hooks likeuserhooksandon.exit. We supporton.exitand rlang'son_load/run_on_load/on_package_load, whose expressions we analyze where they are registered.setHookand the other user hooks are not modelled. (internal ID:hooks) -
Precedence 🔗 (39 tests, slice: 38, dataflow: 1, and backed with output: 4)
🟩 Handle the precedence of operators as explained in the Documentation. We handle the precedence of operators (implicitly with the parser). (internal ID:precedence) -
Attributes 🔗
(internal ID:attributes)2 children (0 fully, 0 partially, 2 not supported)
-
User-Defined 🔗
🔴 Handle attributes likeattr,attributes, ... We do not support attributes. (internal ID:user-defined) -
Built-In 🔗 (25 tests, slice: 7, dataflow: 7, call-graph: 11)
🔴 Handle built-in attributes likedim, ... We do not support them. (internal ID:built-in)
-
User-Defined 🔗
-
-
Types 🔗
(internal ID:types)11 children (0 fully, 7 partially, 4 not supported)
-
Primitive 🔗
🔴 Recognize and resolve primitive types likenumeric,character, ... We do not support typing currently. (internal ID:types-primitive) -
Non-Primitive 🔗
🔴 Recognize and resolve non-primitive/composite types. We do not support typing currently. (internal ID:types-non-primitive) -
Inference 🔗
🔴 Infer types from the code. We do not support typing currently. (internal ID:types-inference) -
Coercion 🔗
🔴 Handle coercion of types. We do not support typing currently. (internal ID:types-coercion) -
Object-Oriented Programming 🔗
(internal ID:object-oriented-programming)7 children (0 fully, 7 partially, 0 not supported)
-
S3 🔗 (19 tests, slice: 10, dataflow: 8, call-graph: 1, and backed with output: 10)
🔶 Handle S3 classes and methods as one unit (with attributes etc.). Including Dispatch and Inheritance. We do not support typing currently and do not handle objects of these classes "as units."
See Advanced R/S3 for more info. (internal ID:oop-s3) -
S4 🔗 (12 tests, slice: 7, dataflow: 5, and backed with output: 7)
🔶 Handle S4 classes and methods as one unit. Including Dispatch and Inheritance We do not support typing currently and do not handle objects of these classes "as units."
See Advanced R/S4 for more info. (internal ID:oop-s4) -
R6 🔗
🔶 _Handle R6 classes and methods as one unit. We do not support typing, inheritance, private/active bindings, or handling objects fully "as units."
See Advanced R/R6 for more info. (internal ID:oop-r6) -
R7/S7 🔗 (5 tests, dataflow: 5)
🔶 Handle R7 classes and methods as one unit. Including Dispatch and Inheritance, as well as its Reference Semantics, Validators, ... We do not support typing currently and do not handle objects of these classes "as units."
See R7 and S7 for more info. (internal ID:oop-r7-s7) -
Class-Based Dependency Attribution 🔗
🔶 Attribute the use of a class to the package that owns it (registers a method for it and exports a same-named constructor), so a class use implies a dependency for library detection and version guessing (backed by the signature database's class-ownership map). (internal ID:oop-class-dependency-attribution)2 children (0 fully, 2 partially, 0 not supported)
-
S3 class ownership 🔗
🔶 The signature database records which package owns each S3 class. A class use is attributed to the owning package -- both from a project's NAMESPACES3method(generic, class)registrations (e.g.S3method("as.irts","zoo")markszooused) and from class-name string literals in plain code (inherits(x, "zoo"),methods::is,new,structure(..., class=)), marking the owner used and bounding its version below by the same-named constructor's export history. Class names that come from a variable or ac(...)vector, and method-definition names likeprint.zoo, are not yet resolved. (internal ID:class-owner-s3) -
S4 class ownership 🔗
🔶 A project'simportClassesFrom/importMethodsFromNAMESPACE directives are tracked, so the source package is attached and marked used like a plainimportFrom. S4 class ownership itself (exportClasses,setClass) is not yet recorded in the signature database, so a bare S4 class use is not attributed to its owning package. (internal ID:class-owner-s4)
-
S3 class ownership 🔗
-
-
-
Structure 🔗
(internal ID:structure)3 children (3 fully, 0 partially, 0 not supported)
-
Comments 🔗 (19 tests, slice: 10, desugar-tree-sitter: 8, desugar-shell: 9, and backed with output: 3)
🟩 Recognize comments like# this is a comment, ... and line-directives (internal ID:comments) -
Semicolons 🔗 (70 tests, slice: 33, desugar: 5, dataflow: 32, and backed with output: 4)
🟩 Recognize and resolve semicolons likea; b; c, ... (internal ID:semicolons) -
Newlines 🔗 (400 tests, slice: 295, desugar: 11, dataflow: 94, and backed with output: 64)
🟩 Recognize and resolve newlines likea b c, ... (internal ID:newlines)
-
Comments 🔗 (19 tests, slice: 10, desugar-tree-sitter: 8, desugar-shell: 9, and backed with output: 3)
-
System, I/O, FFI, and Other Files 🔗
(internal ID:system-i-o-ffi-and-other-files)9 children (1 fully, 4 partially, 4 not supported)
-
Sourcing External Files 🔗 (15 tests, slice: 7, dataflow: 8)
🔶 Handlesource,sys.source, ... We are currently working on supporting the inclusion of external files. Currently we can handlesource. (internal ID:sourcing-external-files) -
Handling Binary Riles 🔗
🔴 Handle files dumped with, e.g.,save, ... due to their frequent usage. We do not support binary files. (internal ID:handling-binary-riles) -
I/O 🔗
🔴 Handleread.csv,write.csv, ... We do not support I/O for the time being but treat them as unknown function calls. (internal ID:i-o) -
Foreign Function Interface 🔗
🔴 Handle.Fortran,C,... We do not support FFI but treat them as unknown function calls. (internal ID:foreign-function-interface) -
System Calls 🔗
🔴 Handlesystem,system.*, ... We do not support system calls but treat them as unknown function calls. (internal ID:system-calls) -
R-Markdown files 🔗 (6 tests)
🟩 Support R-Markdown files as R sources. (internal ID:file:rmd) -
Jupyter Notebook 🔗 (3 tests)
🔶 Support Jupyter Notebooks as R sources. (internal ID:file:ipynb) -
Quarto 🔗 (3 tests)
🔶 Support Quarto files as R sources. (internal ID:file:qmd) -
Sweave 🔗 (12 tests)
🔶 Support for Sweave files as R sources. (internal ID:file:rnw)
-
Sourcing External Files 🔗 (15 tests, slice: 7, dataflow: 8)
-
Pre-Processors/external Tooling 🔗
🟩 Handle pre-processors likeknitr,rmarkdown,roxygen2... We do not support pre-processors for the time being (being unable to handle things like@importFrom) (internal ID:pre-processors-external-tooling)
Currently maintained by Florian Sihler and Oliver Gerstl at Ulm University
Email | GitHub | Penguins | Portfolio
- 🧑💻 Developer Onboarding
- 💻 Setup
- 👓 Overview
- 🪟 Interfacing with flowR
- 🌋 Core
- 🧹 Testing & Linting (Benchmark Page)
⁉️ FAQ- ℹ️ Extra Information