UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

124 lines 5.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NodeId = void 0; exports.recoverName = recoverName; exports.recoverContent = recoverContent; const vertex_1 = require("../../../../../dataflow/graph/vertex"); const retriever_1 = require("../../../../retriever"); const identifier_1 = require("../../../../../dataflow/environments/identifier"); /** * The type of the id assigned to each node. Branded to avoid problematic usages with other string or numeric types. * The default ids are numeric, but we use a branded type to avoid confusion with other numeric types. * Custom ids or scoped ids can be strings, but they will be normalized to numbers if they are numeric strings. */ /** whether the id starts as a number does, which `+id` alone does not tell: it turns a blank string into `0` */ function startsNumeric(id) { const c = id.charCodeAt(0); return c >= 48 && c <= 57 /* 0-9 */ || c === 45 /* - */ || c === 43 /* + */ || c === 46 /* . */; } exports.NodeId = { name: 'NodeId', /** * Normalizes a node id by converting numeric strings to numbers. * This allows us to use numeric ids without storing them as strings, while still allowing custom string ids if needed. */ normalize(id) { if (typeof id === 'string' && startsNumeric(id)) { const num = +id; if (!Number.isNaN(num)) { return num; } } return id; }, /** * The prefix used for built-in function or operator ids. */ builtInPrefix: 'built-in:', /** * Checks if a given node id is a built-in function or operator id by checking if it is a string that starts with the built-in prefix. * @see {@link toBuiltIn} - to convert a built-in function or operator name to a built-in id * @see {@link fromBuiltIn} - to recover the built-in function or operator name from a built-in id */ isBuiltIn(id) { return typeof id === 'string' && id.startsWith(exports.NodeId.builtInPrefix); }, /** * Converts a built-in function or operator name to a built-in id by prefixing it with the built-in prefix. * @see {@link isBuiltIn} - to check if a given node id is a built-in function or operator id * @see {@link fromBuiltIn} - to recover the built-in function or operator name from a built-in id */ toBuiltIn(name) { return `built-in:${name}`; }, /** * The canonical `pkg:fn` identifier of a package's exported function (e.g. `ggplot2:ggplot`). The single * source of this form: `Package.functionIdentifier` delegates here, and {@link fromPkgFn} wraps it. */ pkgFnName(pkg, fn) { return `${pkg}:${fn}`; }, /** * The built-in id of a package's exported function, e.g. `fromPkgFn('ggplot2', 'ggplot')` yields * `built-in:ggplot2:ggplot` -- {@link toBuiltIn} over the {@link pkgFnName} `pkg:fn` form. */ fromPkgFn(pkg, fn) { return exports.NodeId.toBuiltIn(exports.NodeId.pkgFnName(pkg, fn)); }, /** * Inverse of {@link fromPkgFn}: split a package-function built-in id (`built-in:pkg:fn`) into its `[pkg, fn]` * parts, or `undefined` when `id` is not one (a non-builtin id, or a bare builtin without a package such as * `built-in:print`). A package name never contains a `:`, so the first one separates it from the function. */ toPkgFn(id) { if (!exports.NodeId.isBuiltIn(id)) { return undefined; } const rest = exports.NodeId.fromBuiltIn(id); const sep = rest.indexOf(':'); return sep > 0 ? [rest.slice(0, sep), rest.slice(sep + 1)] : undefined; }, /** * Converts a built-in function or operator name or id to a built-in id by prefixing it with the built-in prefix if it is not already a built-in id. * This allows us to accept both built-in names and ids in contexts where we want to work with built-in ids. */ mapBuiltInProc(proc) { const bi = 'builtin:'; return exports.NodeId.toBuiltIn(proc.startsWith(bi) ? proc.slice(bi.length) : proc); }, /** * Recovers the built-in function or operator name from a built-in id by removing the built-in prefix. * @see {@link isBuiltIn} - to check if a given node id is a built-in function or operator id * @see {@link toBuiltIn} - to convert a built-in function or operator name to a built-in id */ fromBuiltIn(id) { return id.slice(builtInPrefixLength); } }; const builtInPrefixLength = exports.NodeId.builtInPrefix.length; /** * Recovers the lexeme of a {@link RNode|node} from its id in the {@link AstIdMap|id map}. * @see {@link recoverContent} - to recover the content of a node */ function recoverName(id, idMap) { return idMap?.get(id)?.lexeme; } /** * Recovers the content of a {@link RNode|node} from its id in the {@link DataflowGraph|dataflow graph}. */ function recoverContent(id, graph) { const vertex = graph.getVertex(id); if (vertex && vertex_1.FunctionCallVertex.is(vertex) && vertex.name) { return identifier_1.Identifier.toString(vertex.name); } const node = graph.idMap?.get(id); if (node === undefined) { return undefined; } const lexeme = node.lexeme ?? node.info.fullLexeme ?? ''; if (vertex_1.UseVertex.is(vertex)) { return (0, retriever_1.removeRQuotes)(lexeme); } return lexeme; } //# sourceMappingURL=node-id.js.map