Merge pull request #1123 from rectorphp/cs-quote

[CodingStyle] Add SymplifyQuoteEscapeRector
This commit is contained in:
Tomáš Votruba 2019-02-27 12:34:20 +01:00 committed by GitHub
commit e7f5a5d112
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 147 additions and 0 deletions

View File

@ -10,3 +10,4 @@ services:
# requires configuration
# Rector\CodingStyle\Rector\ClassMethod\YieldClassMethodToArrayClassMethodRector: ~
# Rector\CodingStyle\Rector\ClassMethod\ReturnArrayClassMethodToYieldRector: ~
Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector: ~

View File

@ -0,0 +1,77 @@
<?php declare(strict_types=1);
namespace Rector\CodingStyle\Rector\String_;
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;
final class SymplifyQuoteEscapeRector extends AbstractRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Prefer quote that not inside the string', [
new CodeSample(
<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$name = "\" Tom";
$name = '\' Sara';
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$name = '" Tom';
$name = "' Sara";
}
}
CODE_SAMPLE
),
]);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [String_::class];
}
/**
* @param String_ $node
*/
public function refactor(Node $node): ?Node
{
$doubleQuoteCount = substr_count($node->value, '"');
$singleQuoteCount = substr_count($node->value, "'");
if ($node->getAttribute(Attribute::KIND) === String_::KIND_SINGLE_QUOTED) {
if ($doubleQuoteCount === 0 && $singleQuoteCount > 0) {
$node->setAttribute(Attribute::KIND, String_::KIND_DOUBLE_QUOTED);
// invoke override
$node->setAttribute(Attribute::ORIGINAL_NODE, null);
}
}
if ($node->getAttribute(Attribute::KIND) === String_::KIND_DOUBLE_QUOTED) {
if ($singleQuoteCount === 0 && $doubleQuoteCount > 0) {
$node->setAttribute(Attribute::KIND, String_::KIND_SINGLE_QUOTED);
// invoke override
$node->setAttribute(Attribute::ORIGINAL_NODE, null);
}
}
return $node;
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Rector\CodingStyle\Tests\Rector\String_\SymplifyQuoteEscapeRector\Fixture;
class SomeClass
{
public function run()
{
$name = "\" Tom";
$name = '\' Sara';
}
}
?>
-----
<?php
namespace Rector\CodingStyle\Tests\Rector\String_\SymplifyQuoteEscapeRector\Fixture;
class SomeClass
{
public function run()
{
$name = '" Tom';
$name = "' Sara";
}
}
?>

View File

@ -0,0 +1,12 @@
<?php
namespace Rector\CodingStyle\Tests\Rector\String_\SymplifyQuoteEscapeRector\Fixture;
class Skip
{
public function run()
{
$name = "\" Tom'";
$name = '\' Sara"';
}
}

View File

@ -0,0 +1,22 @@
<?php declare(strict_types=1);
namespace Rector\CodingStyle\Tests\Rector\String_\SymplifyQuoteEscapeRector;
use Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
final class SymplifyQuoteEscapeRectorTest extends AbstractRectorTestCase
{
public function test(): void
{
$this->doTestFiles([
__DIR__ . '/Fixture/fixture.php.inc',
__DIR__ . '/Fixture/skip.php.inc',
]);
}
protected function getRectorClass(): string
{
return SymplifyQuoteEscapeRector::class;
}
}

View File

@ -100,4 +100,10 @@ final class Attribute
* @var string
*/
public const START_TOKEN_POSITION = 'startTokenPos';
/**
* @var string
* Use often in php-parser
*/
public const KIND = 'kind';
}