diff --git a/rector.php b/rector.php index b24f7fe82f0..375966c5c91 100644 --- a/rector.php +++ b/rector.php @@ -4,6 +4,7 @@ use Rector\CodingStyle\Rector\String_\UseClassKeywordForClassNameResolutionRector; use Rector\Config\RectorConfig; +use Rector\DeadCode\Rector\Cast\RecastingRemovalRector; use Rector\DeadCode\Rector\ConstFetch\RemovePhpVersionIdCheckRector; use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector; @@ -52,4 +53,9 @@ __DIR__ . '/src/Configuration/RectorConfigBuilder.php', __DIR__ . '/src/Console/Notifier.php', ], + + // todo: properly handle, substr() can return false on php 7.x + RecastingRemovalRector::class => [ + __DIR__ . '/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/ClassLikeNameClassNameImportSkipVoter.php', + ], ]); diff --git a/rules-tests/CodeQuality/Rector/ClassMethod/InlineArrayReturnAssignRector/Fixture/with_property_fetch.php.inc b/rules-tests/CodeQuality/Rector/ClassMethod/InlineArrayReturnAssignRector/Fixture/with_property_fetch.php.inc new file mode 100644 index 00000000000..81fb58cc089 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/ClassMethod/InlineArrayReturnAssignRector/Fixture/with_property_fetch.php.inc @@ -0,0 +1,48 @@ +name; + $event['payload'] = $this->bar(); + $event['data'] = $obj?->data; + $event['item'] = $obj?->getItem(); + $event['list'] = clone $obj; + $event['verify'] = $obj instanceof \stdClass; + + return $event; + } + + private function bar(): array + { + return []; + } +} + +?> +----- + $this->name, 'payload' => $this->bar(), 'data' => $obj?->data, 'item' => $obj?->getItem(), 'list' => clone $obj, 'verify' => $obj instanceof \stdClass]; + } + + private function bar(): array + { + return []; + } +} + +?> \ No newline at end of file diff --git a/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/ClassLikeNameClassNameImportSkipVoter.php b/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/ClassLikeNameClassNameImportSkipVoter.php index 035fda21883..be8a44e9ce3 100644 --- a/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/ClassLikeNameClassNameImportSkipVoter.php +++ b/rules/CodingStyle/ClassNameImport/ClassNameImportSkipVoter/ClassLikeNameClassNameImportSkipVoter.php @@ -46,9 +46,8 @@ public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedO $namespace = strtolower((string) $namespace); $shortNameLowered = $fullyQualifiedObjectType->getShortNameLowered(); - $fullyQualifiedObjectTypeNamespace = strtolower( - substr($fullyQualifiedObjectType->getClassName(), 0, -strlen($fullyQualifiedObjectType->getShortName()) - 1) ?: '' - ); + $subClassName = substr($fullyQualifiedObjectType->getClassName(), 0, -strlen($fullyQualifiedObjectType->getShortName()) - 1); + $fullyQualifiedObjectTypeNamespace = strtolower((string) $subClassName); foreach ($classLikeNames as $classLikeName) { if (strtolower($classLikeName) !== $shortNameLowered) { diff --git a/src/PhpParser/Node/NodeFactory.php b/src/PhpParser/Node/NodeFactory.php index eba3a7be6a3..e3744ce7632 100644 --- a/src/PhpParser/Node/NodeFactory.php +++ b/src/PhpParser/Node/NodeFactory.php @@ -23,10 +23,14 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical; use PhpParser\Node\Expr\Cast; use PhpParser\Node\Expr\ClassConstFetch; +use PhpParser\Node\Expr\Clone_; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Expr\Instanceof_; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\New_; +use PhpParser\Node\Expr\NullsafeMethodCall; +use PhpParser\Node\Expr\NullsafePropertyFetch; use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\StaticPropertyFetch; @@ -44,7 +48,6 @@ use PHPStan\Type\Type; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use Rector\Enum\ObjectReference; -use Rector\Exception\NotImplementedYetException; use Rector\Exception\ShouldNotHappenException; use Rector\NodeDecorator\PropertyTypeDecorator; use Rector\NodeTypeResolver\Node\AttributeKey; @@ -377,6 +380,12 @@ private function createArrayItem(mixed $item, string | int | null $key = null): || $item instanceof Scalar || $item instanceof Cast || $item instanceof ConstFetch + || $item instanceof PropertyFetch + || $item instanceof StaticPropertyFetch + || $item instanceof NullsafePropertyFetch + || $item instanceof NullsafeMethodCall + || $item instanceof Clone_ + || $item instanceof Instanceof_ ) { $arrayItem = new ArrayItem($item); } elseif ($item instanceof Identifier) { @@ -411,12 +420,19 @@ private function createArrayItem(mixed $item, string | int | null $key = null): return $arrayItem; } - $nodeClass = is_object($item) ? $item::class : $item; - throw new NotImplementedYetException(sprintf( - 'Not implemented yet. Go to "%s()" and add check for "%s" node.', - __METHOD__, - (string) $nodeClass - )); + // fallback to other nodes + if ($item instanceof Expr) { + $arrayItem = new ArrayItem($item); + $this->decorateArrayItemWithKey($key, $arrayItem); + + return $arrayItem; + } + + $itemValue = BuilderHelpers::normalizeValue($item); + $arrayItem = new ArrayItem($itemValue); + $this->decorateArrayItemWithKey($key, $arrayItem); + + return $arrayItem; } private function decorateArrayItemWithKey(int | string | null $key, ArrayItem $arrayItem): void