@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
69 lines • 3.15 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.controlflow = void 0;
const common_syntax_probability_1 = require("../../common-syntax-probability");
const post_process_1 = require("./post-process");
const unpack_argument_1 = require("../../../../dataflow/internal/process/functions/call/argument/unpack-argument");
const type_1 = require("../../../../r-bridge/lang-4.x/ast/model/type");
const visitor_1 = require("../../../../r-bridge/lang-4.x/ast/model/processing/visitor");
const initialControlflowInfo = {
ifThen: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(),
thenBody: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(),
ifThenElse: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(),
elseBody: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(),
/** can be nested with if-s or if-then-else's */
nestedIfThen: 0,
nestedIfThenElse: 0,
deepestNesting: 0,
/** switch(...) */
switchCase: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)()
};
function visitIfThenElse(info, input) {
const ifThenElseStack = [];
(0, visitor_1.visitAst)(input.normalizedRAst.ast, node => {
if (node.type !== type_1.RType.IfThenElse) {
if (node.type === type_1.RType.FunctionCall && node.named && node.functionName.content === 'switch') {
const initialArg = (0, unpack_argument_1.unpackArgument)(node.arguments[0]);
if (initialArg) {
info.switchCase = (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.switchCase, initialArg);
}
}
return;
}
const ifThenElse = node.otherwise !== undefined;
if (ifThenElseStack.length > 0) {
if (ifThenElse) {
info.nestedIfThenElse++;
}
else {
info.nestedIfThen++;
}
info.deepestNesting = Math.max(info.deepestNesting, ifThenElseStack.length);
}
ifThenElseStack.push(node);
info.thenBody = (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.thenBody, ...node.then.children);
if (ifThenElse) {
info.ifThenElse = (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.ifThenElse, node.condition);
info.elseBody = (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.elseBody, ...node.otherwise.children);
}
else {
info.ifThen = (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.ifThen, node.condition);
}
}, node => {
// drop again :D
if (node.type === type_1.RType.IfThenElse) {
ifThenElseStack.pop();
}
});
}
exports.controlflow = {
name: 'Controlflow',
description: 'Deals with if-then-else and switch-case',
process(existing, input) {
visitIfThenElse(existing, input);
return existing;
},
initialValue: initialControlflowInfo,
postProcess: post_process_1.postProcess
};
//# sourceMappingURL=control-flow.js.map