pneulint
Version:
Static code analysis tool for better code
1 lines • 1.86 kB
JavaScript
import fs from"fs";import path from"path";import*as parser from"@babel/parser";import pkg from"@babel/traverse";import chalk from"chalk";const{default:traverse}=pkg;function realComplexity(e,t,n){const o=parser.parse(e,{plugins:["typescript"],sourceType:"module"}),a=[],r={FunctionDeclaration:1.2,ArrowFunctionExpression:1.2,FunctionExpression:1.2,ForStatement:1.3,ForInStatement:1.3,ForOfStatement:1.3,WhileStatement:1.3,DoWhileStatement:1.3,IfStatement:1.1,SwitchStatement:1.2,TryStatement:1.5,CatchClause:1.4,LogicalExpression:1.1,ConditionalExpression:1.1,ClassDeclaration:1.3,MethodDefinition:1.2,NewExpression:1.3,CallExpression:1.1};traverse(o,{enter(e){if(e.isFunction()){let t=[],n=e.node.id?e.node.id.name:"anonymous",o=e.node.loc?e.node.loc.start.line:"unknown";if("anonymous"===n){let t=e.findParent((e=>e.isCallExpression()||e.isVariableDeclarator()||e.isObjectProperty()||e.isAssignmentExpression()));if(t)if(t.isCallExpression()){const e=t.node.callee;n="MemberExpression"===e.type&&e.property?e.property.name:e.name;const o=t.node.arguments;o.length>0&&("StringLiteral"===o[0].type||"TemplateLiteral"===o[0].type)&&(n+=`(${o[0].value||o[0].quasis[0].value.raw})`)}else t.isVariableDeclarator()&&t.node.id.name?n=t.node.id.name:t.isObjectProperty()&&t.node.key.name?n=t.node.key.name:t.isAssignmentExpression()&&t.node.left.property&&t.node.left.property.name&&(n=t.node.left.property.name)}e.traverse({enter(e){r[e.node.type]&&t.push(r[e.node.type])}});let i=t.reduce(((e,t)=>e*(1+t)),1),s=Math.log(i);a.push({functionName:n,startLine:o,scaledComplexity:s})}}}),a.forEach((e=>{e.scaledComplexity>n&&console.log(chalk.yellow("Warning:")+" High complexity ("+chalk.red(e.scaledComplexity.toFixed(2))+") detected in "+chalk.green(e.functionName)+" at line "+chalk.cyan(e.startLine)+" in "+chalk.magenta(t)+".")}))}export default realComplexity;