UNPKG

eslint-plugin-complexity

Version:
1 lines 10.6 kB
{"version":3,"file":"index.mjs","sources":["../src/index.mjs"],"sourcesContent":["// modified from https://github.com/eslint/eslint/blob/main/lib/rules/complexity.js\n\nimport { getFunctionNameWithKind } from 'eslint-utils'\n\nconst rule = {\n meta: {\n type: 'suggestion',\n\n docs: {\n description: 'cyclomatic complexity exceeding threshold should has a comment',\n recommended: false,\n },\n\n schema: [\n {\n oneOf: [\n {\n type: 'integer',\n minimum: 0\n },\n {\n type: 'object',\n properties: {\n max: {\n type: 'integer',\n minimum: 0\n }\n },\n additionalProperties: false\n }\n ]\n }\n ],\n\n messages: {\n 'complexity-comment': '{{name}} has a complexity of {{complexity}}, expect a comment'\n }\n },\n\n create( context ) {\n const sourceCode = context.getSourceCode()\n const option = context.options[ 0 ]\n let THRESHOLD = 20\n\n if (\n typeof option === 'object' &&\n Object.prototype.hasOwnProperty.call( option, 'max' ) &&\n typeof option.max === 'number'\n ) {\n THRESHOLD = option.max\n } else if ( typeof option === 'number' ) {\n THRESHOLD = option\n }\n\n //--------------------------------------------------------------------------\n // Helpers\n //--------------------------------------------------------------------------\n\n // Using a stack to store complexity per code path\n const complexities = []\n\n function increaseComplexity() {\n complexities[ complexities.length - 1 ]++\n }\n\n //--------------------------------------------------------------------------\n // Public API\n //--------------------------------------------------------------------------\n\n return {\n onCodePathStart() {\n // The initial complexity is 1, representing one execution path in the CodePath\n complexities.push( 1 )\n },\n\n // Each branching in the code adds 1 to the complexity\n CatchClause: increaseComplexity,\n ConditionalExpression: increaseComplexity,\n LogicalExpression: increaseComplexity,\n ForStatement: increaseComplexity,\n ForInStatement: increaseComplexity,\n ForOfStatement: increaseComplexity,\n IfStatement: increaseComplexity,\n WhileStatement: increaseComplexity,\n DoWhileStatement: increaseComplexity,\n\n // Avoid `default`\n 'SwitchCase[test]': increaseComplexity,\n\n // Logical assignment operators have short-circuiting behavior\n AssignmentExpression( node ) {\n if ( isLogicalAssignmentOperator( node.operator ) ) {\n increaseComplexity()\n }\n },\n\n onCodePathEnd( codePath, node ) {\n const complexity = complexities.pop()\n\n if ( !complexity ) {\n return\n }\n\n /*\n * This rule only evaluates complexity of functions, so \"program\" is excluded.\n * Class field initializers and class static blocks are implicit functions. Therefore,\n * they shouldn't contribute to the enclosing function's complexity, but their\n * own complexity should be evaluated.\n */\n if (\n codePath.origin !== 'function' &&\n codePath.origin !== 'class-field-initializer' &&\n codePath.origin !== 'class-static-block'\n ) {\n return\n }\n\n if ( complexity > THRESHOLD ) {\n let name\n\n if ( codePath.origin === 'class-field-initializer' ) {\n name = 'class field initializer'\n } else if ( codePath.origin === 'class-static-block' ) {\n name = 'class static block'\n } else {\n name = getFunctionNameWithKind( node )\n }\n\n if ( !hasComment( sourceCode, node ) ) {\n context.report( {\n node,\n messageId: 'complexity-comment',\n data: {\n name: name,\n complexity,\n max: THRESHOLD\n }\n } )\n }\n }\n }\n }\n }\n}\n\nfunction hasComment( sourceCode, node ) {\n const comments = sourceCode.getAllComments()\n\n const relatedComments = comments.filter( comment => {\n const isCommentAheadOfNode = node.loc.start.line - comment.loc.end.line === 1\n if ( isCommentAheadOfNode ) {\n return isCodeAroundCommentEmpty( sourceCode, comment )\n }\n\n return false\n } )\n\n return relatedComments.length > 0\n}\n\nfunction isCodeAroundCommentEmpty( sourceCode, commentNode ) {\n const startLine = String( sourceCode.lines[ commentNode.loc.start.line - 1 ] )\n const endLine = String( sourceCode.lines[ commentNode.loc.end.line - 1 ] )\n const preamble = startLine.slice( 0, commentNode.loc.start.column ).trim()\n const postamble = endLine.slice( commentNode.loc.end.column ).trim()\n const isPreambleEmpty = !preamble\n const isPostambleEmpty = !postamble\n\n return isPreambleEmpty && isPostambleEmpty\n}\n\nconst LOGICAL_ASSIGNMENT_OPERATORS = new Set( [ '&&=', '||=', '??=' ] )\nfunction isLogicalAssignmentOperator( operator ) {\n return LOGICAL_ASSIGNMENT_OPERATORS.has( operator )\n}\n\nexport default {\n rules: {\n comment: rule\n }\n}\n"],"names":["rule","meta","type","docs","description","recommended","schema","oneOf","minimum","properties","max","additionalProperties","messages","create","context","sourceCode","getSourceCode","option","options","THRESHOLD","Object","prototype","hasOwnProperty","call","complexities","increaseComplexity","length","onCodePathStart","push","CatchClause","ConditionalExpression","LogicalExpression","ForStatement","ForInStatement","ForOfStatement","IfStatement","WhileStatement","DoWhileStatement","AssignmentExpression","node","isLogicalAssignmentOperator","operator","onCodePathEnd","codePath","complexity","pop","origin","name","getFunctionNameWithKind","hasComment","report","messageId","data","comments","getAllComments","relatedComments","filter","comment","isCommentAheadOfNode","loc","start","line","end","isCodeAroundCommentEmpty","commentNode","startLine","String","lines","endLine","preamble","slice","column","trim","postamble","isPreambleEmpty","isPostambleEmpty","LOGICAL_ASSIGNMENT_OPERATORS","Set","has","rules"],"mappings":"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"}