annotate vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractScopeSniff.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@17 1 <?php
Chris@17 2 /**
Chris@17 3 * Allows tests that extend this class to listen for tokens within a particular scope.
Chris@17 4 *
Chris@17 5 * Below is a test that listens to methods that exist only within classes:
Chris@17 6 * <code>
Chris@17 7 * class ClassScopeTest extends PHP_CodeSniffer_Standards_AbstractScopeSniff
Chris@17 8 * {
Chris@17 9 * public function __construct()
Chris@17 10 * {
Chris@17 11 * parent::__construct(array(T_CLASS), array(T_FUNCTION));
Chris@17 12 * }
Chris@17 13 *
Chris@17 14 * protected function processTokenWithinScope(\PHP_CodeSniffer\Files\File $phpcsFile, $stackPtr, $currScope)
Chris@17 15 * {
Chris@17 16 * $className = $phpcsFile->getDeclarationName($currScope);
Chris@17 17 * echo 'encountered a method within class '.$className;
Chris@17 18 * }
Chris@17 19 * }
Chris@17 20 * </code>
Chris@17 21 *
Chris@17 22 * @author Greg Sherwood <gsherwood@squiz.net>
Chris@17 23 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
Chris@17 24 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
Chris@17 25 */
Chris@17 26
Chris@17 27 namespace PHP_CodeSniffer\Sniffs;
Chris@17 28
Chris@17 29 use PHP_CodeSniffer\Files\File;
Chris@17 30 use PHP_CodeSniffer\Exceptions\RuntimeException;
Chris@17 31
Chris@17 32 abstract class AbstractScopeSniff implements Sniff
Chris@17 33 {
Chris@17 34
Chris@17 35 /**
Chris@17 36 * The token types that this test wishes to listen to within the scope.
Chris@17 37 *
Chris@17 38 * @var array
Chris@17 39 */
Chris@17 40 private $tokens = [];
Chris@17 41
Chris@17 42 /**
Chris@17 43 * The type of scope opener tokens that this test wishes to listen to.
Chris@17 44 *
Chris@17 45 * @var string
Chris@17 46 */
Chris@17 47 private $scopeTokens = [];
Chris@17 48
Chris@17 49 /**
Chris@17 50 * True if this test should fire on tokens outside of the scope.
Chris@17 51 *
Chris@17 52 * @var boolean
Chris@17 53 */
Chris@17 54 private $listenOutside = false;
Chris@17 55
Chris@17 56
Chris@17 57 /**
Chris@17 58 * Constructs a new AbstractScopeTest.
Chris@17 59 *
Chris@17 60 * @param array $scopeTokens The type of scope the test wishes to listen to.
Chris@17 61 * @param array $tokens The tokens that the test wishes to listen to
Chris@17 62 * within the scope.
Chris@17 63 * @param boolean $listenOutside If true this test will also alert the
Chris@17 64 * extending class when a token is found outside
Chris@17 65 * the scope, by calling the
Chris@17 66 * processTokenOutsideScope method.
Chris@17 67 *
Chris@17 68 * @see PHP_CodeSniffer.getValidScopeTokeners()
Chris@17 69 * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified tokens array is empty.
Chris@17 70 */
Chris@17 71 public function __construct(
Chris@17 72 array $scopeTokens,
Chris@17 73 array $tokens,
Chris@17 74 $listenOutside=false
Chris@17 75 ) {
Chris@17 76 if (empty($scopeTokens) === true) {
Chris@17 77 $error = 'The scope tokens list cannot be empty';
Chris@17 78 throw new RuntimeException($error);
Chris@17 79 }
Chris@17 80
Chris@17 81 if (empty($tokens) === true) {
Chris@17 82 $error = 'The tokens list cannot be empty';
Chris@17 83 throw new RuntimeException($error);
Chris@17 84 }
Chris@17 85
Chris@17 86 $invalidScopeTokens = array_intersect($scopeTokens, $tokens);
Chris@17 87 if (empty($invalidScopeTokens) === false) {
Chris@17 88 $invalid = implode(', ', $invalidScopeTokens);
Chris@17 89 $error = "Scope tokens [$invalid] can't be in the tokens array";
Chris@17 90 throw new RuntimeException($error);
Chris@17 91 }
Chris@17 92
Chris@17 93 $this->listenOutside = $listenOutside;
Chris@17 94 $this->scopeTokens = array_flip($scopeTokens);
Chris@17 95 $this->tokens = $tokens;
Chris@17 96
Chris@17 97 }//end __construct()
Chris@17 98
Chris@17 99
Chris@17 100 /**
Chris@17 101 * The method that is called to register the tokens this test wishes to
Chris@17 102 * listen to.
Chris@17 103 *
Chris@17 104 * DO NOT OVERRIDE THIS METHOD. Use the constructor of this class to register
Chris@17 105 * for the desired tokens and scope.
Chris@17 106 *
Chris@17 107 * @return int[]
Chris@17 108 * @see __constructor()
Chris@17 109 */
Chris@17 110 final public function register()
Chris@17 111 {
Chris@17 112 return $this->tokens;
Chris@17 113
Chris@17 114 }//end register()
Chris@17 115
Chris@17 116
Chris@17 117 /**
Chris@17 118 * Processes the tokens that this test is listening for.
Chris@17 119 *
Chris@17 120 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
Chris@17 121 * @param int $stackPtr The position in the stack where this
Chris@17 122 * token was found.
Chris@17 123 *
Chris@17 124 * @return void|int Optionally returns a stack pointer. The sniff will not be
Chris@17 125 * called again on the current file until the returned stack
Chris@17 126 * pointer is reached. Return ($phpcsFile->numTokens + 1) to skip
Chris@17 127 * the rest of the file.
Chris@17 128 * @see processTokenWithinScope()
Chris@17 129 */
Chris@17 130 final public function process(File $phpcsFile, $stackPtr)
Chris@17 131 {
Chris@17 132 $tokens = $phpcsFile->getTokens();
Chris@17 133
Chris@17 134 $foundScope = false;
Chris@17 135 $skipPtrs = [];
Chris@17 136 foreach ($tokens[$stackPtr]['conditions'] as $scope => $code) {
Chris@17 137 if (isset($this->scopeTokens[$code]) === true) {
Chris@17 138 $skipPtrs[] = $this->processTokenWithinScope($phpcsFile, $stackPtr, $scope);
Chris@17 139 $foundScope = true;
Chris@17 140 }
Chris@17 141 }
Chris@17 142
Chris@17 143 if ($this->listenOutside === true && $foundScope === false) {
Chris@17 144 $skipPtrs[] = $this->processTokenOutsideScope($phpcsFile, $stackPtr);
Chris@17 145 }
Chris@17 146
Chris@17 147 if (empty($skipPtrs) === false) {
Chris@17 148 return min($skipPtrs);
Chris@17 149 }
Chris@17 150
Chris@17 151 return;
Chris@17 152
Chris@17 153 }//end process()
Chris@17 154
Chris@17 155
Chris@17 156 /**
Chris@17 157 * Processes a token that is found within the scope that this test is
Chris@17 158 * listening to.
Chris@17 159 *
Chris@17 160 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
Chris@17 161 * @param int $stackPtr The position in the stack where this
Chris@17 162 * token was found.
Chris@17 163 * @param int $currScope The position in the tokens array that
Chris@17 164 * opened the scope that this test is
Chris@17 165 * listening for.
Chris@17 166 *
Chris@17 167 * @return void|int Optionally returns a stack pointer. The sniff will not be
Chris@17 168 * called again on the current file until the returned stack
Chris@17 169 * pointer is reached. Return ($phpcsFile->numTokens + 1) to skip
Chris@17 170 * the rest of the file.
Chris@17 171 */
Chris@17 172 abstract protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope);
Chris@17 173
Chris@17 174
Chris@17 175 /**
Chris@17 176 * Processes a token that is found outside the scope that this test is
Chris@17 177 * listening to.
Chris@17 178 *
Chris@17 179 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
Chris@17 180 * @param int $stackPtr The position in the stack where this
Chris@17 181 * token was found.
Chris@17 182 *
Chris@17 183 * @return void|int Optionally returns a stack pointer. The sniff will not be
Chris@17 184 * called again on the current file until the returned stack
Chris@17 185 * pointer is reached. Return (count($tokens) + 1) to skip
Chris@17 186 * the rest of the file.
Chris@17 187 */
Chris@17 188 abstract protected function processTokenOutsideScope(File $phpcsFile, $stackPtr);
Chris@17 189
Chris@17 190
Chris@17 191 }//end class