mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-07 20:00:50 +00:00
[DynamicTypeAnalysis] Drop for too theoretical content, needs real project to test out (#4511)
This commit is contained in:
parent
7da47f444b
commit
63037fe924
|
@ -108,7 +108,6 @@
|
|||
"Rector\\ReadWrite\\": "packages/read-write/src",
|
||||
"Rector\\DowngradePhp74\\": "rules/downgrade-php74/src",
|
||||
"Rector\\DowngradePhp80\\": "rules/downgrade-php80/src",
|
||||
"Rector\\DynamicTypeAnalysis\\": "packages/dynamic-type-analysis/src",
|
||||
"Rector\\FamilyTree\\": "packages/family-tree/src",
|
||||
"Rector\\FileSystemRector\\": "packages/file-system-rector/src",
|
||||
"Rector\\Generic\\": "rules/generic/src",
|
||||
|
@ -236,7 +235,6 @@
|
|||
"Rector\\DowngradePhp73\\Tests\\": "rules/downgrade-php73/tests",
|
||||
"Rector\\DowngradePhp74\\Tests\\": "rules/downgrade-php74/tests",
|
||||
"Rector\\DowngradePhp80\\Tests\\": "rules/downgrade-php80/tests",
|
||||
"Rector\\DynamicTypeAnalysis\\Tests\\": "packages/dynamic-type-analysis/tests",
|
||||
"Rector\\Generic\\Tests\\": "rules/generic/tests",
|
||||
"Rector\\JMS\\Tests\\": "rules/jms/tests",
|
||||
"Rector\\Laravel\\Tests\\": "rules/laravel/tests",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# All 600 Rectors Overview
|
||||
# All 597 Rectors Overview
|
||||
|
||||
- [Projects](#projects)
|
||||
---
|
||||
|
@ -21,7 +21,6 @@
|
|||
- [DowngradePhp73](#downgradephp73) (1)
|
||||
- [DowngradePhp74](#downgradephp74) (7)
|
||||
- [DowngradePhp80](#downgradephp80) (6)
|
||||
- [DynamicTypeAnalysis](#dynamictypeanalysis) (3)
|
||||
- [FileSystemRector](#filesystemrector) (1)
|
||||
- [Generic](#generic) (35)
|
||||
- [JMS](#jms) (2)
|
||||
|
@ -5591,67 +5590,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
<br><br>
|
||||
|
||||
## DynamicTypeAnalysis
|
||||
|
||||
### `AddArgumentTypeWithProbeDataRector`
|
||||
|
||||
- class: [`Rector\DynamicTypeAnalysis\Rector\ClassMethod\AddArgumentTypeWithProbeDataRector`](/packages/dynamic-type-analysis/src/Rector/ClassMethod/AddArgumentTypeWithProbeDataRector.php)
|
||||
- [test fixtures](/packages/dynamic-type-analysis/tests/Rector/ClassMethod/AddArgumentTypeWithProbeDataRector/Fixture)
|
||||
|
||||
Add argument type based on probed data
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
- public function run($arg)
|
||||
+ public function run(string $arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `DecorateMethodWithArgumentTypeProbeRector`
|
||||
|
||||
- class: [`Rector\DynamicTypeAnalysis\Rector\ClassMethod\DecorateMethodWithArgumentTypeProbeRector`](/packages/dynamic-type-analysis/src/Rector/ClassMethod/DecorateMethodWithArgumentTypeProbeRector.php)
|
||||
- [test fixtures](/packages/dynamic-type-analysis/tests/Rector/ClassMethod/DecorateMethodWithArgumentTypeProbeRector/Fixture)
|
||||
|
||||
Add probe that records argument types to `each` method
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
+ \Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe::recordArgumentType($arg, __METHOD__, 0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `RemoveArgumentTypeProbeRector`
|
||||
|
||||
- class: [`Rector\DynamicTypeAnalysis\Rector\StaticCall\RemoveArgumentTypeProbeRector`](/packages/dynamic-type-analysis/src/Rector/StaticCall/RemoveArgumentTypeProbeRector.php)
|
||||
- [test fixtures](/packages/dynamic-type-analysis/tests/Rector/StaticCall/RemoveArgumentTypeProbeRector/Fixture)
|
||||
|
||||
Clean up probe that records argument types
|
||||
|
||||
```diff
|
||||
-use Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe;
|
||||
-
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
- TypeStaticProbe::recordArgumentType($arg, __METHOD__, 0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
## FileSystemRector
|
||||
|
||||
### `RemoveProjectFileRector`
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->defaults()
|
||||
->autowire()
|
||||
->public()
|
||||
->autoconfigure();
|
||||
|
||||
$services->load('Rector\DynamicTypeAnalysis\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector']);
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Contract;
|
||||
|
||||
interface ProbeStorageInterface
|
||||
{
|
||||
public static function recordProbeItem(string $probeItem): void;
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getProbeItems(): array;
|
||||
|
||||
public static function clear(): void;
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Probe;
|
||||
|
||||
use Rector\DynamicTypeAnalysis\Contract\ProbeStorageInterface;
|
||||
use Rector\DynamicTypeAnalysis\ProbeStorage\StaticFileSystemProbeStorage;
|
||||
|
||||
/**
|
||||
* @see https://stackoverflow.com/a/39525458/1348344
|
||||
* @see \Rector\DynamicTypeAnalysis\Tests\Probe\TypeStaticProbeTest
|
||||
*/
|
||||
final class TypeStaticProbe
|
||||
{
|
||||
/**
|
||||
* @var mixed[]
|
||||
*/
|
||||
private static $itemDataByMethodReferenceAndPosition = [];
|
||||
|
||||
/**
|
||||
* @var ProbeStorageInterface|null
|
||||
*/
|
||||
private static $probeStorage;
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function recordArgumentType($value, string $method, int $argumentPosition): void
|
||||
{
|
||||
$probeItem = self::createProbeItem($value, $method, $argumentPosition);
|
||||
|
||||
self::recordProbeItem($probeItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function createProbeItem($value, string $method, int $argumentPosition): string
|
||||
{
|
||||
$type = self::resolveValueTypeToString($value);
|
||||
$data = [$type, $method, $argumentPosition];
|
||||
|
||||
return implode(';', $data) . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object|mixed[]|mixed $value
|
||||
*/
|
||||
public static function resolveValueTypeToString($value): string
|
||||
{
|
||||
if (is_object($value)) {
|
||||
return 'object:' . get_class($value);
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
// try to resolve single nested array types
|
||||
$arrayValueTypes = [];
|
||||
foreach ($value as $singleValue) {
|
||||
$arrayValueTypes[] = self::resolveValueTypeToString($singleValue);
|
||||
}
|
||||
|
||||
$arrayValueTypes = array_unique($arrayValueTypes);
|
||||
$arrayValueTypes = implode('|', $arrayValueTypes);
|
||||
|
||||
return 'array:' . $arrayValueTypes;
|
||||
}
|
||||
|
||||
return gettype($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public static function getDataForMethodByPosition(string $methodReference): array
|
||||
{
|
||||
$probeItemData = self::provideItemDataByMethodReferenceAndPosition();
|
||||
|
||||
return $probeItemData[$methodReference] ?? [];
|
||||
}
|
||||
|
||||
public static function setProbeStorage(ProbeStorageInterface $probeStorage): void
|
||||
{
|
||||
self::$probeStorage = $probeStorage;
|
||||
}
|
||||
|
||||
private static function recordProbeItem(string $probeItem): void
|
||||
{
|
||||
self::getProbeStorage()::recordProbeItem($probeItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
private static function provideItemDataByMethodReferenceAndPosition(): array
|
||||
{
|
||||
if (self::$itemDataByMethodReferenceAndPosition !== []) {
|
||||
return self::$itemDataByMethodReferenceAndPosition;
|
||||
}
|
||||
|
||||
$probeItems = self::getProbeStorage()::getProbeItems();
|
||||
|
||||
$itemData = [];
|
||||
foreach ($probeItems as $probeItem) {
|
||||
$probeItem = trim($probeItem);
|
||||
[$type, $methodReference, $position] = explode(';', $probeItem);
|
||||
|
||||
$itemData[$methodReference][$position][] = $type;
|
||||
}
|
||||
|
||||
self::$itemDataByMethodReferenceAndPosition = $itemData;
|
||||
|
||||
return $itemData;
|
||||
}
|
||||
|
||||
private static function getProbeStorage(): ProbeStorageInterface
|
||||
{
|
||||
if (self::$probeStorage === null) {
|
||||
// set default filesystem storage
|
||||
self::$probeStorage = new StaticFileSystemProbeStorage();
|
||||
}
|
||||
|
||||
return self::$probeStorage;
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\ProbeStorage;
|
||||
|
||||
use Rector\DynamicTypeAnalysis\Contract\ProbeStorageInterface;
|
||||
use Symplify\SmartFileSystem\SmartFileSystem;
|
||||
|
||||
final class StaticFileSystemProbeStorage implements ProbeStorageInterface
|
||||
{
|
||||
public static function recordProbeItem(string $probeItem): void
|
||||
{
|
||||
$storageFile = self::getFile();
|
||||
if (file_exists($storageFile)) {
|
||||
// append
|
||||
file_put_contents($storageFile, $probeItem, FILE_APPEND);
|
||||
} else {
|
||||
// 1st write
|
||||
$smartFileSystem = new SmartFileSystem();
|
||||
$smartFileSystem->dumpFile($storageFile, $probeItem);
|
||||
}
|
||||
}
|
||||
|
||||
public static function clear(): void
|
||||
{
|
||||
$smartFileSystem = new SmartFileSystem();
|
||||
$smartFileSystem->remove(self::getFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getProbeItems(): array
|
||||
{
|
||||
$smartFileSystem = new SmartFileSystem();
|
||||
$probeFileContent = $smartFileSystem->readFile(self::getFile());
|
||||
|
||||
$probeItems = explode(PHP_EOL, $probeFileContent);
|
||||
|
||||
// remove empty values
|
||||
return array_filter($probeItems);
|
||||
}
|
||||
|
||||
private static function getFile(): string
|
||||
{
|
||||
return sys_get_temp_dir() . '/_rector_type_probe.txt';
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Rector\ClassMethod;
|
||||
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* @see \Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\AddArgumentTypeWithProbeDataRector\AddArgumentTypeWithProbeDataRectorTest
|
||||
*/
|
||||
abstract class AbstractArgumentProbeRector extends AbstractRector
|
||||
{
|
||||
protected function shouldSkipClassMethod(ClassMethod $classMethod): bool
|
||||
{
|
||||
// we need at least scalar types to make this work
|
||||
if (! $this->isAtLeastPhpVersion(PhpVersionFeature::SCALAR_TYPES)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
|
||||
|
||||
// skip interfaces
|
||||
if ($classLike instanceof Interface_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// only record public methods = they're the entry points + prevent duplicated type recording
|
||||
if (! $classMethod->isPublic()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// we need some params to analyze
|
||||
if ((array) $classMethod->params === []) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// method without body doesn't need analysis
|
||||
return (array) $classMethod->stmts === [];
|
||||
}
|
||||
|
||||
protected function getClassMethodReference(ClassMethod $classMethod): ?string
|
||||
{
|
||||
$className = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$methodName = $this->getName($classMethod->name);
|
||||
if ($methodName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $className . '::' . $methodName;
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Rector\ClassMethod;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe;
|
||||
|
||||
/**
|
||||
* @see \Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\AddArgumentTypeWithProbeDataRector\AddArgumentTypeWithProbeDataRectorTest
|
||||
*/
|
||||
final class AddArgumentTypeWithProbeDataRector extends AbstractArgumentProbeRector
|
||||
{
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Add argument type based on probed data', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run(string $arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [ClassMethod::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkipClassMethod($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classMethodReference = $this->getClassMethodReference($node);
|
||||
if ($classMethodReference === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$methodData = TypeStaticProbe::getDataForMethodByPosition($classMethodReference);
|
||||
|
||||
// no data for this method → skip
|
||||
if ($methodData === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->completeTypesToClassMethodParams($node, $methodData);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $methodData
|
||||
*/
|
||||
private function completeTypesToClassMethodParams(ClassMethod $classMethod, array $methodData): void
|
||||
{
|
||||
foreach ($classMethod->params as $position => $param) {
|
||||
// do not override existing types
|
||||
if ($param->type !== null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// no data for this parameter → skip
|
||||
if (! isset($methodData[$position])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parameterData = $methodData[$position];
|
||||
// uniquate data
|
||||
$parameterData = array_unique($parameterData);
|
||||
|
||||
if (count($parameterData) > 1) {
|
||||
// is union or nullable type?
|
||||
continue;
|
||||
}
|
||||
|
||||
// single value → can we add it?
|
||||
if (count($parameterData) === 1) {
|
||||
$typeNode = $this->staticTypeMapper->mapStringToPhpParserNode($parameterData[0]);
|
||||
$param->type = $typeNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Rector\ClassMethod;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Scalar\MagicConst\Method;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe;
|
||||
|
||||
/**
|
||||
* @see \Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\DecorateMethodWithArgumentTypeProbeRector\DecorateMethodWithArgumentTypeProbeRectorTest
|
||||
*/
|
||||
final class DecorateMethodWithArgumentTypeProbeRector extends AbstractArgumentProbeRector
|
||||
{
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Add probe that records argument types to each method', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
\Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe::recordArgumentType($arg, __METHOD__, 0);
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [ClassMethod::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkipClassMethod($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$probeStaticCalls = $this->createRecordArgumentTypeStaticCalls($node);
|
||||
$node->stmts = array_merge($probeStaticCalls, (array) $node->stmts);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Expression[]
|
||||
*/
|
||||
private function createRecordArgumentTypeStaticCalls(ClassMethod $classMethod): array
|
||||
{
|
||||
$probeStaticCalls = [];
|
||||
|
||||
foreach ($classMethod->params as $i => $param) {
|
||||
$probeStaticCall = $this->createFromVariableAndPosition($param, $i);
|
||||
$probeStaticCalls[] = new Expression($probeStaticCall);
|
||||
}
|
||||
|
||||
return $probeStaticCalls;
|
||||
}
|
||||
|
||||
private function createFromVariableAndPosition(Param $param, int $i): StaticCall
|
||||
{
|
||||
return $this->createStaticCall(TypeStaticProbe::class, 'recordArgumentType', [
|
||||
$param->var,
|
||||
new Method(),
|
||||
new LNumber($i),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Rector\StaticCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe;
|
||||
|
||||
/**
|
||||
* @see \Rector\DynamicTypeAnalysis\Tests\Rector\StaticCall\RemoveArgumentTypeProbeRector\RemoveArgumentTypeProbeRectorTest
|
||||
*/
|
||||
final class RemoveArgumentTypeProbeRector extends AbstractRector
|
||||
{
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Clean up probe that records argument types', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
use Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
TypeStaticProbe::recordArgumentType($arg, __METHOD__, 0);
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [StaticCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StaticCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isObjectType($node->class, TypeStaticProbe::class)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->removeNode($node);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Probe;
|
||||
|
||||
use Iterator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe;
|
||||
use stdClass;
|
||||
|
||||
final class TypeStaticProbeTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function test($value, string $methodName, int $argumentPosition, string $expectedProbeItem): void
|
||||
{
|
||||
$probeItem = TypeStaticProbe::createProbeItem($value, $methodName, $argumentPosition);
|
||||
$this->assertSame($expectedProbeItem, $probeItem);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
yield [5, 'SomeMethod', 0, 'integer;SomeMethod;0' . PHP_EOL];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @dataProvider provideDataResolveValueTypeToString()
|
||||
*/
|
||||
public function testResolveValueTypeToString($value, string $expectedValueTypeString): void
|
||||
{
|
||||
$this->assertSame($expectedValueTypeString, TypeStaticProbe::resolveValueTypeToString($value));
|
||||
}
|
||||
|
||||
public function provideDataResolveValueTypeToString(): Iterator
|
||||
{
|
||||
yield [5, 'integer'];
|
||||
yield ['hi', 'string'];
|
||||
yield [new stdClass(), 'object:stdClass'];
|
||||
yield [[new stdClass()], 'array:object:stdClass'];
|
||||
yield [[[new stdClass()]], 'array:array:object:stdClass'];
|
||||
yield [[5], 'array:integer'];
|
||||
yield [[5, 'ou'], 'array:integer|string'];
|
||||
yield [[5, ['ou']], 'array:integer|array:string'];
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\ProbeStorage;
|
||||
|
||||
use Rector\DynamicTypeAnalysis\Contract\ProbeStorageInterface;
|
||||
|
||||
final class StaticInMemoryProbeStorage implements ProbeStorageInterface
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private static $probeItems = [];
|
||||
|
||||
public static function recordProbeItem(string $probeItem): void
|
||||
{
|
||||
self::$probeItems[] = $probeItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getProbeItems(): array
|
||||
{
|
||||
// remove empty values
|
||||
return array_filter(self::$probeItems);
|
||||
}
|
||||
|
||||
public static function clear(): void
|
||||
{
|
||||
self::$probeItems = [];
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\AddArgumentTypeWithProbeDataRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe;
|
||||
use Rector\DynamicTypeAnalysis\Rector\ClassMethod\AddArgumentTypeWithProbeDataRector;
|
||||
use Rector\DynamicTypeAnalysis\Tests\ProbeStorage\StaticInMemoryProbeStorage;
|
||||
use Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\AddArgumentTypeWithProbeDataRector\Fixture\SomeClass;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class AddArgumentTypeWithProbeDataRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const METHOD_REFERENCE = SomeClass::class . '::run';
|
||||
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->initializeProbeData();
|
||||
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return AddArgumentTypeWithProbeDataRector::class;
|
||||
}
|
||||
|
||||
private function initializeProbeData(): void
|
||||
{
|
||||
$staticInMemoryProbeStorage = new StaticInMemoryProbeStorage();
|
||||
TypeStaticProbe::setProbeStorage($staticInMemoryProbeStorage);
|
||||
|
||||
$staticInMemoryProbeStorage::clear();
|
||||
|
||||
TypeStaticProbe::recordArgumentType('hey', self::METHOD_REFERENCE, 0);
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\AddArgumentTypeWithProbeDataRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\AddArgumentTypeWithProbeDataRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run(string $arg)
|
||||
{
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\DecorateMethodWithArgumentTypeProbeRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\DynamicTypeAnalysis\Rector\ClassMethod\DecorateMethodWithArgumentTypeProbeRector;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class DecorateMethodWithArgumentTypeProbeRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return DecorateMethodWithArgumentTypeProbeRector::class;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\DecorateMethodWithArgumentTypeProbeRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\DecorateMethodWithArgumentTypeProbeRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
\Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe::recordArgumentType($arg, __METHOD__, 0);
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\ClassMethod\DecorateMethodWithArgumentTypeProbeRector\Fixture;
|
||||
|
||||
class SkipNonPublic
|
||||
{
|
||||
protected function run($arg)
|
||||
{
|
||||
return $arg;
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\StaticCall\RemoveArgumentTypeProbeRector\Fixture;
|
||||
|
||||
use Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
TypeStaticProbe::recordArgumentType($arg, __METHOD__, 0);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\StaticCall\RemoveArgumentTypeProbeRector\Fixture;
|
||||
|
||||
use Rector\DynamicTypeAnalysis\Probe\TypeStaticProbe;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run($arg)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DynamicTypeAnalysis\Tests\Rector\StaticCall\RemoveArgumentTypeProbeRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\DynamicTypeAnalysis\Rector\StaticCall\RemoveArgumentTypeProbeRector;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class RemoveArgumentTypeProbeRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return RemoveArgumentTypeProbeRector::class;
|
||||
}
|
||||
}
|
|
@ -237,9 +237,6 @@ parameters:
|
|||
|
||||
- '#Method Rector\\NodeTypeResolver\\PHPStan\\Type\\TypeFactory\:\:createUnionOrSingleType\(\) should return PHPStan\\Type\\MixedType\|PHPStan\\Type\\UnionType but returns PHPStan\\Type\\Type#'
|
||||
|
||||
# test
|
||||
- '#Class Rector\\DynamicTypeAnalysis\\Tests\\Rector\\ClassMethod\\AddArgumentTypeWithProbeDataRector\\Fixture\\SomeClass not found#'
|
||||
|
||||
-
|
||||
message: '#Class Rector\\Generic\\Tests\\Rector\\StaticCall\\SwapClassMethodArgumentsRector\\Fixture\\SomeClass not found#'
|
||||
path: rules/generic/tests/Rector/StaticCall/SwapClassMethodArgumentsRector/SwapClassMethodArgumentsRectorTest.php
|
||||
|
|
Loading…
Reference in New Issue
Block a user