annotate vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractScopeSniff.php @ 5:12f9dff5fda9 tip

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