@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
208 lines (207 loc) • 10.2 kB
TypeScript
import type { RNode } from '../r-bridge/lang-4.x/ast/model/model';
import type { RNodeWithParent } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
/**
* A source position in a file.
*
* Please note that some packages like `xmlparsedata` use their own start and end only to break ties
* (e.g., `xmlparsedata` calculates them on a max col width approximation)
* @see {@link SourceRange|source ranges} for describing ranges of source positions.
*/
export type SourcePosition = [
/** starts with 1 */
line: number,
/** starts with 1 */
column: number
];
/**
* Utility functions for {@link SourcePosition|source positions}.
*/
export declare const SourcePosition: {
readonly name: "SourcePosition";
/**
* Formats a {@link SourcePosition|source position} as a human-readable string.
*/
readonly format: (this: void, pos: SourcePosition | undefined) => string;
/**
* Creates a source position from the given line and column numbers.
* @param line - line number (starts with 1)
* @param column - column number (starts with 1)
*/
readonly from: (this: void, line: number | string, column: number | string) => SourcePosition;
/**
* returns an invalid source position
*/
readonly invalid: (this: void) => SourcePosition;
/**
* Returns the line of a source position
*/
readonly getLine: (this: void, pos: SourcePosition) => number;
/**
* Returns the column of a source position
*/
readonly getColumn: (this: void, pos: SourcePosition) => number;
};
/**
* **Please note** that for multi-file projects we also have a {@link SourceLocation|source location} type that includes the file name.
* Describe the start and end {@link SourcePosition|source position} of an element.
* @see {@link SourceRange.format} and related utility functions for working with source ranges.
*/
export type SourceRange = [
/** inclusive start position */
startLine: number,
startColumn: number,
/** inclusive end position */
endLine: number,
endColumn: number
];
/**
* Utility functions for {@link SourceRange|source ranges}.
*/
export declare const SourceRange: {
readonly name: "SourceRange";
/**
* Prints a {@link SourceRange|range} as a human-readable string.
*/
readonly format: (this: void, range: SourceRange | undefined) => string;
/**
* Returns the start position of a source range.
*/
readonly getStart: (this: void, range: SourceRange) => SourcePosition;
/**
* Returns the start line of a source range.
*/
readonly getStartLine: (this: void, range: SourceRange) => number;
/**
* Returns the end position of a source range.
*/
readonly getEnd: (this: void, range: SourceRange) => SourcePosition;
/**
* Returns the end line of a source range.
*/
readonly getEndLine: (this: void, range: SourceRange) => number;
/**
* Creates a source range from the given line and column numbers.
* @param sl - start line
* @param sc - start column
* @param el - end line
* @param ec - end column
*/
readonly from: (this: void, sl: number | string, sc: number | string, el?: number | string, ec?: number | string) => SourceRange;
/**
* returns an invalid source range
*/
readonly invalid: (this: void) => SourceRange;
/**
* Merges multiple source ranges into a single source range that spans from the earliest start to the latest end.
* If you are interested in reducing a set of ranges to those none of the others contains, see {@link combineRanges}.
* @throws if no ranges are provided
*/
readonly merge: (this: void, rs: (SourceRange | undefined)[]) => SourceRange;
/**
* @returns true iff `r1` starts and ends before `r2` starts (i.e., if `r1` and `r2` do not overlap and `r1` comes before `r2`
*/
readonly startsCompletelyBefore: (this: void, [, , r1el, r1ec]: SourceRange, [r2sl, r2sc, ,]: SourceRange) => boolean;
/** Checks if the two ranges overlap, i.e. whether neither of them lies completely before the other. */
readonly overlap: (this: void, r1: SourceRange, r2: SourceRange) => boolean;
/**
* Calculates the component-wise sum of two ranges.
*/
readonly add: (this: void, [r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange) => SourceRange;
/**
* Provides a comparator for {@link SourceRange}s that sorts them in ascending order.
* @returns a positive number if `r1` comes after `r2`, a negative number if `r1` comes before `r2`, and `0` if they are equal
*/
readonly compare: (this: void, [r1sl, r1sc, ,]: SourceRange, [r2sl, r2sc, ,]: SourceRange) => number;
/**
* Checks if two ranges are equal (i.e., they start and end at the same position).
*/
readonly equals: (this: void, [r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange) => boolean;
/**
* Checks if a given position (line, column) is contained within the range.
*/
readonly containsPosition: (this: void, [sl, sc, el, ec]: SourceRange, line: number, column: number) => boolean;
/**
* Checks if the first range is a subset of the second range.
*/
readonly isSubsetOf: (this: void, [r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange) => boolean;
/**
* Checks if the first range is a strict subset of the second range (i.e., it is a subset but not equal).
*/
readonly isStrictSubsetOf: (this: void, r1: SourceRange, r2: SourceRange) => boolean;
/**
* Reduces the ranges to those no other one contains, keeping the first of any duplicates. Ranges that merely
* overlap are both kept, as neither contains the other. A non-empty input always yields a non-empty result.
* @see {@link SourceRange.merge} for merging multiple ranges into a single range.
*/
readonly combineRanges: (this: void, ...ranges: SourceRange[]) => SourceRange[];
readonly fromNode: <OtherInfo>(this: void, node: RNode<OtherInfo> | undefined) => SourceRange | undefined;
/**
* "Fuzzy" position match, as opposed to requiring a node to *start* exactly at the position.
* @see {@link SourceRange.innermostNodes} to narrow the result down to the deepest matches
*/
readonly nodesContaining: <OtherInfo>(this: void, nodes: readonly RNodeWithParent<OtherInfo>[], line: number, column?: number) => RNodeWithParent<OtherInfo>[];
/**
* Collects all nodes satisfying the innermost condition: those containing no other of the given nodes.
*
* Nodes may share a range (a function call and the symbol naming it do), so `treatChildAsInner` decides that
* tie: with it, a node sharing its parent's range counts as the inner one and the parent drops out; without
* it, both are kept and the caller may pick between them (e.g. by node type).
*
* A non-empty input always yields a non-empty result: enclosure is a strict order so some node is always minimal,
* and a node carrying no range at all is kept rather than dropped.
* @see {@link SourceRange.nodesContaining} which this usually narrows down
*/
readonly innermostNodes: <OtherInfo>(this: void, nodes: readonly RNodeWithParent<OtherInfo>[], treatChildAsInner?: boolean) => RNodeWithParent<OtherInfo>[];
};
/**
* A source location consisting of a source range and an optional file name.
* @see {@link SourceLocation.format} and related utility functions for working with source locations.
*/
export type SourceLocation = [...r: SourceRange, f?: string];
/**
* Utility functions for {@link SourceLocation|source locations}.
*/
export declare const SourceLocation: {
readonly name: "SourceLocation";
/**
* Formats a {@link SourceLocation|source location} as a human-readable string.
*/
readonly format: (this: void, location: SourceLocation | undefined) => string;
/** Returns the {@link SourceRange|source range} part of a {@link SourceLocation|source location}, file excluded. */
readonly getRange: (this: void, [sl, sc, el, ec]: SourceLocation) => SourceRange;
/**
* Returns the file part of a {@link SourceLocation|source location}, or `undefined` if no file is set.
*/
readonly getFile: (this: void, location: SourceLocation) => string | undefined;
/**
* Creates a {@link SourceLocation|source location} from a {@link SourceRange|source range} and a file name.
*/
readonly from: (this: void, range: SourceRange, file?: string) => SourceLocation;
/**
* The {@link SourceLocation|source location} of an AST node, file included.
* @returns undefined if the given range is undefined
* @see {@link SourceRange.fromNode} for getting the range from an AST node
*/
readonly fromNode: <OtherInfo>(this: void, node: RNode<OtherInfo> | undefined) => SourceLocation | undefined;
/**
* Maps the file part of a {@link SourceLocation|source location} using the given mapper function.
*/
readonly mapFile: (this: void, loc: SourceLocation, fileMapper: (file: string | undefined) => string) => SourceLocation;
/**
* Checks if the first location is a subset of the second location.
* For this, they must be in the same file!
* @see {@link SourceRange.isSubsetOf}
*/
readonly isSubsetOf: (this: void, loc1: SourceLocation, loc2: SourceLocation) => boolean;
readonly compare: (this: void, loc1: SourceLocation, loc2: SourceLocation) => number;
/**
* Returns an invalid source location (i.e., with an invalid range and no file).
*/
readonly invalid: (this: void) => SourceLocation;
/**
* Merges multiple source locations into a single source location that spans from the earliest start to the latest end.
* If the locations are from different files, `undefined` is returned.
* Files may be `undefined` themselves, but if there is at least one defined file, they must all be the same defined file for the merge to succeed.
*/
readonly merge: (this: void, locs: (SourceLocation | undefined)[]) => SourceLocation | undefined;
};