Skip to content

Analyzer

github-actions[bot] edited this page Sep 3, 2026 · 1 revision

Generated from 'wiki-analyzer.ts' on 2026-09-01, 11:38:13 UTC (v2.15.8, R v4.6.1), please do not edit directly.

Overview

No matter whether you want to analyze a single R script, a couple of R notebooks, a complete project, or an R package, your journey starts with the FlowrAnalyzerBuilder (further described in Builder Configuration below). This builder allows you to configure the analysis in many different ways, for example, by specifying which plugins to use or what engine to use for the analysis.

When building the FlowrAnalyzer instance, the builder will take care to

The builder provides two methods for building the analyzer:

  • FlowrAnalyzerBuilder::build
    for an asynchronous build process that also initializes the engine if needed

  • FlowrAnalyzerBuilder::buildSync
    for a synchronous build process, which requires that the engine (e.g., TreeSitter) has already been initialized before calling this method. Yet, as Engines only have to be initialized once per process, this method is often more convenient to use.

    For more information on how to configure the builder, please refer to the Builder Configuration section below.

Overview of the Analyzer

Once you have created an analyzer instance, you can add R files, folders, or even entire projects for analysis using the FlowrAnalyzer::addRequest method. All loaded plugins will be applied fully automatically during the analysis. Please note that adding new files after you already requested analysis results may cause bigger invalidations and cause re-analysis of previously analyzed files. With the files context, you can also add virtual files to the analysis to consider, or overwrite existing files with modified content. For this, have a look at the FlowrAnalyzer::addFile method.

Note

If you want to quickly try out the analyzer, you can use the following code snippet that analyzes a simple R expression:

const analyzer = await new FlowrAnalyzerBuilder()
    .setEngine('tree-sitter')
    .build();
// register a simple inline text-file for analysis
analyzer.addRequest('x <- 1; print(x)');
// get the dataflow
const df = await analyzer.dataflow();
// obtain the identified loading order
console.log(analyzer.inspectContext().files.loadingOrder.getLoadingOrder());
// run a dependency query
const results = await analyzer.query([{ type: 'dependencies' }]);

To reset the analysis (e.g., to provide new requests) you can use FlowrAnalyzer::reset. If you need to pre-compute analysis results (e.g., to speed up future queries), you can use FlowrAnalyzer::runFull.

Conducting Analyses

Please make sure to add all of the files, folder, and projects you want to analyze using the FlowrAnalyzer::addRequest method (or FlowrAnalyzer::addFile for virtual files). Afterwards, you can request different kinds of analysis results, such as:

We work on providing a set of example repositories that demonstrate how to use the analyzer in different scenarios:

Builder Configuration

If you are interested in all available options, have a look at the Builder Reference below. The following sections highlight some of the most important configuration options:

  1. How to configure flowR
  2. How to configure the engine
  3. How to register plugins

Configuring flowR

You can fundamentally change the behavior of flowR using the config file, embedded in the interface FlowrConfig. With the builder you can either provide a complete configuration or amend the default configuration using:

By default, the builder uses flowR's standard configuration obtained with FlowrConfig::default.

Note

During the analysis with the FlowrAnalyzer, you can also access the configuration with the FlowrAnalyzerContext.

Configuring the Engine

FlowR supports multiple engines for parsing and analyzing R code. With the builder, you can select the engine to use with:

By default, the builder uses the TreeSitter engine with the TreeSitter parser. The builder also takes care to initialize the engine if needed during the asynchronous build process with FlowrAnalyzerBuilder::build. If you want to use the synchronous build process with FlowrAnalyzerBuilder::buildSync, please ensure that the engine has already been initialized before calling this method.

Configuring Plugins

There are various ways for you to register plugins with the builder, exemplified by the following snippet relying on the FlowrAnalyzerBuilder::registerPlugins method:

const analyzer = await new FlowrAnalyzerBuilder(false)
    .registerPlugins(
        'file:description',
        new FlowrAnalyzerQmdFilePlugin(),
        ['file:rmd', [/.*.rmd/i]]
    )
    .build();

