From cac6a67bccdaac5c2fe75577735afdd196f95352 Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 6 Dec 2017 13:39:40 +0000 Subject: [PATCH 01/12] Added new sniff Generic.PHP.DeclareStrictTypes --- .../Sniffs/PHP/DeclareStrictTypesSniff.php | 211 ++++++++++++++++++ .../PHP/DeclareStrictTypesUnitTest.1.inc | 7 + .../DeclareStrictTypesUnitTest.1.inc.fixed | 7 + .../PHP/DeclareStrictTypesUnitTest.2.inc | 3 + .../DeclareStrictTypesUnitTest.2.inc.fixed | 2 + .../PHP/DeclareStrictTypesUnitTest.3.inc | 8 + .../DeclareStrictTypesUnitTest.3.inc.fixed | 6 + .../PHP/DeclareStrictTypesUnitTest.4.inc | 2 + .../DeclareStrictTypesUnitTest.4.inc.fixed | 4 + .../PHP/DeclareStrictTypesUnitTest.5.inc | 2 + .../DeclareStrictTypesUnitTest.5.inc.fixed | 2 + .../PHP/DeclareStrictTypesUnitTest.6.inc | 6 + .../DeclareStrictTypesUnitTest.6.inc.fixed | 10 + .../Tests/PHP/DeclareStrictTypesUnitTest.inc | 4 + .../PHP/DeclareStrictTypesUnitTest.inc.fixed | 5 + .../Tests/PHP/DeclareStrictTypesUnitTest.php | 65 ++++++ 16 files changed, 344 insertions(+) create mode 100644 src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.1.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.1.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.2.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.2.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.3.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.3.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.4.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.4.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.5.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.5.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php new file mode 100644 index 0000000000..c90c508c7f --- /dev/null +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -0,0 +1,211 @@ + + * @copyright 2006-2017 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Standards\Generic\Sniffs\PHP; + +use PHP_CodeSniffer\Sniffs\Sniff; +use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Util\Tokens; + +class DeclareStrictTypesSniff implements Sniff +{ + /** + * Comment with one of these tags will be omitted. The strict_types + * declaration will be placed the next line below the comment. + * Otherwise it will be placed line below PHP opening tag. + * + * @var array + */ + public $omitCommentWithTags = [ + '@author', + '@copyright', + '@license', + ]; + + /** + * How declaration should be formatted. + * + * @var string + */ + public $format = 'declare(strict_types=1);'; + + /** + * Number of blank lines before declaration. + * + * @var integer + */ + public $linesBefore = 0; + + /** + * Number of blank lines after declaration. + * + * @var integer + */ + public $linesAfter = 1; + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return [T_OPEN_TAG]; + + }//end register() + + + /** + * Processes this sniff, when one of its tokens is encountered. + * + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in + * the stack passed in $tokens. + * + * @return int + */ + public function process(File $phpcsFile, $stackPtr) + { + $this->linesBefore = (int) $this->linesBefore; + $this->linesAfter = (int) $this->linesAfter; + + $tokens = $phpcsFile->getTokens(); + + $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); + + if ($tokens[$next]['code'] === T_DECLARE) { + $eos = $phpcsFile->findEndOfStatement($next); + $string = $phpcsFile->getTokensAsString($next, ($eos - $next + 1)); + + if (stripos($string, 'strict_types') !== false) { + // Check how many blank lines is before declare statement. + $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($next - 1), null, true); + $linesBefore = ($tokens[$next]['line'] - $tokens[$prev]['line'] - 1); + if ($linesBefore !== $this->linesBefore) { + $error = 'Invalid number of blank lines before declare statement; expected %d, but found %d'; + $data = [ + $this->linesBefore, + $linesBefore, + ]; + $fix = $phpcsFile->addFixableError($error, $next, 'LinesBefore', $data); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + if ($linesBefore > $this->linesBefore) { + // Remove additional blank line(s). + for ($i = ($prev + 1); $i < $next; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + if (($tokens[$next]['line'] - $tokens[($i + 1)]['line'] - 1) === $this->linesBefore) { + break; + } + } + } else { + // Add new blank line(s). + while ($linesBefore < $this->linesBefore) { + $phpcsFile->fixer->addNewlineBefore($next); + ++$linesBefore; + } + } + + $phpcsFile->fixer->endChangeset(); + } + }//end if + + // Check number of blank lines after the declare statement. + $after = $phpcsFile->findNext(T_WHITESPACE, ($eos + 1), null, true); + if ($after !== false) { + $linesAfter = ($tokens[$after]['line'] - $tokens[$eos]['line'] - 1); + if ($linesAfter !== $this->linesAfter) { + $error = 'Invalid number of blank lines after declare statement; expected %d, but found %d'; + $data = [ + $this->linesAfter, + $linesAfter, + ]; + $fix = $phpcsFile->addFixableError($error, $eos, 'LinesAfter', $data); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + if ($linesAfter > $this->linesAfter) { + for ($i = ($eos + 1); $i < $after; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + if (($tokens[($i + 1)]['line'] - $tokens[$after]['line'] - 1) === $this->linesAfter) { + break; + } + } + } else { + while ($linesAfter < $this->linesAfter) { + $phpcsFile->fixer->addNewline($eos); + ++$linesAfter; + } + } + + $phpcsFile->fixer->endChangeset(); + } + }//end if + }//end if + + // Check if declare statement match provided format. + if ($string !== $this->format) { + $error = 'Invalid format of declaration; expected "%s", but found "%s"'; + $data = [ + $this->format, + $string, + ]; + $fix = $phpcsFile->addFixableError($error, $next, 'InvalidFormat', $data); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + for ($i = $next; $i < $eos; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + } + + $phpcsFile->fixer->replaceToken($eos, $this->format); + $phpcsFile->fixer->endChangeset(); + } + } + + return (count($tokens) + 1); + }//end if + }//end if + + $error = 'Missing declaration of strict types at the beginning of the file'; + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotFound'); + + if ($fix === true) { + $after = $stackPtr; + $first = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); + if ($first !== null && $tokens[$first]['code'] === T_DOC_COMMENT_OPEN_TAG) { + foreach ($tokens[$first]['comment_tags'] as $tag) { + if (in_array(strtolower($tokens[$tag]['content']), $this->omitCommentWithTags, true)) { + $after = $tokens[$first]['comment_closer']; + break; + } + } + } + + $phpcsFile->fixer->beginChangeset(); + if ($after > $stackPtr) { + $phpcsFile->fixer->addNewline($after); + } + + $phpcsFile->fixer->addContent($after, 'declare(strict_types=1);'); + if ($after === $stackPtr) { + $phpcsFile->fixer->addNewline($after); + } + + $phpcsFile->fixer->endChangeset(); + }//end if + + return (count($tokens) + 1); + + }//end process() + + +}//end class diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.1.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.1.inc new file mode 100644 index 0000000000..ed04879a34 --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.1.inc @@ -0,0 +1,7 @@ + + * @copyright 2006-2017 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Standards\Generic\Tests\PHP; + +use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; + +class DeclareStrictTypesUnitTest extends AbstractSniffUnitTest +{ + + + /** + * Returns the lines where errors should occur. + * + * The key of the array should represent the line number and the value + * should represent the number of errors that should occur on that line. + * + * @param string $testFile The name of the file being tested. + * + * @return array + */ + public function getErrorList($testFile='') + { + switch ($testFile) { + case 'DeclareStrictTypesUnitTest.1.inc': + return [1 => 1]; + case 'DeclareStrictTypesUnitTest.2.inc': + return [3 => 1]; + case 'DeclareStrictTypesUnitTest.3.inc': + return [8 => 1]; + case 'DeclareStrictTypesUnitTest.4.inc': + return [1 => 1]; + case 'DeclareStrictTypesUnitTest.5.inc': + return [2 => 1]; + case 'DeclareStrictTypesUnitTest.6.inc': + return [5 => 3]; + } + + return [1 => 1]; + + }//end getErrorList() + + + /** + * Returns the lines where warnings should occur. + * + * The key of the array should represent the line number and the value + * should represent the number of warnings that should occur on that line. + * + * @return array + */ + public function getWarningList() + { + return []; + + }//end getWarningList() + + +}//end class From d17c657619eb1973044407f358517dd67605edce Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 6 Dec 2017 19:46:59 +0000 Subject: [PATCH 02/12] Allow declare strict types in one line --- .../Sniffs/PHP/DeclareStrictTypesSniff.php | 129 ++++++++++++++---- .../PHP/DeclareStrictTypesUnitTest.6.inc | 14 +- .../DeclareStrictTypesUnitTest.6.inc.fixed | 18 ++- .../PHP/DeclareStrictTypesUnitTest.7.inc | 11 ++ .../DeclareStrictTypesUnitTest.7.inc.fixed | 8 ++ .../PHP/DeclareStrictTypesUnitTest.8.inc | 15 ++ .../DeclareStrictTypesUnitTest.8.inc.fixed | 13 ++ .../PHP/DeclareStrictTypesUnitTest.9.inc | 6 + .../DeclareStrictTypesUnitTest.9.inc.fixed | 10 ++ .../Tests/PHP/DeclareStrictTypesUnitTest.php | 11 +- 10 files changed, 193 insertions(+), 42 deletions(-) create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.8.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.8.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc.fixed diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index c90c508c7f..04eddc2619 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -85,42 +85,121 @@ public function process(File $phpcsFile, $stackPtr) $string = $phpcsFile->getTokensAsString($next, ($eos - $next + 1)); if (stripos($string, 'strict_types') !== false) { - // Check how many blank lines is before declare statement. - $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($next - 1), null, true); - $linesBefore = ($tokens[$next]['line'] - $tokens[$prev]['line'] - 1); - if ($linesBefore !== $this->linesBefore) { - $error = 'Invalid number of blank lines before declare statement; expected %d, but found %d'; - $data = [ - $this->linesBefore, - $linesBefore, - ]; - $fix = $phpcsFile->addFixableError($error, $next, 'LinesBefore', $data); + $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($next - 1), null, true); + $after = $phpcsFile->findNext(T_WHITESPACE, ($eos + 1), null, true); - if ($fix === true) { - $phpcsFile->fixer->beginChangeset(); - if ($linesBefore > $this->linesBefore) { - // Remove additional blank line(s). + if ($after !== false + && $tokens[$prev]['code'] === T_OPEN_TAG + && $tokens[$after]['code'] === T_CLOSE_TAG + ) { + if ($tokens[$prev]['line'] !== $tokens[$next]['line']) { + $error = 'PHP open tag must be in the same line as declaration.'; + $fix = $phpcsFile->addFixableError($error, $prev, 'OpenTag'); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + $phpcsFile->fixer->replaceToken($prev, 'fixer->replaceToken($i, ''); - if (($tokens[$next]['line'] - $tokens[($i + 1)]['line'] - 1) === $this->linesBefore) { - break; - } - } - } else { - // Add new blank line(s). - while ($linesBefore < $this->linesBefore) { - $phpcsFile->fixer->addNewlineBefore($next); - ++$linesBefore; } + + $phpcsFile->fixer->endChangeset(); } - $phpcsFile->fixer->endChangeset(); + $prev = false; + }//end if + + if ($prev !== false && ($prev < ($next - 1) || $tokens[$prev]['content'] !== 'addFixableError($error, $prev, 'OpenTagSpace'); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + $phpcsFile->fixer->replaceToken($prev, 'fixer->replaceToken($i, ''); + } + + $phpcsFile->fixer->endChangeset(); + } } + + if ($tokens[$after]['line'] !== $tokens[$eos]['line']) { + $error = 'PHP close tag must be in the same line as declaration.'; + $fix = $phpcsFile->addFixableError($error, $after, 'CloseTag'); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + for ($i = ($eos + 1); $i < $after; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + } + + $phpcsFile->fixer->addContentBefore($after, ' '); + $phpcsFile->fixer->endChangeset(); + } + + $after = false; + }//end if + + if ($after !== false && ($after > ($eos + 2) || $tokens[($eos + 1)]['content'] !== ' ')) { + $error = 'Expected single space before PHP close tag and after declaration.'; + $fix = $phpcsFile->addFixableError($error, $after, 'CloseTagSpace'); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + for ($i = ($eos + 1); $i < $after; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + } + + $phpcsFile->fixer->addContentBefore($after, ' '); + $phpcsFile->fixer->endChangeset(); + } + }//end if + + $prev = false; + $after = false; + }//end if + + // Check how many blank lines is before declare statement. + if ($prev !== false) { + $linesBefore = ($tokens[$next]['line'] - $tokens[$prev]['line'] - 1); + if ($linesBefore !== $this->linesBefore) { + $error = 'Invalid number of blank lines before declare statement; expected %d, but found %d'; + $data = [ + $this->linesBefore, + $linesBefore, + ]; + $fix = $phpcsFile->addFixableError($error, $next, 'LinesBefore', $data); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + if ($linesBefore > $this->linesBefore) { + // Remove additional blank line(s). + for ($i = ($prev + 1); $i < $next; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + if (($tokens[$next]['line'] - $tokens[($i + 1)]['line'] - 1) === $this->linesBefore) { + break; + } + } + } else { + // Add new blank line(s). + while ($linesBefore < $this->linesBefore) { + $phpcsFile->fixer->addNewlineBefore($next); + ++$linesBefore; + } + } + + $phpcsFile->fixer->endChangeset(); + } + }//end if }//end if // Check number of blank lines after the declare statement. - $after = $phpcsFile->findNext(T_WHITESPACE, ($eos + 1), null, true); if ($after !== false) { + if ($tokens[$after]['code'] === T_CLOSE_TAG) { + $this->linesAfter = 0; + } + $linesAfter = ($tokens[$after]['line'] - $tokens[$eos]['line'] - 1); if ($linesAfter !== $this->linesAfter) { $error = 'Invalid number of blank lines after declare statement; expected %d, but found %d'; diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc index 9a1c6776b9..a6458b4061 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc @@ -1,6 +1,8 @@ -phpcs:set Generic.PHP.DeclareStrictTypes linesBefore 2 -phpcs:set Generic.PHP.DeclareStrictTypes linesAfter 2 -phpcs:set Generic.PHP.DeclareStrictTypes format declare(strict_types = 1); - + + + <?php echo 'Title'; ?> + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc.fixed b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc.fixed index 628e72be8e..468d36c7e3 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc.fixed +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.6.inc.fixed @@ -1,10 +1,8 @@ -phpcs:set Generic.PHP.DeclareStrictTypes linesBefore 2 -phpcs:set Generic.PHP.DeclareStrictTypes linesAfter 2 -phpcs:set Generic.PHP.DeclareStrictTypes format declare(strict_types = 1); - + + + <?php echo 'Title'; ?> + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc new file mode 100644 index 0000000000..3485107af7 --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc @@ -0,0 +1,11 @@ + + + + <?php echo 'Title'; ?> + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc.fixed b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc.fixed new file mode 100644 index 0000000000..468d36c7e3 --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc.fixed @@ -0,0 +1,8 @@ + + + + <?php echo 'Title'; ?> + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.8.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.8.inc new file mode 100644 index 0000000000..7d570e9783 --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.8.inc @@ -0,0 +1,15 @@ + + + + <?php echo 'Title'; ?> + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.8.inc.fixed b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.8.inc.fixed new file mode 100644 index 0000000000..d01b2c91b6 --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.8.inc.fixed @@ -0,0 +1,13 @@ + + + + <?php echo 'Title'; ?> + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc new file mode 100644 index 0000000000..9a1c6776b9 --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc @@ -0,0 +1,6 @@ +phpcs:set Generic.PHP.DeclareStrictTypes linesBefore 2 +phpcs:set Generic.PHP.DeclareStrictTypes linesAfter 2 +phpcs:set Generic.PHP.DeclareStrictTypes format declare(strict_types = 1); + 1]; case 'DeclareStrictTypesUnitTest.6.inc': + return [1 => 2]; + case 'DeclareStrictTypesUnitTest.7.inc': + return [ + 1 => 1, + 4 => 1, + ]; + case 'DeclareStrictTypesUnitTest.8.inc': + return [6 => 2]; + case 'DeclareStrictTypesUnitTest.9.inc': return [5 => 3]; - } + }//end switch return [1 => 1]; From 7f35bf6f0abd4f69319943a607dc93f82dadd790 Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 6 Dec 2017 21:46:08 +0000 Subject: [PATCH 03/12] Changed default value for $linesBefore to 1 --- .../Generic/Sniffs/PHP/DeclareStrictTypesSniff.php | 2 +- .../Tests/PHP/DeclareStrictTypesUnitTest.1.inc.fixed | 1 + .../Generic/Tests/PHP/DeclareStrictTypesUnitTest.2.inc | 1 - .../Tests/PHP/DeclareStrictTypesUnitTest.2.inc.fixed | 1 + .../Tests/PHP/DeclareStrictTypesUnitTest.3.inc.fixed | 1 + .../Tests/PHP/DeclareStrictTypesUnitTest.4.inc.fixed | 1 + .../Tests/PHP/DeclareStrictTypesUnitTest.5.inc.fixed | 1 + .../Tests/PHP/DeclareStrictTypesUnitTest.8.inc.fixed | 1 + .../Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc | 2 +- .../Tests/PHP/DeclareStrictTypesUnitTest.9.inc.fixed | 4 +--- .../Tests/PHP/DeclareStrictTypesUnitTest.inc.fixed | 1 + .../Generic/Tests/PHP/DeclareStrictTypesUnitTest.php | 8 ++++---- 12 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index 04eddc2619..8b19e2dabd 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -40,7 +40,7 @@ class DeclareStrictTypesSniff implements Sniff * * @var integer */ - public $linesBefore = 0; + public $linesBefore = 1; /** * Number of blank lines after declaration. diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.1.inc.fixed b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.1.inc.fixed index d2eb106e9c..ee5113e7d4 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.1.inc.fixed +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.1.inc.fixed @@ -1,4 +1,5 @@ diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc index 9a1c6776b9..f39a37f915 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc @@ -1,4 +1,4 @@ -phpcs:set Generic.PHP.DeclareStrictTypes linesBefore 2 +phpcs:set Generic.PHP.DeclareStrictTypes linesBefore 0 phpcs:set Generic.PHP.DeclareStrictTypes linesAfter 2 phpcs:set Generic.PHP.DeclareStrictTypes format declare(strict_types = 1); 1]; case 'DeclareStrictTypesUnitTest.2.inc': - return [3 => 1]; + return [2 => 1]; case 'DeclareStrictTypesUnitTest.3.inc': return [8 => 1]; case 'DeclareStrictTypesUnitTest.4.inc': return [1 => 1]; case 'DeclareStrictTypesUnitTest.5.inc': - return [2 => 1]; + return [2 => 2]; case 'DeclareStrictTypesUnitTest.6.inc': return [1 => 2]; case 'DeclareStrictTypesUnitTest.7.inc': @@ -46,9 +46,9 @@ public function getErrorList($testFile='') 4 => 1, ]; case 'DeclareStrictTypesUnitTest.8.inc': - return [6 => 2]; + return [6 => 1]; case 'DeclareStrictTypesUnitTest.9.inc': - return [5 => 3]; + return [5 => 2]; }//end switch return [1 => 1]; From 0053c651b8407587e3998e1db21ab069cac6e8f7 Mon Sep 17 00:00:00 2001 From: webimpress Date: Wed, 31 Jan 2018 17:58:31 +0000 Subject: [PATCH 04/12] DeclareStrictTypesSniff updates --- .../Sniffs/PHP/DeclareStrictTypesSniff.php | 217 +++++++++++++++--- .../PHP/DeclareStrictTypesUnitTest.10.inc | 4 + .../DeclareStrictTypesUnitTest.10.inc.fixed | 6 + .../PHP/DeclareStrictTypesUnitTest.11.inc | 12 + .../DeclareStrictTypesUnitTest.11.inc.fixed | 12 + .../PHP/DeclareStrictTypesUnitTest.12.inc | 6 + .../DeclareStrictTypesUnitTest.12.inc.fixed | 8 + .../PHP/DeclareStrictTypesUnitTest.13.inc | 2 + .../DeclareStrictTypesUnitTest.13.inc.fixed | 3 + .../PHP/DeclareStrictTypesUnitTest.9.inc | 7 +- .../DeclareStrictTypesUnitTest.9.inc.fixed | 9 +- .../Tests/PHP/DeclareStrictTypesUnitTest.php | 16 +- 12 files changed, 253 insertions(+), 49 deletions(-) create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.10.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.10.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.11.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.11.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.12.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.12.inc.fixed create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.13.inc create mode 100644 src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.13.inc.fixed diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index 8b19e2dabd..c31cbc2c20 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -3,7 +3,7 @@ * Checks that strict types are declared in the PHP file. * * @author Michał Bundyra - * @copyright 2006-2017 Squiz Pty Ltd (ABN 77 084 670 600) + * @copyright 2006-2018 Squiz Pty Ltd (ABN 77 084 670 600) * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ @@ -78,13 +78,58 @@ public function process(File $phpcsFile, $stackPtr) $tokens = $phpcsFile->getTokens(); + if ($stackPtr > 0) { + $before = trim($phpcsFile->getTokensAsString(0, $stackPtr)); + + if ($before === '') { + $error = 'Unexpected whitespace before PHP opening tag'; + $fix = $phpcsFile->addFixableError($error, 0, 'Whitespace'); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + for ($i = 0; $i < $stackPtr; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + } + + $phpcsFile->fixer->endChangeset(); + } + } else { + $error = 'Missing strict type declaration as first statement in the script'; + $fix = $phpcsFile->addFixableError($error, 0, 'Missing'); + + if ($fix === true) { + $phpcsFile->fixer->addContentBefore( + 0, + sprintf('%s', $this->format, $phpcsFile->eolChar) + ); + } + }//end if + + $this->checkOtherDeclarations($phpcsFile); + + return $phpcsFile->numTokens; + }//end if + $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); if ($tokens[$next]['code'] === T_DECLARE) { - $eos = $phpcsFile->findEndOfStatement($next); - $string = $phpcsFile->getTokensAsString($next, ($eos - $next + 1)); + $string = $phpcsFile->findNext( + T_STRING, + ($tokens[$next]['parenthesis_opener'] + 1), + $tokens[$next]['parenthesis_closer'] + ); + + if ($string !== false + && stripos($tokens[$string]['content'], 'strict_types') !== false + ) { + if (isset($tokens[$next]['scope_closer']) === true + && $next === $tokens[$next]['scope_condition'] + ) { + $eos = $tokens[$next]['scope_closer']; + } else { + $eos = $phpcsFile->findEndOfStatement($next); + } - if (stripos($string, 'strict_types') !== false) { $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($next - 1), null, true); $after = $phpcsFile->findNext(T_WHITESPACE, ($eos + 1), null, true); @@ -93,7 +138,7 @@ public function process(File $phpcsFile, $stackPtr) && $tokens[$after]['code'] === T_CLOSE_TAG ) { if ($tokens[$prev]['line'] !== $tokens[$next]['line']) { - $error = 'PHP open tag must be in the same line as declaration.'; + $error = 'PHP open tag must be on the same line as strict type declaration.'; $fix = $phpcsFile->addFixableError($error, $prev, 'OpenTag'); if ($fix === true) { @@ -110,7 +155,7 @@ public function process(File $phpcsFile, $stackPtr) }//end if if ($prev !== false && ($prev < ($next - 1) || $tokens[$prev]['content'] !== 'addFixableError($error, $prev, 'OpenTagSpace'); if ($fix === true) { @@ -125,7 +170,7 @@ public function process(File $phpcsFile, $stackPtr) } if ($tokens[$after]['line'] !== $tokens[$eos]['line']) { - $error = 'PHP close tag must be in the same line as declaration.'; + $error = 'PHP close tag must be on the same line as strict type declaration.'; $fix = $phpcsFile->addFixableError($error, $after, 'CloseTag'); if ($fix === true) { @@ -160,16 +205,22 @@ public function process(File $phpcsFile, $stackPtr) $after = false; }//end if - // Check how many blank lines is before declare statement. + // Check how many blank lines there are before declare statement. if ($prev !== false) { $linesBefore = ($tokens[$next]['line'] - $tokens[$prev]['line'] - 1); if ($linesBefore !== $this->linesBefore) { - $error = 'Invalid number of blank lines before declare statement; expected %d, but found %d'; - $data = [ - $this->linesBefore, - $linesBefore, - ]; - $fix = $phpcsFile->addFixableError($error, $next, 'LinesBefore', $data); + if ($linesBefore < 0) { + $error = 'Strict type declaration must be in new line'; + $data = []; + } else { + $error = 'Invalid number of blank lines before declare statement; expected %d, but found %d'; + $data = [ + $this->linesBefore, + $linesBefore, + ]; + } + + $fix = $phpcsFile->addFixableError($error, $next, 'LinesBefore', $data); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); @@ -182,15 +233,22 @@ public function process(File $phpcsFile, $stackPtr) } } } else { + // Clear whitespaces between prev and next, but no new lines. + if ($linesBefore < 0) { + for ($i = ($prev + 1); $i < $next; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + } + } + // Add new blank line(s). while ($linesBefore < $this->linesBefore) { $phpcsFile->fixer->addNewlineBefore($next); ++$linesBefore; } - } + }//end if $phpcsFile->fixer->endChangeset(); - } + }//end if }//end if }//end if @@ -202,12 +260,18 @@ public function process(File $phpcsFile, $stackPtr) $linesAfter = ($tokens[$after]['line'] - $tokens[$eos]['line'] - 1); if ($linesAfter !== $this->linesAfter) { - $error = 'Invalid number of blank lines after declare statement; expected %d, but found %d'; - $data = [ - $this->linesAfter, - $linesAfter, - ]; - $fix = $phpcsFile->addFixableError($error, $eos, 'LinesAfter', $data); + if ($linesAfter < 0) { + $error = 'Strict type declaration must be the only statement in the line'; + $data = []; + } else { + $error = 'Invalid number of blank lines after declare statement; expected %d, but found %d'; + $data = [ + $this->linesAfter, + $linesAfter, + ]; + } + + $fix = $phpcsFile->addFixableError($error, $eos, 'LinesAfter', $data); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); @@ -219,42 +283,60 @@ public function process(File $phpcsFile, $stackPtr) } } } else { + // Remove whitespaces between EOS and after token. + if ($linesAfter < 0) { + for ($i = ($eos + 1); $i < $after; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + } + } + + // Add new lines after the statement. while ($linesAfter < $this->linesAfter) { $phpcsFile->fixer->addNewline($eos); ++$linesAfter; } - } + }//end if $phpcsFile->fixer->endChangeset(); - } + }//end if }//end if }//end if // Check if declare statement match provided format. + $string = $phpcsFile->getTokensAsString($next, ($eos - $next + 1)); if ($string !== $this->format) { - $error = 'Invalid format of declaration; expected "%s", but found "%s"'; + $error = 'Invalid format of strict type declaration; expected "%s", but found "%s"'; $data = [ $this->format, $string, ]; - $fix = $phpcsFile->addFixableError($error, $next, 'InvalidFormat', $data); - if ($fix === true) { - $phpcsFile->fixer->beginChangeset(); - for ($i = $next; $i < $eos; ++$i) { - $phpcsFile->fixer->replaceToken($i, ''); - } + if ($this->normalize($string) === $this->normalize($this->format)) { + $fix = $phpcsFile->addFixableError($error, $next, 'InvalidFormat', $data); + + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + for ($i = $next; $i < $eos; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + } - $phpcsFile->fixer->replaceToken($eos, $this->format); - $phpcsFile->fixer->endChangeset(); + $phpcsFile->fixer->replaceToken($eos, $this->format); + $phpcsFile->fixer->endChangeset(); + } + } else { + $phpcsFile->addError($error, $next, 'InvalidFormatNotFixable', $data); } - } + }//end if + + $this->checkOtherDeclarations($phpcsFile, $next); return (count($tokens) + 1); }//end if }//end if - $error = 'Missing declaration of strict types at the beginning of the file'; + $this->checkOtherDeclarations($phpcsFile, $next); + + $error = 'Missing strict type declaration at the beginning of the file'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotFound'); if ($fix === true) { @@ -262,7 +344,7 @@ public function process(File $phpcsFile, $stackPtr) $first = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); if ($first !== null && $tokens[$first]['code'] === T_DOC_COMMENT_OPEN_TAG) { foreach ($tokens[$first]['comment_tags'] as $tag) { - if (in_array(strtolower($tokens[$tag]['content']), $this->omitCommentWithTags, true)) { + if (in_array(strtolower($tokens[$tag]['content']), $this->omitCommentWithTags, true) === true) { $after = $tokens[$first]['comment_closer']; break; } @@ -287,4 +369,67 @@ public function process(File $phpcsFile, $stackPtr) }//end process() + /** + * Normalize given string by removing all white characters + * and changed to lower case. + * + * @param string $string String to be normalized. + * + * @return string + */ + private function normalize($string) + { + return strtolower(preg_replace('/\s/', '', $string)); + + }//end normalize() + + + /** + * Process other strict_type declaration in the file and remove them. + * The declaration has to be the very first statement in the script. + * + * @param File $phpcsFile The file being scanned. + * @param int $declare The position of the first declaration. + * + * @return void + */ + private function checkOtherDeclarations(File $phpcsFile, $declare=0) + { + $tokens = $phpcsFile->getTokens(); + + while (($declare = $phpcsFile->findNext(T_DECLARE, ($declare + 1))) !== false) { + $string = $phpcsFile->findNext( + T_STRING, + ($tokens[$declare]['parenthesis_opener'] + 1), + $tokens[$declare]['parenthesis_closer'] + ); + + if ($string !== false + && stripos($tokens[$string]['content'], 'strict_types') !== false + ) { + $error = 'Strict type declaration must be the very first statement in the script'; + $fix = $phpcsFile->addFixableError($error, $declare, 'NotFirstStatement'); + + if ($fix === true) { + $end = $phpcsFile->findNext( + (Tokens::$emptyTokens + [T_SEMICOLON]), + ($tokens[$declare]['parenthesis_closer'] + 1), + null, + true + ); + + if ($end === false) { + $end = $phpcsFile->numTokens; + } + + for ($i = $declare; $i < $end; ++$i) { + $phpcsFile->fixer->replaceToken($i, ''); + } + } + }//end if + }//end while + + }//end checkOtherDeclarations() + + }//end class diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.10.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.10.inc new file mode 100644 index 0000000000..f769717f7a --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.10.inc @@ -0,0 +1,4 @@ + + + + <?php + declare(strict_types=1); + echo 'Title'; + ?> + + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.11.inc.fixed b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.11.inc.fixed new file mode 100644 index 0000000000..cfad003bc5 --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.11.inc.fixed @@ -0,0 +1,12 @@ + + + + + <?php + echo 'Title'; + ?> + + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.12.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.12.inc new file mode 100644 index 0000000000..5ab5fb76bd --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.12.inc @@ -0,0 +1,6 @@ + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.12.inc.fixed b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.12.inc.fixed new file mode 100644 index 0000000000..eb1c6a1503 --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.12.inc.fixed @@ -0,0 +1,8 @@ + + + + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.13.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.13.inc new file mode 100644 index 0000000000..b5c390ae46 --- /dev/null +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.13.inc @@ -0,0 +1,2 @@ + diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc.fixed b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc.fixed index 5953ebc2c9..2e2406790e 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc.fixed +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.9.inc.fixed @@ -1,8 +1,5 @@ -phpcs:set Generic.PHP.DeclareStrictTypes linesBefore 0 -phpcs:set Generic.PHP.DeclareStrictTypes linesAfter 2 -phpcs:set Generic.PHP.DeclareStrictTypes format declare(strict_types = 1); - diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php index 9941fd07c4..7bf7c1e8f3 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php @@ -48,7 +48,21 @@ public function getErrorList($testFile='') case 'DeclareStrictTypesUnitTest.8.inc': return [6 => 1]; case 'DeclareStrictTypesUnitTest.9.inc': - return [5 => 2]; + return [1 => 2]; + case 'DeclareStrictTypesUnitTest.10.inc': + return [ + 1 => 1, + 4 => 1, + ]; + case 'DeclareStrictTypesUnitTest.11.inc': + return [ + 1 => 1, + 5 => 1, + ]; + case 'DeclareStrictTypesUnitTest.12.inc': + return [3 => 2]; + case 'DeclareStrictTypesUnitTest.13.inc': + return [2 => 2]; }//end switch return [1 => 1]; From 3b0645aa9efe5bd415bcd716fd2e7de8ac62716f Mon Sep 17 00:00:00 2001 From: webimpress Date: Sun, 25 Mar 2018 16:13:18 +0100 Subject: [PATCH 05/12] Renamed properties - linesBefore -> spacingBefore - linesAfter -> spacingAfter --- .../Sniffs/PHP/DeclareStrictTypesSniff.php | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index c31cbc2c20..21e50771bc 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -40,14 +40,14 @@ class DeclareStrictTypesSniff implements Sniff * * @var integer */ - public $linesBefore = 1; + public $spacingBefore = 1; /** * Number of blank lines after declaration. * * @var integer */ - public $linesAfter = 1; + public $spacingAfter = 1; /** @@ -73,8 +73,8 @@ public function register() */ public function process(File $phpcsFile, $stackPtr) { - $this->linesBefore = (int) $this->linesBefore; - $this->linesAfter = (int) $this->linesAfter; + $this->spacingBefore = (int) $this->spacingBefore; + $this->spacingAfter = (int) $this->spacingAfter; $tokens = $phpcsFile->getTokens(); @@ -208,14 +208,14 @@ public function process(File $phpcsFile, $stackPtr) // Check how many blank lines there are before declare statement. if ($prev !== false) { $linesBefore = ($tokens[$next]['line'] - $tokens[$prev]['line'] - 1); - if ($linesBefore !== $this->linesBefore) { + if ($linesBefore !== $this->spacingBefore) { if ($linesBefore < 0) { $error = 'Strict type declaration must be in new line'; $data = []; } else { $error = 'Invalid number of blank lines before declare statement; expected %d, but found %d'; $data = [ - $this->linesBefore, + $this->spacingBefore, $linesBefore, ]; } @@ -224,11 +224,11 @@ public function process(File $phpcsFile, $stackPtr) if ($fix === true) { $phpcsFile->fixer->beginChangeset(); - if ($linesBefore > $this->linesBefore) { + if ($linesBefore > $this->spacingBefore) { // Remove additional blank line(s). for ($i = ($prev + 1); $i < $next; ++$i) { $phpcsFile->fixer->replaceToken($i, ''); - if (($tokens[$next]['line'] - $tokens[($i + 1)]['line'] - 1) === $this->linesBefore) { + if (($tokens[$next]['line'] - $tokens[($i + 1)]['line'] - 1) === $this->spacingBefore) { break; } } @@ -241,7 +241,7 @@ public function process(File $phpcsFile, $stackPtr) } // Add new blank line(s). - while ($linesBefore < $this->linesBefore) { + while ($linesBefore < $this->spacingBefore) { $phpcsFile->fixer->addNewlineBefore($next); ++$linesBefore; } @@ -255,18 +255,18 @@ public function process(File $phpcsFile, $stackPtr) // Check number of blank lines after the declare statement. if ($after !== false) { if ($tokens[$after]['code'] === T_CLOSE_TAG) { - $this->linesAfter = 0; + $this->spacingAfter = 0; } $linesAfter = ($tokens[$after]['line'] - $tokens[$eos]['line'] - 1); - if ($linesAfter !== $this->linesAfter) { + if ($linesAfter !== $this->spacingAfter) { if ($linesAfter < 0) { $error = 'Strict type declaration must be the only statement in the line'; $data = []; } else { $error = 'Invalid number of blank lines after declare statement; expected %d, but found %d'; $data = [ - $this->linesAfter, + $this->spacingAfter, $linesAfter, ]; } @@ -275,10 +275,10 @@ public function process(File $phpcsFile, $stackPtr) if ($fix === true) { $phpcsFile->fixer->beginChangeset(); - if ($linesAfter > $this->linesAfter) { + if ($linesAfter > $this->spacingAfter) { for ($i = ($eos + 1); $i < $after; ++$i) { $phpcsFile->fixer->replaceToken($i, ''); - if (($tokens[($i + 1)]['line'] - $tokens[$after]['line'] - 1) === $this->linesAfter) { + if (($tokens[($i + 1)]['line'] - $tokens[$after]['line'] - 1) === $this->spacingAfter) { break; } } @@ -291,7 +291,7 @@ public function process(File $phpcsFile, $stackPtr) } // Add new lines after the statement. - while ($linesAfter < $this->linesAfter) { + while ($linesAfter < $this->spacingAfter) { $phpcsFile->fixer->addNewline($eos); ++$linesAfter; } From 0b073f3bc06042ce694793b6c865ec8d0dfa3c7c Mon Sep 17 00:00:00 2001 From: webimpress Date: Mon, 26 Mar 2018 11:39:44 +0100 Subject: [PATCH 06/12] Simplify code as findEndOfStatement now works correctly --- .../Generic/Sniffs/PHP/DeclareStrictTypesSniff.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index 21e50771bc..d5bfe2eed2 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -122,14 +122,7 @@ public function process(File $phpcsFile, $stackPtr) if ($string !== false && stripos($tokens[$string]['content'], 'strict_types') !== false ) { - if (isset($tokens[$next]['scope_closer']) === true - && $next === $tokens[$next]['scope_condition'] - ) { - $eos = $tokens[$next]['scope_closer']; - } else { - $eos = $phpcsFile->findEndOfStatement($next); - } - + $eos = $phpcsFile->findEndOfStatement($next); $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($next - 1), null, true); $after = $phpcsFile->findNext(T_WHITESPACE, ($eos + 1), null, true); From b9025eac533b783ef2f5aeb80f1f0f763187560f Mon Sep 17 00:00:00 2001 From: webimpress Date: Mon, 26 Mar 2018 11:40:15 +0100 Subject: [PATCH 07/12] Removed `omitCommentWithTags` property --- .../Sniffs/PHP/DeclareStrictTypesSniff.php | 38 +------------------ .../Tests/PHP/DeclareStrictTypesUnitTest.inc | 10 +++-- .../PHP/DeclareStrictTypesUnitTest.inc.fixed | 5 +-- .../Tests/PHP/DeclareStrictTypesUnitTest.php | 5 ++- 4 files changed, 15 insertions(+), 43 deletions(-) diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index d5bfe2eed2..cb4d053093 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -15,19 +15,6 @@ class DeclareStrictTypesSniff implements Sniff { - /** - * Comment with one of these tags will be omitted. The strict_types - * declaration will be placed the next line below the comment. - * Otherwise it will be placed line below PHP opening tag. - * - * @var array - */ - public $omitCommentWithTags = [ - '@author', - '@copyright', - '@license', - ]; - /** * How declaration should be formatted. * @@ -333,29 +320,8 @@ public function process(File $phpcsFile, $stackPtr) $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotFound'); if ($fix === true) { - $after = $stackPtr; - $first = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); - if ($first !== null && $tokens[$first]['code'] === T_DOC_COMMENT_OPEN_TAG) { - foreach ($tokens[$first]['comment_tags'] as $tag) { - if (in_array(strtolower($tokens[$tag]['content']), $this->omitCommentWithTags, true) === true) { - $after = $tokens[$first]['comment_closer']; - break; - } - } - } - - $phpcsFile->fixer->beginChangeset(); - if ($after > $stackPtr) { - $phpcsFile->fixer->addNewline($after); - } - - $phpcsFile->fixer->addContent($after, 'declare(strict_types=1);'); - if ($after === $stackPtr) { - $phpcsFile->fixer->addNewline($after); - } - - $phpcsFile->fixer->endChangeset(); - }//end if + $phpcsFile->fixer->addContent($stackPtr, $this->format.$phpcsFile->eolChar); + } return (count($tokens) + 1); diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.inc index 6eb422a41d..7438d056ff 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.inc +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.inc @@ -1,4 +1,8 @@ + + 2]; }//end switch - return [1 => 1]; + return [ + 1 => 1, + 5 => 1, + ]; }//end getErrorList() From 855f68cbcc7ef8fbe4fa4b2cf5e6c14704bec39c Mon Sep 17 00:00:00 2001 From: webimpress Date: Mon, 26 Mar 2018 11:40:53 +0100 Subject: [PATCH 08/12] Updated tests to cover all cases --- src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php | 4 ++-- .../Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc | 2 ++ .../Generic/Tests/PHP/DeclareStrictTypesUnitTest.php | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index cb4d053093..53eba55853 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -258,7 +258,7 @@ public function process(File $phpcsFile, $stackPtr) if ($linesAfter > $this->spacingAfter) { for ($i = ($eos + 1); $i < $after; ++$i) { $phpcsFile->fixer->replaceToken($i, ''); - if (($tokens[($i + 1)]['line'] - $tokens[$after]['line'] - 1) === $this->spacingAfter) { + if (($tokens[$after]['line'] - $tokens[($i + 1)]['line'] - 1) === $this->spacingAfter) { break; } } @@ -371,7 +371,7 @@ private function checkOtherDeclarations(File $phpcsFile, $declare=0) if ($fix === true) { $end = $phpcsFile->findNext( - (Tokens::$emptyTokens + [T_SEMICOLON]), + (Tokens::$emptyTokens + [T_SEMICOLON => T_SEMICOLON]), ($tokens[$declare]['parenthesis_closer'] + 1), null, true diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc index 3485107af7..0dd39dd47f 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.7.inc @@ -1,4 +1,6 @@ diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php index 3c8c6cce89..0f7a88de54 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php @@ -43,7 +43,7 @@ public function getErrorList($testFile='') case 'DeclareStrictTypesUnitTest.7.inc': return [ 1 => 1, - 4 => 1, + 6 => 1, ]; case 'DeclareStrictTypesUnitTest.8.inc': return [6 => 1]; From 6165428b1f137e3a79878abedb0321f351fe0712 Mon Sep 17 00:00:00 2001 From: webimpress Date: Tue, 27 Mar 2018 13:41:37 +0100 Subject: [PATCH 09/12] Use $phpcsFile->numTokens instead of counting tokens --- src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index 53eba55853..a536ac533c 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -310,7 +310,7 @@ public function process(File $phpcsFile, $stackPtr) $this->checkOtherDeclarations($phpcsFile, $next); - return (count($tokens) + 1); + return $phpcsFile->numTokens; }//end if }//end if @@ -323,7 +323,7 @@ public function process(File $phpcsFile, $stackPtr) $phpcsFile->fixer->addContent($stackPtr, $this->format.$phpcsFile->eolChar); } - return (count($tokens) + 1); + return $phpcsFile->numTokens; }//end process() From 6e947affc3c82dbd5870e7055b804f6fbf2f0340 Mon Sep 17 00:00:00 2001 From: webimpress Date: Tue, 27 Mar 2018 14:21:55 +0100 Subject: [PATCH 10/12] Returns ($phpcsFile->numTokens + 1) when nothing else to process - per @jrfnl --- .../Generic/Sniffs/PHP/DeclareStrictTypesSniff.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index a536ac533c..d8284e4033 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -94,7 +94,7 @@ public function process(File $phpcsFile, $stackPtr) $this->checkOtherDeclarations($phpcsFile); - return $phpcsFile->numTokens; + return ($phpcsFile->numTokens + 1); }//end if $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); @@ -310,7 +310,7 @@ public function process(File $phpcsFile, $stackPtr) $this->checkOtherDeclarations($phpcsFile, $next); - return $phpcsFile->numTokens; + return ($phpcsFile->numTokens + 1); }//end if }//end if @@ -323,7 +323,7 @@ public function process(File $phpcsFile, $stackPtr) $phpcsFile->fixer->addContent($stackPtr, $this->format.$phpcsFile->eolChar); } - return $phpcsFile->numTokens; + return ($phpcsFile->numTokens + 1); }//end process() From 69ad7d034ec16c94ec0fa177661c466e0af8d779 Mon Sep 17 00:00:00 2001 From: webimpress Date: Thu, 24 Jan 2019 08:04:30 +0000 Subject: [PATCH 11/12] Changed format property to private We don't want this configuration option to be available - per @gsherwood --- src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index d8284e4033..8537ee0ac1 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -20,7 +20,7 @@ class DeclareStrictTypesSniff implements Sniff * * @var string */ - public $format = 'declare(strict_types=1);'; + private $format = 'declare(strict_types=1);'; /** * Number of blank lines before declaration. From 4cd331fdbb65a9bc3138554d7e9d6dfed8f5de2e Mon Sep 17 00:00:00 2001 From: webimpress Date: Thu, 24 Jan 2019 08:04:43 +0000 Subject: [PATCH 12/12] Updated year in copyright headers --- src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php | 2 +- src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php index 8537ee0ac1..1bb3a5970c 100644 --- a/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php +++ b/src/Standards/Generic/Sniffs/PHP/DeclareStrictTypesSniff.php @@ -3,7 +3,7 @@ * Checks that strict types are declared in the PHP file. * * @author Michał Bundyra - * @copyright 2006-2018 Squiz Pty Ltd (ABN 77 084 670 600) + * @copyright 2006-2019 Squiz Pty Ltd (ABN 77 084 670 600) * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ diff --git a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php index 0f7a88de54..4e23ade8c3 100644 --- a/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php +++ b/src/Standards/Generic/Tests/PHP/DeclareStrictTypesUnitTest.php @@ -3,7 +3,7 @@ * Unit test class for the DeclareStrictTypes sniff. * * @author Michał Bundyra - * @copyright 2006-2017 Squiz Pty Ltd (ABN 77 084 670 600) + * @copyright 2006-2019 Squiz Pty Ltd (ABN 77 084 670 600) * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */