Completed
Push — feature/isClassProperty-additi... ( 286703...879b22 )
by Juliette
01:45
created

processTokenOutsideScope()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.0534
c 0
b 0
f 0
cc 4
eloc 12
nc 4
nop 2
1
<?php
2
/**
3
 * \PHPCompatibility\Sniffs\PHP\ReservedFunctionNamesSniff.
4
 *
5
 * @category PHP
6
 * @package  PHPCompatibility
7
 * @author   Juliette Reinders Folmer <[email protected]>
8
 */
9
10
namespace PHPCompatibility\Sniffs\PHP;
11
12
use PHPCompatibility\PHPCSHelper;
13
14
/**
15
 * \PHPCompatibility\Sniffs\PHP\ReservedFunctionNamesSniff.
16
 *
17
 * All function and method names starting with double underscore are reserved by PHP.
18
 *
19
 * {@internal Extends an upstream sniff to benefit from the properties contained therein.
20
 *            The properties are lists of valid PHP magic function and method names, which
21
 *            should be ignored for the purposes of this sniff.
22
 *            As this sniff is not PHP version specific, we don't need access to the utility
23
 *            methods in the PHPCompatibility\Sniff, so extending the upstream sniff is fine.
24
 *            As the upstream sniff checks the same (and more, but we don't need the rest),
25
 *            the logic in this sniff is largely the same as used upstream.
26
 *            Extending the upstream sniff instead of including it via the ruleset, however,
27
 *            prevents hard to debug issues of errors not being reported from the upstream sniff
28
 *            if this library is used in combination with other rulesets.}}
29
 *
30
 * @category PHP
31
 * @package  PHPCompatibility
32
 * @author   Juliette Reinders Folmer <[email protected]>
33
 */
34
class ReservedFunctionNamesSniff extends \Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff
35
{
36
37
    /**
38
     * Overload the constructor to work round various PHPCS cross-version compatibility issues.
39
     */
40
    public function __construct()
41
    {
42
        $scopeTokens = array(T_CLASS, T_INTERFACE);
43
        if (defined('T_TRAIT')) {
44
            // phpcs:ignore PHPCompatibility.PHP.NewConstants.t_traitFound
45
            $scopeTokens[] = T_TRAIT;
46
        }
47
        if (defined('T_ANON_CLASS')) {
48
            // phpcs:ignore PHPCompatibility.PHP.NewConstants.t_anon_classFound
49
            $scopeTokens[] = T_ANON_CLASS;
50
        }
51
52
        // Call the grand-parent constructor directly.
53
        \PHP_CodeSniffer_Standards_AbstractScopeSniff::__construct($scopeTokens, array(T_FUNCTION), true);
54
55
        $phpcsVersion = PHPCSHelper::getVersion();
56
57
        if (version_compare($phpcsVersion, '2.0.0', '<') === true) {
58
            $this->magicMethods            = array_flip($this->magicMethods);
59
            $this->methodsDoubleUnderscore = array_flip($this->methodsDoubleUnderscore);
60
            $this->magicFunctions          = array_flip($this->magicFunctions);
61
        }
62
63
        // Make sure debuginfo is included in the array. Upstream only includes it since 2.5.1.
64
        $this->magicMethods['debuginfo'] = true;
65
    }
66
67
68
    /**
69
     * Processes the tokens within the scope.
70
     *
71
     * @param \PHP_CodeSniffer_File $phpcsFile The file being processed.
72
     * @param int                   $stackPtr  The position where this token was
73
     *                                         found.
74
     * @param int                   $currScope The position of the current scope.
75
     *
76
     * @return void
77
     */
78
    protected function processTokenWithinScope(\PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope)
79
    {
80
        $tokens = $phpcsFile->getTokens();
81
82
        $methodName = $phpcsFile->getDeclarationName($stackPtr);
83
        if ($methodName === null) {
84
            // Ignore closures.
85
            return;
86
        }
87
88
        // Is this a magic method. i.e., is prefixed with "__" ?
89
        if (preg_match('|^__[^_]|', $methodName) > 0) {
90
            $magicPart = strtolower(substr($methodName, 2));
91
            if (isset($this->magicMethods[$magicPart]) === false
92
                && isset($this->methodsDoubleUnderscore[$magicPart]) === false
93
            ) {
94
                $className = '[anonymous class]';
95
                if (defined('T_ANON_CLASS') === false || $tokens[$currScope]['type'] !== 'T_ANON_CLASS') {
96
                    $className = $phpcsFile->getDeclarationName($currScope);
97
                }
98
99
                $phpcsFile->addWarning(
100
                    'Method name "%s" is discouraged; PHP has reserved all method names with a double underscore prefix for future use.',
101
                    $stackPtr,
102
                    'MethodDoubleUnderscore',
103
                    array($className.'::'.$methodName)
104
                );
105
            }
106
        }
107
    }
108
109
110
    /**
111
     * Processes the tokens outside the scope.
112
     *
113
     * @param \PHP_CodeSniffer_File $phpcsFile The file being processed.
114
     * @param int                   $stackPtr  The position where this token was
115
     *                                         found.
116
     *
117
     * @return void
118
     */
119
    protected function processTokenOutsideScope(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
120
    {
121
        $functionName = $phpcsFile->getDeclarationName($stackPtr);
122
        if ($functionName === null) {
123
            // Ignore closures.
124
            return;
125
        }
126
127
        // Is this a magic function. i.e., it is prefixed with "__".
128
        if (preg_match('|^__[^_]|', $functionName) > 0) {
129
            $magicPart = strtolower(substr($functionName, 2));
130
            if (isset($this->magicFunctions[$magicPart]) === false) {
131
                $phpcsFile->addWarning(
132
                    'Function name "%s" is discouraged; PHP has reserved all method names with a double underscore prefix for future use.',
133
                    $stackPtr,
134
                    'FunctionDoubleUnderscore',
135
                    array($functionName)
136
                );
137
            }
138
        }
139
    }
140
141
}//end class
142