This indicates three ways to add a new plugin:

  1. By using a predefined name (e.g., file:description for the FlowrAnalyzerDescriptionFilePlugin)
    These mappings are controlled by the registerPluginMaker function in the PluginRegistry. Under the hood, this relies on makePlugin to create the plugin instance from the name.
  2. By providing an already instantiated plugin (e.g., the new FlowrAnalyzerQmdFilePlugin instance).
    You can pass these by reference, instantiating any class that conforms to the plugin specification.
  3. By providing a tuple of the plugin name and its constructor arguments (e.g., ['file:rmd', [/.*.rmd/i]] for the FlowrAnalyzerRmdFilePlugin).
    This will also use the makePlugin function under the hood to create the plugin instance.

Please note, that by passing false to the builder constructor, no default plugins (see FlowrDefaultPlugins) are registered (otherwise, all of the plugins in the example above would be registered by default). If you want to unregister specific plugins, you can use the FlowrAnalyzerBuilder::unregisterPlugins method.

Note

If you directly access the API, please prefer creating the objects yourself by instantiating the respective classes instead of relying on the plugin registry. This avoids the indirection and potential issues with naming collisions in the registry. Moreover, this allows you to directly provide custom configuration to the plugin constructors in a readable fashion, and to re-use plugin instances. Instantiation by text is mostly for serialized communications (e.g., via a CLI or config format).

For more information on the different plugin types and how to create new plugins, please refer to the Plugins section below.

Builder Reference

The builder provides a plethora of methods to configure the resulting analyzer instance:

  • FlowrAnalyzerBuilder::amendConfig
    Apply an amendment to the configuration the builder currently holds. This is mostly intended for more complex logic to transform the config. Please consider using FlowrAnalyzerBuilder.configure to set/amend individual values Per default, the value returned by FlowrConfig.default is used.
  • FlowrAnalyzerBuilder::configure
    Set a specific value in the configuration used by the resulting analyzer. Besides the configuration's own paths this takes an EngineConfigPath , so an engine option that lives in an array entry is reachable the same way as everything else:
  • FlowrAnalyzerBuilder::registerPlugins
    Register one or multiple additional plugins. For the default plugin set, please refer to FlowrDefaultPlugins , they can be registered by passing true to the FlowrAnalyzerBuilder constructor.
  • FlowrAnalyzerBuilder::setConfig
    Overwrite the configuration used by the resulting analyzer. This also unloads all default plugins and reloads them as set in the new config if the withDefaultPlugins flag was set in the constructor
  • FlowrAnalyzerBuilder::setEngine
    Set the engine and hence the parser that will be used by the analyzer. This is an alternative to FlowrAnalyzerBuilder#setParser if you do not have a parser instance at hand.
  • FlowrAnalyzerBuilder::setInput
    Additional parameters for the analyses.
  • FlowrAnalyzerBuilder::setParser
    Set the parser instance used by the analyzer. This is an alternative to FlowrAnalyzerBuilder#setEngine if you already have a parser instance. Please be aware, that if you want to parallelize multiple analyzers, there should be separate parser instances.
  • FlowrAnalyzerBuilder::unregisterPlugins
    Remove one or multiple plugins.

