-
-
Notifications
You must be signed in to change notification settings - Fork 190
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #735 from PHPCompatibility/php-7.3/718-new-depreca…
…ted-namespaced-assert-sniff PHP 7.3: New sniff to recognize deprecated assert() function declarations
- Loading branch information
Showing
4 changed files
with
274 additions
and
0 deletions.
There are no files selected for viewing
92 changes: 92 additions & 0 deletions
92
PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedNamespacedAssertSniff.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,92 @@ | ||
<?php | ||
/** | ||
* \PHPCompatibility\Sniffs\FunctionNameRestrictions\RemovedNamespacedAssertSniff. | ||
* | ||
* PHP version 7.3 | ||
* | ||
* @category PHP | ||
* @package PHPCompatibility | ||
* @author Juliette Reinders Folmer <phpcompatibility_nospam@adviesenzo.nl> | ||
*/ | ||
|
||
namespace PHPCompatibility\Sniffs\FunctionNameRestrictions; | ||
|
||
use PHPCompatibility\Sniff; | ||
|
||
/** | ||
* Removed Namespaced Assert. | ||
* | ||
* As of PHP 7.3, a compile-time deprecation warning will be thrown when a function | ||
* called `assert()` is declared. In PHP 8 this will become a compile-error. | ||
* | ||
* Methods are unaffected. | ||
* Global, non-namespaced, assert() function declarations were always a fatal | ||
* "function already declared" error, so not the concern of this sniff. | ||
* | ||
* @category PHP | ||
* @package PHPCompatibility | ||
* @author Juliette Reinders Folmer <phpcompatibility_nospam@adviesenzo.nl> | ||
*/ | ||
class RemovedNamespacedAssertSniff extends Sniff | ||
{ | ||
/** | ||
* Scopes in which an `assert` function can be declared without issue. | ||
* | ||
* @var array | ||
*/ | ||
private $scopes = array( | ||
T_CLASS, | ||
T_INTERFACE, | ||
T_TRAIT, | ||
T_CLOSURE, | ||
); | ||
|
||
/** | ||
* Returns an array of tokens this test wants to listen for. | ||
* | ||
* @return array | ||
*/ | ||
public function register() | ||
{ | ||
// Enrich the scopes list. | ||
if (defined('T_ANON_CLASS')) { | ||
$this->scopes[] = T_ANON_CLASS; | ||
} | ||
|
||
return array(T_FUNCTION); | ||
} | ||
|
||
/** | ||
* Processes this test, when one of its tokens is encountered. | ||
* | ||
* @param \PHP_CodeSniffer_File $phpcsFile The file being scanned. | ||
* @param int $stackPtr The position of the current token in the | ||
* stack passed in $tokens. | ||
* | ||
* @return void | ||
*/ | ||
public function process(\PHP_CodeSniffer_File $phpcsFile, $stackPtr) | ||
{ | ||
if ($this->supportsAbove('7.3') === false) { | ||
return; | ||
} | ||
|
||
$funcName = $phpcsFile->getDeclarationName($stackPtr); | ||
|
||
if (strtolower($funcName) !== 'assert') { | ||
return; | ||
} | ||
|
||
if ($phpcsFile->hasCondition($stackPtr, $this->scopes) === true) { | ||
return; | ||
} | ||
|
||
if ($this->determineNamespace($phpcsFile, $stackPtr) === '') { | ||
// Not a namespaced function declaration. Parse error, but not our concern. | ||
return; | ||
} | ||
|
||
$phpcsFile->addWarning('Declaring a free-standing function called assert() is deprecated since PHP 7.3.', $stackPtr, 'Found'); | ||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
PHPCompatibility/Tests/Sniffs/FunctionNameRestrictions/RemovedNamespacedAssertUnitTest.1.inc
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,23 @@ | ||
<?php | ||
|
||
function assert($something) {} | ||
|
||
class fooclass { | ||
public function assert($something) {} | ||
} | ||
|
||
interface foointerface { | ||
public function assert($something); | ||
} | ||
|
||
trait footrait { | ||
public function assert($something) {} | ||
} | ||
|
||
fooanonclass(new class { | ||
private function assert($something) {} | ||
}); | ||
|
||
namespace ScopedNS { | ||
function assert($something) {} | ||
} |
21 changes: 21 additions & 0 deletions
21
PHPCompatibility/Tests/Sniffs/FunctionNameRestrictions/RemovedNamespacedAssertUnitTest.2.inc
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,21 @@ | ||
<?php | ||
|
||
namespace AssertDeprecations; | ||
|
||
function assert($something) {} | ||
|
||
class fooclass { | ||
public function assert($something) {} | ||
} | ||
|
||
interface foointerface { | ||
public function assert($something); | ||
} | ||
|
||
trait footrait { | ||
public function assert($something) {} | ||
} | ||
|
||
fooanonclass(new class { | ||
private function assert($something) {} | ||
}); |
138 changes: 138 additions & 0 deletions
138
PHPCompatibility/Tests/Sniffs/FunctionNameRestrictions/RemovedNamespacedAssertUnitTest.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,138 @@ | ||
<?php | ||
/** | ||
* Removal of namespaced free-standing assert() declarations for PHP 7.3 sniff test. | ||
* | ||
* @package PHPCompatibility | ||
*/ | ||
|
||
namespace PHPCompatibility\Tests\Sniffs\FunctionNameRestrictions; | ||
|
||
use PHPCompatibility\Tests\BaseSniffTest; | ||
use PHPCompatibility\PHPCSHelper; | ||
|
||
/** | ||
* Removal of namespaced free-standing assert() declarations for PHP 7.3 sniff test. | ||
* | ||
* @group removedNamespacedAssert | ||
* @group functionNameRestrictions | ||
* | ||
* @covers \PHPCompatibility\Sniffs\FunctionNameRestrictions\RemovedNamespacedAssertSniff | ||
* | ||
* @uses \PHPCompatibility\Tests\BaseSniffTest | ||
* @package PHPCompatibility | ||
* @author Juliette Reinders Folmer <phpcompatibility_nospam@adviesenzo.nl> | ||
*/ | ||
class RemovedNamespacedAssertUnitTest extends BaseSniffTest | ||
{ | ||
const TEST_FILE = 'Sniffs/FunctionNameRestrictions/RemovedNamespacedAssertUnitTest.1.inc'; | ||
const TEST_FILE_NAMESPACED = 'Sniffs/FunctionNameRestrictions/RemovedNamespacedAssertUnitTest.2.inc'; | ||
|
||
/** | ||
* Whether or not traits and interfaces will be properly scoped in PHPCS. | ||
* | ||
* @var bool | ||
*/ | ||
protected static $recognizesTraitsAndInterfaces = true; | ||
|
||
/** | ||
* Set up skip condition. | ||
* | ||
* @return void | ||
*/ | ||
public static function setUpBeforeClass() | ||
{ | ||
// When using PHPCS 2.3.4 or lower combined with PHP 5.3 or lower, traits are | ||
// not recognized and the scope condition for interfaces will not be set. | ||
if (version_compare(PHPCSHelper::getVersion(), '2.4.0', '<') && version_compare(PHP_VERSION_ID, '50400', '<')) { | ||
self::$recognizesTraitsAndInterfaces = false; | ||
} | ||
parent::setUpBeforeClass(); | ||
} | ||
|
||
/** | ||
* Test deprecation of namespaced free-standing assert() function declaration. | ||
* | ||
* @dataProvider dataIsDeprecated | ||
* | ||
* @param string $testFile The file to test | ||
* @param int $line The line number where the error should occur. | ||
* | ||
* @return void | ||
*/ | ||
public function testIsDeprecated($testFile, $line) | ||
{ | ||
$file = $this->sniffFile($testFile, '7.3'); | ||
$this->assertWarning($file, $line, 'Declaring a free-standing function called assert() is deprecated since PHP 7.3'); | ||
} | ||
|
||
/** | ||
* dataIsDeprecated | ||
* | ||
* @see testIsDeprecated() | ||
* | ||
* @return array | ||
*/ | ||
public function dataIsDeprecated() | ||
{ | ||
return array( | ||
array(self::TEST_FILE, 22), | ||
array(self::TEST_FILE_NAMESPACED, 5), | ||
); | ||
} | ||
|
||
/** | ||
* testNoFalsePositives | ||
* | ||
* @dataProvider dataNoFalsePositives | ||
* | ||
* @param string $testFile The file to test | ||
* @param int $line The line number. | ||
* @param bool $maybeSkip Whether this test needs to be skipped on old PHP/PHPCS combis. | ||
* | ||
* @return void | ||
*/ | ||
public function testNoFalsePositives($testFile, $line, $maybeSkip = false) | ||
{ | ||
if ($maybeSkip === true && self::$recognizesTraitsAndInterfaces === false) { | ||
$this->markTestSkipped('Traits are not recognized and interface scope conditions not added on PHPCS < 2.4.0 in combination with PHP < 5.4'); | ||
return; | ||
} | ||
|
||
$file = $this->sniffFile($testFile, '7.3'); | ||
$this->assertNoViolation($file, $line); | ||
} | ||
|
||
/** | ||
* Data provider. | ||
* | ||
* @see testNoFalsePositives() | ||
* | ||
* @return array | ||
*/ | ||
public function dataNoFalsePositives() | ||
{ | ||
return array( | ||
array(self::TEST_FILE, 3), | ||
array(self::TEST_FILE, 6), | ||
array(self::TEST_FILE, 10), | ||
array(self::TEST_FILE, 14), | ||
array(self::TEST_FILE, 18), | ||
array(self::TEST_FILE_NAMESPACED, 8), | ||
array(self::TEST_FILE_NAMESPACED, 12, true), | ||
array(self::TEST_FILE_NAMESPACED, 16, true), | ||
array(self::TEST_FILE_NAMESPACED, 20), | ||
); | ||
} | ||
|
||
|
||
/** | ||
* Verify no notices are thrown at all. | ||
* | ||
* @return void | ||
*/ | ||
public function testNoViolationsInFileOnValidVersion() | ||
{ | ||
$file = $this->sniffFile(self::TEST_FILE, '7.2'); | ||
$this->assertNoViolation($file); | ||
} | ||
} |