1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/** |
3
|
|
|
* PSR2_Sniffs_Methods_MethodDeclarationSniff. |
4
|
|
|
* |
5
|
|
|
* PHP version 5 |
6
|
|
|
* |
7
|
|
|
* @category PHP |
8
|
|
|
* @package PHP_CodeSniffer |
9
|
|
|
* @author Greg Sherwood <[email protected]> |
10
|
|
|
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) |
11
|
|
|
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence |
12
|
|
|
* @link http://pear.php.net/package/PHP_CodeSniffer |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace PSR2R\Sniffs\Methods; |
16
|
|
|
|
17
|
|
|
use PHP_CodeSniffer_Exception; |
18
|
|
|
use PHP_CodeSniffer_File; |
19
|
|
|
use PHP_CodeSniffer_Standards_AbstractScopeSniff; |
20
|
|
|
use PHP_CodeSniffer_Tokens; |
21
|
|
|
|
22
|
|
|
if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) { |
23
|
|
|
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found'); |
24
|
|
|
} |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* PSR2_Sniffs_Methods_MethodDeclarationSniff. |
28
|
|
|
* |
29
|
|
|
* Checks that the method declaration is correct. |
30
|
|
|
* |
31
|
|
|
* @author Greg Sherwood <[email protected]> |
32
|
|
|
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) |
33
|
|
|
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence |
34
|
|
|
* @version Release: @package_version@ |
35
|
|
|
* @link http://pear.php.net/package/PHP_CodeSniffer |
36
|
|
|
*/ |
37
|
|
|
class MethodDeclarationSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff { |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @inheritDoc |
41
|
|
|
*/ |
42
|
|
|
public function __construct() { |
43
|
|
|
parent::__construct([T_CLASS, T_INTERFACE], [T_FUNCTION]); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @inheritDoc |
48
|
|
|
*/ |
49
|
|
|
protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) { |
50
|
|
|
$tokens = $phpcsFile->getTokens(); |
51
|
|
|
|
52
|
|
|
$methodName = $phpcsFile->getDeclarationName($stackPtr); |
53
|
|
|
if ($methodName === null) { |
54
|
|
|
// Ignore closures. |
55
|
|
|
return; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
$visibility = 0; |
59
|
|
|
$static = 0; |
60
|
|
|
$abstract = 0; |
61
|
|
|
$final = 0; |
62
|
|
|
|
63
|
|
|
$find = PHP_CodeSniffer_Tokens::$methodPrefixes; |
64
|
|
|
$find[] = T_WHITESPACE; |
65
|
|
|
$prev = $phpcsFile->findPrevious($find, ($stackPtr - 1), null, true); |
66
|
|
|
|
67
|
|
|
$prefix = $stackPtr; |
68
|
|
View Code Duplication |
while (($prefix = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$methodPrefixes, ($prefix - 1), $prev)) !== false) { |
|
|
|
|
69
|
|
|
switch ($tokens[$prefix]['code']) { |
70
|
|
|
case T_STATIC: |
71
|
|
|
$static = $prefix; |
72
|
|
|
break; |
73
|
|
|
case T_ABSTRACT: |
74
|
|
|
$abstract = $prefix; |
75
|
|
|
break; |
76
|
|
|
case T_FINAL: |
77
|
|
|
$final = $prefix; |
78
|
|
|
break; |
79
|
|
|
default: |
80
|
|
|
$visibility = $prefix; |
81
|
|
|
break; |
82
|
|
|
} |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
$fixes = []; |
86
|
|
|
|
87
|
|
View Code Duplication |
if ($visibility !== 0 && $final > $visibility) { |
|
|
|
|
88
|
|
|
$error = 'The final declaration must precede the visibility declaration'; |
89
|
|
|
$fix = $phpcsFile->addFixableError($error, $final, 'FinalAfterVisibility'); |
|
|
|
|
90
|
|
|
if ($fix === true) { |
91
|
|
|
$fixes[$final] = ''; |
92
|
|
|
$fixes[($final + 1)] = ''; |
93
|
|
|
if (isset($fixes[$visibility]) === true) { |
94
|
|
|
$fixes[$visibility] = 'final ' . $fixes[$visibility]; |
95
|
|
|
} else { |
96
|
|
|
$fixes[$visibility] = 'final ' . $tokens[$visibility]['content']; |
97
|
|
|
} |
98
|
|
|
} |
99
|
|
|
} |
100
|
|
|
|
101
|
|
View Code Duplication |
if ($visibility !== 0 && $abstract > $visibility) { |
|
|
|
|
102
|
|
|
$error = 'The abstract declaration must precede the visibility declaration'; |
103
|
|
|
$fix = $phpcsFile->addFixableError($error, $abstract, 'AbstractAfterVisibility'); |
|
|
|
|
104
|
|
|
if ($fix === true) { |
105
|
|
|
$fixes[$abstract] = ''; |
106
|
|
|
$fixes[($abstract + 1)] = ''; |
107
|
|
|
if (isset($fixes[$visibility]) === true) { |
108
|
|
|
$fixes[$visibility] = 'abstract ' . $fixes[$visibility]; |
109
|
|
|
} else { |
110
|
|
|
$fixes[$visibility] = 'abstract ' . $tokens[$visibility]['content']; |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
} |
114
|
|
|
|
115
|
|
View Code Duplication |
if ($static !== 0 && $static < $visibility) { |
|
|
|
|
116
|
|
|
$error = 'The static declaration must come after the visibility declaration'; |
117
|
|
|
$fix = $phpcsFile->addFixableError($error, $static, 'StaticBeforeVisibility'); |
|
|
|
|
118
|
|
|
if ($fix === true) { |
119
|
|
|
$fixes[$static] = ''; |
120
|
|
|
$fixes[($static + 1)] = ''; |
121
|
|
|
if (isset($fixes[$visibility]) === true) { |
122
|
|
|
$fixes[$visibility] = $fixes[$visibility] . ' static'; |
123
|
|
|
} else { |
124
|
|
|
$fixes[$visibility] = $tokens[$visibility]['content'] . ' static'; |
125
|
|
|
} |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
// Batch all the fixes together to reduce the possibility of conflicts. |
130
|
|
|
if (empty($fixes) === false) { |
131
|
|
|
$phpcsFile->fixer->beginChangeset(); |
132
|
|
|
foreach ($fixes as $stackPtr => $content) { |
133
|
|
|
$phpcsFile->fixer->replaceToken($stackPtr, $content); |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
$phpcsFile->fixer->endChangeset(); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
} |
142
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.