To build the analyzer after you have configured the builder, you can use one of the following:

  • FlowrAnalyzerBuilder::build
    Create the FlowrAnalyzer instance using the given information. Please note that the only reason this is async is that if no parser is set, we need to retrieve the default engine instance which is an async operation. If you have already initialized the engine (e.g., with TreeSitterExecutor#initTreeSitter ), you can use the synchronous version FlowrAnalyzerBuilder#buildSync instead.
  • FlowrAnalyzerBuilder::buildSync
    Synchronous version of FlowrAnalyzerBuilder#build , please only use this if you have set the parser using FlowrAnalyzerBuilder#setParser before, otherwise an error will be thrown.

Plugins

Plugins allow you to extend the capabilities of the analyzer in many different ways. For example, they can be used to support other file formats, or to provide new algorithms to determine the loading order of files in a project. All plugins have to extend the FlowrAnalyzerPlugin base class and specify their PluginType. During the analysis, the analyzer will apply all registered plugins of the different types at the appropriate stages of the analysis. If you just want to use these plugins, you can usually ignore their type and just register them with the builder as described in the Builder Configuration section above. However, if you want to create new plugins, you should be aware of the different plugin types and when they are applied during the analysis.

Currently, flowR supports the following plugin types built-in:

Name Type What it does Class
file-roles:inst file-load Loads installed files. FlowrAnalyzerMetaInstFilesPlugin
file-roles:test file-load Loads test files. FlowrAnalyzerMetaTestFilesPlugin
file-roles:vignette file-load Loads vignette files. FlowrAnalyzerMetaVignetteFilesPlugin
file:datalist file-load Reads data/datalist into the objects each dataset provides. FlowrAnalyzerDataListFilePlugin
file:description file-load Reads DESCRIPTION files into key-value pairs. FlowrAnalyzerDescriptionFilePlugin
file:ipynb file-load Parses Jupyter files FlowrAnalyzerJupyterFilePlugin
file:license file-load Loads license files. FlowrAnalyzerLicenseFilePlugin
file:namespace file-load Reads NAMESPACE files into the NAMESPACE format. FlowrAnalyzerNamespaceFilesPlugin
file:news file-load Reads NEWS files into version chunks. FlowrAnalyzerNewsFilePlugin
file:qmd file-load Parses Quarto R Markdown files FlowrAnalyzerQmdFilePlugin
file:rd file-load Reads .Rd manual pages into the Rd page format. FlowrAnalyzerRdFilePlugin
file:rd-index file-load Reads an installed package's help/AnIndex into the alias-to-topic mapping. FlowrAnalyzerRdIndexFilePlugin
file:rd-macros file-load Reads the \newcommand definitions of man/macros/ files. FlowrAnalyzerRdMacroFilePlugin
file:rd-meta file-load Reads an installed package's Meta/Rd.rds help table. FlowrAnalyzerRdMetaFilePlugin
file:rd-topics file-load Reads INDEX/00Index topic tables into their topic-to-title mapping. FlowrAnalyzerRdTopicIndexFilePlugin
file:rda file-load Reads RDA/RData workspace files into their contained R objects. FlowrAnalyzerRdaFilePlugin
file:rmd file-load Parses R Markdown files FlowrAnalyzerRmdFilePlugin
file:rnw file-load Parses R Sweave files FlowrAnalyzerSweaveFilePlugin
file:rprofile file-load Marks R startup files (.Rprofile, Rprofile.site, .Renviron, Renviron.site). FlowrAnalyzerRprofileFilePlugin
file:rproject file-load Marks the rproject.toml manifest of an rv project. FlowrAnalyzerRProjectFilePlugin
file:sysdata file-load Reads R/sysdata.rda into the objects it lazy-loads into the package namespace. FlowrAnalyzerSysdataFilePlugin
file:uvr file-load Marks the uvr.toml manifest of a uvr project. FlowrAnalyzerUvrManifestFilePlugin
file:virtualenv file-load Marks virtual-environment lockfiles (renv.lock, rv.lock, uvr.lock). FlowrAnalyzerVirtualEnvFilePlugin
loading-order:description loading-order Orders the files by the Collate field of a DESCRIPTION file. FlowrAnalyzerLoadingOrderDescriptionFilePlugin
loading-order:implicit-sources loading-order Orders the files a framework loads implicitly, as configured by project.implicitSources. FlowrAnalyzerLoadingOrderImplicitSourcesPlugin
loading-order:included-files loading-order Drops files that another document includes from the loading order. FlowrAnalyzerLoadingOrderIncludedFilesPlugin
loading-order:rprofile loading-order Loads the R startup profiles (.Rprofile, Rprofile.site) before any project code. FlowrAnalyzerLoadingOrderRprofilePlugin
meta:description package-versions Extracts package meta information from DESCRIPTION files. FlowrAnalyzerMetaDescriptionFilePlugin
meta:rproject package-versions Extracts project meta information and dependencies from an rproject.toml. FlowrAnalyzerMetaRProjectFilePlugin
meta:uvr package-versions Extracts project meta information and dependencies from a uvr.toml. FlowrAnalyzerMetaUvrManifestFilePlugin
project-discovery:default project-discovery Detects the project kind and discovers only the files it needs (unless project.discovery.full). FlowrAnalyzerDefaultProjectDiscoveryPlugin
project-discovery:full project-discovery Collects every file below the project root (greedy discovery). FlowrAnalyzerFullProjectDiscoveryPlugin
project-discovery:gitignore project-discovery Wraps a project discovery plugin and filters results by .gitignore rules. FlowrAnalyzerGitignoreProjectDiscoveryPlugin
project-discovery:ignore-files project-discovery Wraps a project discovery plugin and filters results by .gitignore and .Rbuildignore rules. FlowrAnalyzerIgnoreFileProjectDiscoveryPlugin
project-discovery:rbuildignore project-discovery Wraps a project discovery plugin and filters results by .Rbuildignore rules. FlowrAnalyzerRbuildignoreProjectDiscoveryPlugin
versions:description package-versions Extracts package versions from DESCRIPTION files. FlowrAnalyzerPackageVersionsDescriptionFilePlugin
versions:library package-versions Recovers the exports of packages no database knows from their installed copy. FlowrAnalyzerPackageVersionsLibraryPlugin
versions:namespace package-versions Extracts package versions from NAMESPACE files. FlowrAnalyzerPackageVersionsNamespaceFilePlugin
versions:packrat package-versions Extracts package versions from a packrat.lock lockfile. FlowrAnalyzerPackageVersionsPackratPlugin
versions:renv package-versions Extracts package versions from an renv.lock lockfile. FlowrAnalyzerPackageVersionsRenvPlugin
versions:rv package-versions Extracts package versions from an rv.lock lockfile. FlowrAnalyzerPackageVersionsRvPlugin
versions:session-info package-versions Extracts package and R versions from a pasted sessionInfo() output block. FlowrAnalyzerPackageVersionsSessionInfoPlugin
versions:sigdb package-versions Resolves library exports (and versioned base R) from precomputed flowr-sigdb databases. FlowrAnalyzerPackageVersionsSigDbPlugin
versions:uvr package-versions Extracts package versions from a uvr.lock lockfile. FlowrAnalyzerPackageVersionsUvrPlugin

Plugin Types

During the construction of a new FlowrAnalyzer, plugins of different types are applied at different stages of the analysis. These plugins are grouped by their PluginType and are applied in the following order (as shown in the documentation of the PluginType):

┌───────────┐   ┌───────────────────┐   ┌─────────────┐   ┌───────────────┐   ┌───────┐
│           │   │                   │   │             │   │               │   │       │
│ *Builder* ├──>│ Project Discovery ├──>│ File Loader ├──>│ Dependencies  ├──>│ *DFA* │
│           │   │  (if necessary)   │   │             │   │   (static)    │   │       │
└───────────┘   └───────────────────┘   └──────┬──────┘   └───────────────┘   └────┬──┘
                                               │                                  ▲│
                                               │          ┌───────────────┐       ││
                                               │          │               │       ││ on-demand
                                               └─────────>│ Loading Order ├───────┘│
                                                          │               │        │  ┌───────────┐
                                                          └───────────────┘        └─>│    Gas    │
                                                                                      └───────────┘

Please note, that every plugin type has a default implementation (e.g., see defaultPlugin) that is always active. We describe the different plugin types in more detail below.

Project Discovery

These plugins trigger when confronted with a project analysis request (see, RProjectAnalysisRequest). Their job is to identify the files that belong to the project and add them to the analysis. flowR provides the FlowrAnalyzerProjectDiscoveryPlugin with a defaultPlugin as the default implementation that simply collects all R source files in the given folder.

Please note that all project discovery plugins should conform to the FlowrAnalyzerProjectDiscoveryPlugin base class.

File Loading

These plugins register for every file encountered by the files context and determine whether and how they can process the file. They are responsible for transforming the raw file content into a representation that flowR can work with during the analysis. For example, the FlowrAnalyzerDescriptionFilePlugin adds support for R DESCRIPTION files by parsing their content into key-value pairs. These can then be used by other plugins, e.g. the FlowrAnalyzerPackageVersionsDescriptionFilePlugin that extracts package version information from these files.

If multiple file plugins could apply (DefaultFlowrAnalyzerFilePlugin::applies) to the same file, the loading order of these plugins determines which plugin gets to process the file. Please ensure that no two file plugins apply to the same file, as this could lead to unexpected behavior. Also, make sure that all file plugins conform to the FlowrAnalyzerFilePlugin base class.

Dependency Identification

These plugins should identify which R packages are required with which versions for the analysis. This information is then used to setup the R environment for the analysis correctly. For example, the FlowrAnalyzerPackageVersionsDescriptionFilePlugin extracts package version information from DESCRIPTION files to identify the required packages and their versions.

All dependency identification plugins should conform to the FlowrAnalyzerPackageVersionsPlugin base class.

Loading Order

These plugins determine the order in which files are loaded and analyzed. This is crucial for correctly understanding the dependencies between files and improved analyses, especially in larger projects. For example, the FlowrAnalyzerLoadingOrderDescriptionFilePlugin provides a basic implementation that orders files based on the specification in a DESCRIPTION file, if present.

All loading order plugins should conform to the FlowrAnalyzerLoadingOrderPlugin base class.

How to add a new plugin

If you want to make a new plugin you first have to decide which type of plugin you want to create (see Plugin Types above). Then, you must create a new class that extends the corresponding base class (e.g., FlowrAnalyzerFilePlugin for file loading plugins). In general, most plugins operate on the context information provided by the analyzer. Usually it is a good idea to have a look at the existing plugins of the same type to get an idea of how to implement your own plugin.

Once you have your plugin you should register it with a sensible name using the registerPluginMaker function. This will allow users to register your plugin easily by name using the builder's FlowrAnalyzerBuilder::registerPlugins method. Otherwise, users will have to provide an instance of your plugin class directly.

Context Information

The FlowrAnalyzer provides various context information during the analysis. You can access the context with FlowrAnalyzer::inspectContext to receive a read-only view of the current analysis context. Likewise, you can use FlowrAnalyzerContext::inspect to get a read-only view of a given context. These read-only views prevent you from accidentally modifying the context during the analysis which may cause inconsistencies (this should be done either by wrapping methods or by plugins). The context is divided into multiple sub-contexts, each responsible for a specific aspect of the analysis. These sub-contexts are described in more detail below.

For the general structure from an implementation perspective, please have a look at FlowrAnalyzerContext.

Tip

If you need a context for testing or to create analyses with lower-level components, you can use either contextFromInput to create a context from input data (which lifts the old requestFromInput) or contextFromSources to create a context from source files (e.g., if you need a virtual file system).

If for whatever reason you need to reset the context during an analysis, you can use FlowrAnalyzerContext::reset.

Files Context

First, let's have look at the FlowrAnalyzerFilesContext class that provides access to the files to be analyzed and their loading order:

Using the available plugins, the files context categorizes files by their FileRole (e.g., source files or DESCRIPTION files) and makes them accessible by these roles (e.g., via FlowrAnalyzerFilesContext::getFilesByRole). It also provides methods to check for whether a file exists (e.g., FlowrAnalyzerFilesContext::hasFile, FlowrAnalyzerFilesContext::exists) and to translate requests so they respect the context (e.g., FlowrAnalyzerFilesContext::resolveRequest).

For legacy reasons it also provides the list of files considered by the dataflow analysis via FlowrAnalyzerFilesContext::consideredFilesList.

Loading Order Context

Note

Please be aware that the loading order is inherently tied to the files context (as it determines which files are available for ordering). Hence, the FlowrAnalyzerLoadingOrderContext is accessible (only) via the FlowrAnalyzerFilesContext.

Here is the structure of the FlowrAnalyzerLoadingOrderContext that provides access to the identified loading order of files:

  • FlowrAnalyzerLoadingOrderContext
    This context is responsible for managing the loading order of script files in a project, including guesses and known orders provided by FlowrAnalyzerLoadingOrderPlugin s. If you are interested in inspecting these orders, refer to ReadOnlyFlowrAnalyzerLoadingOrderContext . Plugins, however, can use this context directly to modify order guesses.
    (Defined at src/project/context/flowr-analyzer-loading-order-context.ts#L50)

    View more (AbstractFlowrAnalyzerContext, ReadOnlyFlowrAnalyzerLoadingOrderContext)
    • AbstractFlowrAnalyzerContext
      Abstract class representing the context, a context may be modified and enriched by plugins (see FlowrAnalyzerPlugin ). Please use the specialized contexts like FlowrAnalyzerFilesContext or FlowrAnalyzerLoadingOrderContext to work with flowR and in general, use the FlowrAnalyzerContext to access the full project context.
      (Defined at src/project/context/abstract-flowr-analyzer-context.ts#L12)

    • ReadOnlyFlowrAnalyzerLoadingOrderContext
      Read-only interface for the loading order context, which is used to determine the order in which script files are loaded in a project. This interface prevents you from modifying the available files, but allows you to inspect them (which is probably what you want when using the FlowrAnalyzer ). If you are a FlowrAnalyzerLoadingOrderPlugin and want to modify the available orders, you can use the FlowrAnalyzerLoadingOrderContext directly.
      (Defined at src/project/context/flowr-analyzer-loading-order-context.ts#L14)

Using the available plugins, the loading order context determines the order in which files are loaded and analyzed by flowR's analyzer. You can inspect the identified loading order using FlowrAnalyzerLoadingOrderContext::getLoadingOrder. If there are multiple possible loading orders (e.g., due to circular dependencies), you can use FlowrAnalyzerLoadingOrderContext::currentGuesses.

Dependencies Context

Here is the structure of the FlowrAnalyzerDependenciesContext that provides access to the identified dependencies and their versions, including the version of R:

Probably the most important method is FlowrAnalyzerDependenciesContext::getDependency that allows you to query for a specific dependency by name.

Functions Context

The FlowrAnalyzerDependenciesContext also provides access to the associated FlowrAnalyzerFunctionsContext via its functionsContext attribute.

  • FlowrAnalyzerFunctionsContext
    This context is responsible for managing the functions identified in the project, including their origins, types, and other metadata. It works in conjunction with FlowrAnalyzerPackageVersionsPlugin s to gather and maintain this information. If you are interested in inspecting these functions, refer to ReadOnlyFlowrAnalyzerFunctionsContext .
    (Defined at src/project/context/flowr-analyzer-functions-context.ts#L49)

    View more (AbstractFlowrAnalyzerContext, ReadOnlyFlowrAnalyzerFunctionsContext)

Probably the most important method is FlowrAnalyzerFunctionsContext::getFunctionInfo that allows you to query for a specific function by name.

Environment Context

Here is the structure of the FlowrAnalyzerEnvironmentContext that provides access to the built-in environment:

The environment context provides access to the built-in environment via FlowrAnalyzerEnvironmentContext::makeCleanEnv. It also provides the empty built-in environment, which only contains primitives, via FlowrAnalyzerEnvironmentContext::makeCleanEnvWithEmptyBuiltIns.

Meta Context

This FlowrAnalyzerMetaContext provides access to the project metadata such as name, version, and namespace:

You can access the project name via FlowrAnalyzerMetaContext::getProjectName, the project version via FlowrAnalyzerMetaContext::getProjectVersion, and the project namespace via FlowrAnalyzerMetaContext::getNamespace.

Gas Context

The FlowrAnalyzerGasContext (reachable as ctx.gas) acts as the resource guard of an analysis:

Expensive analysis sites ask for the current resource pressure with FlowrAnalyzerGasContext::checkGas, passing the name of the feature they are about to run (see GasFeatureKey), and may then degrade or skip their work. The level combines the current heap usage and the time elapsed within the contingent of the current operation, each scaled by the per-feature factor from config.gas.features and compared against the thresholds configured for that key (see GasThresholdSpec). Registered FlowrAnalyzerGasPlugins may escalate the level for any key.

Every operation gets a contingent of its own, and anything beginning a new analysis (an added file, a cache invalidation, a FlowrAnalyzerContext::reset) restarts it. To restart it between your own phases, call FlowrAnalyzerGasContext::reset on the writeable context (analyzer.context().gas.reset()). To bound a single call, pass gas overrides to it (analyzer.query([...], { gas: { slicer: { critical: 30_000 } } })) or derive a bounded view with FlowrAnalyzerGasContext::scope.

Note

Gas is disabled for every feature by default, and with no gas plugins registered FlowrAnalyzerGasContext::checkGas returns GasLevel.Normal without measuring anything. See the gas section of the Core wiki page for the levels, the configuration, and how to write a gas plugin.

Incremental Analysis Context

The FlowrAnalyzerIncrementalAnalysisContext is a context that stores analysis information needed for making the next analysis run incremental by reusing the previous analysis results:

This context is not an analysis-result cache by itself. Instead, it carries forward the minimal state needed by future incremental phases after an invalidation happened. At the moment, it is used for incremental parsing with Tree-sitter, but it is intended to become the shared context for additional incremental analysis stages as well.

If the analyzer or context is reset, the incremental information is discarded via FlowrAnalyzerIncrementalAnalysisContext::reset. In other words, this context only transports incremental handoff state between analysis runs.

Incremental Parsing

This context is used to exploit Tree-sitter's incremental parsing feature. For one file, the incremental state follows a fixed lifecycle:

  1. After a successful parse-oriented analysis run, the analyzer cache stores the latest Tree-sitter parse tree via FlowrAnalyzerIncrementalAnalysisContext::storeOldParseResults. This tree is the baseline for the next incremental parse of that file.

  2. When a mutable file provider such as FlowrInlineTextFile is invalidated via FlowrFile::invalidate, the analyzer receives a file invalidation event and stores the file path together with the old source text. If the same file is invalidated again before the next parse, this stored old text is intentionally not replaced: the stored parse tree still belongs to the version from before the first invalidation, so the incremental parse must keep that matching old-content baseline.

  3. When parsing is requested again, flowR retrieves

    Using these together with the current file content, computeEditRegion derives a minimal tree-sitter Parser.Edit, only when a new parse is actually requested. If the file content did not change, the previous tree can be reused directly. Otherwise, the edit is applied to the previous tree and Tree-sitter reparses incrementally instead of starting from scratch.

  4. The stored old-content entry is removed when it is used because it belongs only to that previous parse snapshot. After the new parse succeeds, the analyzer stores a new parse tree baseline. A later invalidation must then be able to record a fresh old-content value that matches this new tree. If the old-content entry were kept, later invalidations of the same file would not replace it, and the next incremental parse could compare the current file content against stale old text that no longer matches the stored previous tree.

Incremental Dataflow

This context is planned to also support future incremental dataflow graph computation.

Caching

To speed up analyses, flowR provides a caching mechanism that stores intermediate results of the analysis. The cache is maintained by the FlowrAnalyzerCache class and is used automatically by the analyzer during the analysis. Underlying, it relies on the PipelineExecutor to cache results of different pipeline stages.

Usually, you do not have to worry about the cache, as it is managed automatically by the analyzer. If you want to overwrite cache information, the analysis methods in FlowrAnalyzer (see Conducting Analyses above) usually provide an optional force parameter to control whether to use the cache or recompute the results.

Clone this wiki locally