Completed
Pull Request — master (#291)
by Juliette
02:26
created

getNonVersionArrayKeys()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * PHPCompatibility_Sniffs_PHP_NewLanguageConstructsSniff.
4
 *
5
 * PHP version 5.5
6
 *
7
 * @category  PHP
8
 * @package   PHPCompatibility
9
 * @author    Wim Godden <[email protected]>
10
 * @copyright 2013 Cu.be Solutions bvba
11
 */
12
13
/**
14
 * PHPCompatibility_Sniffs_PHP_NewLanguageConstructsSniff.
15
 *
16
 * @category  PHP
17
 * @package   PHPCompatibility
18
 * @author    Wim Godden <[email protected]>
19
 * @version   1.0.0
20
 * @copyright 2013 Cu.be Solutions bvba
21
 */
22
class PHPCompatibility_Sniffs_PHP_NewLanguageConstructsSniff
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
23
    extends PHPCompatibility_AbstractNewFeatureSniff
0 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
24
{
25
26
    /**
27
     * A list of new language constructs, not present in older versions.
28
     *
29
     * The array lists : version number with false (not present) or true (present).
30
     * If's sufficient to list the first version where the keyword appears.
31
     *
32
     * @var array(string => array(string => int|string|null))
33
     */
34
    protected $newConstructs = array(
35
                                        'T_NS_SEPARATOR' => array(
36
                                            '5.2' => false,
37
                                            '5.3' => true,
38
                                            'description' => 'the \ operator (for namespaces)'
39
                                        ),
40
                                        'T_POW' => array(
41
                                            '5.5' => false,
42
                                            '5.6' => true,
43
                                            'description' => 'power operator (**)'
44
                                        ), // identified in PHPCS 1.5 as T_MULTIPLY + T_MULTIPLY
45
                                        'T_POW_EQUAL' => array(
46
                                            '5.5' => false,
47
                                            '5.6' => true,
48
                                            'description' => 'power assignment operator (**=)'
49
                                        ), // identified in PHPCS 1.5 as T_MULTIPLY + T_MUL_EQUAL
50
                                        'T_ELLIPSIS' => array(
51
                                            '5.5' => false,
52
                                            '5.6' => true,
53
                                            'description' => 'variadic functions using ...'
54
                                        ),
55
                                        'T_SPACESHIP' => array(
56
                                            '5.6' => false,
57
                                            '7.0' => true,
58
                                            'description' => 'spaceship operator (<=>)'
59
                                        ), // identified in PHPCS 1.5 as T_IS_SMALLER_OR_EQUAL + T_GREATER_THAN
60
                                        'T_COALESCE' => array(
61
                                            '5.6' => false,
62
                                            '7.0' => true,
63
                                            'description' => 'null coalescing operator (??)'
64
                                        ), // identified in PHPCS 1.5 as T_INLINE_THEN + T_INLINE_THEN
65
                                    );
66
67
68
    /**
69
     * A list of new language constructs which are not recognized in PHPCS 1.x.
70
     *
71
     * The array lists an alternative token to listen for.
72
     *
73
     * @var array(string => int)
74
     */
75
    protected $newConstructsPHPCSCompat = array(
76
                                        'T_POW'       => T_MULTIPLY,
77
                                        'T_POW_EQUAL' => T_MUL_EQUAL,
78
                                        'T_SPACESHIP' => T_GREATER_THAN,
79
                                        'T_COALESCE'  => T_INLINE_THEN,
80
                                    );
81
82
    /**
83
     * Translation table for PHPCS 1.x tokens.
84
     *
85
     * The 'before' index lists the token which would have to be directly before the
86
     * token found for it to be one of the new language constructs.
87
     * The 'real_token' index indicates which language construct was found in that case.
88
     *
89
     * {@internal 'before' was choosen rather than 'after' as that allowed for a 1-on-1
90
     * translation list with the current tokens.}}
91
     *
92
     * @var array(string => array(string => string))
93
     */
94
    protected $PHPCSCompatTranslate = array(
95
                                        'T_MULTIPLY' => array(
96
                                            'before' => 'T_MULTIPLY',
97
                                            'real_token' => 'T_POW',
98
                                        ),
99
                                        'T_MUL_EQUAL' => array(
100
                                            'before' => 'T_MULTIPLY',
101
                                            'real_token' => 'T_POW_EQUAL',
102
                                        ),
103
                                        'T_GREATER_THAN' => array(
104
                                            'before' => 'T_IS_SMALLER_OR_EQUAL',
105
                                            'real_token' => 'T_SPACESHIP',
106
                                        ),
107
                                        'T_INLINE_THEN' => array(
108
                                            'before' => 'T_INLINE_THEN',
109
                                            'real_token' => 'T_COALESCE',
110
                                        ),
111
                                    );
112
113
    /**
114
     * Returns an array of tokens this test wants to listen for.
115
     *
116
     * @return array
117
     */
118
    public function register()
119
    {
120
        $tokens = array();
121
        foreach ($this->newConstructs as $token => $versions) {
122
            if (defined($token)) {
123
                $tokens[] = constant($token);
124
            }
125
            else if(isset($this->newConstructsPHPCSCompat[$token])) {
126
                $tokens[] = $this->newConstructsPHPCSCompat[$token];
127
            }
128
        }
129
        return $tokens;
130
    }//end register()
131
132
133
    /**
134
     * Processes this test, when one of its tokens is encountered.
135
     *
136
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
137
     * @param int                  $stackPtr  The position of the current token in
138
     *                                        the stack passed in $tokens.
139
     *
140
     * @return void
141
     */
142
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
143
    {
144
        $tokens    = $phpcsFile->getTokens();
145
        $tokenType = $tokens[$stackPtr]['type'];
146
147
        // Translate pre-PHPCS 2.0 tokens for new constructs to the actual construct.
148
        if (isset($this->newConstructs[$tokenType]) === false) {
149
            if (
150
                isset($this->PHPCSCompatTranslate[$tokenType])
151
                &&
152
                $tokens[$stackPtr - 1]['type'] === $this->PHPCSCompatTranslate[$tokenType]['before']
153
            ) {
154
                $tokenType = $this->PHPCSCompatTranslate[$tokenType]['real_token'];
155
            }
156
        }
157
158
        // If the translation did not yield one of the tokens we are looking for, bow out.
159
        if (isset($this->newConstructs[$tokenType]) === false) {
160
            return;
161
        }
162
163
        $itemInfo = array(
164
            'name'   => $tokenType,
165
        );
166
        $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
167
168
    }//end process()
169
170
171
    /**
172
     * Get the relevant sub-array for a specific item from a multi-dimensional array.
173
     *
174
     * @param array $itemInfo Base information about the item.
175
     *
176
     * @return array Version and other information about the item.
177
     */
178
    public function getItemArray(array $itemInfo)
179
    {
180
        return $this->newConstructs[$itemInfo['name']];
181
    }
182
183
184
    /**
185
     * Get an array of the non-PHP-version array keys used in a sub-array.
186
     *
187
     * @return array
188
     */
189
    protected function getNonVersionArrayKeys()
190
    {
191
        return array('description');
192
    }
193
194
195
    /**
196
     * Retrieve the relevant detail (version) information for use in an error message.
197
     *
198
     * @param array $itemArray Version and other information about the item.
199
     * @param array $itemInfo  Base information about the item.
200
     *
201
     * @return array
202
     */
203
    public function getErrorInfo(array $itemArray, array $itemInfo)
204
    {
205
        $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
206
        $errorInfo['description'] = $itemArray['description'];
207
208
        return $errorInfo;
209
210
    }
211
212
213
    /**
214
     * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
215
     *
216
     * @param array $data      The error data array which was created.
217
     * @param array $itemInfo  Base information about the item this error message applied to.
218
     * @param array $errorInfo Detail information about an item this error message applied to.
219
     *
220
     * @return array
221
     */
222
    protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
223
    {
224
        $data[0] = $errorInfo['description'];
225
        return $data;
226
    }
227
228
229
}//end class
230