Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@17
|
3 * \Drupal\Sniffs\NamingConventions\ValidFunctionNameSniff.
|
Chris@0
|
4 *
|
Chris@0
|
5 * @category PHP
|
Chris@0
|
6 * @package PHP_CodeSniffer
|
Chris@0
|
7 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
8 */
|
Chris@0
|
9
|
Chris@17
|
10 namespace Drupal\Sniffs\NamingConventions;
|
Chris@17
|
11
|
Chris@17
|
12 use PHP_CodeSniffer\Files\File;
|
Chris@17
|
13 use PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff;
|
Chris@17
|
14 use PHP_CodeSniffer\Util\Common;
|
Chris@17
|
15
|
Chris@0
|
16 /**
|
Chris@17
|
17 * \Drupal\Sniffs\NamingConventions\ValidFunctionNameSniff.
|
Chris@0
|
18 *
|
Chris@17
|
19 * Extends
|
Chris@17
|
20 * \PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff
|
Chris@17
|
21 * to also check global function names outside the scope of classes and to not
|
Chris@17
|
22 * allow methods beginning with an underscore.
|
Chris@0
|
23 *
|
Chris@0
|
24 * @category PHP
|
Chris@0
|
25 * @package PHP_CodeSniffer
|
Chris@0
|
26 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
27 */
|
Chris@17
|
28 class ValidFunctionNameSniff extends CamelCapsFunctionNameSniff
|
Chris@0
|
29 {
|
Chris@0
|
30
|
Chris@0
|
31
|
Chris@0
|
32 /**
|
Chris@0
|
33 * Processes the tokens within the scope.
|
Chris@0
|
34 *
|
Chris@17
|
35 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being processed.
|
Chris@17
|
36 * @param int $stackPtr The position where this token was
|
Chris@17
|
37 * found.
|
Chris@17
|
38 * @param int $currScope The position of the current scope.
|
Chris@0
|
39 *
|
Chris@0
|
40 * @return void
|
Chris@0
|
41 */
|
Chris@17
|
42 protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
|
Chris@0
|
43 {
|
Chris@0
|
44 $methodName = $phpcsFile->getDeclarationName($stackPtr);
|
Chris@0
|
45 if ($methodName === null) {
|
Chris@0
|
46 // Ignore closures.
|
Chris@0
|
47 return;
|
Chris@0
|
48 }
|
Chris@0
|
49
|
Chris@0
|
50 $className = $phpcsFile->getDeclarationName($currScope);
|
Chris@0
|
51 $errorData = array($className.'::'.$methodName);
|
Chris@0
|
52
|
Chris@0
|
53 // Is this a magic method. i.e., is prefixed with "__" ?
|
Chris@0
|
54 if (preg_match('|^__|', $methodName) !== 0) {
|
Chris@0
|
55 $magicPart = strtolower(substr($methodName, 2));
|
Chris@0
|
56 if (isset($this->magicMethods[$magicPart]) === false
|
Chris@0
|
57 && isset($this->methodsDoubleUnderscore[$magicPart]) === false
|
Chris@0
|
58 ) {
|
Chris@0
|
59 $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore';
|
Chris@0
|
60 $phpcsFile->addError($error, $stackPtr, 'MethodDoubleUnderscore', $errorData);
|
Chris@0
|
61 }
|
Chris@0
|
62
|
Chris@0
|
63 return;
|
Chris@0
|
64 }
|
Chris@0
|
65
|
Chris@0
|
66 $methodProps = $phpcsFile->getMethodProperties($stackPtr);
|
Chris@17
|
67 if (Common::isCamelCaps($methodName, false, true, $this->strict) === false) {
|
Chris@0
|
68 if ($methodProps['scope_specified'] === true) {
|
Chris@0
|
69 $error = '%s method name "%s" is not in lowerCamel format';
|
Chris@0
|
70 $data = array(
|
Chris@0
|
71 ucfirst($methodProps['scope']),
|
Chris@0
|
72 $errorData[0],
|
Chris@0
|
73 );
|
Chris@0
|
74 $phpcsFile->addError($error, $stackPtr, 'ScopeNotCamelCaps', $data);
|
Chris@0
|
75 } else {
|
Chris@0
|
76 $error = 'Method name "%s" is not in lowerCamel format';
|
Chris@0
|
77 $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData);
|
Chris@0
|
78 }
|
Chris@0
|
79
|
Chris@0
|
80 $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'no');
|
Chris@0
|
81 return;
|
Chris@0
|
82 } else {
|
Chris@0
|
83 $phpcsFile->recordMetric($stackPtr, 'CamelCase method name', 'yes');
|
Chris@0
|
84 }
|
Chris@0
|
85
|
Chris@0
|
86 }//end processTokenWithinScope()
|
Chris@0
|
87
|
Chris@0
|
88
|
Chris@0
|
89 /**
|
Chris@0
|
90 * Processes the tokens outside the scope.
|
Chris@0
|
91 *
|
Chris@17
|
92 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being processed.
|
Chris@17
|
93 * @param int $stackPtr The position where this token was
|
Chris@17
|
94 * found.
|
Chris@0
|
95 *
|
Chris@0
|
96 * @return void
|
Chris@0
|
97 */
|
Chris@17
|
98 protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
|
Chris@0
|
99 {
|
Chris@0
|
100 $functionName = $phpcsFile->getDeclarationName($stackPtr);
|
Chris@0
|
101 if ($functionName === null) {
|
Chris@0
|
102 // Ignore closures.
|
Chris@0
|
103 return;
|
Chris@0
|
104 }
|
Chris@0
|
105
|
Chris@0
|
106 $isApiFile = substr($phpcsFile->getFilename(), -8) === '.api.php';
|
Chris@0
|
107 $isHookExample = substr($functionName, 0, 5) === 'hook_';
|
Chris@0
|
108 if ($isApiFile === true && $isHookExample === true) {
|
Chris@0
|
109 // Ignore for examaple hook_ENTITY_TYPE_insert() functions in .api.php
|
Chris@0
|
110 // files.
|
Chris@0
|
111 return;
|
Chris@0
|
112 }
|
Chris@0
|
113
|
Chris@0
|
114 if ($functionName !== strtolower($functionName)) {
|
Chris@0
|
115 $expected = strtolower(preg_replace('/([^_])([A-Z])/', '$1_$2', $functionName));
|
Chris@0
|
116 $error = 'Invalid function name, expected %s but found %s';
|
Chris@0
|
117 $data = array(
|
Chris@0
|
118 $expected,
|
Chris@0
|
119 $functionName,
|
Chris@0
|
120 );
|
Chris@0
|
121 $phpcsFile->addError($error, $stackPtr, 'InvalidName', $data);
|
Chris@0
|
122 }
|
Chris@0
|
123
|
Chris@0
|
124 }//end processTokenOutsideScope()
|
Chris@0
|
125
|
Chris@0
|
126
|
Chris@0
|
127 }//end class
|