Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php
<?php
/**
 * Tests self member references.
 *
 * Verifies that :
 * - self:: is used instead of Self::
 * - self:: is used for local static member reference
 * - self:: is used instead of self ::
 *
 * @author    Greg Sherwood <gsherwood@squiz.net>
 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
 */

namespace PHP_CodeSniffer\Standards\Squiz\Sniffs\Classes;

use
PHP_CodeSniffer\Files\File;
use
PHP_CodeSniffer\Sniffs\AbstractScopeSniff;
use
PHP_CodeSniffer\Util\Tokens;

class
SelfMemberReferenceSniff extends AbstractScopeSniff
{


   
/**
     * Constructs a Squiz_Sniffs_Classes_SelfMemberReferenceSniff.
     */
   
public function __construct()
    {
       
parent::__construct([T_CLASS], [T_DOUBLE_COLON]);

    }
//end __construct()


    /**
     * Processes the function tokens within the class.
     *
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
     * @param int                         $stackPtr  The position where the token was found.
     * @param int                         $currScope The current scope opener token.
     *
     * @return void
     */
   
protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
    {
       
$tokens = $phpcsFile->getTokens();

       
// Determine if this is a double colon which needs to be examined.
       
$conditions = $tokens[$stackPtr]['conditions'];
       
$conditions = array_reverse($conditions, true);
        foreach (
$conditions as $conditionToken => $tokenCode) {
            if (
$tokenCode === T_CLASS || $tokenCode === T_ANON_CLASS || $tokenCode === T_CLOSURE) {
                break;
            }
        }

        if (
$conditionToken !== $currScope) {
            return;
        }

       
$calledClassName = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
        if (
$calledClassName === false) {
           
// Parse error.
           
return;
        }

        if (
$tokens[$calledClassName]['code'] === T_SELF) {
            if (
$tokens[$calledClassName]['content'] !== 'self') {
               
$error = 'Must use "self::" for local static member reference; found "%s::"';
               
$data  = [$tokens[$calledClassName]['content']];
               
$fix   = $phpcsFile->addFixableError($error, $calledClassName, 'IncorrectCase', $data);
                if (
$fix === true) {
                   
$phpcsFile->fixer->replaceToken($calledClassName, 'self');
                }

                return;
            }
        } else if (
$tokens[$calledClassName]['code'] === T_STRING) {
           
// If the class is called with a namespace prefix, build fully qualified
            // namespace calls for both current scope class and requested class.
           
$prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($calledClassName - 1), null, true);
            if (
$prevNonEmpty !== false && $tokens[$prevNonEmpty]['code'] === T_NS_SEPARATOR) {
               
$declarationName        = $this->getDeclarationNameWithNamespace($tokens, $calledClassName);
               
$declarationName        = ltrim($declarationName, '\\');
               
$fullQualifiedClassName = $this->getNamespaceOfScope($phpcsFile, $currScope);
                if (
$fullQualifiedClassName === '\\') {
                   
$fullQualifiedClassName = '';
                } else {
                   
$fullQualifiedClassName .= '\\';
                }

               
$fullQualifiedClassName .= $phpcsFile->getDeclarationName($currScope);
            } else {
               
$declarationName        = $phpcsFile->getDeclarationName($currScope);
               
$fullQualifiedClassName = $tokens[$calledClassName]['content'];
            }

            if (
$declarationName === $fullQualifiedClassName) {
               
// Class name is the same as the current class, which is not allowed.
               
$error = 'Must use "self::" for local static member reference';
               
$fix   = $phpcsFile->addFixableError($error, $calledClassName, 'NotUsed');

                if (
$fix === true) {
                   
$phpcsFile->fixer->beginChangeset();

                   
$currentPointer = ($stackPtr - 1);
                    while (
$tokens[$currentPointer]['code'] === T_NS_SEPARATOR
                       
|| $tokens[$currentPointer]['code'] === T_STRING
                       
|| isset(Tokens::$emptyTokens[$tokens[$currentPointer]['code']]) === true
                   
) {
                        if (isset(
Tokens::$emptyTokens[$tokens[$currentPointer]['code']]) === true) {
                            --
$currentPointer;
                            continue;
                        }

                       
$phpcsFile->fixer->replaceToken($currentPointer, '');
                        --
$currentPointer;
                    }

                   
$phpcsFile->fixer->replaceToken($stackPtr, 'self::');
                   
$phpcsFile->fixer->endChangeset();

                   
// Fix potential whitespace issues in the next loop.
                   
return;
                }
//end if
           
}//end if
       
}//end if

       
if ($tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) {
           
$found = $tokens[($stackPtr - 1)]['length'];
           
$error = 'Expected 0 spaces before double colon; %s found';
           
$data  = [$found];
           
$fix   = $phpcsFile->addFixableError($error, ($stackPtr - 1), 'SpaceBefore', $data);

            if (
$fix === true) {
               
$phpcsFile->fixer->beginChangeset();

                for (
$i = ($stackPtr - 1); $tokens[$i]['code'] === T_WHITESPACE; $i--) {
                   
$phpcsFile->fixer->replaceToken($i, '');
                }

               
$phpcsFile->fixer->endChangeset();
            }
        }

        if (
$tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) {
           
$found = $tokens[($stackPtr + 1)]['length'];
           
$error = 'Expected 0 spaces after double colon; %s found';
           
$data  = [$found];
           
$fix   = $phpcsFile->addFixableError($error, ($stackPtr - 1), 'SpaceAfter', $data);

            if (
$fix === true) {
               
$phpcsFile->fixer->beginChangeset();

                for (
$i = ($stackPtr + 1); $tokens[$i]['code'] === T_WHITESPACE; $i++) {
                   
$phpcsFile->fixer->replaceToken($i, '');
                }

               
$phpcsFile->fixer->endChangeset();
            }
        }

    }
