UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

80 lines 3.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.loops = void 0; const common_syntax_probability_1 = require("../../common-syntax-probability"); const post_process_1 = require("./post-process"); const type_1 = require("../../../../r-bridge/lang-4.x/ast/model/type"); const statistics_file_1 = require("../../../output/statistics-file"); const visitor_1 = require("../../../../r-bridge/lang-4.x/ast/model/processing/visitor"); const initialLoopInfo = { forLoops: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(), forLoopVar: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(), forBody: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(), whileLoops: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(), whileBody: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(), repeatLoops: 0n, repeatBody: (0, common_syntax_probability_1.emptyCommonSyntaxTypeCounts)(), breakStatements: 0, nextStatements: 0, /** apply, tapply, lapply, ...*/ implicitLoops: 0, nestedExplicitLoops: 0, deepestExplicitNesting: 0 }; const isImplicitLoop = /[lsvmt]?apply/; function visitLoops(info, input) { // holds number of loops and their nesting depths const loopStack = []; (0, visitor_1.visitAst)(input.normalizedRAst.ast, node => { switch (node.type) { case type_1.RType.Next: info.nextStatements++; return; case type_1.RType.Break: info.breakStatements++; return; case type_1.RType.FunctionCall: if (node.named && isImplicitLoop.test(node.functionName.lexeme)) { info.implicitLoops++; (0, statistics_file_1.appendStatisticsFile)(exports.loops.name, 'implicit-loop', [node.functionName.info.fullLexeme ?? node.functionName.lexeme], input.filepath); } return; case type_1.RType.ForLoop: (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.forLoops, node.vector); (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.forLoopVar, node.variable); (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.forBody, ...node.body.children); break; case type_1.RType.WhileLoop: (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.whileLoops, node.condition); (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.whileBody, ...node.body.children); break; case type_1.RType.RepeatLoop: info.repeatLoops++; (0, common_syntax_probability_1.updateCommonSyntaxTypeCounts)(info.repeatBody, ...node.body.children); break; default: return; } (0, statistics_file_1.appendStatisticsFile)(exports.loops.name, 'all-loops', [node.info.fullLexeme ?? node.lexeme], input.filepath); if (loopStack.length > 0) { info.nestedExplicitLoops++; info.deepestExplicitNesting = Math.max(info.deepestExplicitNesting, loopStack.length); } loopStack.push(node); }, node => { // drop again :D if (node.type === type_1.RType.ForLoop || node.type === type_1.RType.WhileLoop || node.type === type_1.RType.RepeatLoop) { loopStack.pop(); } }); } exports.loops = { name: 'Loops', description: 'All looping structures in the document', process(existing, input) { visitLoops(existing, input); return existing; }, initialValue: initialLoopInfo, postProcess: post_process_1.postProcess }; //# sourceMappingURL=loops.js.map