~ubuntu-branches/ubuntu/wily/php-codesniffer/wily-proposed

« back to all changes in this revision

Viewing changes to PHP_CodeSniffer-2.3.2/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/JumbledIncrementerSniff.php

  • Committer: Package Import Robot
  • Author(s): David Prévot, Greg Sherwood
  • Date: 2015-06-24 13:41:36 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20150624134136-dv60dnl6s20tdxwr
Tags: 2.3.3-1
[ Greg Sherwood ]
Prepare for 2.3.3 release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
/**
3
 
 * This file is part of the CodeAnalysis add-on for PHP_CodeSniffer.
4
 
 *
5
 
 * PHP version 5
6
 
 *
7
 
 * @category  PHP
8
 
 * @package   PHP_CodeSniffer
9
 
 * @author    Greg Sherwood <gsherwood@squiz.net>
10
 
 * @author    Manuel Pichler <mapi@manuel-pichler.de>
11
 
 * @copyright 2007-2014 Manuel Pichler. All rights reserved.
12
 
 * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
13
 
 * @link      http://pear.php.net/package/PHP_CodeSniffer
14
 
 */
15
 
 
16
 
/**
17
 
 * Detects incrementer jumbling in for loops.
18
 
 *
19
 
 * This rule is based on the PMD rule catalog. The jumbling incrementer sniff
20
 
 * detects the usage of one and the same incrementer into an outer and an inner
21
 
 * loop. Even it is intended this is confusing code.
22
 
 *
23
 
 * <code>
24
 
 * class Foo
25
 
 * {
26
 
 *     public function bar($x)
27
 
 *     {
28
 
 *         for ($i = 0; $i < 10; $i++)
29
 
 *         {
30
 
 *             for ($k = 0; $k < 20; $i++)
31
 
 *             {
32
 
 *                 echo 'Hello';
33
 
 *             }
34
 
 *         }
35
 
 *     }
36
 
 * }
37
 
 * </code>
38
 
 *
39
 
 * @category  PHP
40
 
 * @package   PHP_CodeSniffer
41
 
 * @author    Manuel Pichler <mapi@manuel-pichler.de>
42
 
 * @copyright 2007-2014 Manuel Pichler. All rights reserved.
43
 
 * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
44
 
 * @version   Release: 2.3.2
45
 
 * @link      http://pear.php.net/package/PHP_CodeSniffer
46
 
 */
47
 
class Generic_Sniffs_CodeAnalysis_JumbledIncrementerSniff implements PHP_CodeSniffer_Sniff
48
 
{
49
 
 
50
 
 
51
 
    /**
52
 
     * Registers the tokens that this sniff wants to listen for.
53
 
     *
54
 
     * @return int[]
55
 
     */
56
 
    public function register()
57
 
    {
58
 
        return array(T_FOR);
59
 
 
60
 
    }//end register()
61
 
 
62
 
 
63
 
    /**
64
 
     * Processes this test, when one of its tokens is encountered.
65
 
     *
66
 
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
67
 
     * @param int                  $stackPtr  The position of the current token
68
 
     *                                        in the stack passed in $tokens.
69
 
     *
70
 
     * @return void
71
 
     */
72
 
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
73
 
    {
74
 
        $tokens = $phpcsFile->getTokens();
75
 
        $token  = $tokens[$stackPtr];
76
 
 
77
 
        // Skip for-loop without body.
78
 
        if (isset($token['scope_opener']) === false) {
79
 
            return;
80
 
        }
81
 
 
82
 
        // Find incrementors for outer loop.
83
 
        $outer = $this->findIncrementers($tokens, $token);
84
 
 
85
 
        // Skip if empty.
86
 
        if (count($outer) === 0) {
87
 
            return;
88
 
        }
89
 
 
90
 
        // Find nested for loops.
91
 
        $start = ++$token['scope_opener'];
92
 
        $end   = --$token['scope_closer'];
93
 
 
94
 
        for (; $start <= $end; ++$start) {
95
 
            if ($tokens[$start]['code'] !== T_FOR) {
96
 
                continue;
97
 
            }
98
 
 
99
 
            $inner = $this->findIncrementers($tokens, $tokens[$start]);
100
 
            $diff  = array_intersect($outer, $inner);
101
 
 
102
 
            if (count($diff) !== 0) {
103
 
                $error = 'Loop incrementor (%s) jumbling with inner loop';
104
 
                $data  = array(join(', ', $diff));
105
 
                $phpcsFile->addWarning($error, $stackPtr, 'Found', $data);
106
 
            }
107
 
        }
108
 
 
109
 
    }//end process()
110
 
 
111
 
 
112
 
    /**
113
 
     * Get all used variables in the incrementer part of a for statement.
114
 
     *
115
 
     * @param array(integer=>array) $tokens Array with all code sniffer tokens.
116
 
     * @param array(string=>mixed)  $token  Current for loop token
117
 
     *
118
 
     * @return string[] List of all found incrementer variables.
119
 
     */
120
 
    protected function findIncrementers(array $tokens, array $token)
121
 
    {
122
 
        // Skip invalid statement.
123
 
        if (isset($token['parenthesis_opener']) === false) {
124
 
            return array();
125
 
        }
126
 
 
127
 
        $start = ++$token['parenthesis_opener'];
128
 
        $end   = --$token['parenthesis_closer'];
129
 
 
130
 
        $incrementers = array();
131
 
        $semicolons   = 0;
132
 
        for ($next = $start; $next <= $end; ++$next) {
133
 
            $code = $tokens[$next]['code'];
134
 
            if ($code === T_SEMICOLON) {
135
 
                ++$semicolons;
136
 
            } else if ($semicolons === 2 && $code === T_VARIABLE) {
137
 
                $incrementers[] = $tokens[$next]['content'];
138
 
            }
139
 
        }
140
 
 
141
 
        return $incrementers;
142
 
 
143
 
    }//end findIncrementers()
144
 
 
145
 
 
146
 
}//end class