//end processTokenWithinScope()


    /**
     * Processes a token that is found within the scope that this test is
     * listening to.
     *
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
     * @param int                         $stackPtr  The position in the stack where this
     *                                               token was found.
     *
     * @return void
     */
   
protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
    {

    }
//end processTokenOutsideScope()


    /**
     * Returns the declaration names for classes/interfaces/functions with a namespace.
     *
     * @param array $tokens   Token stack for this file
     * @param int   $stackPtr The position where the namespace building will start.
     *
     * @return string
     */
   
protected function getDeclarationNameWithNamespace(array $tokens, $stackPtr)
    {
       
$nameParts      = [];
       
$currentPointer = $stackPtr;
        while (
$tokens[$currentPointer]['code'] === T_NS_SEPARATOR
           
|| $tokens[$currentPointer]['code'] === T_STRING
           
|| isset(Tokens::$emptyTokens[$tokens[$currentPointer]['code']]) === true
       
) {
            if (isset(
Tokens::$emptyTokens[$tokens[$currentPointer]['code']]) === true) {
                --
$currentPointer;
                continue;
            }

           
$nameParts[] = $tokens[$currentPointer]['content'];
            --
$currentPointer;
        }

       
$nameParts = array_reverse($nameParts);
        return
implode('', $nameParts);

    }
//end getDeclarationNameWithNamespace()


    /**
     * Returns the namespace declaration of a file.
     *
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
     * @param int                         $stackPtr  The position where the search for the
     *                                               namespace declaration will start.
     *
     * @return string
     */
   
protected function getNamespaceOfScope(File $phpcsFile, $stackPtr)
    {
       
$namespace            = '\\';
       
$namespaceDeclaration = $phpcsFile->findPrevious(T_NAMESPACE, $stackPtr);

        if (
$namespaceDeclaration !== false) {
           
$endOfNamespaceDeclaration = $phpcsFile->findNext([T_SEMICOLON, T_OPEN_CURLY_BRACKET], $namespaceDeclaration);
           
$namespace = $this->getDeclarationNameWithNamespace(
               
$phpcsFile->getTokens(),
                (
$endOfNamespaceDeclaration - 1)
            );
        }

        return
$namespace;

    }
//end getNamespaceOfScope()


}//end class