UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

115 lines 4.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveSingleIndex = resolveSingleIndex; exports.filterIndices = filterIndices; exports.constructNestedAccess = constructNestedAccess; exports.addSubIndicesToLeafIndices = addSubIndicesToLeafIndices; const resolve_by_name_1 = require("../dataflow/environments/resolve-by-name"); const vertex_1 = require("../dataflow/graph/vertex"); const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call"); const type_1 = require("../r-bridge/lang-4.x/ast/model/type"); /** * Resolves {@link accessedArg} in the {@link environment} and filters its indices according to {@link accessArg}. * * @param accessedArg - The argument to resolve * @param accessArg - The argument which is used to filter the indices * @param environment - The environment in which {@link accessedArg} is resolved * @returns The filtered {@link ContainerIndicesCollection} of the resolved {@link accessedArg} */ function resolveSingleIndex(accessedArg, accessArg, environment) { const definitions = (0, resolve_by_name_1.resolveByName)(accessedArg.lexeme, environment); const indicesCollection = definitions?.flatMap(def => def?.indicesCollection ?? []); const accessedIndicesCollection = filterIndices(indicesCollection, accessArg); return accessedIndicesCollection; } /** * Filters the single indices of the {@link indicesCollection} according to the lexeme of the {@link accessArg}. * * @param indicesCollection - The {@link ContainerIndicesCollection} to filter * @param accessArg - The argument which is used to filter {@link indicesCollection} * @returns The filtered copy of {@link indicesCollection} */ function filterIndices(indicesCollection, accessArg) { let accessedIndicesCollection = undefined; for (const indices of indicesCollection ?? []) { const filteredIndices = indices.indices.filter(index => accessArg.lexeme === index.lexeme); if (filteredIndices.length == 0) { continue; } accessedIndicesCollection ??= []; accessedIndicesCollection.push({ indices: filteredIndices, isContainer: indices.isContainer }); } return accessedIndicesCollection; } /** * Constructs the definition of a nested access. * * Example: * ```r * person$credentials$username * ``` * would result in a list with the index `credentials`, which has the subIndex `username`. * * @param accessedArg - The top level argument that is accessed * @param leafIndices - The index at the end of the nested access i.e. `c` in `a$b$c`. * @returns The constructed nested access */ function constructNestedAccess(accessedArg, leafIndices) { const accessed = accessedArg.accessed; const accesses = accessedArg.access.filter(arg => arg !== r_function_call_1.EmptyArgument).map(arg => arg); const indices = []; for (const access of accesses) { const newIndices = { indices: [ { lexeme: access.lexeme, nodeId: access.info.id, subIndices: [leafIndices], } ], isContainer: false, }; if (accessed.type === type_1.RType.Access) { const nestedIndices = constructNestedAccess(accessed, newIndices); indices.push(...nestedIndices); } else { indices.push(newIndices); } } return indices; } /** * Adds the passed list of {@link leafSubIndices} to the leaf (sub-)indices of {@link indicesCollection}. * * @param indicesCollection - Indices where to add the sub indices. * @param leafSubIndices - Indices that are added to the leaf indices. */ function addSubIndicesToLeafIndices(indicesCollection, leafSubIndices) { const result = []; for (const indices of indicesCollection) { const newIndices = []; for (const index of indices.indices) { let newSubIndices = []; if ((0, vertex_1.isParentContainerIndex)(index)) { newSubIndices = addSubIndicesToLeafIndices(index.subIndices, leafSubIndices); } else { newSubIndices = leafSubIndices; } newIndices.push({ ...index, subIndices: newSubIndices, }); } result.push({ ...indices, indices: newIndices, }); } return result; } //# sourceMappingURL=list-access.js.map