-
-
Notifications
You must be signed in to change notification settings - Fork 170
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
61c5250
commit 716a873
Showing
11 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
107 changes: 107 additions & 0 deletions
107
SlevomatCodingStandard/Sniffs/Typehints/DeclareStrictTypesSniff.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<?php | ||
|
||
namespace SlevomatCodingStandard\Sniffs\Typehints; | ||
|
||
use PHP_CodeSniffer_File; | ||
use SlevomatCodingStandard\Helpers\TokenHelper; | ||
|
||
class DeclareStrictTypesSniff implements \PHP_CodeSniffer_Sniff | ||
{ | ||
|
||
const CODE_DECLARE_STRICT_TYPES_MISSING = 'declareStrictTypesMissing'; | ||
|
||
const CODE_INCORRECT_WHITESPACE_BETWEEN_OPEN_TAG_AND_DECLARE = 'incorrectWhitespaceBetweenOpenTagAndDeclare'; | ||
|
||
public $newlinesCountBetweenOpenTagAndDeclare = 0; | ||
|
||
/** @var string[] */ | ||
private static $alreadyProcessedFiles = []; | ||
|
||
/** | ||
* @return integer[] | ||
*/ | ||
public function register() | ||
{ | ||
return [ | ||
T_OPEN_TAG, | ||
]; | ||
} | ||
|
||
/** | ||
* @param \PHP_CodeSniffer_File $phpcsFile | ||
* @param integer $openTagPointer | ||
*/ | ||
public function process(PHP_CodeSniffer_File $phpcsFile, $openTagPointer) | ||
{ | ||
if (isset(self::$alreadyProcessedFiles[$phpcsFile->getFilename()])) { | ||
return; | ||
} | ||
|
||
self::$alreadyProcessedFiles[$phpcsFile->getFilename()] = true; | ||
|
||
$tokens = $phpcsFile->getTokens(); | ||
$declarePointer = TokenHelper::findNextNonWhitespace($phpcsFile, $openTagPointer + 1); | ||
if ($tokens[$declarePointer]['code'] !== T_DECLARE) { | ||
$this->reportMissingDeclareStrict($phpcsFile, $openTagPointer); | ||
return; | ||
} | ||
$stringPointer = $phpcsFile->findNext(T_STRING, $declarePointer + 1); | ||
if ($tokens[$stringPointer]['content'] !== 'strict_types') { | ||
$this->reportMissingDeclareStrict($phpcsFile, $declarePointer); | ||
return; | ||
} | ||
|
||
$numberPointer = $phpcsFile->findNext(T_LNUMBER, $stringPointer + 1); | ||
if ($tokens[$numberPointer]['content'] !== '1') { | ||
$this->reportMissingDeclareStrict($phpcsFile, $declarePointer); | ||
return; | ||
} | ||
|
||
$openingWhitespace = substr($tokens[$openTagPointer]['content'], strlen('<?php')); | ||
$newlinesCountBetweenOpenTagAndDeclare = (int) trim($this->newlinesCountBetweenOpenTagAndDeclare); | ||
if ($newlinesCountBetweenOpenTagAndDeclare === 0) { | ||
if ($openingWhitespace !== ' ') { | ||
$phpcsFile->addError( | ||
'There must be a single space between the PHP open tag and declare statement.', | ||
$declarePointer, | ||
self::CODE_INCORRECT_WHITESPACE_BETWEEN_OPEN_TAG_AND_DECLARE | ||
); | ||
} | ||
} else { | ||
$startToken = $openTagPointer + 1; | ||
do { | ||
$possibleWhitespacePointer = TokenHelper::findNextAnyToken($phpcsFile, $startToken); | ||
if ($possibleWhitespacePointer !== null && $tokens[$possibleWhitespacePointer]['code'] === T_WHITESPACE) { | ||
$openingWhitespace .= $tokens[$possibleWhitespacePointer]['content']; | ||
} | ||
$startToken++; | ||
} while ($possibleWhitespacePointer !== null && $tokens[$possibleWhitespacePointer]['code'] === T_WHITESPACE); | ||
$newlinesCount = substr_count($openingWhitespace, $phpcsFile->eolChar); | ||
if ($newlinesCount !== $newlinesCountBetweenOpenTagAndDeclare) { | ||
$phpcsFile->addError( | ||
sprintf( | ||
'Expected %d newlines between PHP open tag and declare statement, found %d.', | ||
$newlinesCountBetweenOpenTagAndDeclare, | ||
$newlinesCount | ||
), | ||
$declarePointer, | ||
self::CODE_INCORRECT_WHITESPACE_BETWEEN_OPEN_TAG_AND_DECLARE | ||
); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @param \PHP_CodeSniffer_File $phpcsFile | ||
* @param integer $openTagPointer | ||
*/ | ||
private function reportMissingDeclareStrict(PHP_CodeSniffer_File $phpcsFile, $openTagPointer) | ||
{ | ||
$phpcsFile->addError( | ||
'Missing declare(strict_types=1).', | ||
$openTagPointer, | ||
self::CODE_DECLARE_STRICT_TYPES_MISSING | ||
); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
|
||
namespace SlevomatCodingStandard\Sniffs\Typehints; | ||
|
||
class DeclareStrictTypesSniffTest extends \SlevomatCodingStandard\Sniffs\TestCase | ||
{ | ||
|
||
public function testMultipleOpenTagsInFile() | ||
{ | ||
$this->assertNoSniffErrorInFile($this->checkFile(__DIR__ . '/data/declareStrictTypesMultipleOpenTags.php')); | ||
} | ||
|
||
public function dataDeclareStrictTypesMissing() | ||
{ | ||
return [ | ||
[ | ||
__DIR__ . '/data/declareStrictTypesMissing.php', | ||
1, | ||
], | ||
[ | ||
__DIR__ . '/data/declareTicks.php', | ||
3, | ||
], | ||
[ | ||
__DIR__ . '/data/declareStrictTypesZero.php', | ||
3, | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* @dataProvider dataDeclareStrictTypesMissing | ||
* @param string $file | ||
* @param integer $line | ||
*/ | ||
public function testDeclareStrictTypesMissing($file, $line) | ||
{ | ||
$report = $this->checkFile($file); | ||
$this->assertSniffError( | ||
$report, | ||
$line, | ||
DeclareStrictTypesSniff::CODE_DECLARE_STRICT_TYPES_MISSING | ||
); | ||
} | ||
|
||
public function testDeclareStrictTwoNewlines() | ||
{ | ||
$file = __DIR__ . '/data/declareStrictTypesTwoNewlines.php'; | ||
$this->assertNoSniffErrorInFile($this->checkFile($file, [ | ||
'newlinesCountBetweenOpenTagAndDeclare' => ' 2 ', | ||
])); | ||
} | ||
|
||
public function testDeclareStrictTwoNewlinesError() | ||
{ | ||
$report = $this->checkFile(__DIR__ . '/data/declareStrictTypesTwoNewlinesError.php'); | ||
$this->assertSniffError( | ||
$report, | ||
3, | ||
DeclareStrictTypesSniff::CODE_INCORRECT_WHITESPACE_BETWEEN_OPEN_TAG_AND_DECLARE, | ||
'There must be a single space between the PHP open tag and declare statement.' | ||
); | ||
} | ||
|
||
public function testDeclareStrictOneSpaceError() | ||
{ | ||
$report = $this->checkFile(__DIR__ . '/data/declareStrictTypesOneSpaceError.php', [ | ||
'newlinesCountBetweenOpenTagAndDeclare' => '2', | ||
]); | ||
$this->assertSniffError( | ||
$report, | ||
1, | ||
DeclareStrictTypesSniff::CODE_INCORRECT_WHITESPACE_BETWEEN_OPEN_TAG_AND_DECLARE, | ||
'Expected 2 newlines between PHP open tag and declare statement, found 0.' | ||
); | ||
} | ||
|
||
public function testDeclareStrictOneSpace() | ||
{ | ||
$this->assertNoSniffErrorInFile($this->checkFile(__DIR__ . '/data/declareStrictTypesOneSpace.php')); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?php | ||
|
||
class Foo | ||
{ | ||
|
||
} |
5 changes: 5 additions & 0 deletions
5
tests/Sniffs/Typehints/data/declareStrictTypesMultipleOpenTags.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
?><html><?php | ||
|
||
?></html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<?php declare(strict_types=1); |
1 change: 1 addition & 0 deletions
1
tests/Sniffs/Typehints/data/declareStrictTypesOneSpaceError.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<?php declare(strict_types=1); |
3 changes: 3 additions & 0 deletions
3
tests/Sniffs/Typehints/data/declareStrictTypesTwoNewlines.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<?php | ||
|
||
declare(strict_types=1); |
3 changes: 3 additions & 0 deletions
3
tests/Sniffs/Typehints/data/declareStrictTypesTwoNewlinesError.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<?php | ||
|
||
declare(strict_types=1); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<?php | ||
|
||
declare(strict_types=0); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<?php | ||
|
||
declare(ticks = 1000); |