mirror of https://github.com/rectorphp/rector.git
init
This commit is contained in:
commit
764ce4bb08
|
@ -0,0 +1,2 @@
|
|||
/vendor
|
||||
composer.lock
|
|
@ -0,0 +1,14 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This allows to load "vendor/autoload.php" both from
|
||||
* "composer create-project ..." and "composer require" installation.
|
||||
*/
|
||||
$possibleAutoloadPaths = [__DIR__ . '/../vendor/autoload.php', __DIR__ . '/../../../vendor/autoload.php'];
|
||||
|
||||
foreach ($possibleAutoloadPaths as $possibleAutoloadPath) {
|
||||
if (is_file($possibleAutoloadPath)) {
|
||||
require_once $possibleAutoloadPath;
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/rector.php';
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
use Rector\DependencyInjection\ContainerFactory;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
// Performance boost
|
||||
gc_disable();
|
||||
|
||||
// Require Composer autoload.php
|
||||
require_once __DIR__ . '/bootstrap.php';
|
||||
|
||||
// Build DI container
|
||||
$container = (new ContainerFactory())->create();
|
||||
|
||||
// Run Console Application
|
||||
/** @var Application $application */
|
||||
$application = $container->get(Application::class);
|
||||
$application->run();
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "rector/rector",
|
||||
"description": "Tool that reconstructs your legacy code to modern codebase.",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{ "name": "Tomas Votruba", "email": "tomas.vot@gmail.com", "homepage": "https://tomasvotruba.com" },
|
||||
{ "name": "Rector Contributors", "homepage": "https://github.com/TomasVotruba/Rector/graphs/contributors" }
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"symfony/console": "^3.3",
|
||||
"symfony/dependency-injection": "^3.3",
|
||||
"nikic/php-parser": "^3.0",
|
||||
"ocramius/code-generator-utils": "^0.4.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.2",
|
||||
"tracy/tracy": "^2.4",
|
||||
"symplify/easy-coding-standard": "^2.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Rector\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Rector\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"phpstan": "phpstan analyse src tests --level 7"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<phpunit
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
verbose="true"
|
||||
>
|
||||
<!-- tests directories to run -->
|
||||
<testsuite>
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
<!-- source to check coverage for -->
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
|
@ -0,0 +1,73 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Application;
|
||||
|
||||
use PhpParser\Parser;
|
||||
use Rector\Dispatcher\NodeDispatcher;
|
||||
use Rector\Printer\CodeStyledPrinter;
|
||||
use SplFileInfo;
|
||||
|
||||
final class FileProcessor
|
||||
{
|
||||
/**
|
||||
* @var Parser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* @var NodeDispatcher
|
||||
*/
|
||||
private $nodeDispatcher;
|
||||
|
||||
/**
|
||||
* @var CodeStyledPrinter
|
||||
*/
|
||||
private $codeStyledPrinter;
|
||||
|
||||
public function __construct(Parser $parser, CodeStyledPrinter $codeStyledPrinter, NodeDispatcher $nodeDispatcher)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
$this->nodeDispatcher = $nodeDispatcher;
|
||||
$this->codeStyledPrinter = $codeStyledPrinter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var SplFileInfo[]
|
||||
*/
|
||||
public function processFiles(array $files): void
|
||||
{
|
||||
foreach ($files as $file) {
|
||||
$this->processFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function processFile(SplFileInfo $file): void
|
||||
{
|
||||
$fileContent = file_get_contents($file->getRealPath());
|
||||
$nodes = $this->parser->parse($fileContent);
|
||||
if ($nodes === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$originalNodes = $this->cloneArrayOfObjects($nodes);
|
||||
|
||||
foreach ($nodes as $node) {
|
||||
$this->nodeDispatcher->dispatch($node);
|
||||
}
|
||||
|
||||
$this->codeStyledPrinter->printToFile($file, $originalNodes, $nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object[] $data
|
||||
* @return object[]
|
||||
*/
|
||||
private function cloneArrayOfObjects(array $data): array
|
||||
{
|
||||
foreach ($data as $key => $value) {
|
||||
$data[$key] = clone $value;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Console\Command;
|
||||
|
||||
use Nette\Utils\Finder;
|
||||
use Rector\Application\FileProcessor;
|
||||
use SplFileInfo;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
final class ReconstructCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const NAME = 'reconstruct';
|
||||
|
||||
/**
|
||||
* @var FileProcessor
|
||||
*/
|
||||
private $fileProcessor;
|
||||
|
||||
public function __construct(FileProcessor $fileProcessor)
|
||||
{
|
||||
$this->fileProcessor = $fileProcessor;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const ARGUMENT_SOURCE_NAME = 'source';
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->setName(self::NAME);
|
||||
$this->setDescription('Reconstruct set of your code.');
|
||||
|
||||
// @todo: use modular configure from ApiGen
|
||||
$this->addArgument(
|
||||
self::ARGUMENT_SOURCE_NAME,
|
||||
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
|
||||
'The path(s) to be checked.'
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$source = $input->getArgument(self::ARGUMENT_SOURCE_NAME);
|
||||
$files = $this->findPhpFilesInDirectories($source);
|
||||
$this->fileProcessor->processFiles($files);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $directories
|
||||
* @return SplFileInfo[] array
|
||||
*/
|
||||
private function findPhpFilesInDirectories(array $directories): array
|
||||
{
|
||||
$finder = Finder::find('*.php')
|
||||
->in($directories);
|
||||
|
||||
return iterator_to_array($finder->getIterator());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Contract\Dispatcher;
|
||||
|
||||
use PhpParser\Node;
|
||||
|
||||
interface ReconstructorInterface
|
||||
{
|
||||
public function isCandidate(Node $node): bool;
|
||||
|
||||
public function reconstruct(Node $classNode): void;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection;
|
||||
|
||||
use Rector\DependencyInjection\CompilerPass\CollectorCompilerPass;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
|
||||
final class AppKernel extends Kernel
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('dev', true);
|
||||
}
|
||||
|
||||
public function registerContainerConfiguration(LoaderInterface $loader): void
|
||||
{
|
||||
$loader->load(__DIR__ . '/../config/services.yml');
|
||||
}
|
||||
|
||||
public function getCacheDir(): string
|
||||
{
|
||||
return sys_get_temp_dir() . '/_rector_cache';
|
||||
}
|
||||
|
||||
public function getLogDir(): string
|
||||
{
|
||||
return sys_get_temp_dir() . '/_rector_log';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BundleInterface[]
|
||||
*/
|
||||
public function registerBundles(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function build(ContainerBuilder $containerBuilder): void
|
||||
{
|
||||
$containerBuilder->addCompilerPass(new CollectorCompilerPass);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\CompilerPass;
|
||||
|
||||
use Rector\Contract\Dispatcher\ReconstructorInterface;
|
||||
use Rector\Dispatcher\NodeDispatcher;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symplify\PackageBuilder\Adapter\Symfony\DependencyInjection\DefinitionCollector;
|
||||
|
||||
final class CollectorCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $containerBuilder): void
|
||||
{
|
||||
$this->collectCommandsToConsoleApplication($containerBuilder);
|
||||
$this->collectReconstructorsToNodeDispatcher($containerBuilder);
|
||||
}
|
||||
|
||||
private function collectCommandsToConsoleApplication(ContainerBuilder $containerBuilder): void
|
||||
{
|
||||
DefinitionCollector::loadCollectorWithType(
|
||||
$containerBuilder,
|
||||
Application::class,
|
||||
Command::class,
|
||||
'add'
|
||||
);
|
||||
}
|
||||
|
||||
private function collectReconstructorsToNodeDispatcher(ContainerBuilder $containerBuilder): void
|
||||
{
|
||||
DefinitionCollector::loadCollectorWithType(
|
||||
$containerBuilder,
|
||||
NodeDispatcher::class,
|
||||
ReconstructorInterface::class,
|
||||
'addReconstructor'
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
final class ContainerFactory
|
||||
{
|
||||
public function create(): ContainerInterface
|
||||
{
|
||||
$appKernel = new AppKernel;
|
||||
$appKernel->boot();
|
||||
|
||||
return $appKernel->getContainer();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Dispatcher;
|
||||
|
||||
use PhpParser\Node;
|
||||
use Rector\Contract\Dispatcher\ReconstructorInterface;
|
||||
|
||||
final class NodeDispatcher
|
||||
{
|
||||
/**
|
||||
* @var ReconstructorInterface[]
|
||||
*/
|
||||
private $reconstructors;
|
||||
|
||||
public function addReconstructor(ReconstructorInterface $reconstructor): void
|
||||
{
|
||||
$this->reconstructors[] = $reconstructor;
|
||||
}
|
||||
|
||||
public function dispatch(Node $node): void
|
||||
{
|
||||
// todo: build hash map
|
||||
foreach ($this->reconstructors as $reconstructor) {
|
||||
if ($reconstructor->isCandidate($node)) {
|
||||
$reconstructor->reconstruct($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Parser;
|
||||
|
||||
use PhpParser\Parser;
|
||||
use PhpParser\ParserFactory as NikicParserFactory;
|
||||
|
||||
final class ParserFactory
|
||||
{
|
||||
public function create(): Parser
|
||||
{
|
||||
return (new NikicParserFactory)->create(NikicParserFactory::PREFER_PHP7);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Printer;
|
||||
|
||||
use PhpParser\PrettyPrinter\Standard;
|
||||
use SplFileInfo;
|
||||
|
||||
final class CodeStyledPrinter
|
||||
{
|
||||
/**
|
||||
* @var Standard
|
||||
*/
|
||||
private $prettyPrinter;
|
||||
|
||||
public function __construct(Standard $prettyPrinter)
|
||||
{
|
||||
$this->prettyPrinter = $prettyPrinter;
|
||||
}
|
||||
|
||||
public function printToFile(SplFileInfo $file, array $originalNodes, array $newNodes): void
|
||||
{
|
||||
if ($originalNodes === $newNodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
file_put_contents($file->getRealPath(), $this->printToString($newNodes));
|
||||
// @todo: run ecs with minimal set to code look nice
|
||||
}
|
||||
|
||||
public function printToString(array $newNodes): string
|
||||
{
|
||||
return '<?php ' . $this->prettyPrinter->prettyPrint($newNodes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Reconstructor\DependencyInjection;
|
||||
|
||||
use PhpCsFixer\DocBlock\DocBlock;
|
||||
use PhpParser\Builder\Method;
|
||||
use PhpParser\BuilderFactory;
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Parser;
|
||||
use Rector\Contract\Dispatcher\ReconstructorInterface;
|
||||
|
||||
final class InjectAnnotationToConstructorReconstructor implements ReconstructorInterface
|
||||
{
|
||||
/**
|
||||
* @var BuilderFactory
|
||||
*/
|
||||
private $builderFactory;
|
||||
/**
|
||||
* @var Parser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
public function __construct(BuilderFactory $builderFactory, Parser $parser)
|
||||
{
|
||||
$this->builderFactory = $builderFactory;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
public function isCandidate(Node $node): bool
|
||||
{
|
||||
return $node instanceof Class_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_|Node $classNode
|
||||
*/
|
||||
public function reconstruct(Node $classNode): void
|
||||
{
|
||||
foreach ($classNode->stmts as $classElementStatement) {
|
||||
if (! $classElementStatement instanceof Property) {
|
||||
continue;
|
||||
}
|
||||
$propertyNode = $classElementStatement;
|
||||
|
||||
$propertyDocBlock = $this->createDocBlock($propertyNode);
|
||||
$injectAnnotations = $propertyDocBlock->getAnnotationsOfType('inject');
|
||||
if (! $injectAnnotations) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$propertyType = $propertyDocBlock->getAnnotationsOfType('var')[0]->getTypes()[0];
|
||||
|
||||
// 1. remove @inject annotation
|
||||
foreach ($injectAnnotations as $injectAnnotation) {
|
||||
$injectAnnotation->remove();
|
||||
}
|
||||
$propertyNode->setDocComment(new Doc($propertyDocBlock->getContent()));
|
||||
|
||||
// 2. make public property private
|
||||
$propertyNode->flags = Class_::MODIFIER_PRIVATE;
|
||||
$propertyName = $propertyNode->props[0]->name;
|
||||
|
||||
// build assignment for constructor method body
|
||||
/** @var Node[] $assign */
|
||||
$assign = $this->parser->parse(sprintf(
|
||||
'<?php $this->%s = $%s;',
|
||||
$propertyName,
|
||||
$propertyName
|
||||
));
|
||||
|
||||
$constructorMethod = $classNode->getMethod('__construct') ?: null;
|
||||
|
||||
/** @var ClassMethod $constructorMethod */
|
||||
if ($constructorMethod) {
|
||||
$constructorMethod->params[] = $this->builderFactory->param($propertyName)
|
||||
->setTypeHint($propertyType)->getNode();
|
||||
|
||||
$constructorMethod->stmts[] = $assign[0];
|
||||
} else {
|
||||
/** @var Method $constructorMethod */
|
||||
$constructorMethod = $this->builderFactory->method('__construct')
|
||||
->makePublic()
|
||||
->addParam($this->builderFactory->param($propertyName)
|
||||
->setTypeHint($propertyType)
|
||||
)
|
||||
->addStmts($assign);
|
||||
|
||||
$classNode->stmts[] = $constructorMethod->getNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function createDocBlock(Property $propertyNode): DocBlock
|
||||
{
|
||||
return new DocBlock($propertyNode->getDocComment());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Testing\Application;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Parser;
|
||||
use Rector\Contract\Dispatcher\ReconstructorInterface;
|
||||
use Rector\Printer\CodeStyledPrinter;
|
||||
use SplFileInfo;
|
||||
|
||||
final class FileReconstructor
|
||||
{
|
||||
/**
|
||||
* @var Parser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* @var CodeStyledPrinter
|
||||
*/
|
||||
private $codeStyledPrinter;
|
||||
|
||||
public function __construct(Parser $parser, CodeStyledPrinter $codeStyledPrinter)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
$this->codeStyledPrinter = $codeStyledPrinter;
|
||||
}
|
||||
|
||||
public function processFileWithReconstructor(SplFileInfo $file, ReconstructorInterface $reconstructor): string
|
||||
{
|
||||
$fileContent = file_get_contents($file->getRealPath());
|
||||
|
||||
/** @var Node[] $nodes */
|
||||
$nodes = $this->parser->parse($fileContent);
|
||||
|
||||
foreach ($nodes as $node) {
|
||||
if ($reconstructor->isCandidate($node)) {
|
||||
$reconstructor->reconstruct($node);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->codeStyledPrinter->printToString($nodes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
# PSR-4 autodiscovery
|
||||
Rector\:
|
||||
resource: '../../src'
|
||||
|
||||
# 3rd party services
|
||||
Symfony\Component\Console\Application:
|
||||
arguments:
|
||||
$name: "Rector"
|
||||
PhpParser\Parser:
|
||||
factory: ['@Rector\Parser\ParserFactory', 'create']
|
||||
PhpParser\BuilderFactory: ~
|
||||
PhpParser\PrettyPrinter\Standard: ~
|
||||
|
||||
# $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
|
||||
# $statements = $parser->parse(file_get_contents(__DIR__ . '/../source/ClassWithInjects
|
|
@ -0,0 +1,33 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Rector\DependencyInjection\ContainerFactory;
|
||||
|
||||
abstract class AbstractContainerAwareTestCase extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
private static $cachedContainer;
|
||||
|
||||
/**
|
||||
* @param mixed[] $data
|
||||
*/
|
||||
public function __construct(?string $name = null, array $data = [], string $dataName = '')
|
||||
{
|
||||
if (! self::$cachedContainer) {
|
||||
self::$cachedContainer = (new ContainerFactory)->create();
|
||||
}
|
||||
$this->container = self::$cachedContainer;
|
||||
|
||||
parent::__construct($name, $data, $dataName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests;
|
||||
|
||||
use Rector\Contract\Dispatcher\ReconstructorInterface;
|
||||
use Rector\Testing\Application\FileReconstructor;
|
||||
use SplFileInfo;
|
||||
|
||||
abstract class AbstractReconstructorTestCase extends AbstractContainerAwareTestCase
|
||||
{
|
||||
/**
|
||||
* @var FileReconstructor
|
||||
*/
|
||||
private $fileReconstructor;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->fileReconstructor = $this->container->get(FileReconstructor::class);
|
||||
}
|
||||
|
||||
protected function doTestFileMatchesExpectedContent(string $file, string $reconstructedFile): void
|
||||
{
|
||||
$reconstructedFileContent = $this->fileReconstructor->processFileWithReconstructor(
|
||||
new SplFileInfo($file), $this->getReconstructor()
|
||||
);
|
||||
|
||||
$this->assertStringEqualsFile($reconstructedFile, $reconstructedFileContent);
|
||||
}
|
||||
|
||||
abstract protected function getReconstructorClass(): string;
|
||||
|
||||
private function getReconstructor(): ReconstructorInterface
|
||||
{
|
||||
return $this->container->get($this->getReconstructorClass());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Reconstructor\DependencyInjection;
|
||||
|
||||
use Rector\Reconstructor\DependencyInjection\InjectAnnotationToConstructorReconstructor;
|
||||
use Rector\Tests\AbstractReconstructorTestCase;
|
||||
|
||||
final class InjectAnnotationToConstructorReconstructorTest extends AbstractReconstructorTestCase
|
||||
{
|
||||
public function test(): void
|
||||
{
|
||||
$this->doTestFileMatchesExpectedContent(__DIR__ . '/wrong/wrong.php.inc', __DIR__ . '/correct/correct.php.inc');
|
||||
}
|
||||
|
||||
protected function getReconstructorClass(): string
|
||||
{
|
||||
return InjectAnnotationToConstructorReconstructor::class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php declare (strict_types=1);
|
||||
class ClassWithInjects
|
||||
{
|
||||
/**
|
||||
* @var stdClass
|
||||
*/
|
||||
private $property;
|
||||
/**
|
||||
* @var DateTimeInterface
|
||||
*/
|
||||
private $otherProperty;
|
||||
public function __construct(stdClass $property, DateTimeInterface $otherProperty)
|
||||
{
|
||||
$this->property = $property;
|
||||
$this->otherProperty = $otherProperty;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php declare (strict_types=1);
|
||||
|
||||
class ClassWithInjects
|
||||
{
|
||||
/**
|
||||
* @var stdClass
|
||||
* @inject
|
||||
*/
|
||||
public $property;
|
||||
|
||||
/**
|
||||
* @var DateTimeInterface
|
||||
* @inject
|
||||
*/
|
||||
public $otherProperty;
|
||||
}
|
Loading…
Reference in New Issue