CRAP |
Complexity |
Coverage |
Location |
1.00 |
1 |
17/18 (94.44%) |
eslint-plugin-crap/complexity.ts
(L27 - L135)
|
create(context) {
// Using a stack to store complexity per code path
const complexities: number[] = [];
function increaseComplexity(): void {
complexities[complexities.length - 1]++;
}
return {
onCodePathStart() {
// The initial complexity is 1, representing one execution path in the CodePath
complexities.push(1);
},
// Each branching in the code adds 1 to the complexity
CatchClause: increaseComplexity,
ConditionalExpression: increaseComplexity,
LogicalExpression: increaseComplexity,
ForStatement: increaseComplexity,
ForInStatement: increaseComplexity,
ForOfStatement: increaseComplexity,
IfStatement: increaseComplexity,
WhileStatement: increaseComplexity,
DoWhileStatement: increaseComplexity,
// Avoid `default`
"SwitchCase[test]": increaseComplexity,
// Logical assignment operators have short-circuiting behavior
AssignmentExpression(node) {
if (isLogicalAssignmentOperator(node.operator)) {
increaseComplexity();
}
},
onCodePathEnd: ((codePath: any, node: any) => {
const complexity = complexities.pop()!;
/*
* This rule only evaluates complexity of functions, so "program" is excluded.
*/
if (codePath.origin !== "function") {
return;
}
context.report({
node,
messageId: "function",
data: {
name: ASTUtils.getFunctionNameWithKind(node),
complexity,
},
});
}) as any, // onCodePathEnd is not typed in @typescript-eslint/utils, neither is CodePath
// report enums, so that we can match them against the coverage data
TSEnumDeclaration: (node) => {
context.report({
node,
messageId: "enum",
data: {
name: `enum '${node.id.name}'`,
},
});
},
// report classes, so that we can match them against the coverage data
ClassDeclaration: (node) => {
const name = node.id ? `class '${node.id.name}'` : "anonymous class";
context.report({
node,
messageId: "class",
data: {
name,
},
});
},
ClassExpression: (node) => {
const name = node.id ? `class '${node.id.name}'` : "anonymous class";
context.report({
node,
messageId: "class",
data: {
name,
},
});
},
// report exports, so that we can match them against the coverage data
ExportAllDeclaration: (node) => {
context.report({
node,
messageId: "export",
});
},
ExportDefaultDeclaration: (node) => {
context.report({
node,
messageId: "export",
});
},
ExportNamedDeclaration: (node) => {
context.report({
node,
messageId: "export",
});
},
};
},