Merge pull request #604 from rectorphp/yaml-parse-string

[Symfony] Add ParseFileRector [closes #600]
This commit is contained in:
Tomáš Votruba 2018-08-29 12:26:00 +02:00 committed by GitHub
commit 8fea703d13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 190 additions and 0 deletions

View File

@ -0,0 +1,3 @@
services:
# Yaml::parse('file.yml') → Yaml::parse(file_get_contents('file.yml'))
Rector\Symfony\Rector\Yaml\ParseFileRector: ~

View File

@ -60,6 +60,7 @@ parameters:
- 'src/Rector/Property/PropertyNameReplacerRector.php'
- 'src/Rector/Annotation/AnnotationReplacerRector.php'
- 'src/Rector/Argument/ArgumentAdderRector.php'
- 'src/Rector/Form/Helper/FormTypeStringToTypeProvider.php'
# empty arguments passing
PHP_CodeSniffer\Standards\PEAR\Sniffs\Functions\ValidDefaultValueSniff.NotAtEnd:

View File

@ -0,0 +1,108 @@
<?php declare(strict_types=1);
namespace Rector\Symfony\Rector\Yaml;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name;
use PHPStan\Analyser\Scope;
use PHPStan\Type\Constant\ConstantStringType;
use Rector\NodeTypeResolver\Node\Attribute;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\Printer\BetterStandardPrinter;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
final class ParseFileRector extends AbstractRector
{
/**
* @var NodeTypeResolver
*/
private $nodeTypeResolver;
/**
* @var BetterStandardPrinter
*/
private $betterStandardPrinter;
public function __construct(NodeTypeResolver $nodeTypeResolver, BetterStandardPrinter $betterStandardPrinter)
{
$this->nodeTypeResolver = $nodeTypeResolver;
$this->betterStandardPrinter = $betterStandardPrinter;
}
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('session > use_strict_mode is true by default and can be removed', [
new CodeSample('session > use_strict_mode: true', 'session:'),
]);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [StaticCall::class];
}
/**
* Process Node of matched type
*
* @param StaticCall $staticCallNode
*/
public function refactor(Node $staticCallNode): ?Node
{
if ((string) $staticCallNode->name !== 'parse') {
return null;
}
$staticCallNodeTypes = $this->nodeTypeResolver->resolve($staticCallNode->class);
if (! in_array('Symfony\Component\Yaml\Yaml', $staticCallNodeTypes, true)) {
return null;
}
if (! $this->isArgumentYamlFile($staticCallNode)) {
return null;
}
$fileGetContentsFunCallNode = new FuncCall(new Name('file_get_contents'), [$staticCallNode->args[0]]);
$staticCallNode->args[0] = new Arg($fileGetContentsFunCallNode);
return $staticCallNode;
}
private function isArgumentYamlFile(StaticCall $staticCallNode): bool
{
$possibleFileNode = $staticCallNode->args[0]->value;
$possibleFileNodeAsString = $this->betterStandardPrinter->prettyPrint([$possibleFileNode]);
// is yml/yaml file
if (Strings::match($possibleFileNodeAsString, '#\.(yml|yaml)(\'|")$#')) {
return true;
}
// is probably a file variable
if (Strings::match($possibleFileNodeAsString, '#\File$#')) {
return true;
}
// try to detect current value
/** @var Scope $nodeScope */
$nodeScope = $possibleFileNode->getAttribute(Attribute::SCOPE);
$nodeType = $nodeScope->getType($possibleFileNode);
if ($nodeType instanceof ConstantStringType) {
if (Strings::match($nodeType->getValue(), '#\.(yml|yaml)$#')) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,9 @@
<?php declare(strict_types=1);
use Symfony\Component\Yaml\Yaml;
$parsedFile = Yaml::parse(file_get_contents('someFile.yml'));
$parsedFile = Yaml::parse(file_get_contents('someFile.yaml'));
$parsedFile = Yaml::parse(file_get_contents("someFile.yaml"));
$parsedFile = Yaml::parse(file_get_contents($directory . "someFile.yaml"));
$parsedFile = Yaml::parse(file_get_contents(__DIR__ . 'someFile.yaml'));

View File

@ -0,0 +1,6 @@
<?php declare(strict_types=1);
use Symfony\Component\Yaml\Yaml;
$someFile = __DIR__ . '/someFile.yaml';
$parsedFile = Yaml::parse(file_get_contents($someFile));

View File

@ -0,0 +1,7 @@
<?php declare(strict_types=1);
use Symfony\Component\Yaml\Yaml;
function someFunction($someFile) {
return Yaml::parse(file_get_contents($someFile));
}

View File

@ -0,0 +1,32 @@
<?php declare(strict_types=1);
namespace Rector\Symfony\Tests\Yaml\ParseFileRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
/**
* @covers \Rector\Symfony\Rector\Yaml\ParseFileRector
*/
final class ParseFileRectorTest 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'];
yield [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc'];
yield [__DIR__ . '/Wrong/wrong3.php.inc', __DIR__ . '/Correct/correct3.php.inc'];
}
protected function provideConfig(): string
{
return __DIR__ . '/config.yml';
}
}

View File

@ -0,0 +1,9 @@
<?php declare(strict_types=1);
use Symfony\Component\Yaml\Yaml;
$parsedFile = Yaml::parse('someFile.yml');
$parsedFile = Yaml::parse('someFile.yaml');
$parsedFile = Yaml::parse("someFile.yaml");
$parsedFile = Yaml::parse($directory . "someFile.yaml");
$parsedFile = Yaml::parse(__DIR__ . 'someFile.yaml');

View File

@ -0,0 +1,6 @@
<?php declare(strict_types=1);
use Symfony\Component\Yaml\Yaml;
$someFile = __DIR__ . '/someFile.yaml';
$parsedFile = Yaml::parse($someFile);

View File

@ -0,0 +1,7 @@
<?php declare(strict_types=1);
use Symfony\Component\Yaml\Yaml;
function someFunction($someFile) {
return Yaml::parse($someFile);
}

View File

@ -0,0 +1,2 @@
services:
Rector\Symfony\Rector\Yaml\ParseFileRector: ~