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

Breadcrumb

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

function ModernClassNameReferenceSniff::checkFunctionCall

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

File

vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Classes/ModernClassNameReferenceSniff.php, line 79

Class

ModernClassNameReferenceSniff

Namespace

SlevomatCodingStandard\Sniffs\Classes

Code

private function checkFunctionCall(File $phpcsFile, int $functionPointer) : void {
    $tokens = $phpcsFile->getTokens();
    $functionName = ltrim(strtolower($tokens[$functionPointer]['content']), '\\');
    $functionNames = [
        'get_class',
        'get_parent_class',
        'get_called_class',
    ];
    if (!in_array($functionName, $functionNames, true)) {
        return;
    }
    $openParenthesisPointer = TokenHelper::findNextEffective($phpcsFile, $functionPointer + 1);
    if ($tokens[$openParenthesisPointer]['code'] !== T_OPEN_PARENTHESIS) {
        return;
    }
    $previousPointer = TokenHelper::findPreviousEffective($phpcsFile, $functionPointer - 1);
    if (in_array($tokens[$previousPointer]['code'], [
        T_OBJECT_OPERATOR,
        T_DOUBLE_COLON,
        T_FUNCTION,
    ], true)) {
        return;
    }
    $parameterPointer = TokenHelper::findNextEffective($phpcsFile, $openParenthesisPointer + 1, $tokens[$openParenthesisPointer]['parenthesis_closer']);
    $isObjectParameter = static function () use ($phpcsFile, $tokens, $openParenthesisPointer, $parameterPointer) : bool {
        if ($tokens[$parameterPointer]['code'] !== T_VARIABLE) {
            return false;
        }
        $pointerAfterParameterPointer = TokenHelper::findNextEffective($phpcsFile, $parameterPointer + 1);
        return $pointerAfterParameterPointer === $tokens[$openParenthesisPointer]['parenthesis_closer'];
    };
    $isThisParameter = static function () use ($tokens, $parameterPointer, $isObjectParameter) : bool {
        if (!$isObjectParameter()) {
            return false;
        }
        $parameterName = strtolower($tokens[$parameterPointer]['content']);
        return $parameterName === '$this';
    };
    if ($functionName === 'get_class') {
        if ($parameterPointer === null) {
            $fixedContent = 'self::class';
        }
        elseif ($isThisParameter()) {
            $fixedContent = 'static::class';
        }
        elseif ($this->enableOnObjects && $isObjectParameter()) {
            $fixedContent = sprintf('%s::class', $tokens[$parameterPointer]['content']);
        }
        else {
            return;
        }
    }
    elseif ($functionName === 'get_parent_class') {
        if ($parameterPointer !== null) {
            if (!$isThisParameter()) {
                return;
            }
            
            /** @var int $classPointer */
            $classPointer = FunctionHelper::findClassPointer($phpcsFile, $functionPointer);
            if (!ClassHelper::isFinal($phpcsFile, $classPointer)) {
                return;
            }
        }
        $fixedContent = 'parent::class';
    }
    else {
        $fixedContent = 'static::class';
    }
    $fix = $phpcsFile->addFixableError(sprintf('Class name referenced via call of function %s().', $functionName), $functionPointer, self::CODE_CLASS_NAME_REFERENCED_VIA_FUNCTION_CALL);
    if (!$fix) {
        return;
    }
    $phpcsFile->fixer
        ->beginChangeset();
    if ($tokens[$functionPointer - 1]['code'] === T_NS_SEPARATOR) {
        $phpcsFile->fixer
            ->replaceToken($functionPointer - 1, '');
    }
    FixerHelper::change($phpcsFile, $functionPointer, $tokens[$openParenthesisPointer]['parenthesis_closer'], $fixedContent);
    $phpcsFile->fixer
        ->endChangeset();
}
RSS feed
Powered by Drupal