UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

154 lines (153 loc) 6.69 kB
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 {};