Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. CognitiveSniff.php

function CognitiveSniff::computeForFunctionFromTokensAndPosition

1 call to CognitiveSniff::computeForFunctionFromTokensAndPosition()
CognitiveSniff::process in vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Complexity/CognitiveSniff.php
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint *

File

vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Complexity/CognitiveSniff.php, line 178

Class

CognitiveSniff
Cognitive Complexity

Namespace

SlevomatCodingStandard\Sniffs\Complexity

Code

public function computeForFunctionFromTokensAndPosition(int $position) : int {
    if (FunctionHelper::isAbstract($this->phpcsFile, $position)) {
        return 0;
    }
    $tokens = $this->phpcsFile
        ->getTokens();
    // Detect start and end of this function definition
    $functionStartPosition = $tokens[$position]['scope_opener'];
    $functionEndPosition = $tokens[$position]['scope_closer'];
    $this->lastBooleanOperator = 0;
    $this->cognitiveComplexity = 0;
    
    /*
    	Keep track of parser's level stack
    	We push to this stak whenever we encounter a Tokens::$scopeOpeners
    */
    $levelStack = [];
    
    /*
    	We look for changes in token[level] to know when to remove from the stack
    	however ['level'] only increases when there are tokens inside {}
    	after pushing to the stack watch for a level change
    */
    $levelIncreased = false;
    for ($i = $functionStartPosition + 1; $i < $functionEndPosition; $i++) {
        $currentToken = $tokens[$i];
        $isNestingToken = false;
        if (in_array($currentToken['code'], Tokens::$scopeOpeners, true)) {
            $isNestingToken = true;
            if ($levelIncreased === false && count($levelStack) > 0) {
                // parser's level never increased
                // caused by empty condition such as `if ($x) { }`
                array_pop($levelStack);
            }
            $levelStack[] = $currentToken;
            $levelIncreased = false;
        }
        elseif (isset($tokens[$i - 1]) && $currentToken['level'] < $tokens[$i - 1]['level']) {
            $diff = $tokens[$i - 1]['level'] - $currentToken['level'];
            array_splice($levelStack, 0 - $diff);
        }
        elseif (isset($tokens[$i - 1]) && $currentToken['level'] > $tokens[$i - 1]['level']) {
            $levelIncreased = true;
        }
        $this->resolveBooleanOperatorChain($currentToken);
        if (!$this->isIncrementingToken($currentToken, $tokens, $i)) {
            continue;
        }
        $this->cognitiveComplexity++;
        $addNestingIncrement = isset(self::NESTING_INCREMENTS[$currentToken['code']]) && in_array($currentToken['code'], [
            T_ELSEIF,
            T_ELSE,
        ], true) === false;
        if (!$addNestingIncrement) {
            continue;
        }
        $measuredNestingLevel = count(array_filter($levelStack, static function (array $token) {
            return in_array($token['code'], self::NESTING_INCREMENTS, true);
        }));
        if ($isNestingToken) {
            $measuredNestingLevel--;
        }
        // B3. Nesting increment
        if ($measuredNestingLevel > 0) {
            $this->cognitiveComplexity += $measuredNestingLevel;
        }
    }
    return $this->cognitiveComplexity;
}
RSS feed
Powered by Drupal