UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

72 lines 3.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.STOP_WITH_CALL_ARG = void 0; const linter_format_1 = require("../linter-format"); const range_1 = require("../../util/range"); const flowr_search_builder_1 = require("../../search/flowr-search-builder"); const linter_tags_1 = require("../linter-tags"); const assert_1 = require("../../util/assert"); const vertex_1 = require("../../dataflow/graph/vertex"); const alias_tracking_1 = require("../../dataflow/eval/resolve/alias-tracking"); const dfg_get_origin_1 = require("../../dataflow/origin/dfg-get-origin"); const linker_1 = require("../../dataflow/internal/linker"); const general_1 = require("../../dataflow/eval/values/general"); exports.STOP_WITH_CALL_ARG = { createSearch: () => flowr_search_builder_1.Q.var('stop').filter(vertex_1.VertexType.FunctionCall), processSearchResult: (elements, _config, { dataflow, analyzer }) => { const meta = { consideredNodes: 0 }; return { results: elements.getElements() .filter(element => { //only built-in functions const origins = (0, dfg_get_origin_1.getOriginInDfg)(dataflow.graph, element.node.info.id); if ((0, assert_1.isNotUndefined)(origins)) { const builtIn = origins.every(e => e.type === 3 /* OriginType.BuiltInFunctionOrigin */); if (!builtIn) { return false; } } const fCall = dataflow.graph.getVertex(element.node.info.id); //filter out function calls with argument "call." set to false const stopParamMap = { '...': '...', 'call.': 'call.', 'domain': 'domain' }; const mapping = (0, linker_1.pMatch)(fCall.args, stopParamMap); const mappedToStop = mapping.get('call.') ?? []; for (const argId of mappedToStop) { const res = (0, alias_tracking_1.resolveIdToValue)(argId, { graph: dataflow.graph, environment: fCall.environment, ctx: analyzer.inspectContext() }); const values = (0, general_1.valueSetGuard)(res); if (values?.type === 'set' && values.elements.length !== 0) { if (values.elements[0].type === 'logical') { return values.elements[0].value; } } } return true; }) .map(element => ({ certainty: linter_format_1.LintingResultCertainty.Uncertain, involvedId: element.node.info.id, loc: range_1.SourceLocation.fromNode(element.node) })) .filter(element => (0, assert_1.isNotUndefined)(element.loc)), '.meta': meta }; }, prettyPrint: { [linter_format_1.LintingPrettyPrintContext.Query]: result => `Code at ${range_1.SourceLocation.format(result.loc)}`, [linter_format_1.LintingPrettyPrintContext.Full]: result => `Code at ${range_1.SourceLocation.format(result.loc)} does call stop without setting call. to FALSE`, }, info: { name: 'Stop without call.=False argument', tags: [linter_tags_1.LintingRuleTag.Smell], certainty: linter_format_1.LintingRuleCertainty.BestEffort, description: 'Checks whether stop calls without call. argument set to FALSE are used.', defaultConfig: {} } }; //# sourceMappingURL=stop-with-call-arg.js.map