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",
                    });
                },
            };
        },