diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md
index 40977587831..e90a4d280fd 100644
--- a/docs/rector_rules_overview.md
+++ b/docs/rector_rules_overview.md
@@ -1,4 +1,4 @@
-# 355 Rules Overview
+# 354 Rules Overview
@@ -46,7 +46,7 @@
- [Php83](#php83) (3)
-- [Privatization](#privatization) (5)
+- [Privatization](#privatization) (4)
- [Removing](#removing) (5)
@@ -5136,6 +5136,8 @@ Decorate read-only property with `readonly` attribute
Refactor Spatie enum class to native Enum
+:wrench: **configure it!**
+
- class: [`Rector\Php81\Rector\Class_\SpatieEnumClassToEnumRector`](../rules/Php81/Rector/Class_/SpatieEnumClassToEnumRector.php)
```diff
@@ -5304,25 +5306,6 @@ Combine separated host and port on `ldap_connect()` args
## Privatization
-### FinalizeClassesWithoutChildrenCollectorRector
-
-Finalize classes without children using collectors
-
-- class: [`Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenCollectorRector`](../rules/Privatization/Rector/Class_/FinalizeClassesWithoutChildrenCollectorRector.php)
-
-```diff
--class FirstClass extends SecondClass
-+final class FirstClass extends SecondClass
- {
- }
-
- class SecondClass
- {
- }
-```
-
-
-
### FinalizeClassesWithoutChildrenRector
Finalize every class that has no children
diff --git a/rules/Php81/NodeFactory/EnumFactory.php b/rules/Php81/NodeFactory/EnumFactory.php
index 71609d8c951..c81cc1418dd 100644
--- a/rules/Php81/NodeFactory/EnumFactory.php
+++ b/rules/Php81/NodeFactory/EnumFactory.php
@@ -58,6 +58,11 @@ final class EnumFactory
* @see https://regex101.com/r/Zv4JhD/1 for changing needsReview to needs_Review
*/
private const PASCAL_CASE_TO_UNDERSCORE_REGEX = '/(?<=[A-Z])(?=[A-Z][a-z])|(?<=[^A-Z])(?=[A-Z])|(?<=[A-Za-z])(?=[^A-Za-z])/';
+ /**
+ * @var string
+ * @see https://regex101.com/r/FneU33/1
+ */
+ private const MULTI_UNDERSCORES_REGEX = '#_{2,}#';
public function __construct(NodeNameResolver $nodeNameResolver, PhpDocInfoFactory $phpDocInfoFactory, BuilderFactory $builderFactory, ValueResolver $valueResolver, BetterNodeFinder $betterNodeFinder)
{
$this->nodeNameResolver = $nodeNameResolver;
@@ -121,6 +126,7 @@ final class EnumFactory
$enumValue = $mapping[$nodeValue->methodName] ?? $nodeValue->methodName;
if ($enumNameInSnakeCase) {
$enumName = \strtoupper(Strings::replace($nodeValue->methodName, self::PASCAL_CASE_TO_UNDERSCORE_REGEX, '_$0'));
+ $enumName = Strings::replace($enumName, self::MULTI_UNDERSCORES_REGEX, '_');
} else {
$enumName = \strtoupper($nodeValue->methodName);
}
diff --git a/rules/Php81/Rector/Class_/SpatieEnumClassToEnumRector.php b/rules/Php81/Rector/Class_/SpatieEnumClassToEnumRector.php
index 75b74d80cb9..46f3baa9033 100644
--- a/rules/Php81/Rector/Class_/SpatieEnumClassToEnumRector.php
+++ b/rules/Php81/Rector/Class_/SpatieEnumClassToEnumRector.php
@@ -12,7 +12,7 @@ use Rector\Php81\NodeFactory\EnumFactory;
use Rector\Rector\AbstractRector;
use Rector\ValueObject\PhpVersionFeature;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
-use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
+use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://wiki.php.net/rfc/enumerations
@@ -31,6 +31,10 @@ final class SpatieEnumClassToEnumRector extends AbstractRector implements MinPhp
* @var bool
*/
private $toUpperSnakeCase = \false;
+ /**
+ * @var string
+ */
+ public const TO_UPPER_SNAKE_CASE = 'toUpperSnakeCase';
public function __construct(EnumFactory $enumFactory)
{
$this->enumFactory = $enumFactory;
@@ -41,7 +45,7 @@ final class SpatieEnumClassToEnumRector extends AbstractRector implements MinPhp
}
public function getRuleDefinition() : RuleDefinition
{
- return new RuleDefinition('Refactor Spatie enum class to native Enum', [new CodeSample(<<<'CODE_SAMPLE'
+ return new RuleDefinition('Refactor Spatie enum class to native Enum', [new ConfiguredCodeSample(<<<'CODE_SAMPLE'
use \Spatie\Enum\Enum;
/**
@@ -61,7 +65,7 @@ enum StatusEnum : string
case ARCHIVED = 'archived';
}
CODE_SAMPLE
-)]);
+, [\Rector\Php81\Rector\Class_\SpatieEnumClassToEnumRector::TO_UPPER_SNAKE_CASE => \false])]);
}
/**
* @return array>
@@ -85,6 +89,6 @@ CODE_SAMPLE
*/
public function configure(array $configuration) : void
{
- $this->toUpperSnakeCase = \true === ($configuration['toUpperSnakeCase'] ?? \false);
+ $this->toUpperSnakeCase = $configuration[self::TO_UPPER_SNAKE_CASE] ?? \false;
}
}
diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php
index 44552d1034f..7857540a9bb 100644
--- a/src/Application/VersionResolver.php
+++ b/src/Application/VersionResolver.php
@@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
- public const PACKAGE_VERSION = 'ee89fb7b82b6fa37412bd5d0cbaac9b49258eb3f';
+ public const PACKAGE_VERSION = '07df7dc1a344c52711441149d61251a4fe10366d';
/**
* @api
* @var string
*/
- public const RELEASE_DATE = '2024-01-16 01:17:41';
+ public const RELEASE_DATE = '2024-01-16 11:19:36';
/**
* @var int
*/
diff --git a/src/Config/RectorConfig.php b/src/Config/RectorConfig.php
index 456c3362790..8b6598fe912 100644
--- a/src/Config/RectorConfig.php
+++ b/src/Config/RectorConfig.php
@@ -8,7 +8,6 @@ use PHPStan\Collectors\Collector;
use Rector\Caching\Contract\ValueObject\Storage\CacheStorageInterface;
use Rector\Configuration\Option;
use Rector\Configuration\Parameter\SimpleParameterProvider;
-use Rector\Contract\Rector\CollectorRectorInterface;
use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\Contract\Rector\RectorInterface;
use Rector\DependencyInjection\Laravel\ContainerMemento;
@@ -153,9 +152,6 @@ final class RectorConfig extends Container
Assert::isAOf($rectorClass, RectorInterface::class);
$this->singleton($rectorClass);
$this->tag($rectorClass, RectorInterface::class);
- if (\is_a($rectorClass, CollectorRectorInterface::class, \true)) {
- $this->tag($rectorClass, CollectorRectorInterface::class);
- }
// for cache invalidation in case of change
SimpleParameterProvider::addParameter(Option::REGISTERED_RECTOR_RULES, $rectorClass);
}
diff --git a/src/DependencyInjection/LazyContainerFactory.php b/src/DependencyInjection/LazyContainerFactory.php
index f8d9393a2d6..7fe3ead5899 100644
--- a/src/DependencyInjection/LazyContainerFactory.php
+++ b/src/DependencyInjection/LazyContainerFactory.php
@@ -57,7 +57,6 @@ use Rector\Console\Output\OutputFormatterCollector;
use Rector\Console\Style\RectorStyle;
use Rector\Console\Style\SymfonyStyleFactory;
use Rector\Contract\DependencyInjection\ResetableInterface;
-use Rector\Contract\Rector\CollectorRectorInterface;
use Rector\Contract\Rector\RectorInterface;
use Rector\NodeDecorator\CreatedByRuleDecorator;
use Rector\NodeNameResolver\Contract\NodeNameResolverInterface;
@@ -272,7 +271,6 @@ final class LazyContainerFactory
$rectorConfig->when(ConstExprParser::class)->needs('$usedAttributes')->give(['lines' => \true, 'indexes' => \true]);
$rectorConfig->alias(TypeParser::class, BetterTypeParser::class);
$rectorConfig->when(RectorNodeTraverser::class)->needs('$rectors')->giveTagged(RectorInterface::class);
- $rectorConfig->when(RectorNodeTraverser::class)->needs('$collectorRectors')->giveTagged(CollectorRectorInterface::class);
$rectorConfig->when(ConfigInitializer::class)->needs('$rectors')->giveTagged(RectorInterface::class);
$rectorConfig->when(ClassNameImportSkipper::class)->needs('$classNameImportSkipVoters')->giveTagged(ClassNameImportSkipVoterInterface::class);
$rectorConfig->singleton(DynamicSourceLocatorProvider::class, static function (Container $container) : DynamicSourceLocatorProvider {
diff --git a/src/PhpParser/NodeTraverser/RectorNodeTraverser.php b/src/PhpParser/NodeTraverser/RectorNodeTraverser.php
index d8058900b2d..cdcafbc3d9c 100644
--- a/src/PhpParser/NodeTraverser/RectorNodeTraverser.php
+++ b/src/PhpParser/NodeTraverser/RectorNodeTraverser.php
@@ -5,7 +5,6 @@ namespace Rector\PhpParser\NodeTraverser;
use PhpParser\Node;
use PhpParser\NodeTraverser;
-use Rector\Contract\Rector\CollectorRectorInterface;
use Rector\Contract\Rector\RectorInterface;
use Rector\VersionBonding\PhpVersionedFilter;
final class RectorNodeTraverser extends NodeTraverser
@@ -63,11 +62,7 @@ final class RectorNodeTraverser extends NodeTraverser
return;
}
// filer out by version
- $activeRectors = $this->phpVersionedFilter->filter($this->rectors);
- $nonCollectorActiveRectors = \array_filter($activeRectors, static function (RectorInterface $rector) : bool {
- return !$rector instanceof CollectorRectorInterface;
- });
- $this->visitors = \array_merge($this->visitors, $nonCollectorActiveRectors);
+ $this->visitors = $this->phpVersionedFilter->filter($this->rectors);
$this->areNodeVisitorsPrepared = \true;
}
}
diff --git a/src/Testing/PHPUnit/AbstractRectorTestCase.php b/src/Testing/PHPUnit/AbstractRectorTestCase.php
index fb1ad93aa15..4e7ae31c84f 100644
--- a/src/Testing/PHPUnit/AbstractRectorTestCase.php
+++ b/src/Testing/PHPUnit/AbstractRectorTestCase.php
@@ -7,7 +7,6 @@ use RectorPrefix202401\Illuminate\Container\RewindableGenerator;
use Iterator;
use RectorPrefix202401\Nette\Utils\FileSystem;
use RectorPrefix202401\Nette\Utils\Strings;
-use PHPStan\Collectors\Collector;
use PHPUnit\Framework\ExpectationFailedException;
use Rector\Application\ApplicationFileProcessor;
use Rector\Autoloading\AdditionalAutoloader;
@@ -16,7 +15,6 @@ use Rector\Configuration\ConfigurationFactory;
use Rector\Configuration\Option;
use Rector\Configuration\Parameter\SimpleParameterProvider;
use Rector\Contract\DependencyInjection\ResetableInterface;
-use Rector\Contract\Rector\CollectorRectorInterface;
use Rector\Contract\Rector\RectorInterface;
use Rector\DependencyInjection\Laravel\ContainerMemento;
use Rector\Exception\ShouldNotHappenException;
@@ -83,8 +81,6 @@ abstract class AbstractRectorTestCase extends \Rector\Testing\PHPUnit\AbstractLa
$rectorConfig->resetRuleConfigurations();
// this has to be always empty, so we can add new rules with their configuration
$this->assertEmpty($rectorConfig->tagged(RectorInterface::class));
- $this->assertEmpty($rectorConfig->tagged(CollectorRectorInterface::class));
- $this->assertEmpty($rectorConfig->tagged(Collector::class));
$this->bootFromConfigFiles([$configFile]);
$rectorsGenerator = $rectorConfig->tagged(RectorInterface::class);
$rectors = $rectorsGenerator instanceof RewindableGenerator ? \iterator_to_array($rectorsGenerator->getIterator()) : [];
@@ -145,8 +141,6 @@ abstract class AbstractRectorTestCase extends \Rector\Testing\PHPUnit\AbstractLa
$rectorConfig = self::getContainer();
// 1. forget tagged services
ContainerMemento::forgetTag($rectorConfig, RectorInterface::class);
- ContainerMemento::forgetTag($rectorConfig, Collector::class);
- ContainerMemento::forgetTag($rectorConfig, CollectorRectorInterface::class);
// 2. remove after binding too, to avoid setting configuration over and over again
$privatesAccessor = new PrivatesAccessor();
$privatesAccessor->propertyClosure($rectorConfig, 'afterResolvingCallbacks', static function (array $afterResolvingCallbacks) : array {