UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

73 lines 3.83 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 linker_1 = require("../../dataflow/internal/linker"); const general_1 = require("../../dataflow/eval/values/general"); const resolve_helper_1 = require("../../dataflow/environments/resolve-helper"); const df_helper_1 = require("../../dataflow/graph/df-helper"); exports.STOP_WITH_CALL_ARG = { createSearch: () => flowr_search_builder_1.Q.var('stop').filter(vertex_1.VertexType.FunctionCall), processSearchResult: async (elements, _config, data) => { const dataflow = await data.dataflow(); const meta = { consideredNodes: 0 }; return { results: elements.getElements() .filter(element => { //only built-in functions const origins = df_helper_1.Dataflow.origin(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 = resolve_helper_1.Resolve.toValue(argId, { graph: dataflow.graph, environment: fCall.environment, ctx: data.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 => `\`stop()\` without \`call. = FALSE\` at ${range_1.SourceLocation.format(result.loc)}`, [linter_format_1.LintingPrettyPrintContext.Full]: result => `\`stop()\` at ${range_1.SourceLocation.format(result.loc)} is called without \`call. = FALSE\`; the originating call is then appended to the error message, which is usually not intended - pass \`call. = FALSE\` to suppress it`, }, 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