ProtectedgetThe logical the call's only argument resolves to, undefined if the call does not take exactly one
argument or if that argument does not resolve to a single logical.
ProtectedgetProtectedgetGet the dataflow graph vertex for the given id
ProtectedgetProtectedgetA helper function to get the normalized AST node for the given id or fail if it does not exist.
ProtectedgetProtectedgetProtectedonProtectedonFires for every call to a *apply function, e.g. lapply(1:10, function(x) { x + 1 }).
ProtectedonFires for every assignment call, e.g. <- in x <- 42, assign("x", 42), or the data.table assign := in DT[, x := 42].
Replacements with a function call on the target side, like names(x) <- 3, go through SemanticCfgGuidedVisitor#onReplacementCall|onReplacementCall instead.
ProtectedonProtectedonProtectedonFires for every named call not handled by a specific overload, e.g. foo(x) for a user-defined foo. flowR does not care about the dataflow
impact of these (currently); use SemanticCfgGuidedVisitor#getOrigins|getOrigins to get the call's origins. Anonymous calls, which cannot
be resolved via the active environment, go through SemanticCfgGuidedVisitor#onUnnamedCall|onUnnamedCall instead.
ProtectedonProtected
This function is responsible for dispatching the appropriate event based on a given dataflow vertex. The default serves as a backend for the event functions below, each of which relates to the corresponding BuiltInProcessorMapper handler.
onDispatchFunctionCallOrigins for the aggregation in case the function call target is ambiguous.
ProtectedonProtected
Given a function call that has multiple targets (e.g., two potential built-in definitions). This function is responsible for calling onDispatchFunctionCallOrigin for each of the origins, and aggregating their results (which is just additive by default). If you want to change the behavior in case of multiple potential function definition targets, simply overwrite this function with the logic you desire.
ProtectedonFires for every call to eval, e.g. eval(parse(text = "x + 1")).
ProtectedonFires for every expression list, implicit or explicit, other than the root program (see SemanticCfgGuidedVisitor#onProgram|onProgram
for that) - e.g. the { } block, or the implicit list x <- x + 1 forms in for(x in 1:10) x <- x + 1.
ProtectedonProtectedonFires for every for loop, e.g. for(i in 1:10) { print(i) }.
ProtectedonFires for every anonymous function definition, e.g. function(x) { x + 1 } in lapply(1:10, function(x) { x + 1 }).
ProtectedonFires for every call to get, e.g. get("x"), which is used to access variables in the global environment.
As flowR resolves get during the dataflow analysis, this may also trigger SemanticCfgGuidedVisitor#onVariableUse|onVariableUse.
ProtectedonProtectedonFires for every call that loads a library, e.g. library(dplyr).
ProtectedonFires for every call that (to flowR's knowledge) constructs a list, e.g. list(1, 2, 3).
ProtectedonProtectedonFires for every call that performs a local call, e.g. local({ x <- 1; y <- 2; x + y }).
ProtectedonFires for every constant logical, e.g. TRUE in if(TRUE) { ... }.
ProtectedonFires for every NULL occurrence; other symbols go through SemanticCfgGuidedVisitor#onSymbolConstant|onSymbolConstant instead.
ProtectedonFires for every constant number, e.g. 42 in print(42).
ProtectedonFires for every call to R's pipe operator |>.
ProtectedonFires for the root program node being analyzed.
ProtectedonProtectedonProtectedonFires for every call to Recall, used to recall the function closure (usually in recursive functions).
ProtectedonFires for every call that registers a hook, e.g. on.exit(print("exiting function")).
ProtectedonFires for every repeat loop, e.g. repeat { i <- i + 1; if(i >= 10) break }.
ProtectedonFires for every call that replaces a value in a container, e.g. names in names(x) <- 3 (but not for x <- 3).
Unlike SemanticCfgGuidedVisitor#onAssignmentCall|onAssignmentCall, this does not assign a value to a variable.
ProtectedonFires for every return call, e.g. f <- function() { return(42) }.
ProtectedonFires for every call to rm, e.g. rm(x), which removes variables from the environment.
ProtectedonFires for every call that performs an S3-like dispatch, e.g. UseMethod("print").
ProtectedonFires for every call that performs an S3-like next dispatch, e.g. NextMethod().
ProtectedonFires for every call that performs an S7 dispatch, e.g. S7_dispatch.
ProtectedonFires for every call that creates a new S7 generic, e.g. new_generic.
ProtectedonFires for every call to source, e.g. source("script.R"). Does not provide the resolved source file by default;
use the DataflowGraph to ask for sourced files.
ProtectedonFires for every special binary operator call, i.e. a binary call whose name starts and ends with %, e.g. x %in% y.
ProtectedonProtectedonProtectedonProtectedonFires for every constant string, e.g. "Hello World" in print("Hello World").
ProtectedonFires for every constant symbol used as itself (non-standard evaluation, not resolved to a value), e.g. foo in library(foo) or a in l$a.
NULL goes through SemanticCfgGuidedVisitor#onNullConstant|onNullConstant instead.
ProtectedonFires for every call to try, e.g. try(stop("error")), which catches possible errors.
ProtectedonFires for every anonymous call, e.g. (function(x) { x + 1 })(42) or the second call in a()(), whose target cannot be inferred from a name
(use SemanticCfgGuidedVisitor#getOrigins|getOrigins). Named calls go through SemanticCfgGuidedVisitor#onDefaultFunctionCall|onDefaultFunctionCall instead.
ProtectedonFires for every variable write, e.g. x in x <- 42 or assign("x", 42). Use getOrigins for its origins.
See SemanticCfgGuidedVisitor#onAssignmentCall|onAssignmentCall for the assignment call itself, which also carries the source.
ProtectedonFires for every variable read, e.g. x in print(x). Use getOrigins for its origins.
ProtectedonFires for every call that (to flowR's knowledge) constructs a vector, e.g. c(1, 2, 3).
ProtectedonProtectedonFires for every while loop, e.g. while(i < 10) { i <- i + 1 }.
Start the visiting process.
ProtectedstartProtectedvisitProtectedvisitDispatches SemanticCfgGuidedVisitor#onUnnamedCall|onUnnamedCall for anonymous calls, or SemanticCfgGuidedVisitor#onDispatchFunctionCallOrigins|onDispatchFunctionCallOrigins for named ones; overwrite those instead of this base-dispatch override.
ProtectedvisitDispatches SemanticCfgGuidedVisitor#onFunctionDefinition|onFunctionDefinition; overwrite that instead of this base-dispatch override.
Protectedvisitcall this function to indicate that a node is to be considered visited.
true if the node was not visited before, false otherwise
ProtectedvisitDispatches SemanticCfgGuidedVisitor#onProgram|onProgram for the root program node.
If you overwrite this, call the base implementation too so onProgram keeps firing.
ProtectedvisitSee DataflowAwareCfgGuidedVisitor#visitValue for the base implementation. This now dispatches the value to the appropriate event handler based on its type.
ProtectedvisitDispatches SemanticCfgGuidedVisitor#onVariableDefinition|onVariableDefinition; overwrite that instead of this base-dispatch override.
ProtectedvisitDispatches SemanticCfgGuidedVisitor#onVariableUse|onVariableUse; overwrite that instead of this base-dispatch override.
This visitor extends on the DataflowAwareCfgGuidedVisitor by dispatching visitors for separate function calls as well, providing more information! In a way, this is the mixin of syntactic and dataflow guided visitation.
Overwrite the functions starting with
onto implement your logic. In general, there is just one special case that you need to be aware of:In the context of a function call, flowR may be unsure to which origin the call relates! Consider the following example:
Obtaining the origins of the call to
foowill return both built-in functionslibraryandrm. The general semantic visitor cannot decide on how to combine these cases, and it is up to your overload of SemanticCfgGuidedVisitor#onDispatchFunctionCallOrigins|onDispatchFunctionCallOrigins to decide how to handle this.Use BasicCfgGuidedVisitor#start to start the traversal.