UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

115 lines 5.04 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EdgeType = void 0; exports.edgeTypeToName = edgeTypeToName; exports.splitEdgeTypes = splitEdgeTypes; exports.edgeTypesToNames = edgeTypesToNames; exports.edgeIncludesType = edgeIncludesType; exports.edgeDoesNotIncludeType = edgeDoesNotIncludeType; exports.shouldTraverseEdge = shouldTraverseEdge; /** * Represents the relationship between the source and the target vertex in the dataflow graph. * The actual value is represented as a bitmask so use {@link edgeTypesToNames} to get something more human-readable. * Similarly, you can access {@link EdgeTypeName} to access the name counterpart. */ var EdgeType; (function (EdgeType) { /** The edge determines that source reads target */ EdgeType[EdgeType["Reads"] = 1] = "Reads"; /** The edge determines that source is defined by target */ EdgeType[EdgeType["DefinedBy"] = 2] = "DefinedBy"; /** The edge determines that the source calls the target */ EdgeType[EdgeType["Calls"] = 4] = "Calls"; /** The source returns target on call */ EdgeType[EdgeType["Returns"] = 8] = "Returns"; /** * The edge determines that source (probably argument) defines the target (probably parameter). * This may also link a function call to definitions it causes to be active (as part of the closure) of the called function definition. */ EdgeType[EdgeType["DefinesOnCall"] = 16] = "DefinesOnCall"; /** * Usually the inverse of `defines-on-call` (in the context of arguments and parameters). * This may also link an open read (within a function) to the definition that is active at the call site. */ EdgeType[EdgeType["DefinedByOnCall"] = 32] = "DefinedByOnCall"; /** Formal used as argument to a function call */ EdgeType[EdgeType["Argument"] = 64] = "Argument"; /** The edge determines that the source is a side effect that happens when the target is called */ EdgeType[EdgeType["SideEffectOnCall"] = 128] = "SideEffectOnCall"; /** The Edge determines that the reference is affected by a non-standard evaluation (e.g., a for-loop body or a quotation) */ EdgeType[EdgeType["NonStandardEvaluation"] = 256] = "NonStandardEvaluation"; })(EdgeType || (exports.EdgeType = EdgeType = {})); const edgeTypeToHumanReadableName = new Map([ [EdgeType.Reads, "reads" /* EdgeTypeName.Reads */], [EdgeType.DefinedBy, "defined-by" /* EdgeTypeName.DefinedBy */], [EdgeType.Calls, "calls" /* EdgeTypeName.Calls */], [EdgeType.Returns, "returns" /* EdgeTypeName.Returns */], [EdgeType.DefinesOnCall, "defines-on-call" /* EdgeTypeName.DefinesOnCall */], [EdgeType.DefinedByOnCall, "defined-by-on-call" /* EdgeTypeName.DefinedByOnCall */], [EdgeType.Argument, "argument" /* EdgeTypeName.Argument */], [EdgeType.SideEffectOnCall, "side-effect-on-call" /* EdgeTypeName.SideEffectOnCall */], [EdgeType.NonStandardEvaluation, "non-standard-evaluation" /* EdgeTypeName.NonStandardEvaluation */] ]); /** * Only use this function to retrieve a human-readable name if you know that it is a single bitmask. * Otherwise, use {@link edgeTypesToNames} which handles these cases. */ function edgeTypeToName(type) { return edgeTypeToHumanReadableName.get(type); } function splitEdgeTypes(types) { const split = []; for (const bit of edgeTypeToHumanReadableName.keys()) { if ((types & bit) !== 0) { split.push(bit); } } return split; } function edgeTypesToNames(bits) { const types = new Set(); for (const [bit, name] of edgeTypeToHumanReadableName.entries()) { if ((bits & bit) !== 0) { types.add(name); } } return types; } /** * Check if the given-edge type has any of the given types. * @example * * ```typescript * edgeIncludesType(EdgeType.Reads, EdgeType.Reads | EdgeType.DefinedBy) // true *``` * * Counterpart of {@link edgeDoesNotIncludeType}. */ function edgeIncludesType(type, typesToInclude) { return (typesToInclude & type) !== 0; } /** * Check if the given-edge type does not include the given type. * Counterpart of {@link edgeIncludesType}. */ function edgeDoesNotIncludeType(type, types) { return (types & type) === 0; } const alwaysTraverseEdgeTypes = EdgeType.Reads | EdgeType.DefinedBy | EdgeType.Argument | EdgeType.Calls; const definedByOnCallTypes = EdgeType.DefinesOnCall | EdgeType.DefinedByOnCall; function shouldTraverseEdge(types) { if (edgeIncludesType(types, EdgeType.NonStandardEvaluation)) { return 0 /* TraverseEdge.Never */; } else if (edgeIncludesType(types, alwaysTraverseEdgeTypes)) { return 3 /* TraverseEdge.Always */; } else if (edgeIncludesType(types, definedByOnCallTypes)) { return 2 /* TraverseEdge.OnlyIfBoth */; } else if (edgeIncludesType(types, EdgeType.SideEffectOnCall)) { return 1 /* TraverseEdge.SideEffect */; } return 0 /* TraverseEdge.Never */; } //# sourceMappingURL=edge.js.map