Skip to content

Normalized AST

github-actions[bot] edited this page Jun 13, 2026 · 1 revision

This document was generated from 'src/documentation/wiki-normalized-ast.ts' on 2026-06-06, 11:14:26 UTC presenting an overview of flowR's normalized ast (v2.10.7, using R v4.5.0). Please do not edit this file/wiki page directly.

flowR produces a normalized version of R's abstract syntax tree (AST), offering the following benefits:

  1. abstract away from intricacies of the R parser
  2. provide a version-independent representation of the program
  3. decorate the AST with additional information, e.g., parent relations and nesting information

In general, the mapping should be rather intuitive and focused primarily on the syntactic structure of the program. As with other types in flowR, you get corresponding helper objects. So if you want to work with an RBinaryOp node, you can use the RBinaryOp object to check whether a node is an RBinaryOp and to access its fields (e.g., with RBinaryOp::is). Consider the following example which shows the normalized AST of the code

x <- 2 * 3 + 1

Each node in the AST contains the type, the id, and the lexeme (if applicable). Each edge is labeled with the type of the parent-child relationship (the "role").

flowchart LR
    n7(["RExpressionList (7)
 "])
    n6(["RBinaryOp (6)
#60;#45;"])
    n7 -->|"el-c-0"| n6
    n0(["RSymbol (0)
x"])
    n6 -->|"bin-l"| n0
    n5(["RBinaryOp (5)
#43;"])
    n6 -->|"bin-r"| n5
    n3(["RBinaryOp (3)
#42;"])
    n5 -->|"bin-l"| n3
    n1(["RNumber (1)
2"])
    n3 -->|"bin-l"| n1
    n2(["RNumber (2)
3"])
    n3 -->|"bin-r"| n2
    n4(["RNumber (4)
1"])
    n5 -->|"bin-r"| n4

Loading

(The analysis required 5.5 ms (including parsing with the tree-sitter engine) within the generation environment.)

Tip

If you want to investigate the normalized AST, you can either use the Visual Studio Code extension or the :normalize* command in the REPL (see the Interface wiki page for more information).

Indicative of the normalization is the root RProject node, which is present in every normalized AST and provides the RExpressionList nodes for each file in the project. In general, we provide node types for:

  1. literals (e.g., numbers and strings)
  2. references (e.g., symbols, parameters and function calls)
  3. constructs (e.g., loops and function definitions)
  4. branches (e.g., next and break)
  5. operators (e.g. +, -, and *)
Complete Class Diagram

Every node is a link, which directly refers to the implementation in the source code. Grayed-out parts are used for structuring the AST, grouping together related nodes.

---
  config:
    class:
      hideEmptyMembersBox: true
---
classDiagram
direction RL
class RNode~Info = NoInfo~{
    <<type>>
}
style RNode opacity:.35,fill:#FAFAFA
click RNode href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L268" "The #96;RNode#96; type is the union of all possible nodes in the R#45;ast. It should be used whenever you either not care what kind of node you are dealing with or if you want to handle all possible nodes. #60;p#62; All other subtypes (like; #60;code#62;RLoopConstructs#60;/code#62;; ) listed above can be used to restrict the kind of node. They do not have to be exclusive, some nodes can appear in multiple subtypes."
class RExpressionList~Info = NoInfo~{
    <<interface>>
    type#58; RType.ExpressionList
    grouping#58; #91;start#58; RSymbol#60;Info, Identifier#62;, end#58; RSymbol#60;Info, Identifier#62;#93;
}
click RExpressionList href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.ts#L10" "Holds a list of expressions (and hence may be the root of an AST, summarizing all expressions in a file). The #96;grouping#96; property holds information on if the expression list is structural or created by a wrapper like #96;#123;#125;#96; or #96;()#96;."
class WithChildren~Info, Children extends RAstNodeBase<Info, string | undefined>~{
    <<interface>>
    children#58; #123;#125;
}
click WithChildren href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L81" ""
class RAstNodeBase~Info, LexemeType = string~{
    <<interface>>
    type#58; RType
    lexeme#58; LexemeType
    info#58; Info #38; Source
}
click RAstNodeBase href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L73" "Provides the common base of all; #60;code#62;RNodes#60;/code#62;; ."
class MergeableRecord{
    <<type>>
}
style MergeableRecord opacity:.35,fill:#FAFAFA
click MergeableRecord href "https://github.com/flowr-analysis/flowr/tree/main/src/util/objects.ts#L11" ""
class Record{
    <<variable>>
}
click Record href "https://github.com/flowr-analysis/flowr/tree/main/src/util/record.ts#L4" "Helper for transforming records."
class string{
    <<variable>>
}
click string href "https://github.com/flowr-analysis/flowr/tree/main/src/documentation/wiki-absint.ts#L91" ""
class domain{
    <<variable>>
}
click domain href "https://github.com/flowr-analysis/flowr/tree/main/src/documentation/wiki-absint.ts#L89" ""
class unknown{
    <<variable>>
}
click unknown href "https://github.com/flowr-analysis/flowr/tree/main/src/dataflow/graph/graph-helper.ts#L109" ""
class Info{
    <<enum>>
}
click Info href "https://github.com/flowr-analysis/flowr/tree/main/src/util/log.ts#L55" ""
class LogLevel{
    <<enum>>
    Silly#58; LogLevel.Silly
    Trace#58; LogLevel.Trace
    Debug#58; LogLevel.Debug
    Info#58; LogLevel.Info
    Warn#58; LogLevel.Warn
    Error#58; LogLevel.Error
    Fatal#58; LogLevel.Fatal
}
click LogLevel href "https://github.com/flowr-analysis/flowr/tree/main/src/util/log.ts#L51" ""
class RFunctions~Info~{
    <<type>>
}
style RFunctions opacity:.35,fill:#FAFAFA
click RFunctions href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L216" "This subtype of; #60;code#62;RNode#60;/code#62;; represents all types related to functions (calls and definitions) in the normalized AST."
class RFunctionDefinition~Info = NoInfo~{
    <<interface>>
    type#58; RType.FunctionDefinition
    parameters#58; #123;#125;
    body#58; RNode#60;Info#62;
}
click RFunctionDefinition href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.ts#L16" "#96;#96;#96;r function(#60;parameters#62;) #60;body#62; #96;#96;#96; or#58; #96;#96;#96;r #92;(#60;parameters#62;) #60;body#62; #96;#96;#96;"
class Location{
    <<interface>>
    location#58; SourceRange
}
click Location href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L99" "Indicates, that the respective; #60;code#62;RAstNodeBase#60;/code#62;; node has known source code location information."
class RFunctionCall~Info = NoInfo~{
    <<type>>
}
style RFunctionCall opacity:.35,fill:#FAFAFA
click RFunctionCall href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-function-call.ts#L38" ""
class RNamedFunctionCall~Info = NoInfo~{
    <<interface>>
    type#58; RType.FunctionCall
    named#58; true
    functionName#58; RSymbol#60;Info, Identifier#62;
    arguments#58; #123;#125;
}
click RNamedFunctionCall href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-function-call.ts#L15" "Calls of functions like #96;a()#96; and #96;foo(42, #34;hello#34;)#96;."
class RUnnamedFunctionCall~Info = NoInfo~{
    <<interface>>
    type#58; RType.FunctionCall
    named#58; false
    calledFunction#58; RNode#60;Info#62;
    infixSpecial#58; boolean
    arguments#58; #123;#125;
}
click RUnnamedFunctionCall href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-function-call.ts#L28" "Direct calls of functions like #96;(function(x) #123; x #125;)(3)#96;."
class RParameter~Info = NoInfo~{
    <<interface>>
    type#58; RType.Parameter
    name#58; RSymbol#60;Info, BrandedIdentifier#62;
    special#58; boolean
    defaultValue#58; RNode#60;Info#62;
}
click RParameter href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-parameter.ts#L10" "Represents a parameter of a function definition in R."
class RArgument~Info = NoInfo~{
    <<interface>>
    type#58; RType.Argument
    name#58; RSymbol#60;Info, BrandedIdentifier#62;
    value#58; RNode#60;Info#62;
}
click RArgument href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-argument.ts#L14" "Represents a named or unnamed argument of a function definition in R."
class ROther~Info~{
    <<type>>
}
style ROther opacity:.35,fill:#FAFAFA
click ROther href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L239" "This subtype of; #60;code#62;RNode#60;/code#62;; represents all types of otherwise hard to categorize nodes in the normalized AST. At the moment these are the comment#45;like nodes."
class RComment~Info = NoInfo~{
    <<interface>>
    type#58; RType.Comment
}
click RComment href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-comment.ts#L10" "#96;#96;#96;r # I am a line comment #96;#96;#96;"
class Leaf{
    <<type>>
}
style Leaf opacity:.35,fill:#FAFAFA
click Leaf href "https://github.com/flowr-analysis/flowr/tree/main/src/search/flowr-search-filters.ts#L128" ""
class LeafRType{
    <<type>>
}
style LeafRType opacity:.35,fill:#FAFAFA
click LeafRType href "https://github.com/flowr-analysis/flowr/tree/main/src/search/flowr-search-filters.ts#L124" ""
class LeafVertexType{
    <<type>>
}
style LeafVertexType opacity:.35,fill:#FAFAFA
click LeafVertexType href "https://github.com/flowr-analysis/flowr/tree/main/src/search/flowr-search-filters.ts#L125" ""
class LeafSpecial{
    <<type>>
}
style LeafSpecial opacity:.35,fill:#FAFAFA
click LeafSpecial href "https://github.com/flowr-analysis/flowr/tree/main/src/search/flowr-search-filters.ts#L126" ""
class RLineDirective~Info = NoInfo~{
    <<interface>>
    type#58; RType.LineDirective
    line#58; number
    file#58; string
}
click RLineDirective href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.ts#L8" "Special comment to signal line mappings (e.g., in generated code) to the interpreter."
class RConstructs~Info~{
    <<type>>
}
style RConstructs opacity:.35,fill:#FAFAFA
click RConstructs href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L193" "As an extension to; #60;code#62;RLoopConstructs#60;/code#62;; , this subtype of; #60;code#62;RNode#60;/code#62;; includes the; #60;code#62;RIfThenElse#60;/code#62;; construct as well."
class RLoopConstructs~Info~{
    <<type>>
}
style RLoopConstructs opacity:.35,fill:#FAFAFA
click RLoopConstructs href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L170" "This subtype of; #60;code#62;RNode#60;/code#62;; represents all looping constructs in the normalized AST."
class RForLoop~Info = NoInfo~{
    <<interface>>
    type#58; RType.ForLoop
    variable#58; RSymbol#60;Info, Identifier#62;
    vector#58; RNode#60;Info#62;
    body#58; RExpressionList#60;Info#62;
}
click RForLoop href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.ts#L12" "#96;#96;#96;r for(#60;variable#62; in #60;vector#62;) #60;body#62; #96;#96;#96;"
class RRepeatLoop~Info = NoInfo~{
    <<interface>>
    type#58; RType.RepeatLoop
    body#58; RExpressionList#60;Info#62;
}
click RRepeatLoop href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.ts#L11" "#96;#96;#96;r repeat #60;body#62; #96;#96;#96;"
class RWhileLoop~Info = NoInfo~{
    <<interface>>
    type#58; RType.WhileLoop
    condition#58; RNode#60;Info#62;
    body#58; RExpressionList#60;Info#62;
}
click RWhileLoop href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.ts#L11" "#96;#96;#96;r while(#60;condition#62;) #60;body#62; #96;#96;#96;"
class RIfThenElse~Info = NoInfo~{
    <<interface>>
    type#58; RType.IfThenElse
    condition#58; RNode#60;Info#62;
    then#58; RExpressionList#60;Info#62;
    otherwise#58; RExpressionList#60;Info#62;
}
click RIfThenElse href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.ts#L11" "#96;#96;#96;r if(#60;condition#62;) #60;then#62; #91;else #60;otherwise#62;#93; #96;#96;#96;"
class RNamedAccess~Info = NoInfo~{
    <<interface>>
    operator#58; #34;$#34; | #34;@#34;
    access#58; #91;RUnnamedArgument#60;Info#62;#93;
}
click RNamedAccess href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-access.ts#L20" "Represents an R named access operation with #96;$#96; or #96;@#96;, the field is a string."
class RAccessBase~Info = NoInfo~{
    <<interface>>
    type#58; RType.Access
    accessed#58; RNode#60;Info#62;
    operator#58; #34;$#34; | #34;@#34; | #34;#91;#34; | #34;#91;#91;#34;
}
click RAccessBase href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-access.ts#L10" "Represents an R Indexing operation with #96;$#96;, #96;@#96;, #96;#91;#91;#96;, or #96;#91;#96;."
class RIndexAccess~Info = NoInfo~{
    <<interface>>
    operator#58; #34;#91;#34; | #34;#91;#91;#34;
    access#58; #123;#125;
}
click RIndexAccess href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-access.ts#L26" "access can be a number, a variable or an expression that resolves to one, a filter etc."
class RUnaryOp~Info = NoInfo~{
    <<interface>>
    type#58; RType.UnaryOp
    operator#58; string
    operand#58; RNode#60;Info#62;
}
click RUnaryOp href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.ts#L10" "Unary operations like #96;#43;#96; and #96;#45;#96;"
class RBinaryOp~Info = NoInfo~{
    <<interface>>
    type#58; RType.BinaryOp
    operator#58; string
    lhs#58; RNode#60;Info#62;
    rhs#58; RNode#60;Info#62;
}
click RBinaryOp href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.ts#L10" "Operators like #96;#43;#96;, #96;==#96;, #96;#38;#38;#96;, etc."
class RSingleNode~Info~{
    <<type>>
}
style RSingleNode opacity:.35,fill:#FAFAFA
click RSingleNode href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L145" "This subtype of; #60;code#62;RNode#60;/code#62;; represents all types of; #60;code#62;Leaf#60;/code#62;; nodes in the normalized AST."
class RSymbol~Info = NoInfo, T extends Identifier = Identifier~{
    <<interface>>
    type#58; RType.Symbol
    content#58; T
}
click RSymbol href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-symbol.ts#L13" "Represents identifiers (variables) such as #96;x#96; in #96;x #60;#45; 42#96; or #96;a#58;#58;foo#96; in #96;a#58;#58;foo()#96;. See; #60;code#62;Identifier#60;/code#62;; for more information about how identifiers are represented."
class RConstant~Info~{
    <<type>>
}
style RConstant opacity:.35,fill:#FAFAFA
click RConstant href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/model.ts#L118" "This subtype of; #60;code#62;RNode#60;/code#62;; represents all types of constants represented in the normalized AST."
class RNumber~Info = NoInfo~{
    <<interface>>
    type#58; RType.Number
    content#58; RNumberValue
}
click RNumber href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-number.ts#L11" "A number like #96;3#96;, #96;#45;2.14#96;, #96;1L#96;, or #96;2i#96;. Includes numeric, integer, and complex. See; #60;code#62;RNumberValue#60;/code#62;; for more information."
class RString~Info = NoInfo~{
    <<interface>>
    type#58; RType.String
    content#58; RStringValue
}
click RString href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-string.ts#L12" "Represents a string like #96;#34;hello#34;#96;, including raw strings like #96;r#34;(hello)#34;#96;."
class RLogical~Info = NoInfo~{
    <<interface>>
    type#58; RType.Logical
    content#58; boolean
}
click RLogical href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-logical.ts#L10" "Represents logical values (#96;TRUE#96; or #96;FALSE#96;)."
class RBreak~Info = NoInfo~{
    <<interface>>
    type#58; RType.Break
}
click RBreak href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-break.ts#L8" "A #96;break#96; statement."
class RNext~Info = NoInfo~{
    <<interface>>
    type#58; RType.Next
}
click RNext href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-next.ts#L8" "A #96;next#96; statement."
class RPipe~Info = NoInfo~{
    <<interface>>
    type#58; RType.Pipe
    lhs#58; RNode#60;Info#62;
    rhs#58; RNode#60;Info#62;
}
click RPipe href "https://github.com/flowr-analysis/flowr/tree/main/src/r-bridge/lang-4.x/ast/model/nodes/r-pipe.ts#L10" "Variant of the binary operator, specifically for the new, built#45;in pipe operator."
RExpressionList .. RNode
WithChildren <|-- RExpressionList
RAstNodeBase <|-- RExpressionList
MergeableRecord .. RAstNodeBase
Record .. MergeableRecord
string .. MergeableRecord
domain <|-- string
unknown .. MergeableRecord
Info .. RNode
LogLevel <|-- Info
RFunctions .. RNode
RFunctionDefinition .. RFunctions
RAstNodeBase <|-- RFunctionDefinition
Location <|-- RFunctionDefinition
Info .. RFunctions
RFunctionCall .. RFunctions
RNamedFunctionCall .. RFunctionCall
RAstNodeBase <|-- RNamedFunctionCall
Location <|-- RNamedFunctionCall
Info .. RFunctionCall
RUnnamedFunctionCall .. RFunctionCall
RAstNodeBase <|-- RUnnamedFunctionCall
Location <|-- RUnnamedFunctionCall
Info .. RFunctionCall
Info .. RFunctions
RParameter .. RFunctions
RAstNodeBase <|-- RParameter
Location <|-- RParameter
Info .. RFunctions
RArgument .. RFunctions
RAstNodeBase <|-- RArgument
Location <|-- RArgument
Info .. RFunctions
Info .. RNode
ROther .. RNode
RComment .. ROther
Location <|-- RComment
Leaf .. RComment
LeafRType .. Leaf
LeafVertexType .. Leaf
LeafSpecial .. Leaf
Info .. ROther
RLineDirective .. ROther
Location <|-- RLineDirective
Leaf .. RLineDirective
Info .. ROther
Info .. RNode
RConstructs .. RNode
RLoopConstructs .. RConstructs
RForLoop .. RLoopConstructs
RAstNodeBase <|-- RForLoop
Location <|-- RForLoop
Info .. RLoopConstructs
RRepeatLoop .. RLoopConstructs
RAstNodeBase <|-- RRepeatLoop
Location <|-- RRepeatLoop
Info .. RLoopConstructs
RWhileLoop .. RLoopConstructs
RAstNodeBase <|-- RWhileLoop
Location <|-- RWhileLoop
Info .. RLoopConstructs
Info .. RConstructs
RIfThenElse .. RConstructs
RAstNodeBase <|-- RIfThenElse
Location <|-- RIfThenElse
Info .. RConstructs
Info .. RNode
RNamedAccess .. RNode
RAccessBase <|-- RNamedAccess
RAstNodeBase <|-- RAccessBase
Location <|-- RAccessBase
Info .. RNode
RIndexAccess .. RNode
RAccessBase <|-- RIndexAccess
Info .. RNode
RUnaryOp .. RNode
RAstNodeBase <|-- RUnaryOp
Location <|-- RUnaryOp
Info .. RNode
RBinaryOp .. RNode
RAstNodeBase <|-- RBinaryOp
Location <|-- RBinaryOp
Info .. RNode
RSingleNode .. RNode
RComment .. RSingleNode
Info .. RSingleNode
RSymbol .. RSingleNode
Leaf .. RSymbol
Location <|-- RSymbol
Info .. RSingleNode
RConstant .. RSingleNode
RNumber .. RConstant
Leaf .. RNumber
Location <|-- RNumber
Info .. RConstant
RString .. RConstant
Leaf .. RString
Location <|-- RString
Info .. RConstant
RLogical .. RConstant
Leaf .. RLogical
Location <|-- RLogical
Info .. RConstant
Info .. RSingleNode
RBreak .. RSingleNode
Location <|-- RBreak
Leaf .. RBreak
Info .. RSingleNode
RNext .. RSingleNode
Location <|-- RNext
Leaf .. RNext
Info .. RSingleNode
RLineDirective .. RSingleNode
Info .. RSingleNode
Info .. RNode
RPipe .. RNode
RAstNodeBase <|-- RPipe
Location <|-- RPipe
Info .. RNode
Loading

Node types are controlled by the RType enum (see ./src/r-bridge/lang-4.x/ast/model/type.ts), which is used to distinguish between different types of nodes. Additionally, every AST node is generic with respect to the Info type which allows for arbitrary decorations (e.g., parent inforamtion or dataflow constraints). Most notably, the info field holds the id of the node, which is used to reference the node in the dataflow graph.

In summary, we have the following types:

Normalized AST Node Types
  • RNode
    The RNode type is the union of all possible nodes in the R-ast. It should be used whenever you either not care what kind of node you are dealing with or if you want to handle all possible nodes.

    All other subtypes (like RLoopConstructs ) listed above can be used to restrict the kind of node. They do not have to be exclusive, some nodes can appear in multiple subtypes.

    Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L268
    /**
     * The `RNode` type is the union of all possible nodes in the R-ast.
     * It should be used whenever you either not care what kind of
     * node you are dealing with or if you want to handle all possible nodes.
     * <p>
     *
     * All other subtypes (like {@link RLoopConstructs}) listed above
     * can be used to restrict the kind of node. They do not have to be
     * exclusive, some nodes can appear in multiple subtypes.
     * @see {@link recoverName} - to receive the name/lexeme from such a node
     * @see {@link recoverContent} - for a more rigorous approach to get the content of a node within a {@link DataflowGraph|dataflow graph}
     * @see {@link RNode.getLocation} - to get the location of a node and other helpful functions provided by the {@link RNode} helper object
     */
    export type RNode<Info = NoInfo>  = RExpressionList<Info> | RFunctions<Info>
        | ROther<Info> | RConstructs<Info> | RNamedAccess<Info> | RIndexAccess<Info>
        | RUnaryOp<Info> | RBinaryOp<Info> | RSingleNode<Info>  | RPipe<Info>;
    • RExpressionList
      Holds a list of expressions (and hence may be the root of an AST, summarizing all expressions in a file). The grouping property holds information on if the expression list is structural or created by a wrapper like {} or ().

      Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.ts#L10
      /**
       * Holds a list of expressions (and hence may be the root of an AST, summarizing all expressions in a file).
       * The `grouping` property holds information on if the expression list is structural or created by a wrapper like `{}` or `()`.
       */
      export interface RExpressionList<Info = NoInfo> extends WithChildren<Info, RNode<Info>>, RAstNodeBase<Info, string | undefined>, Partial<Location> {
          readonly type:     RType.ExpressionList;
          /** encodes wrappers like `{}` or `()` */
          readonly grouping: undefined | [start: RSymbol<Info>, end: RSymbol<Info>]
      }
      • RAstNodeBase
        Provides the common base of all RNodes .

        Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
        /**
         * Provides the common base of all {@link RNode|RNodes}.
         * @typeParam Info       - can be used to store additional information about the node
         * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
         */
        export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
            type:   RType
            /** the original string retrieved from R, can be used for further identification */
            lexeme: LexemeType
            /** allows to attach additional information to the node */
            info:   Info & Source
        }
    • RFunctions
      This subtype of RNode represents all types related to functions (calls and definitions) in the normalized AST.

      Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L216
      /**
       * This subtype of {@link RNode} represents all types related to functions
       * (calls and definitions) in the normalized AST.
       */
      export type RFunctions<Info>      = RFunctionDefinition<Info> | RFunctionCall<Info> | RParameter<Info> | RArgument<Info>;
      • RFunctionDefinition

        function(<parameters>) <body>

        or:

        \(<parameters>) <body>
        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.ts#L16
        /**
         * ```r
         * function(<parameters>) <body>
         * ```
         * or:
         * ```r
         * \(<parameters>) <body>
         * ```
         */
        export interface RFunctionDefinition<Info = NoInfo> extends RAstNodeBase<Info>, Location {
            readonly type: RType.FunctionDefinition;
            /** the R formals, to our knowledge, they must be unique */
            parameters:    RParameter<Info>[];
            body:          RNode<Info>;
        }
        • RAstNodeBase
          Provides the common base of all RNodes .

          Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
          /**
           * Provides the common base of all {@link RNode|RNodes}.
           * @typeParam Info       - can be used to store additional information about the node
           * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
           */
          export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
              type:   RType
              /** the original string retrieved from R, can be used for further identification */
              lexeme: LexemeType
              /** allows to attach additional information to the node */
              info:   Info & Source
          }
      • RFunctionCall

        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-function-call.ts#L38
        export type RFunctionCall<Info = NoInfo> = RNamedFunctionCall<Info> | RUnnamedFunctionCall<Info>;
        • RNamedFunctionCall
          Calls of functions like a() and foo(42, "hello").

          Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-function-call.ts#L15
          /**
           * Calls of functions like `a()` and `foo(42, "hello")`.
           * @see RUnnamedFunctionCall
           */
          export interface RNamedFunctionCall<Info = NoInfo> extends RAstNodeBase<Info>, Location {
              readonly type:      RType.FunctionCall;
              readonly named:     true;
              functionName:       RSymbol<Info>;
              /** arguments can be empty, for example when calling as `a(1, ,3)` */
              readonly arguments: readonly PotentiallyEmptyRArgument<Info>[];
          }
          • RAstNodeBase
            Provides the common base of all RNodes .

            Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
            /**
             * Provides the common base of all {@link RNode|RNodes}.
             * @typeParam Info       - can be used to store additional information about the node
             * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
             */
            export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
                type:   RType
                /** the original string retrieved from R, can be used for further identification */
                lexeme: LexemeType
                /** allows to attach additional information to the node */
                info:   Info & Source
            }
        • RUnnamedFunctionCall
          Direct calls of functions like (function(x) { x })(3).

          Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-function-call.ts#L28
          /**
           * Direct calls of functions like `(function(x) { x })(3)`.
           * @see RNamedFunctionCall
           */
          export interface RUnnamedFunctionCall<Info = NoInfo> extends RAstNodeBase<Info>, Location {
              readonly type:      RType.FunctionCall;
              readonly named:     false | undefined;
              calledFunction:     RNode<Info>; /* can be either a function definition or another call that returns a function etc. */
              /** marks function calls like `3 %xx% 4` which have been written in special infix notation; deprecated in v2 */
              infixSpecial?:      boolean;
              /** arguments can be undefined, for example when calling as `a(1, ,3)` */
              readonly arguments: readonly PotentiallyEmptyRArgument<Info>[];
          }
          • RAstNodeBase
            Provides the common base of all RNodes .

            Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
            /**
             * Provides the common base of all {@link RNode|RNodes}.
             * @typeParam Info       - can be used to store additional information about the node
             * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
             */
            export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
                type:   RType
                /** the original string retrieved from R, can be used for further identification */
                lexeme: LexemeType
                /** allows to attach additional information to the node */
                info:   Info & Source
            }
      • RParameter
        Represents a parameter of a function definition in R.

        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-parameter.ts#L10
        /**
         * Represents a parameter of a function definition in R.
         */
        export interface RParameter<Info = NoInfo> extends RAstNodeBase<Info>, Location {
            readonly type: RType.Parameter;
            /* the name is represented as a symbol to additionally get location information */
            name:          RSymbol<Info, BrandedIdentifier>;
            /** is it the special ... parameter? */
            special:       boolean;
            defaultValue:  RNode<Info> | undefined;
        }
        • RAstNodeBase
          Provides the common base of all RNodes .

          Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
          /**
           * Provides the common base of all {@link RNode|RNodes}.
           * @typeParam Info       - can be used to store additional information about the node
           * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
           */
          export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
              type:   RType
              /** the original string retrieved from R, can be used for further identification */
              lexeme: LexemeType
              /** allows to attach additional information to the node */
              info:   Info & Source
          }
      • RArgument
        Represents a named or unnamed argument of a function definition in R.

        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-argument.ts#L14
        /**
         * Represents a named or unnamed argument of a function definition in R.
         */
        export interface RArgument<Info = NoInfo> extends RAstNodeBase<Info>, Location {
            readonly type: RType.Argument;
            /* the name is represented as a symbol to additionally get location information */
            name:          RSymbol<Info, BrandedIdentifier> | undefined;
            value:         RNode<Info> | undefined;
        }
        • RAstNodeBase
          Provides the common base of all RNodes .

          Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
          /**
           * Provides the common base of all {@link RNode|RNodes}.
           * @typeParam Info       - can be used to store additional information about the node
           * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
           */
          export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
              type:   RType
              /** the original string retrieved from R, can be used for further identification */
              lexeme: LexemeType
              /** allows to attach additional information to the node */
              info:   Info & Source
          }
    • ROther
      This subtype of RNode represents all types of otherwise hard to categorize nodes in the normalized AST. At the moment these are the comment-like nodes.

      Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L239
      /**
       * This subtype of {@link RNode} represents all types of otherwise hard to categorize
       * nodes in the normalized AST. At the moment these are the comment-like nodes.
       */
      export type ROther<Info>          = RComment<Info> | RLineDirective<Info>;
    • RConstructs
      As an extension to RLoopConstructs , this subtype of RNode includes the RIfThenElse construct as well.

      Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L193
      /**
       * As an extension to {@link RLoopConstructs}, this subtype of {@link RNode} includes
       * the {@link RIfThenElse} construct as well.
       */
      export type RConstructs<Info>     = RLoopConstructs<Info> | RIfThenElse<Info>;
      • RLoopConstructs
        This subtype of RNode represents all looping constructs in the normalized AST.

        Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L170
        /**
         * This subtype of {@link RNode} represents all looping constructs in the normalized AST.
         */
        export type RLoopConstructs<Info> = RForLoop<Info> | RRepeatLoop<Info> | RWhileLoop<Info>;
        • RForLoop

          for(<variable> in <vector>) <body>
          Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.ts#L12
          /**
           * ```r
           * for(<variable> in <vector>) <body>
           * ```
           */
          export interface RForLoop<Info = NoInfo> extends RAstNodeBase<Info>, Location {
              readonly type: RType.ForLoop
              /** variable used in for-loop: <p> `for(<variable> in ...) ...`*/
              variable:      RSymbol<Info>
              /** vector used in for-loop: <p> `for(... in <vector>) ...`*/
              vector:        RNode<Info>
              /** body used in for-loop: <p> `for(... in ...) <body>`*/
              body:          RExpressionList<Info>
          }
          • RAstNodeBase
            Provides the common base of all RNodes .

            Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
            /**
             * Provides the common base of all {@link RNode|RNodes}.
             * @typeParam Info       - can be used to store additional information about the node
             * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
             */
            export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
                type:   RType
                /** the original string retrieved from R, can be used for further identification */
                lexeme: LexemeType
                /** allows to attach additional information to the node */
                info:   Info & Source
            }
        • RRepeatLoop

          repeat <body>
          Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.ts#L11
          /**
           * ```r
           * repeat <body>
           * ```
           */
          export interface RRepeatLoop<Info = NoInfo> extends RAstNodeBase<Info>, Location {
              readonly type: RType.RepeatLoop
              body:          RExpressionList<Info>
          }
          • RAstNodeBase
            Provides the common base of all RNodes .

            Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
            /**
             * Provides the common base of all {@link RNode|RNodes}.
             * @typeParam Info       - can be used to store additional information about the node
             * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
             */
            export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
                type:   RType
                /** the original string retrieved from R, can be used for further identification */
                lexeme: LexemeType
                /** allows to attach additional information to the node */
                info:   Info & Source
            }
        • RWhileLoop

          while(<condition>) <body>
          Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.ts#L11
          /**
           * ```r
           * while(<condition>) <body>
           * ```
           */
          export interface RWhileLoop<Info = NoInfo> extends RAstNodeBase<Info>, Location {
              readonly type: RType.WhileLoop
              condition:     RNode<Info>
              body:          RExpressionList<Info>
          }
          • RAstNodeBase
            Provides the common base of all RNodes .

            Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
            /**
             * Provides the common base of all {@link RNode|RNodes}.
             * @typeParam Info       - can be used to store additional information about the node
             * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
             */
            export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
                type:   RType
                /** the original string retrieved from R, can be used for further identification */
                lexeme: LexemeType
                /** allows to attach additional information to the node */
                info:   Info & Source
            }
      • RIfThenElse

        if(<condition>) <then> [else <otherwise>]
        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.ts#L11
        /**
         * ```r
         * if(<condition>) <then> [else <otherwise>]
         * ```
         */
        export interface RIfThenElse<Info = NoInfo> extends RAstNodeBase<Info>, Location {
            readonly type: RType.IfThenElse;
            condition:     RNode<Info>;
            then:          RExpressionList<Info>;
            otherwise?:    RExpressionList<Info>;
        }
        • RAstNodeBase
          Provides the common base of all RNodes .

          Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
          /**
           * Provides the common base of all {@link RNode|RNodes}.
           * @typeParam Info       - can be used to store additional information about the node
           * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
           */
          export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
              type:   RType
              /** the original string retrieved from R, can be used for further identification */
              lexeme: LexemeType
              /** allows to attach additional information to the node */
              info:   Info & Source
          }
    • RNamedAccess
      Represents an R named access operation with $ or @, the field is a string.

      Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-access.ts#L20
      /**
       * Represents an R named access operation with `$` or `@`, the field is a string.
       */
      export interface RNamedAccess<Info = NoInfo> extends RAccessBase<Info> {
          operator: '$' | '@';
          access:   [RUnnamedArgument<Info>];
      }
    • RIndexAccess
      access can be a number, a variable or an expression that resolves to one, a filter etc.

      Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-access.ts#L26
      /** access can be a number, a variable or an expression that resolves to one, a filter etc. */
      export interface RIndexAccess<Info = NoInfo> extends RAccessBase<Info> {
          operator: '[' | '[[';
          /** is null if the access is empty, e.g. `a[,3]` */
          access:   readonly (RArgument<Info> | typeof EmptyArgument)[]
      }
    • RUnaryOp
      Unary operations like + and -

      Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.ts#L10
      /**
       * Unary operations like `+` and `-`
       */
      export interface RUnaryOp<Info = NoInfo> extends RAstNodeBase<Info>, Location {
          readonly type: RType.UnaryOp;
          operator:      string;
          operand:       RNode<Info>;
      }
      • RAstNodeBase
        Provides the common base of all RNodes .

        Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
        /**
         * Provides the common base of all {@link RNode|RNodes}.
         * @typeParam Info       - can be used to store additional information about the node
         * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
         */
        export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
            type:   RType
            /** the original string retrieved from R, can be used for further identification */
            lexeme: LexemeType
            /** allows to attach additional information to the node */
            info:   Info & Source
        }
    • RBinaryOp
      Operators like +, ==, &&, etc.

      Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.ts#L10
      /**
       * Operators like `+`, `==`, `&&`, etc.
       */
      export interface RBinaryOp<Info = NoInfo> extends RAstNodeBase<Info>, Location {
          readonly type: RType.BinaryOp;
          operator:      string;
          lhs:           RNode<Info>;
          rhs:           RNode<Info>;
      }
      • RAstNodeBase
        Provides the common base of all RNodes .

        Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
        /**
         * Provides the common base of all {@link RNode|RNodes}.
         * @typeParam Info       - can be used to store additional information about the node
         * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
         */
        export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
            type:   RType
            /** the original string retrieved from R, can be used for further identification */
            lexeme: LexemeType
            /** allows to attach additional information to the node */
            info:   Info & Source
        }
    • RSingleNode
      This subtype of RNode represents all types of Leaf nodes in the normalized AST.

      Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L145
      /**
       * This subtype of {@link RNode} represents all types of {@link Leaf} nodes in the
       * normalized AST.
       */
      export type RSingleNode<Info>     = RComment<Info> | RSymbol<Info> | RConstant<Info> | RBreak<Info> | RNext<Info> | RLineDirective<Info>;
      • RComment

        # I am a line comment
        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-comment.ts#L10
        /**
         * ```r
         * # I am a line comment
         * ```
         */
        export interface RComment<Info = NoInfo> extends Location, Leaf<Info> {
            readonly type: RType.Comment;
        }
      • RSymbol
        Represents identifiers (variables) such as x in x <- 42 or a::foo in a::foo(). See Identifier for more information about how identifiers are represented.

        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-symbol.ts#L13
        /**
         * Represents identifiers (variables) such as `x` in `x <- 42` or `a::foo` in `a::foo()`.
         * See {@link Identifier} for more information about how identifiers are represented.
         * @typeParam Info - can be used to store additional information about the node
         * @typeParam T    - the type used to represent the identifier, by default {@link Identifier}
         */
        export interface RSymbol<Info = NoInfo, T extends Identifier = Identifier> extends Leaf<Info>, Location {
            readonly type: RType.Symbol;
            content:       T;
        }
      • RConstant
        This subtype of RNode represents all types of constants represented in the normalized AST.

        Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L118
        /**
         * This subtype of {@link RNode} represents all types of constants
         * represented in the normalized AST.
         */
        export type RConstant<Info>       = RNumber<Info> | RString<Info> | RLogical<Info>;
        • RNumber
          A number like 3, -2.14, 1L, or 2i. Includes numeric, integer, and complex. See RNumberValue for more information.

          Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-number.ts#L11
          /**
           * A number like `3`, `-2.14`, `1L`, or `2i`.
           * Includes numeric, integer, and complex.
           * See {@link RNumberValue} for more information.
           */
          export interface RNumber<Info = NoInfo> extends Leaf<Info>, Location {
              readonly type: RType.Number
              content:       RNumberValue
          }
        • RString
          Represents a string like "hello", including raw strings like r"(hello)".

          Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-string.ts#L12
          /**
           * Represents a string like `"hello"`, including raw strings like `r"(hello)"`.
           * @see {@link isRString} - to check whether a node is an R string
           */
          export interface RString<Info = NoInfo> extends Leaf<Info>, Location {
              readonly type: RType.String;
              content:       RStringValue;
          }
        • RLogical
          Represents logical values (TRUE or FALSE).

          Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-logical.ts#L10
          /**
           * Represents logical values (`TRUE` or `FALSE`).
           */
          export interface RLogical<Info = NoInfo> extends Leaf<Info>, Location {
              readonly type: RType.Logical
              content:       RLogicalValue
          }
      • RBreak
        A break statement.

        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-break.ts#L8
        /**
         * A `break` statement.
         */
        export interface RBreak<Info = NoInfo> extends Location, Leaf<Info> {
            readonly type: RType.Break;
        }
      • RNext
        A next statement.

        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-next.ts#L8
        /**
         * A `next` statement.
         */
        export interface RNext<Info = NoInfo> extends Location, Leaf<Info> {
            readonly type: RType.Next;
        }
      • RLineDirective
        Special comment to signal line mappings (e.g., in generated code) to the interpreter.

        Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.ts#L8
        /**
         * Special comment to signal line mappings (e.g., in generated code) to the interpreter.
         */
        export interface RLineDirective<Info = NoInfo> extends Location, Leaf<Info> {
            readonly type: RType.LineDirective;
            line:          number;
            file:          string;
        }
    • RPipe
      Variant of the binary operator, specifically for the new, built-in pipe operator.

      Defined at src/r-bridge/lang-4.x/ast/model/nodes/r-pipe.ts#L10
      /**
       * Variant of the binary operator, specifically for the new, built-in pipe operator.
       */
      export interface RPipe<Info = NoInfo> extends RAstNodeBase<Info>, Location {
          readonly type: RType.Pipe;
          readonly lhs:  RNode<Info>;
          readonly rhs:  RNode<Info>;
      }
      • RAstNodeBase
        Provides the common base of all RNodes .

        Defined at src/r-bridge/lang-4.x/ast/model/model.ts#L73
        /**
         * Provides the common base of all {@link RNode|RNodes}.
         * @typeParam Info       - can be used to store additional information about the node
         * @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
         */
        export interface RAstNodeBase<Info, LexemeType = string> extends MergeableRecord {
            type:   RType
            /** the original string retrieved from R, can be used for further identification */
            lexeme: LexemeType
            /** allows to attach additional information to the node */
            info:   Info & Source
        }

The following segments intend to give you an overview of how to work with the normalized AST:

Tip

If you want to get more information on roxygen comments attached to AST nodes, check out parseRoxygenCommentsOfNode.

How to Get a Normalized AST

As explained alongside the Interface wiki page, you can use an instance of FlowrAnalyzer to get the NormalizedAst:

const analyzer = await new FlowrAnalyzerBuilder().build();
analyzer.addRequest(code);
const result = await analyzer.normalize();

From the REPL, you can use the :normalize command.

Multi-File Projects

With the FlowrAnalyzer, you can analyze multiple files at once:

const analyzer = await new FlowrAnalyzerBuilder()
    .setEngine('tree-sitter')
    .build();
analyzer.addFile(new FlowrInlineTextFile('foo.R', 'x <- 12; source("a.R")'));
analyzer.addFile(new FlowrInlineTextFile('a.R', 'y <- x + 3'));
analyzer.addFile(new FlowrInlineTextFile('b.R', 'print(x, y)'));
analyzer.addRequest(
    { request: 'file', content: 'a.R' },
    { request: 'file', content: 'b.R' },
    { request: 'file', content: 'foo.R' }
);
const n = await analyzer.normalize();

Visualizing the resulting AST yields the following.

Mermaid Diagram
flowchart LR
    subgraph "File: a.R"
    direction LR
    n5(["RExpressionList (5)
 "])
    n4(["RBinaryOp (4)
#60;#45;"])
    n5 -->|"el-c-0"| n4
    n0(["RSymbol (0)
y"])
    n4 -->|"bin-l"| n0
    n3(["RBinaryOp (3)
#43;"])
    n4 -->|"bin-r"| n3
    n1(["RSymbol (1)
x"])
    n3 -->|"bin-l"| n1
    n2(["RNumber (2)
3"])
    n3 -->|"bin-r"| n2
    end
    subgraph "File: b.R"
    direction LR
    n12(["RExpressionList (12)
 "])
    n11(["RFunctionCall (11)
print"])
    n12 -->|"el-c-0"| n11
    n6(["RSymbol (6)
print"])
    n11 -->|"call-name"| n6
    n8(["RArgument (8)
x"])
    n11 -->|"call-arg-1"| n8
    n7(["RSymbol (7)
x"])
    n8 -->|"arg-v"| n7
    n10(["RArgument (10)
y"])
    n11 -->|"call-arg-2"| n10
    n9(["RSymbol (9)
y"])
    n10 -->|"arg-v"| n9
    end
    subgraph "File: foo.R"
    direction LR
    n20(["RExpressionList (20)
 "])
    n15(["RBinaryOp (15)
#60;#45;"])
    n20 -->|"el-c-0"| n15
    n13(["RSymbol (13)
x"])
    n15 -->|"bin-l"| n13
    n14(["RNumber (14)
12"])
    n15 -->|"bin-r"| n14
    n19(["RFunctionCall (19)
source"])
    n20 -->|"el-c-1"| n19
    n16(["RSymbol (16)
source"])
    n19 -->|"call-name"| n16
    n18(["RArgument (18)
#34;a.R#34;"])
    n19 -->|"call-arg-1"| n18
    n17(["RString (17)
#34;a.R#34;"])
    n18 -->|"arg-v"| n17
    end

Loading

Traversing the Normalized AST

We provide a visitor to traverse the normalized AST. Please note, that it usually operates on the RExpressionList level, and it is up to you to decide how you want to traverse multiple files with a RProject in the AST (you can, for example, simplify flat-map over the files). The RProject node cannot appear nested within other nodes, so you can safely assume that any child of a node is not an RProject.

Tip

When working with names and identifiers, consider using the utilities provided with the Identifier object.

Visitors

If you want a simple visitor which traverses the AST, the RNode::visitAst function is a good starting point. You may specify functions to be called whenever you enter and exit a node during the traversal, and any computation is to be done by side effects. For example, if you want to collect all the ids present within a normalized (sub-)AST, as it is done by the RNode::collectAllIds (and corresponding RNode::collectAllIdsWithStop, RProject::collectAllIds, ...) function, you can use the following visitor:

const ids = new Set<NodeId>();
visitAst(nodes, node => {
    ids.add(node.info.id);
});
return ids;

Stateful Fold

A stateful fold over the normalized AST can be performed with the foldAstStateful function. It allows you to specify a down function which is called during the down-pass and can pass information to child nodes, and fold functions which are called after the down-pass in conventional fold-fashion.

Clone this wiki locally