Skip to content

Commit

Permalink
Merge pull request #735 from PHPCompatibility/php-7.3/718-new-depreca…
Browse files Browse the repository at this point in the history
…ted-namespaced-assert-sniff

PHP 7.3: New sniff to recognize deprecated assert() function declarations
  • Loading branch information
wimg committed Sep 22, 2018
2 parents c25995f + 4ce6fd3 commit c0535ca
Show file tree
Hide file tree
Showing 4 changed files with 274 additions and 0 deletions.
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');
}

}
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) {}
}
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) {}
});
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);
}
}

0 comments on commit c0535ca

Please sign in to comment.