mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-18 22:08:00 +01:00
[PHP] Add SensitiveHereNowDocRector
This commit is contained in:
parent
25e3c6c511
commit
5de35b9706
@ -3,3 +3,4 @@ services:
|
|||||||
Rector\Php\Rector\FuncCall\ArrayKeyFirstLastRector: ~
|
Rector\Php\Rector\FuncCall\ArrayKeyFirstLastRector: ~
|
||||||
Rector\Php\Rector\FuncCall\SensitiveDefineRector: ~
|
Rector\Php\Rector\FuncCall\SensitiveDefineRector: ~
|
||||||
Rector\Php\Rector\ConstFetch\SensitiveConstantNameRector: ~
|
Rector\Php\Rector\ConstFetch\SensitiveConstantNameRector: ~
|
||||||
|
Rector\Php\Rector\String\SensitiveHereNowDocRector: ~
|
||||||
|
@ -115,9 +115,9 @@ final class CreateRectorCommand extends Command
|
|||||||
'_Category_' => $configuration->getCategory(),
|
'_Category_' => $configuration->getCategory(),
|
||||||
'_Description_' => $configuration->getDescription(),
|
'_Description_' => $configuration->getDescription(),
|
||||||
'_Name_' => $configuration->getName(),
|
'_Name_' => $configuration->getName(),
|
||||||
'_CodeBefore_' => $configuration->getCodeBefore(),
|
'_CodeBefore_' => trim($configuration->getCodeBefore()) . PHP_EOL,
|
||||||
'_CodeBeforeExample_' => $this->prepareCodeForDefinition($configuration->getCodeBefore()),
|
'_CodeBeforeExample_' => $this->prepareCodeForDefinition($configuration->getCodeBefore()),
|
||||||
'_CodeAfter_' => $configuration->getCodeAfter(),
|
'_CodeAfter_' => trim($configuration->getCodeAfter()) . PHP_EOL,
|
||||||
'_CodeAfterExample_' => $this->prepareCodeForDefinition($configuration->getCodeAfter()),
|
'_CodeAfterExample_' => $this->prepareCodeForDefinition($configuration->getCodeAfter()),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
84
packages/Php/src/Rector/String/SensitiveHereNowDocRector.php
Normal file
84
packages/Php/src/Rector/String/SensitiveHereNowDocRector.php
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Rector\Php\Rector\String;
|
||||||
|
|
||||||
|
use Nette\Utils\Strings;
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Scalar\String_;
|
||||||
|
use Rector\NodeTypeResolver\Node\Attribute;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Rector\RectorDefinition\CodeSample;
|
||||||
|
use Rector\RectorDefinition\RectorDefinition;
|
||||||
|
use function Safe\sprintf;
|
||||||
|
|
||||||
|
final class SensitiveHereNowDocRector extends AbstractRector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private const WRAP_SUFFIX = '_WRAP';
|
||||||
|
|
||||||
|
public function getDefinition(): RectorDefinition
|
||||||
|
{
|
||||||
|
return new RectorDefinition('Changes heredoc/nowdoc that contains closing word to safe wrapper name', [
|
||||||
|
new CodeSample(
|
||||||
|
<<<'CODE_SAMPLE'
|
||||||
|
$value = <<<A
|
||||||
|
A
|
||||||
|
A
|
||||||
|
CODE_SAMPLE
|
||||||
|
,
|
||||||
|
<<<'CODE_SAMPLE'
|
||||||
|
$value = <<<A_WRAP
|
||||||
|
A
|
||||||
|
A_WRAP
|
||||||
|
CODE_SAMPLE
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getNodeTypes(): array
|
||||||
|
{
|
||||||
|
return [String_::class];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param String_ $node
|
||||||
|
*/
|
||||||
|
public function refactor(Node $node): ?Node
|
||||||
|
{
|
||||||
|
if (! in_array($node->getAttribute('kind'), [String_::KIND_HEREDOC, String_::KIND_NOWDOC], true)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the doc label is not in the string → ok
|
||||||
|
$docLabel = $node->getAttribute('docLabel');
|
||||||
|
|
||||||
|
if (! Strings::contains($node->value, $docLabel)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$node->setAttribute('docLabel', $this->uniquateDocLabel($node->value, $docLabel));
|
||||||
|
|
||||||
|
// invoke redraw
|
||||||
|
$node->setAttribute(Attribute::ORIGINAL_NODE, null);
|
||||||
|
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function uniquateDocLabel(string $value, string $docLabel): string
|
||||||
|
{
|
||||||
|
$docLabel .= self::WRAP_SUFFIX;
|
||||||
|
$docLabelCounterTemplate = $docLabel . '_%d';
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
while (Strings::contains($value, $docLabel)) {
|
||||||
|
$docLabel = sprintf($docLabelCounterTemplate, ++$i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $docLabel;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$value = <<<CODE_SAMPLE_WRAP
|
||||||
|
CODE_SAMPLE_2
|
||||||
|
CODE_SAMPLE_WRAP;
|
||||||
|
|
||||||
|
$value = <<<CODE_SAMPLE_WRAP_1
|
||||||
|
CODE_SAMPLE_WRAP_2
|
||||||
|
CODE_SAMPLE_WRAP_1;
|
||||||
|
|
||||||
|
// examples from RFC
|
||||||
|
$value = <<<END_WRAP
|
||||||
|
a
|
||||||
|
b
|
||||||
|
ENDING
|
||||||
|
END_WRAP;
|
@ -0,0 +1,30 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Rector\Php\Tests\Rector\String\SensitiveHereNowDocRector;
|
||||||
|
|
||||||
|
use Iterator;
|
||||||
|
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Rector\Php\Rector\String\SensitiveHereNowDocRector
|
||||||
|
*/
|
||||||
|
final class SensitiveHereNowDocRectorTest 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,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$value = <<<CODE_SAMPLE
|
||||||
|
CODE_SAMPLE_2
|
||||||
|
CODE_SAMPLE;
|
||||||
|
|
||||||
|
$value = <<<CODE_SAMPLE
|
||||||
|
CODE_SAMPLE_WRAP_2
|
||||||
|
CODE_SAMPLE;
|
||||||
|
|
||||||
|
// examples from RFC
|
||||||
|
$value = <<<END
|
||||||
|
a
|
||||||
|
b
|
||||||
|
ENDING
|
||||||
|
END;
|
@ -0,0 +1,2 @@
|
|||||||
|
services:
|
||||||
|
Rector\Php\Rector\String\SensitiveHereNowDocRector: ~
|
Loading…
x
Reference in New Issue
Block a user