@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
72 lines • 3.66 kB
JavaScript
;
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