PHP_CodeSniffer
[ class tree: PHP_CodeSniffer ] [ index: PHP_CodeSniffer ] [ all elements ]

Source for file SelfMemberReferenceSniff.php

Documentation is available at SelfMemberReferenceSniff.php

  1. <?php
  2. /**
  3.  * Tests self member references.
  4.  *
  5.  * Verifies that :
  6.  * - self:: is used instead of Self::
  7.  * - self:: is used for local static member reference
  8.  * - self:: is used instead of self ::
  9.  *
  10.  * @author    Greg Sherwood <gsherwood@squiz.net>
  11.  * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  12.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  13.  */
  14.  
  15. namespace PHP_CodeSniffer\Standards\Squiz\Sniffs\Classes;
  16.  
  17. use PHP_CodeSniffer\Sniffs\AbstractScopeSniff;
  18. use PHP_CodeSniffer\Files\File;
  19.  
  20. class SelfMemberReferenceSniff extends AbstractScopeSniff
  21. {
  22.  
  23.  
  24.     /**
  25.      * Constructs a Squiz_Sniffs_Classes_SelfMemberReferenceSniff.
  26.      */
  27.     public function __construct()
  28.     {
  29.         parent::__construct(array(T_CLASS)array(T_DOUBLE_COLON));
  30.  
  31.     }//end __construct()
  32.  
  33.  
  34.     /**
  35.      * Processes the function tokens within the class.
  36.      *
  37.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
  38.      * @param int                         $stackPtr  The position where the token was found.
  39.      * @param int                         $currScope The current scope opener token.
  40.      *
  41.      * @return void 
  42.      */
  43.     protected function processTokenWithinScope(File $phpcsFile$stackPtr$currScope)
  44.     {
  45.         $tokens $phpcsFile->getTokens();
  46.  
  47.         $calledClassName ($stackPtr - 1);
  48.         if ($tokens[$calledClassName]['code'=== T_SELF{
  49.             if ($tokens[$calledClassName]['content'!== 'self'{
  50.                 $error 'Must use "self::" for local static member reference; found "%s::"';
  51.                 $data  = array($tokens[$calledClassName]['content']);
  52.                 $fix   $phpcsFile->addFixableError($error$calledClassName'IncorrectCase'$data);
  53.                 if ($fix === true{
  54.                     $phpcsFile->fixer->replaceToken($calledClassName'self');
  55.                 }
  56.  
  57.                 return;
  58.             }
  59.         else if ($tokens[$calledClassName]['code'=== T_STRING{
  60.             // If the class is called with a namespace prefix, build fully qualified
  61.             // namespace calls for both current scope class and requested class.
  62.             if ($tokens[($calledClassName - 1)]['code'=== T_NS_SEPARATOR{
  63.                 $declarationName        $this->getDeclarationNameWithNamespace($tokens$calledClassName);
  64.                 $declarationName        substr($declarationName1);
  65.                 $fullQualifiedClassName $this->getNamespaceOfScope($phpcsFile$currScope);
  66.                 if ($fullQualifiedClassName === '\\'{
  67.                     $fullQualifiedClassName '';
  68.                 else {
  69.                     $fullQualifiedClassName .= '\\';
  70.                 }
  71.  
  72.                 $fullQualifiedClassName .= $phpcsFile->getDeclarationName($currScope);
  73.             else {
  74.                 $declarationName        $phpcsFile->getDeclarationName($currScope);
  75.                 $fullQualifiedClassName $tokens[$calledClassName]['content'];
  76.             }
  77.  
  78.             if ($declarationName === $fullQualifiedClassName{
  79.                 // Class name is the same as the current class, which is not allowed
  80.                 // except if being used inside a closure.
  81.                 if ($phpcsFile->hasCondition($stackPtrT_CLOSURE=== false{
  82.                     $error 'Must use "self::" for local static member reference';
  83.                     $fix   $phpcsFile->addFixableError($error$calledClassName'NotUsed');
  84.  
  85.                     if ($fix === true{
  86.                         $prev $phpcsFile->findPrevious(array(T_NS_SEPARATORT_STRING)($stackPtr - 1)nulltrue);
  87.                         $phpcsFile->fixer->beginChangeset();
  88.                         for ($i ($prev + 1)$i $stackPtr$i++{
  89.                             $phpcsFile->fixer->replaceToken($i'');
  90.                         }
  91.  
  92.                         $phpcsFile->fixer->replaceToken($stackPtr'self::');
  93.                         $phpcsFile->fixer->endChangeset();
  94.                     }
  95.  
  96.                     return;
  97.                 }
  98.             }//end if
  99.         }//end if
  100.  
  101.         if ($tokens[($stackPtr - 1)]['code'=== T_WHITESPACE{
  102.             $found strlen($tokens[($stackPtr - 1)]['content']);
  103.             $error 'Expected 0 spaces before double colon; %s found';
  104.             $data  = array($found);
  105.             $fix   $phpcsFile->addFixableError($error$calledClassName'SpaceBefore'$data);
  106.  
  107.             if ($fix === true{
  108.                 $phpcsFile->fixer->replaceToken(($stackPtr - 1)'');
  109.             }
  110.         }
  111.  
  112.         if ($tokens[($stackPtr + 1)]['code'=== T_WHITESPACE{
  113.             $found strlen($tokens[($stackPtr + 1)]['content']);
  114.             $error 'Expected 0 spaces after double colon; %s found';
  115.             $data  = array($found);
  116.             $fix   $phpcsFile->addFixableError($error$calledClassName'SpaceAfter'$data);
  117.  
  118.             if ($fix === true{
  119.                 $phpcsFile->fixer->replaceToken(($stackPtr + 1)'');
  120.             }
  121.         }
  122.  
  123.     }//end processTokenWithinScope()
  124.  
  125.  
  126.     /**
  127.      * Processes a token that is found within the scope that this test is
  128.      * listening to.
  129.      *
  130.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
  131.      * @param int                         $stackPtr  The position in the stack where this
  132.      *                                                token was found.
  133.      *
  134.      * @return void 
  135.      */
  136.     protected function processTokenOutsideScope(File $phpcsFile$stackPtr)
  137.     {
  138.  
  139.     }//end processTokenOutsideScope()
  140.  
  141.  
  142.     /**
  143.      * Returns the declaration names for classes/interfaces/functions with a namespace.
  144.      *
  145.      * @param array $tokens   Token stack for this file
  146.      * @param int   $stackPtr The position where the namespace building will start.
  147.      *
  148.      * @return string 
  149.      */
  150.     protected function getDeclarationNameWithNamespace(array $tokens$stackPtr)
  151.     {
  152.         $nameParts      = array();
  153.         $currentPointer $stackPtr;
  154.         while ($tokens[$currentPointer]['code'=== T_NS_SEPARATOR
  155.             || $tokens[$currentPointer]['code'=== T_STRING
  156.         {
  157.             $nameParts[$tokens[$currentPointer]['content'];
  158.             $currentPointer--;
  159.         }
  160.  
  161.         $nameParts = array_reverse($nameParts);
  162.         return implode(''$nameParts);
  163.  
  164.     }//end getDeclarationNameWithNamespace()
  165.  
  166.  
  167.     /**
  168.      * Returns the namespace declaration of a file.
  169.      *
  170.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
  171.      * @param int                         $stackPtr  The position where the search for the
  172.      *                                                namespace declaration will start.
  173.      *
  174.      * @return string 
  175.      */
  176.     protected function getNamespaceOfScope(File $phpcsFile$stackPtr)
  177.     {
  178.         $namespace            '\\';
  179.         $namespaceDeclaration $phpcsFile->findPrevious(T_NAMESPACE$stackPtr);
  180.  
  181.         if ($namespaceDeclaration !== false{
  182.             $endOfNamespaceDeclaration $phpcsFile->findNext(T_SEMICOLON$namespaceDeclaration);
  183.             $namespace $this->getDeclarationNameWithNamespace(
  184.                 $phpcsFile->getTokens(),
  185.                 ($endOfNamespaceDeclaration - 1)
  186.             );
  187.         }
  188.  
  189.         return $namespace;
  190.  
  191.     }//end getNamespaceOfScope()
  192.  
  193.  
  194. }//end class

Documentation generated on Mon, 11 Mar 2019 15:27:46 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.