/**
 * This module holds the definition of what a {@link Feature} that can be extracted from an R AST is.
 *
 * Furthermore, it contains the definition of all features that are known in {@link ALL_FEATURES}.
 * @module
 */
import type { EvalOptions } from 'xpath-ts2/src/parse-api';
import type { MetaStatistics } from '../meta-statistics';
import type { StatisticsSummarizerConfiguration } from '../summarizer/summarizer';
import type { MergeableRecord } from '../../util/objects';
import type { DataflowInformation } from '../../dataflow/info';
import type { NormalizedAst } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
import type { Document } from '@xmldom/xmldom';
/**
 * Maps each sub-feature name to the number of occurrences of that sub-feature.
 * Allows for one nesting level to denote hierarchical features.
 * <p>
 * Since we are writing to files {@link process}, we only count feature occurrences (some feature/parts are not written to file)
 */
export type FeatureInfo = Record<string, unknown> & MergeableRecord;
/**
 * The information and context that a {@link FeatureProcessor} may operate in.
 */
export interface FeatureProcessorInput extends MergeableRecord {
    /** The XML Document representing the parsed (non-normalized) R AST */
    readonly parsedRAst: Document;
    /** The R AST, after the normalization step */
    readonly normalizedRAst: NormalizedAst;
    /** The dataflow information for the given input */
    readonly dataflow: DataflowInformation;
    /** The filepath that the document originated from (if present, may be undefined if the input was provided as text). This can be relative to the common root directory of requests. */
    readonly filepath: string | undefined;
}
/**
 * A function that processes the analysis results of a document and returns the feature information.
 */
export type FeatureProcessor<T extends FeatureInfo> = (existing: T, input: FeatureProcessorInput) => T;
/**
 * A feature is something to be retrieved by the statistics.
 * @typeParam T - The type of what should be collected for the feature
 * @see ALL_FEATURES
 */
export interface Feature<T extends FeatureInfo> {
    /** A descriptive, yet unique name of the feature */
    readonly name: string;
    /** A description of the feature */
    readonly description: string;
    /** A function that retrieves the feature in the document appends it to the existing feature set (we could use a monoid :D), the filepath corresponds to the active file (if any) */
    process: FeatureProcessor<T>;
    /**
     * If present, this feature allows to post-process the results of the feature extraction (for the summarizer).
     * <p>
     * The extraction can use the output path to write files to, and should return the final output.
     * @param featureRoot - The root path to the feature directory which should contain all the files the feature can write to (already merged for every file processed)
     * @param info        - The feature statistic maps each file name/context encountered to the feature information as well as the meta statistics for the file
     * @param outputPath  - The path to write the output to (besides what is collected in the output and meta information)
     * @param config      - The configuration for the summarizer (e.g., to obtain the number of folders to skip for the feature root)
     */
    postProcess?: (featureRoot: string, info: Map<string, FeatureStatisticsWithMeta>, outputPath: string, config: StatisticsSummarizerConfiguration) => void;
    /** Values to start the existing track from */
    initialValue: T;
}
/**
 * The source of truth for all features that are supported by the statistics.
 */
export declare const ALL_FEATURES: {
    readonly usedPackages: Feature<import("ts-essentials").Writable<{
        library: number;
        require: number;
        loadNamespace: number;
        requireNamespace: number;
        attachNamespace: number;
        withinApply: number;
        '::': number;
        ':::': number;
        '<loadedByVariable>': number;
    }>>;
    readonly comments: Feature<import("ts-essentials").Writable<{
        totalAmount: number;
        roxygenComments: number;
        import: number;
        importFrom: number;
        importMethodsFrom: number;
        importClassesFrom: number;
        useDynLib: number;
        export: number;
        exportClass: number;
        exportMethod: number;
        exportS3Method: number;
        exportPattern: number;
    }>>;
    readonly definedFunctions: Feature<import("ts-essentials").Writable<{
        total: number;
        lambdasOnly: number;
        assignedFunctions: number;
        nestedFunctions: number;
        recursive: number;
        deepestNesting: number;
    }>>;
    readonly usedFunctions: Feature<import("ts-essentials").Writable<{
        allFunctionCalls: number;
        args: Record<number, bigint | import("./common-syntax-probability").CommonSyntaxTypeCounts>;
        nestedFunctionCalls: number;
        deepestNesting: number;
        unnamedCalls: number;
    }>>;
    readonly values: Feature<import("ts-essentials").Writable<{
        allNumerics: number;
        imaginaryNumbers: number;
        integers: number;
        floatHex: number;
        logical: number;
        specialConstants: number;
        strings: number;
    }>>;
    readonly assignments: Feature<import("ts-essentials").Writable<{
        assignmentOperator: Record<string, bigint>;
        assigned: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        deepestNesting: number;
        nestedOperatorAssignment: number;
    }>>;
    readonly loops: Feature<import("ts-essentials").Writable<{
        forLoops: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        forLoopVar: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        forBody: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        whileLoops: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        whileBody: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        repeatLoops: bigint;
        repeatBody: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        breakStatements: number;
        nextStatements: number;
        implicitLoops: number;
        nestedExplicitLoops: number;
        deepestExplicitNesting: number;
    }>>;
    readonly controlflow: Feature<import("ts-essentials").Writable<{
        ifThen: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        thenBody: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        ifThenElse: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        elseBody: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
        nestedIfThen: number;
        nestedIfThenElse: number;
        deepestNesting: number;
        switchCase: import("./common-syntax-probability").CommonSyntaxTypeCounts<bigint>;
    }>>;
    readonly dataAccess: Feature<import("ts-essentials").Writable<{
        singleBracket: Record<number, bigint | import("./common-syntax-probability").CommonSyntaxTypeCounts>;
        doubleBracket: Record<number, bigint | import("./common-syntax-probability").CommonSyntaxTypeCounts>;
        chainedOrNestedAccess: number;
        longestChain: number;
        deepestNesting: number;
        byName: number;
        bySlot: number;
    }>>;
    readonly expressionList: Feature<import("ts-essentials").Writable<{
        allExpressionLists: number;
        deepestNesting: number;
    }>>;
    readonly variables: Feature<import("ts-essentials").Writable<{
        numberOfVariableUses: number;
        numberOfDefinitions: number;
        numberOfRedefinitions: number;
        unknownVariables: number;
    }>>;
};
export type FeatureKey = keyof typeof ALL_FEATURES;
export type FeatureValue<K extends FeatureKey> = ReturnType<typeof ALL_FEATURES[K]['process']>;
/** If the user passes `all`, this should be every feature present in {@link ALL_FEATURES} (see {@link allFeatureNames})*/
export type FeatureSelection = Set<FeatureKey>;
export declare const allFeatureNames: Set<FeatureKey>;
export type FeatureStatistics = {
    [K in FeatureKey]: FeatureInfo;
};
export type FeatureStatisticsWithMeta = FeatureStatistics & {
    stats: MetaStatistics;
};
export interface Query {
    select(options?: EvalOptions): Node[];
}
