Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ComplexityRule = rule.Rule{ Name: "complexity", Run: func(ctx rule.RuleContext, options any) rule.RuleListeners { threshold, isModified := parseOptions(options) counters := map[*ast.Node]int{} findOwner := func(n *ast.Node) *ast.Node { cur := n.Parent prev := n for cur != nil { if ast.IsFunctionLikeDeclaration(cur) { return cur } if cur.Kind == ast.KindClassStaticBlockDeclaration { return cur } if cur.Kind == ast.KindPropertyDeclaration { propDecl := cur.AsPropertyDeclaration() if propDecl != nil && propDecl.Initializer != nil && propDecl.Initializer == prev && !ast.IsFunctionLikeDeclaration(propDecl.Initializer) { return cur } } prev = cur cur = cur.Parent } return nil } increment := func(node *ast.Node) { owner := findOwner(node) if owner == nil { return } counters[owner]++ } startFunc := func(node *ast.Node) { counters[node] = 1 } endFunc := func(node *ast.Node) { complexity, ok := counters[node] if !ok { return } delete(counters, node) if complexity > threshold { name := utils.UpperCaseFirstASCII(getFunctionNameWithKind(node)) loc := utils.GetFunctionHeadLoc(ctx.SourceFile, node) ctx.ReportRange(loc, makeMessage(name, complexity, threshold)) } } startStaticBlock := func(node *ast.Node) { counters[node] = 1 } endStaticBlock := func(node *ast.Node) { complexity, ok := counters[node] if !ok { return } delete(counters, node) if complexity > threshold { trimmedStart := utils.TrimNodeTextRange(ctx.SourceFile, node).Pos() tokenRange := scanner.GetRangeOfTokenAtPosition(ctx.SourceFile, trimmedStart) ctx.ReportRange(tokenRange, makeMessage("Class static block", complexity, threshold)) } } startProp := func(node *ast.Node) { propDecl := node.AsPropertyDeclaration() if propDecl == nil || propDecl.Initializer == nil || ast.IsFunctionLikeDeclaration(propDecl.Initializer) { return } counters[node] = 1 } endProp := func(node *ast.Node) { complexity, ok := counters[node] if !ok { return } delete(counters, node) if complexity > threshold { propDecl := node.AsPropertyDeclaration() if propDecl == nil || propDecl.Initializer == nil { return } loc := utils.TrimNodeTextRange(ctx.SourceFile, propDecl.Initializer) ctx.ReportRange(loc, makeMessage("Class field initializer", complexity, threshold)) } } return rule.RuleListeners{ ast.KindFunctionDeclaration: startFunc, rule.ListenerOnExit(ast.KindFunctionDeclaration): endFunc, ast.KindFunctionExpression: startFunc, rule.ListenerOnExit(ast.KindFunctionExpression): endFunc, ast.KindArrowFunction: startFunc, rule.ListenerOnExit(ast.KindArrowFunction): endFunc, ast.KindMethodDeclaration: startFunc, rule.ListenerOnExit(ast.KindMethodDeclaration): endFunc, ast.KindGetAccessor: startFunc, rule.ListenerOnExit(ast.KindGetAccessor): endFunc, ast.KindSetAccessor: startFunc, rule.ListenerOnExit(ast.KindSetAccessor): endFunc, ast.KindConstructor: startFunc, rule.ListenerOnExit(ast.KindConstructor): endFunc, ast.KindClassStaticBlockDeclaration: startStaticBlock, rule.ListenerOnExit(ast.KindClassStaticBlockDeclaration): endStaticBlock, ast.KindPropertyDeclaration: startProp, rule.ListenerOnExit(ast.KindPropertyDeclaration): endProp, ast.KindCatchClause: increment, ast.KindConditionalExpression: increment, ast.KindIfStatement: increment, ast.KindWhileStatement: increment, ast.KindDoStatement: increment, ast.KindForStatement: increment, ast.KindForInStatement: increment, ast.KindForOfStatement: increment, ast.KindBinaryExpression: func(node *ast.Node) { bin := node.AsBinaryExpression() if bin == nil || bin.OperatorToken == nil { return } switch bin.OperatorToken.Kind { case ast.KindAmpersandAmpersandToken, ast.KindBarBarToken, ast.KindQuestionQuestionToken, ast.KindAmpersandAmpersandEqualsToken, ast.KindBarBarEqualsToken, ast.KindQuestionQuestionEqualsToken: increment(node) } }, ast.KindCaseClause: func(node *ast.Node) { if !isModified { increment(node) } }, ast.KindSwitchStatement: func(node *ast.Node) { if isModified { increment(node) } }, ast.KindPropertyAccessExpression: func(node *ast.Node) { pae := node.AsPropertyAccessExpression() if pae != nil && pae.QuestionDotToken != nil { increment(node) } }, ast.KindElementAccessExpression: func(node *ast.Node) { eae := node.AsElementAccessExpression() if eae != nil && eae.QuestionDotToken != nil { increment(node) } }, ast.KindCallExpression: func(node *ast.Node) { ce := node.AsCallExpression() if ce != nil && ce.QuestionDotToken != nil { increment(node) } }, ast.KindParameter: func(node *ast.Node) { pd := node.AsParameterDeclaration() if pd != nil && pd.Initializer != nil { increment(node) } }, ast.KindBindingElement: func(node *ast.Node) { be := node.AsBindingElement() if be != nil && be.Initializer != nil { increment(node) } }, } }, }
ComplexityRule enforces a maximum cyclomatic complexity allowed in a program. https://eslint.org/docs/latest/rules/complexity
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.