@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
186 lines (185 loc) • 12.5 kB
TypeScript
import { FlowrAnalyzerFilesContext, type RAnalysisRequest, type ReadOnlyFlowrAnalyzerFilesContext } from './flowr-analyzer-files-context';
import type { ProjectKind } from './project-kind';
import { FlowrAnalyzerDependenciesContext, type ReadOnlyFlowrAnalyzerDependenciesContext } from './flowr-analyzer-dependencies-context';
import type { Range } from 'semver';
import { type FlowrAnalyzerPlugin, PluginType } from '../plugins/flowr-analyzer-plugin';
import type { fileProtocol, RParseRequestFromFile, RParseRequests } from '../../r-bridge/retriever';
import { FlowrConfig } from '../../config';
import type { DeepPartial } from 'ts-essentials';
import type { FlowrFileProvider } from './flowr-file';
import type { ReadOnlyFlowrAnalyzerEnvironmentContext } from './flowr-analyzer-environment-context';
import { FlowrAnalyzerEnvironmentContext } from './flowr-analyzer-environment-context';
import type { ReadOnlyFlowrAnalyzerMetaContext } from './flowr-analyzer-meta-context';
import { FlowrAnalyzerMetaContext } from './flowr-analyzer-meta-context';
import type { FlowrAnalyzer } from '../flowr-analyzer';
import type { ReadOnlyFlowrAnalyzerIncrementalAnalysisContext } from './flowr-analyzer-incremental-analysis-context';
import { FlowrAnalyzerIncrementalAnalysisContext } from './flowr-analyzer-incremental-analysis-context';
import type { InvalidationEvent, InvalidationEventReceiver } from '../cache/flowr-cache';
import { FlowrAnalyzerGasContext, type ReadOnlyFlowrAnalyzerGasContext } from './flowr-analyzer-gas-context';
/**
* This is a read-only interface to the {@link FlowrAnalyzerContext}.
* It prevents you from modifying the context, but allows you to inspect it (which is probably what you want when using the {@link FlowrAnalyzer}).
* If you are a {@link FlowrAnalyzerPlugin} and want to modify the context, you can use the {@link FlowrAnalyzerContext} directly.
*/
export interface ReadOnlyFlowrAnalyzerContext {
/** Project metadata such as name, version, and namespace. */
readonly meta: ReadOnlyFlowrAnalyzerMetaContext;
/** Files to be analyzed and their loading order. */
readonly files: ReadOnlyFlowrAnalyzerFilesContext;
/** Identified dependencies and their versions. */
readonly deps: ReadOnlyFlowrAnalyzerDependenciesContext;
/** Environment information used during analysis. */
readonly env: ReadOnlyFlowrAnalyzerEnvironmentContext;
/** The incremental context provides potential information for the next incremental analysis run */
readonly inc: ReadOnlyFlowrAnalyzerIncrementalAnalysisContext;
/** The configuration options used by the analyzer. */
readonly config: FlowrConfig;
/** class names of plugins that activated (produced a result) since the last reset; only filled when `config.repl.showPlugins` is set */
readonly activatedPlugins: ReadonlySet<string>;
/** The project kind the effective {@link config} is specialized for and the overrides it applies, or `undefined` when no specialization is in effect. */
configSpecialization(): {
readonly kind: ProjectKind;
readonly overwrite: DeepPartial<FlowrConfig>;
} | undefined;
/** The R version analysis assumes when resolving versioned (base-R) exports (see `solver.sigdb.assumedRVersion`). */
readonly resolvedRVersion: string;
/** Whether {@link resolvedRVersion} is a genuine signal (a config pin, project metadata, or an engine-detected version) rather than the fallback default. */
readonly rVersionKnown: boolean;
/** Where {@link resolvedRVersion} comes from, as only {@link RVersionOrigin.Config} and {@link RVersionOrigin.Metadata} say anything about the analyzed code. */
readonly rVersionOrigin: RVersionOrigin;
/** Classify the {@link ProjectKind} of the project, see {@link ReadOnlyFlowrAnalyzerFilesContext#projectKind}. */
projectKind(): ProjectKind;
/** The versions a dependency can possibly have, see {@link ReadOnlyFlowrAnalyzerDependenciesContext#inferredRange}. */
inferredRange(name: string): Range | undefined;
/**
* Resource-usage guard (gas).
* Call `ctx.gas.checkGas(key)` at expensive analysis sites to obtain the current pressure level.
* Returns `GasLevel.Normal` with zero overhead when gas is disabled for `key`.
* @see {@link ReadOnlyFlowrAnalyzerGasContext}
*/
readonly gas: ReadOnlyFlowrAnalyzerGasContext;
}
/** Where the R version an analysis assumes comes from, see {@link ReadOnlyFlowrAnalyzerContext.rVersionOrigin}. */
export declare const enum RVersionOrigin {
/** pinned via `solver.sigdb.assumedRVersion` */
Config = "config",
/** stated by the project itself (e.g. a `DESCRIPTION` `Depends: R (>= x)`) */
Metadata = "metadata",
/** detected from the R installation running the analysis, which says nothing about the analyzed code */
Engine = "engine",
/** nothing said anything, so the fallback default is used */
Default = "default"
}
/**
* This summarizes the other context layers used by the {@link FlowrAnalyzer}.
* Have a look at the attributes and layers listed below (e.g., {@link files} and {@link deps})
* to get an idea of the capabilities provided by this context.
* Besides these, this layer only orchestrates the different steps and layers, providing a collection of convenience methods.
* In general, you do not have to worry about these details, as the {@link FlowrAnalyzerBuilder} and {@link FlowrAnalyzer} take care of them.
*
* To inspect, e.g., the loading order, you can do so via {@link files.loadingOrder.getLoadingOrder}. To get information on a specific library, use
* {@link deps.getDependency}.
* If you are just interested in inspecting the context, you can use {@link ReadOnlyFlowrAnalyzerContext} instead (e.g., via {@link inspect}).
*/
export declare class FlowrAnalyzerContext implements ReadOnlyFlowrAnalyzerContext, InvalidationEventReceiver {
readonly meta: FlowrAnalyzerMetaContext;
readonly files: FlowrAnalyzerFilesContext;
readonly deps: FlowrAnalyzerDependenciesContext;
readonly env: FlowrAnalyzerEnvironmentContext;
readonly inc: FlowrAnalyzerIncrementalAnalysisContext;
/** class names of plugins that activated since the last reset; only filled when `config.repl.showPlugins` is set */
readonly activatedPlugins: Set<string>;
readonly gas: FlowrAnalyzerGasContext;
private _analyzer;
/** an auto-detected R version (from the engine), recorded once at the analyzer boundary; see {@link resolvedRVersion} */
private _detectedR;
/** the configuration as given, i.e. before {@link FlowrConfig.specializeConfig} is applied */
readonly baseConfig: FlowrConfig;
/** {@link baseConfig}, specialized for {@link _configKind} */
private _config;
/** the {@link ProjectKind} {@link _config} holds, `undefined` as long as it has to be resolved */
private _configKind;
/** set while classifying, as the classification must not read the config it decides, see {@link kindToSpecializeFor} */
private _classifying;
/** accumulated runtime overrides from {@link updateConfig}, applied on top of the specialized config so they always win */
private runtimeOverrides;
/** memoized {@link config}: {@link specializedConfig} merged with {@link runtimeOverrides} */
private _effective;
private _appliedLogLevel;
/** the specialized object {@link _effective} was built from, for identity-based invalidation on a kind change */
private _effectiveOf;
/**
* {@link baseConfig} specialized for the project {@link ProjectKind}, with any {@link updateConfig|runtime
* overrides} applied on top (those win over both base and specialization).
*/
get config(): FlowrConfig;
/** {@link baseConfig} with the {@link FlowrConfig.specializeConfig} of the project's kind applied ({@link FlowrConfig.forKind}), resolved once per kind. */
private specializedConfig;
/**
* Apply a runtime {@link FlowrConfig} update. It is layered on top of the specialized config (so it wins over
* project-kind specialization) and never mutates the shared {@link baseConfig}. The analysis cache must be
* invalidated separately (see {@link FlowrAnalyzer.updateConfig}), as the results were computed under the old config.
*/
updateConfig(update: DeepPartial<FlowrConfig>): void;
/** Discards every {@link updateConfig} override made so far, reverting {@link config} back to {@link baseConfig} (specialized for the project kind). */
resetConfig(): void;
/** The project kind the effective {@link config} is specialized for, plus the overrides it applies, or `undefined` when no specialization is in effect. */
configSpecialization(): {
readonly kind: ProjectKind;
readonly overwrite: DeepPartial<FlowrConfig>;
} | undefined;
/** {@link projectKind}, resolved with {@link baseConfig}, as classifying the project reads the config again */
private kindToSpecializeFor;
constructor(config: FlowrConfig, plugins: ReadonlyMap<PluginType, readonly FlowrAnalyzerPlugin[]>);
/**
* Provides the analyzer associated with this context, if any.
* This is usually set when the context is used within an analyzer instance.
* Please note, that this may be `undefined` if the context is used standalone (e.g., during setup or in plugins that do not have access to the analyzer).
*/
get analyzer(): FlowrAnalyzer | undefined;
setAnalyzer(analyzer: FlowrAnalyzer): void;
/** Record the engine's auto-detected R version (used when `solver.sigdb.assumedRVersion` is `"auto"`). */
setDetectedRVersion(version: string): void;
/** The R version analysis assumes when resolving versioned (base-R) exports (see {@link resolveAssumedRVersion}). */
get resolvedRVersion(): string;
/** Whether {@link resolvedRVersion} is a genuine signal (a config pin, project metadata, or engine detection) rather than the fallback default. */
get rVersionKnown(): boolean;
/** Where {@link resolvedRVersion} comes from, which decides what it says about the analyzed code. */
get rVersionOrigin(): RVersionOrigin;
/** Classify the {@link ProjectKind} of the project (delegates to the cached {@link FlowrAnalyzerFilesContext#projectKind}). */
projectKind(): ProjectKind;
/** The versions a dependency can possibly have (delegates to {@link FlowrAnalyzerDependenciesContext#inferredRange}). */
inferredRange(name: string): Range | undefined;
/** delegate request addition */
addRequests(requests: readonly RAnalysisRequest[]): void;
addFile(f: string | FlowrFileProvider | RParseRequestFromFile): void;
addFiles(f: (string | FlowrFileProvider | RParseRequestFromFile)[]): void;
/**
* Get a read-only version of this context.
* This is useful if you want to pass the context to a place where you do not want it to be modified or just to reduce
* the available methods.
*/
inspect(): ReadOnlyFlowrAnalyzerContext;
/**
* Reset the context to its initial state, e.g., removing all files, dependencies, and loading orders.
*/
reset(): void;
receive(event: InvalidationEvent): void;
}
/**
* Lifting {@link requestFromInput} to create a full {@link FlowrAnalyzerContext} from input requests.
* Please use this only for a "quick" setup, or to have compatibility with the pre-project flowR era.
* Otherwise, refer to a {@link FlowrAnalyzerBuilder} to create a fully customized {@link FlowrAnalyzer} instance.
* @see {@link requestFromInput} - for details on how inputs are processed into requests.
* @see {@link contextFromSources} - to create a context from source code strings directly.
*/
export declare function contextFromInput(input: `${typeof fileProtocol}${string}` | string | readonly string[] | RParseRequests, config?: FlowrConfig, plugins?: FlowrAnalyzerPlugin[]): FlowrAnalyzerContext;
/**
* Create a {@link FlowrAnalyzerContext} from a set of source code strings.
* @param sources - A record mapping file paths to their source code content.
* @param config - Configuration options for the analyzer.
* @param plugins - Optional plugins to extend the analyzer's functionality.
* @see {@link contextFromInput} - to create a context from input requests.
* @see {@link FlowrInlineTextFile} - to create inline text files for the sources.
*/
export declare function contextFromSources(sources: Record<string, string>, config?: FlowrConfig, plugins?: FlowrAnalyzerPlugin[]): FlowrAnalyzerContext;