getTokens(); /* * Validate the received function input. */ if (isset($tokens[$stackPtr], $tokens[$secondPtr]) === false || $tokens[$stackPtr]['code'] === \T_WHITESPACE || $tokens[$secondPtr]['code'] === \T_WHITESPACE ) { throw new RuntimeException('The $stackPtr and the $secondPtr token must exist and not be whitespace'); } $expected = false; if ($expectedSpaces === 'newline') { $expected = $expectedSpaces; } elseif (\is_int($expectedSpaces) === true && $expectedSpaces >= 0) { $expected = $expectedSpaces; } elseif (\is_string($expectedSpaces) === true && Numbers::isDecimalInt($expectedSpaces) === true) { $expected = (int) $expectedSpaces; } if ($expected === false) { throw new RuntimeException( 'The $expectedSpaces setting should be either "newline", 0 or a positive integer' ); } $ptrA = $stackPtr; $ptrB = $secondPtr; if ($stackPtr > $secondPtr) { $ptrA = $secondPtr; $ptrB = $stackPtr; } $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($ptrA + 1), null, true); if ($nextNonEmpty !== false && $nextNonEmpty < $ptrB) { throw new RuntimeException( 'The $stackPtr and the $secondPtr token must be adjacent tokens separated only' . ' by whitespace and/or comments' ); } /* * Determine how many spaces are between the two tokens. */ $found = 0; $foundPhrase = 'no spaces'; if ($tokens[$ptrA]['line'] !== $tokens[$ptrB]['line']) { $found = 'newline'; $foundPhrase = 'a new line'; if (($tokens[$ptrA]['line'] + 1) !== $tokens[$ptrB]['line']) { $foundPhrase = 'multiple new lines'; } } elseif (($ptrA + 1) !== $ptrB) { if ($tokens[($ptrA + 1)]['code'] === \T_WHITESPACE) { $found = $tokens[($ptrA + 1)]['length']; $foundPhrase = $found . (($found === 1) ? ' space' : ' spaces'); } else { $found = 'non-whitespace tokens'; $foundPhrase = 'non-whitespace tokens'; } } if ($metricName !== '') { $phpcsFile->recordMetric($stackPtr, $metricName, $foundPhrase); } if ($found === $expected) { return; } /* * Handle the violation message. */ $expectedPhrase = 'no space'; if ($expected === 'newline') { $expectedPhrase = 'a new line'; } elseif ($expected === 1) { $expectedPhrase = $expected . ' space'; } elseif ($expected > 1) { $expectedPhrase = $expected . ' spaces'; } $fixable = true; $nextNonWhitespace = $phpcsFile->findNext(\T_WHITESPACE, ($ptrA + 1), null, true); if ($nextNonWhitespace !== $ptrB) { // Comment found between the tokens and we don't know where it should go, so don't auto-fix. $fixable = false; } if ($found === 'newline' && $tokens[$ptrA]['code'] === \T_COMMENT && \substr($tokens[$ptrA]['content'], -2) !== '*/' ) { /* * $ptrA is a slash-style trailing comment, removing the new line would comment out * the code, so don't auto-fix. */ $fixable = false; } $method = 'add'; $method .= ($fixable === true) ? 'Fixable' : ''; $method .= ($errorType === 'error') ? 'Error' : 'Warning'; $recorded = $phpcsFile->$method( $errorTemplate, $stackPtr, $errorCode, [$expectedPhrase, $foundPhrase], $errorSeverity ); if ($fixable === false || $recorded === false) { return; } /* * Fix the violation. */ $phpcsFile->fixer->beginChangeset(); /* * Remove existing whitespace. No need to check if it's whitespace as otherwise the fixer * wouldn't have kicked in. */ for ($i = ($ptrA + 1); $i < $ptrB; $i++) { $phpcsFile->fixer->replaceToken($i, ''); } // If necessary: add the correct amount whitespace. if ($expected !== 0) { if ($expected === 'newline') { $phpcsFile->fixer->addContent($ptrA, $phpcsFile->eolChar); } else { $replacement = $tokens[$ptrA]['content'] . \str_repeat(' ', $expected); $phpcsFile->fixer->replaceToken($ptrA, $replacement); } } $phpcsFile->fixer->endChangeset(); } }