1<?php
2/**
3 * PSR2_Sniffs_Methods_FunctionClosingBraceSniff.
4 *
5 * PHP version 5
6 *
7 * @category  PHP
8 * @package   PHP_CodeSniffer
9 * @author    Greg Sherwood <gsherwood@squiz.net>
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/**
16 * PSR2_Sniffs_Methods_FunctionClosingBraceSniff.
17 *
18 * Checks that the closing brace of a function goes directly after the body.
19 *
20 * @category  PHP
21 * @package   PHP_CodeSniffer
22 * @author    Greg Sherwood <gsherwood@squiz.net>
23 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
24 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25 * @version   Release: @package_version@
26 * @link      http://pear.php.net/package/PHP_CodeSniffer
27 */
28class PSR2_Sniffs_Methods_FunctionClosingBraceSniff implements PHP_CodeSniffer_Sniff
29{
30
31
32    /**
33     * Returns an array of tokens this test wants to listen for.
34     *
35     * @return array
36     */
37    public function register()
38    {
39        return array(
40                T_FUNCTION,
41                T_CLOSURE,
42               );
43
44    }//end register()
45
46
47    /**
48     * Processes this test, when one of its tokens is encountered.
49     *
50     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
51     * @param int                  $stackPtr  The position of the current token
52     *                                        in the stack passed in $tokens.
53     *
54     * @return void
55     */
56    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
57    {
58        $tokens = $phpcsFile->getTokens();
59
60        if (isset($tokens[$stackPtr]['scope_closer']) === false) {
61            // Probably an interface method.
62            return;
63        }
64
65        $closeBrace  = $tokens[$stackPtr]['scope_closer'];
66        $prevContent = $phpcsFile->findPrevious(T_WHITESPACE, ($closeBrace - 1), null, true);
67        $found       = ($tokens[$closeBrace]['line'] - $tokens[$prevContent]['line'] - 1);
68
69        if ($found < 0) {
70            // Brace isn't on a new line, so not handled by us.
71            return;
72        }
73
74        if ($found === 0) {
75            // All is good.
76            return;
77        }
78
79        $error = 'Function closing brace must go on the next line following the body; found %s blank lines before brace';
80        $data  = array($found);
81        $fix   = $phpcsFile->addFixableError($error, $closeBrace, 'SpacingBeforeClose', $data);
82
83        if ($fix === true) {
84            $phpcsFile->fixer->beginChangeset();
85            for ($i = ($prevContent + 1); $i < $closeBrace; $i++) {
86                if ($tokens[$i]['line'] === $tokens[$prevContent]['line']) {
87                    continue;
88                }
89
90                // Don't remove any identation before the brace.
91                if ($tokens[$i]['line'] === $tokens[$closeBrace]['line']) {
92                    break;
93                }
94
95                $phpcsFile->fixer->replaceToken($i, '');
96            }
97
98            $phpcsFile->fixer->endChangeset();
99        }
100
101    }//end process()
102
103
104}//end class
105