1<?php
2/**
3 * Verifies that class methods have scope modifiers.
4 *
5 * @author    Greg Sherwood <gsherwood@squiz.net>
6 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
7 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8 */
9
10namespace PHP_CodeSniffer\Standards\Squiz\Sniffs\Scope;
11
12use PHP_CodeSniffer\Files\File;
13use PHP_CodeSniffer\Sniffs\AbstractScopeSniff;
14use PHP_CodeSniffer\Util\Tokens;
15
16class MethodScopeSniff extends AbstractScopeSniff
17{
18
19
20    /**
21     * Constructs a Squiz_Sniffs_Scope_MethodScopeSniff.
22     */
23    public function __construct()
24    {
25        parent::__construct(Tokens::$ooScopeTokens, [T_FUNCTION]);
26
27    }//end __construct()
28
29
30    /**
31     * Processes the function tokens within the class.
32     *
33     * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
34     * @param int                         $stackPtr  The position where the token was found.
35     * @param int                         $currScope The current scope opener token.
36     *
37     * @return void
38     */
39    protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
40    {
41        $tokens = $phpcsFile->getTokens();
42
43        // Determine if this is a function which needs to be examined.
44        $conditions = $tokens[$stackPtr]['conditions'];
45        end($conditions);
46        $deepestScope = key($conditions);
47        if ($deepestScope !== $currScope) {
48            return;
49        }
50
51        $methodName = $phpcsFile->getDeclarationName($stackPtr);
52        if ($methodName === null) {
53            // Ignore closures.
54            return;
55        }
56
57        $modifier = null;
58        for ($i = ($stackPtr - 1); $i > 0; $i--) {
59            if ($tokens[$i]['line'] < $tokens[$stackPtr]['line']) {
60                break;
61            } else if (isset(Tokens::$scopeModifiers[$tokens[$i]['code']]) === true) {
62                $modifier = $i;
63                break;
64            }
65        }
66
67        if ($modifier === null) {
68            $error = 'Visibility must be declared on method "%s"';
69            $data  = [$methodName];
70            $phpcsFile->addError($error, $stackPtr, 'Missing', $data);
71        }
72
73    }//end processTokenWithinScope()
74
75
76    /**
77     * Processes a token that is found within the scope that this test is
78     * listening to.
79     *
80     * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
81     * @param int                         $stackPtr  The position in the stack where this
82     *                                               token was found.
83     *
84     * @return void
85     */
86    protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
87    {
88
89    }//end processTokenOutsideScope()
90
91
92}//end class
93