Skip to content

Cognitive complexity (CognitiveComplexity)

Type Scope Severity Activated
by default
Minutes
to fix
Tags
Code smell BSL
OS
Critical Yes 15 brainoverload

Parameters

Name Type Description Default value
complexityThreshold Integer Complexity threshold 15
checkModuleBody Boolean Check module body true

Description

Cognitive complexity shows how difficult it is to perceive the written code.
High cognitive complexity clearly indicates the need for refactoring to make future support easier.
The most effective way to reduce cognitive complexity is to decompose the code, split the methods into simpler ones, and also optimize logical expressions.

Cognitive Complexity calculation

Bellow are given code analysis rules, conditions increase cognitive complexity.

Each next block increases complexity by 1

// Loop `For each`
For Each Element in Collection Do                    // +1
EndDo;

// Loop `For`
For i = StartValue To EndValue Do                    // +1
EndDo;

// Loop `While`
While Condition Do                                   // +1
EndDo;


// Condition
If Condition1 Then                                   // +1

// Alternative condition branch
ElseIf Condition2 Then                               // +1

// default branch
Else
EndIf;

// ternary operator
Value = ?(Condition, ValueTrue, ValueFalse);         // +1

Try
// Exception handling
Except                                               // +1
EndTry;

// Go to label
Goto ~Label;                                          // +1

// Binary logical operations

While Condition1 Or Condition2 Do                    // +2
EndDo;

If Condition1 And Condition2 Then                    // +2

ElseIf Condition2                                    // +1
        Or Condition3 And Condition4 Then            // +2

EndIf;

Value = ?(Condition1 Or Condition2 Or Not Condition3,// +3
                ValueTrue, ValueFalse);

Value = First Or Second;                             // +1

Value = A <> B;                                      // +1

For each nesting level, next blocks get additional 1 to complexity

// Loop `For each`
For Each Element in Collection Do
EndDo;

// Loop `For`
For i = StartValue To EndValue Do
EndDo;

// Loop `While`
While Condition Do
EndDo;

// Condition
If Condition1 Then
EndIf;

// ternary operator
Value = ?(Condition, ValueTrue, ValueFalse);

Try
// Exception handling
Except
EndTry;

~Label:

Alternative branches, binary operations, and go to label do not increase cognitive complexity when nested

Examples

Bellow are code examples and their cognitive complexity calculation.

Function Example1(ClassType)
    If ClassType.Unknown() Then                                                  // +1, condition expression, no nesting
        Return Chars.UnknownSymbol;
    EndIf;

    AmbiguityFound = False;
    ListSymbols = ClassType.GetSymbol().Children.Find("name");
    For Each Symbol in ListSymbols Do
// +1, loop, no nesting
        If Symbol.HasType(Symbols.Strage)                                         // +2, condition nested in loop, nesting 1
            AND NOT Symbols.Export() Then                                            // +1, logival operation, nesting not taken into account

            If CanOverride(Symbol) Then                                     // +3, nested condition, nesting 2
                Overrideability = CheckOverrideability(Symbol, ClassType);
                If Overrideability = Undefined Then                           // +4, nested condition, nesting 3
                    If NOT AmbiguityFound Then                                 // +5, nested condition, nesting 4
                        AmbiguityFound = True;
                    EndIf;
                ElseIf Overrideability Then                                     // +1, alternative condition branch, nesting not taken into account
                    Return Symbol;
                EndIf;
            Else                                                                      // +1, default branch, nesting not taken into account
                Continue;
            EndIf;
        EndIf;
    EndDo;

    If AmbiguityFound Then                                                   // +1, no nesting
        Return Symbols.UnknownSymbol;
    EndIf;

    Return Undefined;
EndFunction
Function Example2(Document)
    StartTransaction();
    NeedPost = ?(Document.Posted, FALSE,                                                         // +1, ternary operator
                                        ?(Document.DeletionMark, FALSE, TRUE));                  // +2, nested ternary operator, nesting 1
    Try                                                                                          // +0, try increases nesting level
        DocumentObject = Document.GetObject();
        If DocumentObject.Posted Then                                                            // +2, nested condition, nesting 1
            For Each TabularSectionLine Из DocumentObject.TabularSection Do                      // +3, nested loop, nesting 2
                If TabularSectionLine.Column1 = 7                                                // +4, nested condition, nesting 3
                        OR TabularSectionLine.Column2 = 7 Then                                   // +1, logical operation, nesting not taken into account
                    Continue;
                EndIf;
                If TabularSectionLine.Column4 > 1 Then                                          // +4, nested condition, nesting 3
                    Break;
                Else                                                                            // +1, default branch, nesting not taken into account
                    If TabularSectionLine.Column1 + TabularSectionLine.Column2 = 2 Then         // +5, nested condition, nesting 4
                        TabularSectionLine.Column10 = TabularSectionLine.Column1 * 2;
                    EndIf;
                EndIf;
            EndDo;
        Else                                                                                    // +1, default branch, nesting not taken into account
            NeedPost = DocumentObject.Date > CurrentDate();                                     // +1, logical operation, nesting not taken into account
            Goto ~Label;                                                                        // +1, go to label, nesting not taken into account
        EndIf;

        If NeedPost Then                                                                        // +2, nested condition, nesting 1
            DocumentObject.Write(DocumentWriteMode.Posting);
        ElseIf NOT NeedPost Then                                                                // +1, alternative branch, nesting not taken into account
            DocumentObject.Write(DocumentWriteMode.Write);
        Else                                                                                    // +1, default branch, nesting not taken into account
            Raise "Why?";
        EndIf;
    Except                                                                                      // +1, except processing
        RetryWrite = FALSE;
        Try                                                                                     // +0, try, increases nesting level
            If DocumentObject.Posted Then                                                       // +3, nested condition, nesting 2
                DocumentObject.Write(DocumentWriteMode.Write);
            EndIf;
        Raise                                                                                   // +2, except processing, nesting 1
            RetryWrite = ИСТИНА;
        EndTry;
        If NOT RetryWrite Then                                                                  // +2, nested condition, nesting 1
            While TransactionIsActive() Do                                                      // +3, nested loop, nesting 2
                CancelTransaction();
            EndDo;
        EndIf;
        Raise "Error"
    EndTry;

    ~Label:
    Return Undefined;
EndFunction

Sources

Snippets

Diagnostic ignorance in code

// BSLLS:CognitiveComplexity-off
// BSLLS:CognitiveComplexity-on

Parameter for config

"CognitiveComplexity": {
    "complexityThreshold": 15,
    "checkModuleBody": true
}