162 lines
6.0 KiB
PHP
162 lines
6.0 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* CodeIgniter_Sniffs_NamingConventions_ValidMethodNameSniff.
|
||
|
*
|
||
|
* PHP version 5
|
||
|
*
|
||
|
* @category PHP
|
||
|
* @package PHP_CodeSniffer
|
||
|
* @author Thomas Ernest <thomas.ernest@baoabz.com>
|
||
|
* @copyright 2010 Thomas Ernest
|
||
|
* @license http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License
|
||
|
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||
|
*/
|
||
|
/**
|
||
|
* CodeIgniter_Sniffs_NamingConventions_ValidMethodNameSniff.
|
||
|
*
|
||
|
* Ensures that class methods and functions areentirely lowercased and that
|
||
|
* words are separated with an underscore, and not CamelCased.
|
||
|
* Ensures that private class methods are prefixed with an underscore and that
|
||
|
* all other methods are not prefixed with an underscored.
|
||
|
* Ensures that names longer than 50 chars are prohibited. Likewise names longer
|
||
|
* than 35 chars raise a warning.
|
||
|
*
|
||
|
* @todo Use a rule property or a configuration variable to allow users to set
|
||
|
* their own maximum lengths for function and method names. Have a look at
|
||
|
* CodeIgniter_Sniffs_Files_ClosingLocationCommentSniff and application root.
|
||
|
*
|
||
|
* @category PHP
|
||
|
* @package PHP_CodeSniffer
|
||
|
* @author Thomas Ernest <thomas.ernest@baoabz.com>
|
||
|
* @copyright 2010 Thomas Ernest
|
||
|
* @license http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License
|
||
|
* @link http://pear.php.net/package/PHP_CodeSniffer
|
||
|
*/
|
||
|
|
||
|
namespace CodeIgniter\Sniffs\NamingConventions;
|
||
|
|
||
|
use PHP_CodeSniffer\Sniffs\AbstactScopeSniff;
|
||
|
use PHP_CodeSniffer\Files\File;
|
||
|
|
||
|
class ValidMethodNameSniff extends AbstractScopeSniff
|
||
|
{
|
||
|
/**
|
||
|
* A list of all PHP magic methods.
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected static $magicMethods = array(
|
||
|
'construct',
|
||
|
'destruct',
|
||
|
'call',
|
||
|
'callStatic',
|
||
|
'get',
|
||
|
'set',
|
||
|
'isset',
|
||
|
'unset',
|
||
|
'sleep',
|
||
|
'wakeup',
|
||
|
'toString',
|
||
|
'set_state',
|
||
|
'clone',
|
||
|
);
|
||
|
|
||
|
/**
|
||
|
* Defines which token(s) in which scope(s) will be proceed.
|
||
|
*/
|
||
|
public function __construct()
|
||
|
{
|
||
|
parent::__construct(array(T_CLASS, T_INTERFACE), array(T_FUNCTION), true);
|
||
|
|
||
|
}//end __construct()
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Processes the tokens within the scope.
|
||
|
*
|
||
|
* @param File $phpcsFile The file being processed.
|
||
|
* @param int $stackPtr The position where this token was
|
||
|
* found.
|
||
|
* @param int $currScope The position of the current scope.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
|
||
|
{
|
||
|
$methodName = $phpcsFile->getDeclarationName($stackPtr);
|
||
|
if ($methodName === null) {
|
||
|
// Ignore closures.
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$className = $phpcsFile->getDeclarationName($currScope);
|
||
|
|
||
|
// Is this a magic method i.e. is prefixed with "__".
|
||
|
if (0 === strcmp(substr($methodName, 0, 2), '__')) {
|
||
|
$magicPart = substr($methodName, 2);
|
||
|
if (in_array($magicPart, self::$magicMethods) === false) {
|
||
|
$error = "Method name \"$className::$methodName\" is invalid; only PHP magic methods should be prefixed with a double underscore";
|
||
|
$phpcsFile->addError($error, $stackPtr);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// PHP4 constructors are allowed to break our rules.
|
||
|
if ($methodName === $className) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// PHP4 destructors are allowed to break our rules.
|
||
|
if ($methodName === '_'.$className) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (0 !== strcmp($methodName, strtolower($methodName))) {
|
||
|
$uscrdMethodName = preg_replace('/([A-Z])/', '_${1}', $methodName);
|
||
|
$expectedMethodName = strtolower($uscrdMethodName);
|
||
|
$error = "Class methods should be entirely lowercased. Please consider \"$expectedMethodName\" instead of \"$methodName\".";
|
||
|
$phpcsFile->addError($error, $stackPtr);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$methodProps = $phpcsFile->getMethodProperties($stackPtr);
|
||
|
$scope = $methodProps['scope'];
|
||
|
$scopeSpecified = $methodProps['scope_specified'];
|
||
|
|
||
|
// If it's a private method, it must have an underscore on the front.
|
||
|
if ($scope === 'private' && $methodName{0} !== '_') {
|
||
|
$error = "Private method name \"$className::$methodName\" must be prefixed with an underscore";
|
||
|
$phpcsFile->addError($error, $stackPtr);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// If it's not a private method, it must not have an underscore on the front.
|
||
|
if ($scope !== 'private' && $methodName{0} === '_') {
|
||
|
if (true === $scopeSpecified) {
|
||
|
$error = "Public method name \"$className::$methodName\" must not be prefixed with an underscore";
|
||
|
} else {
|
||
|
$error = ucfirst($scope)." method name \"$className::$methodName\" must not be prefixed with an underscore";
|
||
|
}
|
||
|
$phpcsFile->addError($error, $stackPtr);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// If name is too verbose,
|
||
|
// then either an error or a warning is displayed.
|
||
|
$error_limit = 50;
|
||
|
$warning_limit = 35;
|
||
|
if (strlen($methodName) > $error_limit) {
|
||
|
$error = "Overly long and verbose names are prohibited. Please find a name shorter than $error_limit chars.";
|
||
|
$phpcsFile->addError($error, $stackPtr);
|
||
|
return;
|
||
|
} else if (strlen($methodName) > $warning_limit) {
|
||
|
$warning = "Try to avoid overly long and verbose names in finding a name shorter than $warning_limit chars.";
|
||
|
$phpcsFile->addWarning($warning, $stackPtr);
|
||
|
}
|
||
|
}//end processTokenWithinScope()
|
||
|
|
||
|
}//end class
|
||
|
|
||
|
?>
|