class ConstructorNameSniff
Hierarchy
- class \PHP_CodeSniffer\Sniffs\AbstractScopeSniff implements \PHP_CodeSniffer\Sniffs\Sniff
- class \PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\ConstructorNameSniff extends \PHP_CodeSniffer\Sniffs\AbstractScopeSniff
Expanded class hierarchy of ConstructorNameSniff
File
-
vendor/
squizlabs/ php_codesniffer/ src/ Standards/ Generic/ Sniffs/ NamingConventions/ ConstructorNameSniff.php, line 20
Namespace
PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventionsView source
class ConstructorNameSniff extends AbstractScopeSniff {
/**
* The name of the class we are currently checking.
*
* @var string
*/
private $currentClass = '';
/**
* A list of functions in the current class.
*
* @var string[]
*/
private $functionList = [];
/**
* Constructs the test with the tokens it wishes to listen for.
*/
public function __construct() {
parent::__construct([
T_CLASS,
T_ANON_CLASS,
], [
T_FUNCTION,
], true);
}
//end __construct()
/**
* Processes this test when one of its tokens is encountered.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The current file being scanned.
* @param int $stackPtr The position of the current token
* in the stack passed in $tokens.
* @param int $currScope A pointer to the start of the scope.
*
* @return void
*/
protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope) {
$tokens = $phpcsFile->getTokens();
// Determine if this is a function which needs to be examined.
$conditions = $tokens[$stackPtr]['conditions'];
end($conditions);
$deepestScope = key($conditions);
if ($deepestScope !== $currScope) {
return;
}
$className = $phpcsFile->getDeclarationName($currScope);
if (empty($className) === false) {
// Not an anonymous class.
$className = strtolower($className);
}
if ($className !== $this->currentClass) {
$this->loadFunctionNamesInScope($phpcsFile, $currScope);
$this->currentClass = $className;
}
$methodName = strtolower($phpcsFile->getDeclarationName($stackPtr));
if ($methodName === $className) {
if (in_array('__construct', $this->functionList, true) === false) {
$error = 'PHP4 style constructors are not allowed; use "__construct()" instead';
$phpcsFile->addError($error, $stackPtr, 'OldStyle');
}
}
else {
if ($methodName !== '__construct') {
// Not a constructor.
return;
}
}
// Stop if the constructor doesn't have a body, like when it is abstract.
if (isset($tokens[$stackPtr]['scope_opener'], $tokens[$stackPtr]['scope_closer']) === false) {
return;
}
$parentClassName = $phpcsFile->findExtendedClassName($currScope);
if ($parentClassName === false) {
return;
}
$parentClassNameLc = strtolower($parentClassName);
$endFunctionIndex = $tokens[$stackPtr]['scope_closer'];
$startIndex = $tokens[$stackPtr]['scope_opener'];
while (($doubleColonIndex = $phpcsFile->findNext(T_DOUBLE_COLON, $startIndex + 1, $endFunctionIndex)) !== false) {
$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $doubleColonIndex + 1, null, true);
if ($tokens[$nextNonEmpty]['code'] !== T_STRING || strtolower($tokens[$nextNonEmpty]['content']) !== $parentClassNameLc) {
$startIndex = $nextNonEmpty;
continue;
}
$prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, $doubleColonIndex - 1, null, true);
if ($tokens[$prevNonEmpty]['code'] === T_PARENT || $tokens[$prevNonEmpty]['code'] === T_SELF || $tokens[$prevNonEmpty]['code'] === T_STATIC || $tokens[$prevNonEmpty]['code'] === T_STRING && strtolower($tokens[$prevNonEmpty]['content']) === $parentClassNameLc) {
$error = 'PHP4 style calls to parent constructors are not allowed; use "parent::__construct()" instead';
$phpcsFile->addError($error, $nextNonEmpty, 'OldStyleCall');
}
$startIndex = $nextNonEmpty;
}
//end while
}
//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()
/**
* Extracts all the function names found in the given scope.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The current file being scanned.
* @param int $currScope A pointer to the start of the scope.
*
* @return void
*/
protected function loadFunctionNamesInScope(File $phpcsFile, $currScope) {
$this->functionList = [];
$tokens = $phpcsFile->getTokens();
for ($i = $tokens[$currScope]['scope_opener'] + 1; $i < $tokens[$currScope]['scope_closer']; $i++) {
if ($tokens[$i]['code'] !== T_FUNCTION) {
continue;
}
$this->functionList[] = trim(strtolower($phpcsFile->getDeclarationName($i)));
if (isset($tokens[$i]['scope_closer']) !== false) {
// Skip past nested functions and such.
$i = $tokens[$i]['scope_closer'];
}
}
}
//end loadFunctionNamesInScope()
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title |
---|---|---|---|---|
AbstractScopeSniff::$listenOutside | private | property | True if this test should fire on tokens outside of the scope. | |
AbstractScopeSniff::$scopeTokens | private | property | The type of scope opener tokens that this test wishes to listen to. | |
AbstractScopeSniff::$tokens | private | property | The token types that this test wishes to listen to within the scope. | |
AbstractScopeSniff::process | final public | function | Processes the tokens that this test is listening for. | Overrides Sniff::process |
AbstractScopeSniff::register | final public | function | The method that is called to register the tokens this test wishes to listen to. |
Overrides Sniff::register |
ConstructorNameSniff::$currentClass | private | property | The name of the class we are currently checking. | |
ConstructorNameSniff::$functionList | private | property | A list of functions in the current class. | |
ConstructorNameSniff::loadFunctionNamesInScope | protected | function | Extracts all the function names found in the given scope. | |
ConstructorNameSniff::processTokenOutsideScope | protected | function | Processes a token that is found within the scope that this test is listening to. |
Overrides AbstractScopeSniff::processTokenOutsideScope |
ConstructorNameSniff::processTokenWithinScope | protected | function | Processes this test when one of its tokens is encountered. | Overrides AbstractScopeSniff::processTokenWithinScope |
ConstructorNameSniff::__construct | public | function | Constructs the test with the tokens it wishes to listen for. | Overrides AbstractScopeSniff::__construct |