mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-18 22:08:00 +01:00
[PHP] Add constant sensitive Rectors
This commit is contained in:
parent
2ad6946baf
commit
b012597fa8
@ -1,3 +1,5 @@
|
||||
services:
|
||||
Rector\Php\Rector\BinaryOp\IsCountableRector: ~
|
||||
Rector\Php\Rector\FuncCall\ArrayKeyFirstLastRector: ~
|
||||
Rector\Php\Rector\FuncCall\SensitiveDefineRector: ~
|
||||
Rector\Php\Rector\ConstFetch\SensitiveConstantNameRector: ~
|
||||
|
@ -0,0 +1,131 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php\Rector\ConstFetch;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\ConstFetch;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
|
||||
/**
|
||||
* @see https://wiki.php.net/rfc/case_insensitive_constant_deprecation
|
||||
*/
|
||||
final class SensitiveConstantNameRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @see http://php.net/manual/en/reserved.constants.php
|
||||
* @var string[]
|
||||
*/
|
||||
private $phpReservedConstants = [
|
||||
'PHP_VERSION',
|
||||
'PHP_MAJOR_VERSION',
|
||||
'PHP_MINOR_VERSION',
|
||||
'PHP_RELEASE_VERSION',
|
||||
'PHP_VERSION_ID',
|
||||
'PHP_EXTRA_VERSION',
|
||||
'PHP_ZTS',
|
||||
'PHP_DEBUG',
|
||||
'PHP_MAXPATHLEN',
|
||||
'PHP_OS',
|
||||
'PHP_OS_FAMILY',
|
||||
'PHP_SAPI',
|
||||
'PHP_EOL',
|
||||
'PHP_INT_MAX',
|
||||
'PHP_INT_MIN',
|
||||
'PHP_INT_SIZE',
|
||||
'PHP_FLOAT_DIG',
|
||||
'PHP_FLOAT_EPSILON',
|
||||
'PHP_FLOAT_MIN',
|
||||
'PHP_FLOAT_MAX',
|
||||
'DEFAULT_INCLUDE_PATH',
|
||||
'PEAR_INSTALL_DIR',
|
||||
'PEAR_EXTENSION_DIR',
|
||||
'PHP_EXTENSION_DIR',
|
||||
'PHP_PREFIX',
|
||||
'PHP_BINDIR',
|
||||
'PHP_BINARY',
|
||||
'PHP_MANDIR',
|
||||
'PHP_LIBDIR',
|
||||
'PHP_DATADIR',
|
||||
'PHP_SYSCONFDIR',
|
||||
'PHP_LOCALSTATEDIR',
|
||||
'PHP_CONFIG_FILE_PATH',
|
||||
'PHP_CONFIG_FILE_SCAN_DIR',
|
||||
'PHP_SHLIB_SUFFIX',
|
||||
'PHP_FD_SETSIZE',
|
||||
'E_ERROR',
|
||||
'E_WARNING',
|
||||
'E_PARSE',
|
||||
'E_NOTICE',
|
||||
'E_CORE_ERROR',
|
||||
'E_CORE_WARNING',
|
||||
'E_COMPILE_ERROR',
|
||||
'E_COMPILE_WARNING',
|
||||
'E_USER_ERROR',
|
||||
'E_USER_WARNING',
|
||||
'E_USER_NOTICE',
|
||||
'E_RECOVERABLE_ERROR',
|
||||
'E_DEPRECATED',
|
||||
'E_USER_DEPRECATED',
|
||||
'E_ALL',
|
||||
'E_STRICT',
|
||||
'__COMPILER_HALT_OFFSET__',
|
||||
'TRUE',
|
||||
'FALSE',
|
||||
'NULL',
|
||||
];
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition(
|
||||
'Changes case insensitive constants to sensitive ones.',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
define('FOO', 42, true);
|
||||
var_dump(FOO);
|
||||
var_dump(foo);
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
define('FOO', 42, true);
|
||||
var_dump(FOO);
|
||||
var_dump(FOO);
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [ConstFetch::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ConstFetch $constFetchNode
|
||||
*/
|
||||
public function refactor(Node $constFetchNode): ?Node
|
||||
{
|
||||
// is system constant?
|
||||
if (in_array(strtoupper((string) $constFetchNode->name), $this->phpReservedConstants, true)) {
|
||||
return $constFetchNode;
|
||||
}
|
||||
|
||||
$currentConstantName = (string) $constFetchNode->name;
|
||||
|
||||
// is uppercase, all good
|
||||
if ($currentConstantName === strtoupper($currentConstantName)) {
|
||||
return $constFetchNode;
|
||||
}
|
||||
|
||||
$constFetchNode->name = new FullyQualified(strtoupper($currentConstantName));
|
||||
|
||||
return $constFetchNode;
|
||||
}
|
||||
}
|
59
packages/Php/src/Rector/FuncCall/SensitiveDefineRector.php
Normal file
59
packages/Php/src/Rector/FuncCall/SensitiveDefineRector.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php\Rector\FuncCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
|
||||
/**
|
||||
* @see https://wiki.php.net/rfc/case_insensitive_constant_deprecation
|
||||
*/
|
||||
final class SensitiveDefineRector extends AbstractRector
|
||||
{
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition(
|
||||
'Changes case insensitive constants to sensitive ones.',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
define('FOO', 42, true);
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
define('FOO', 42);
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [FuncCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FuncCall $funcCallNode
|
||||
*/
|
||||
public function refactor(Node $funcCallNode): ?Node
|
||||
{
|
||||
if ((string) $funcCallNode->name !== 'define') {
|
||||
return $funcCallNode;
|
||||
}
|
||||
|
||||
if (! isset($funcCallNode->args[2])) {
|
||||
return $funcCallNode;
|
||||
}
|
||||
|
||||
unset($funcCallNode->args[2]);
|
||||
|
||||
return $funcCallNode;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
define('FOO', 42, true);
|
||||
|
||||
FOO;
|
||||
var_dump(FOO);
|
||||
|
||||
\FOO;
|
||||
var_dump(\FOO);
|
@ -0,0 +1,30 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php\Tests\Rector\ConstFetch\SensitiveConstantNameRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
|
||||
/**
|
||||
* @covers \Rector\Php\Rector\ConstFetch\SensitiveConstantNameRector
|
||||
*/
|
||||
final class SensitiveConstantNameRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideWrongToFixedFiles()
|
||||
*/
|
||||
public function test(string $wrong, string $fixed): void
|
||||
{
|
||||
$this->doTestFileMatchesExpectedContent($wrong, $fixed);
|
||||
}
|
||||
|
||||
public function provideWrongToFixedFiles(): Iterator
|
||||
{
|
||||
yield [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc'];
|
||||
}
|
||||
|
||||
protected function provideConfig(): string
|
||||
{
|
||||
return __DIR__ . '/config.yml';
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
define('FOO', 42, true);
|
||||
|
||||
FOO;
|
||||
var_dump(FOO);
|
||||
|
||||
foo;
|
||||
var_dump(foo);
|
@ -0,0 +1,2 @@
|
||||
services:
|
||||
Rector\Php\Rector\ConstFetch\SensitiveConstantNameRector: ~
|
@ -0,0 +1,3 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
define('FOO', 42);
|
@ -0,0 +1,30 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php\Tests\Rector\FuncCall\SensitiveDefineRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
|
||||
/**
|
||||
* @covers \Rector\Php\Rector\FuncCall\ArrayKeyFirstLastRector
|
||||
*/
|
||||
final class SensitiveDefineRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideWrongToFixedFiles()
|
||||
*/
|
||||
public function test(string $wrong, string $fixed): void
|
||||
{
|
||||
$this->doTestFileMatchesExpectedContent($wrong, $fixed);
|
||||
}
|
||||
|
||||
public function provideWrongToFixedFiles(): Iterator
|
||||
{
|
||||
yield [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc'];
|
||||
}
|
||||
|
||||
protected function provideConfig(): string
|
||||
{
|
||||
return __DIR__ . '/config.yml';
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
define('FOO', 42, true);
|
@ -0,0 +1,2 @@
|
||||
services:
|
||||
Rector\Php\Rector\FuncCall\SensitiveDefineRector: ~
|
@ -5,13 +5,14 @@ namespace Rector\DependencyInjection\Loader;
|
||||
use Nette\Utils\Strings;
|
||||
use Rector\Exception\DependencyInjection\ClassNotFoundException;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
use function Safe\sprintf;
|
||||
|
||||
final class ClassExistenceValidator
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const CLASS_PART_PATTERN = '[A-Z]\w*[a-z]\w*';
|
||||
private const CLASSY_PATTERN = '#^[\\\\]?[A-Z]\w*(\\\\[A-Z]\w*)*$#';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
@ -33,7 +34,7 @@ final class ClassExistenceValidator
|
||||
}
|
||||
|
||||
// not a class
|
||||
if (! Strings::match($class, $this->getClassyPattern())) {
|
||||
if (! Strings::match($class, self::CLASSY_PATTERN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -48,9 +49,4 @@ final class ClassExistenceValidator
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private function getClassyPattern(): string
|
||||
{
|
||||
return sprintf('#^%s(\\\\%s)+\z#', self::CLASS_PART_PATTERN, self::CLASS_PART_PATTERN);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user