@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
154 lines (153 loc) • 6.69 kB
TypeScript
import type { SourceRange } from '../../../../util/range';
import type { RType } from './type';
import type { MergeableRecord } from '../../../../util/objects';
import type { RNumber } from './nodes/r-number';
import type { RString } from './nodes/r-string';
import type { RLogical } from './nodes/r-logical';
import type { RSymbol } from './nodes/r-symbol';
import type { RComment } from './nodes/r-comment';
import type { RBreak } from './nodes/r-break';
import type { RNext } from './nodes/r-next';
import type { RLineDirective } from './nodes/r-line-directive';
import type { RForLoop } from './nodes/r-for-loop';
import type { RRepeatLoop } from './nodes/r-repeat-loop';
import type { RWhileLoop } from './nodes/r-while-loop';
import type { RIfThenElse } from './nodes/r-if-then-else';
import type { RFunctionDefinition } from './nodes/r-function-definition';
import type { RFunctionCall } from './nodes/r-function-call';
import type { RParameter } from './nodes/r-parameter';
import type { RArgument } from './nodes/r-argument';
import type { RExpressionList } from './nodes/r-expression-list';
import type { RIndexAccess, RNamedAccess } from './nodes/r-access';
import type { RUnaryOp } from './nodes/r-unary-op';
import type { RBinaryOp } from './nodes/r-binary-op';
import type { RPipe } from './nodes/r-pipe';
import type { RDelimiter } from './nodes/info/r-delimiter';
/** Simply an empty type constraint used to say that there are additional decorations (see {@link Base}). */
export type NoInfo = object;
/**
* Will be used to reconstruct the source of the given element in the R-ast.
* This will not be part of most comparisons as it is mainly of interest to the reconstruction of R code.
*/
interface Source {
/**
* The range is different from the assigned {@link Location} as it refers to the complete source range covered by the given
* element.
* <p>
* As an example for the difference, consider a for loop, the location of `for` will be just the three characters,
* but the *range* will be everything including the loop body.
*/
fullRange?: SourceRange;
/**
* Similar to {@link Source.fullRange} this contains the complete R lexeme of the given element.
*/
fullLexeme?: string;
/**
* This may contain additional elements that were part of the original R code, but are not part of the normalized R-ast.
* This allows inline-comments!
*/
additionalTokens?: OtherInfoNode[];
/**
* The file in which the respective node is located
*/
file?: string;
}
/**
* Provides the common base of all {@link RNode|RNodes}.
*
* @typeParam Info - can be used to store additional information about the node
* @typeParam LexemeType - the type of the lexeme, probably always a `string` or `string | undefined`
*/
export interface Base<Info, LexemeType = string> extends MergeableRecord {
type: RType;
/** the original string retrieved from R, can be used for further identification */
lexeme: LexemeType;
/** allows to attach additional information to the node */
info: Info & Source;
}
export interface WithChildren<Info, Children extends Base<Info, string | undefined>> {
children: readonly Children[];
}
/**
* A helper interface we use to "mark" leaf nodes.
* <p>
* Please be aware, that this is not marking from a language perspective,
* as it is equivalent to the {@link Base} interface.
* It is intended to help humans understand the code.
*/
export interface Leaf<Info = NoInfo, LexemeType = string> extends Base<Info, LexemeType> {
}
/**
* Indicates, that the respective {@link Base} node has known source code
* location information.
*/
export interface Location {
/**
* The location may differ from what is stated in {@link Source#fullRange} as it
* represents the location identified by the R parser.
*
* @see Source#fullRange
*/
location: SourceRange;
}
/**
* Represents the type of namespaces in the R programming language.
* At the moment, this is only the name of the namespace.
*/
export type NamespaceIdentifier = string;
/**
* Similar to {@link Location} this is an interface that indicates that
* the respective {@link Base} node has a respective property (a namespace).
*/
export interface Namespace {
/**
* The namespace attached to the given node
* (e.g., a namespaced symbol in `x::y`).
*/
namespace: NamespaceIdentifier | undefined;
}
/**
* This subtype of {@link RNode} represents all types of constants
* represented in the normalized AST.
*/
export type RConstant<Info> = RNumber<Info> | RString<Info> | RLogical<Info>;
/**
* This subtype of {@link RNode} represents all types of {@link Leaf} nodes in the
* normalized AST.
*/
export type RSingleNode<Info> = RComment<Info> | RSymbol<Info> | RConstant<Info> | RBreak<Info> | RNext<Info> | RLineDirective<Info>;
/**
* This subtype of {@link RNode} represents all looping constructs in the normalized AST.
*/
export type RLoopConstructs<Info> = RForLoop<Info> | RRepeatLoop<Info> | RWhileLoop<Info>;
/**
* As an extension to {@link RLoopConstructs}, this subtype of {@link RNode} includes
* the {@link RIfThenElse} construct as well.
*/
export type RConstructs<Info> = RLoopConstructs<Info> | RIfThenElse<Info>;
/**
* This subtype of {@link RNode} represents all types related to functions
* (calls and definitions) in the normalized AST.
*/
export type RFunctions<Info> = RFunctionDefinition<Info> | RFunctionCall<Info> | RParameter<Info> | RArgument<Info>;
/**
* This subtype of {@link RNode} represents all types of otherwise hard to categorize
* nodes in the normalized AST. At the moment these are the comment-like nodes.
*/
export type ROther<Info> = RComment<Info> | RLineDirective<Info>;
/**
* The `RNode` type is the union of all possible nodes in the R-ast.
* It should be used whenever you either not care what kind of
* node you are dealing with or if you want to handle all possible nodes.
* <p>
*
* All other subtypes (like {@link RLoopConstructs}) listed above
* can be used to restrict the kind of node. They do not have to be
* exclusive, some nodes can appear in multiple subtypes.
*
* @see {@link recoverName} - to receive the name/lexeme from such a node
* @see {@link recoverContent} - for a more rigorous approach to get the content of a node within a {@link DataflowGraph|dataflow graph}
*/
export type RNode<Info = NoInfo> = RExpressionList<Info> | RFunctions<Info> | ROther<Info> | RConstructs<Info> | RNamedAccess<Info> | RIndexAccess<Info> | RUnaryOp<Info> | RBinaryOp<Info> | RSingleNode<Info> | RPipe<Info>;
export type OtherInfoNode = RNode | RDelimiter;
export {};