UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

166 lines (165 loc) 8.42 kB
import type { PathLike } from 'fs'; import type { RParseRequest } from '../../r-bridge/retriever'; import type { InvalidationEventHandler } from '../cache/flowr-cache'; /** * Just a readable alias for file paths, mostly for documentation purposes. * We separate {@link PathLike} types from string paths that are used for project paths. */ export type FilePath = string; /** * Some files have a special meaning in R projects, e.g., the `DESCRIPTION` file in R packages. * This list may be extended in the future and reflects files that the {@link FlowrAnalyzer} can do something interesting with. * If you add an interesting file that is only part of your plugin infrastructure, please use the `other` role. */ export declare enum FileRole { /** The `DESCRIPTION` file in R packages, this is the only currently supported special file. */ Description = "description", /** The `NAMESPACE` file in R packages, currently not specially supported. */ Namespace = "namespace", /** The `NEWS` file in R packages */ News = "news", /** Vignette files, e.g., R Markdown files in the `vignettes/` folder */ Vignette = "vignette", /** Test source files, e.g., files in the `tests/` folder */ Test = "test", /** * Files below an `inst/` folder, which R installs verbatim into the package root (resources/scripts, e.g., `inst/REFERENCES.R`, `inst/CITATION`, `inst/extdata/...`). * These are not part of the package namespace source, so tooling may want to treat them separately. */ Install = "install", /** Data files, e.g., `R/sysdata.rda`, currently not specially supported. */ Data = "data", /** Signals separate license files, but please note, that DESCRIPTION files may contain license info too */ License = "license", /** Files describing a project's virtual/pinned package environment, e.g., `renv.lock`, `rv.lock` or `uvr.lock`. */ VirtualEnv = "virtual-env", /** A project manifest that is no `DESCRIPTION`, e.g. the `rproject.toml` of an rv project or the `uvr.toml` of a uvr project. */ Manifest = "manifest", /** * R sources evaluated at startup, before any project code (`.Rprofile`, `Rprofile.site`). * These commonly bootstrap a package manager, e.g. by sourcing `packrat/init.R` or `renv/activate.R`. */ Startup = "startup", /** * Environment-variable definitions read at startup (`.Renviron`, `Renviron.site`). These are `KEY=value` * files, not R source, so they are labeled but not parsed as R. */ Environment = "environment", /** * Catch-all for any file that provides usable R source code to incorporate into the analysis. * Please note, that the loading order/inclusion and even potential relevance of these source files * is determined by the loading order plugins (cf. {@link PluginType.LoadingOrder}) * in the {@link FlowrAnalyzerLoadingOrderContext}. */ Source = "source", /** Other special files that are not specifically supported by flowR but may be interesting for some analyses. */ Other = "other" } export type StringableContent = { toString(): string; }; /** * This is the basic interface for all files known to the FlowrAnalyzer. * You can implement this interface to provide custom file loading mechanisms. * Mostly, we will be interested in text files (or decorations thereof). * If you want to load other file types, you either have to transform them into a presentation supported by flowR * or add your own file loader plugin (similar to the {@link FlowrAnalyzerDescriptionFilePlugin}). * * See {@link FlowrFile} for a basic single-cache implementation and {@link FlowrTextFile} for a text-file specific implementation. * If you want to pass in inline text files, see {@link FlowrInlineTextFile}. * @typeParam Content - The type of the content returned by the `content()` method. */ export interface FlowrFileProvider<Content extends { toString(): string; } = { toString(): string; }> { /** * The role(s) of this file, if any, in general your file should _not_ decide for itself what role it has in the project context, * this is for the loaders plugins to decide (cf. {@link PluginType}) as they can, e.g., respect ignore files, updated mappings, etc. * However, they will 1) set this role as soon as they decide on it (using {@link assignRole}) and 2) try to respect an already assigned role (however, user configurations may override this). */ roles?: readonly FileRole[]; /** * The path to the file, this is used for identification and logging purposes. * If the file does not exist on disk, this can be a virtual path (e.g. for inline files). * Even though this is a getter, please make sure that the operation is cheap and deterministic (some decorators may overwrite the path, e.g., because they support other protocols). */ path(): string; /** * The content of the file, this may be cached by the implementation and does not have to be expensive. * You can used stream based implementations but right now there is no external, project-wide expressions of life cycles for files. * So make sure your implementation closes the resource as soon as possible. */ content(): Content; /** * Assign a role to this file, this should be done by the loader plugins (cf. {@link PluginType}). * **Do not call this method yourself unless you are a file-loader plugin and/or really know what you are doing, this may break plugin assumptions!** */ assignRole(role: FileRole): void; /** * Set the appropriate callback to trigger updates in case of an 'invalidate' */ addOnInvalidate(callback: InvalidationEventHandler<Content>): void; /** * Remove a previously added callback */ removeOnInvalidate(callback: InvalidationEventHandler<Content>): void; /** * Reload the file content because something has changed. */ invalidate(): void; } /** * A basic implementation of the {@link FlowrFileProvider} interface that caches the content after the first load (i.e., updates on disk are ignored). * * See {@link FlowrTextFile} for a text-file specific implementation and {@link FlowrInlineTextFile} for inline text files. */ export declare abstract class FlowrFile<Content extends StringableContent = StringableContent> implements FlowrFileProvider<Content> { private contentCache; protected filePath: PathLike; private _roles?; private onInvalidate; static readonly INLINE_PATH = "@inline"; constructor(filePath: PathLike, roles?: readonly FileRole[]); get roles(): readonly FileRole[] | undefined; path(): string; content(): Content; /** * Allows to overwrite the content cache. * @protected */ protected setContent(content: Content): void; protected abstract loadContent(): Content; assignRole(role: FileRole): void; /** * Creates a {@link FlowrFile} from a given {@link RParseRequest}. * @see {@link FlowrTextFile} * @see {@link FlowrInlineTextFile} */ static fromRequest(request: RParseRequest): FlowrFile<string>; addOnInvalidate(callback: InvalidationEventHandler<Content>): void; removeOnInvalidate(callback: InvalidationEventHandler<Content>): void; invalidate(): void; } /** * A basic implementation of the {@link FlowrFileProvider} interface for text files that caches the content after the first load (i.e., updates on disk are ignored). */ export declare class FlowrTextFile extends FlowrFile<string> { protected loadContent(): string; } /** * A basic implementation of the {@link FlowrFileProvider} interface for (constant) inline text files. * This is also useful for "special" files like the `DESCRIPTION` file in R packages that you want to pass in directly. * These will be handled by the {@link FlowrAnalyzerDescriptionFilePlugin} (e.g., by using the {@link FlowrDescriptionFile#from} method decorator). */ export declare class FlowrInlineTextFile extends FlowrFile<string> { private contentStr; constructor(path: PathLike, content: string); protected loadContent(): string; /** * Update the content of this inline file and invalidate the cache to trigger updates in the analysis. * @see {@link FlowrFile#invalidate} */ updateInlineContent(newContent: string): void; }