Skip to content

Commit

Permalink
extract
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Sep 2, 2024
1 parent deaaff2 commit 91122f1
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 152 deletions.
5 changes: 1 addition & 4 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ parameters:
- '#Callable callable\(PHPStan\\Type\\Type\)\: PHPStan\\Type\\Type invoked with 2 parameters, 1 required#'

# known value
- '#Method Rector\\Php\\PhpVersionProvider\:\:provide\(\) should return 50200\|50300\|50400\|50500\|50600\|70000\|70100\|70200\|70300\|70400\|80000\|80100\|80200\|80300\|80400\|100000 but returns int#'
- '#Method (.*?) should return 50200\|50300\|50400\|50500\|50600\|70000\|70100\|70200\|70300\|70400\|80000\|80100\|80200\|80300\|80400\|100000 but returns int#'

-
message: '#Function "class_exists\(\)" cannot be used/left in the code#'
Expand Down Expand Up @@ -295,8 +295,5 @@ parameters:
- '#Register "Rector\\Php71\\Rector\\ClassConst\\PublicConstantVisibilityRector" service to "php71\.php" config set#'
- '#Public method "Rector\\ValueObject\\Error\\SystemError\:\:getFile\(\)" is never used#'

# known values
- '#Method Rector\\Util\\PhpVersionFactory\:\:createIntVersion\(\) should return 50200\|50300\|50400\|50500\|50600\|70000\|70100\|70200\|70300\|70400\|80000\|80100\|80200\|80300\|80400\|100000 but returns int#'

# soon to be used
- '#Property Rector\\Configuration\\RectorConfigBuilder\:\:\$isWithPhpSetsUsed is never read, only written#'
2 changes: 1 addition & 1 deletion preload.php
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/VarTagValueNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeItemNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeNode.php';
//require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeUnsealedTypeNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayShapeUnsealedTypeNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayTypeNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeNode.php';
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeParameterNode.php';
Expand Down
65 changes: 43 additions & 22 deletions src/Bridge/SetRectorsResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
namespace Rector\Bridge;

use Rector\Config\RectorConfig;
use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\Contract\Rector\RectorInterface;
use ReflectionProperty;
use Webmozart\Assert\Assert;

/**
Expand All @@ -20,25 +18,56 @@
final class SetRectorsResolver
{
/**
* @return array<class-string<RectorInterface>>
* @param string[] $configFilePaths
* @return array<int, class-string<RectorInterface>|array<class-string<RectorInterface>, mixed[]>>
*/
public function resolveFromFilePathForPhpLevel(string $configFilePath): array
public function resolveFromFilePathsIncludingConfiguration(array $configFilePaths): array
{
$rectorClasses = $this->resolveFromFilePath($configFilePath);
Assert::allString($configFilePaths);
Assert::allFileExists($configFilePaths);

$nonConfigurableRectorClasses = array_filter(
$rectorClasses,
fn (string $rectorClass): bool => ! is_a($rectorClass, ConfigurableRectorInterface::class, true)
);
$combinedRectorRulesWithConfiguration = [];

// revert to start from the lowest level
return array_reverse($nonConfigurableRectorClasses);
foreach ($configFilePaths as $configFilePath) {
$rectorRulesWithConfiguration = $this->resolveFromFilePathIncludingConfiguration($configFilePath);

$combinedRectorRulesWithConfiguration = array_merge(
$combinedRectorRulesWithConfiguration,
$rectorRulesWithConfiguration
);
}

return $combinedRectorRulesWithConfiguration;
}

/**
* @return array<class-string<RectorInterface>>
* @return array<int, class-string<RectorInterface>|array<class-string<RectorInterface>, mixed[]>>
*/
public function resolveFromFilePath(string $configFilePath): array
public function resolveFromFilePathIncludingConfiguration(string $configFilePath): array
{
$rectorConfig = $this->loadRectorConfigFromFilePath($configFilePath);

$rectorClassesWithOptionalConfiguration = $rectorConfig->getRectorClasses();

foreach ($rectorConfig->getRuleConfigurations() as $rectorClass => $configuration) {
// remove from non-configurable, if added again with better config
if (in_array($rectorClass, $rectorClassesWithOptionalConfiguration)) {
$rectorRulePosition = array_search($rectorClass, $rectorClassesWithOptionalConfiguration, true);
if (is_int($rectorRulePosition)) {
unset($rectorClassesWithOptionalConfiguration[$rectorRulePosition]);
}
}

$rectorClassesWithOptionalConfiguration[] = [
$rectorClass => $configuration,
];
}

// sort keys
return array_values($rectorClassesWithOptionalConfiguration);
}

private function loadRectorConfigFromFilePath(string $configFilePath): RectorConfig
{
Assert::fileExists($configFilePath);

Expand All @@ -48,14 +77,6 @@ public function resolveFromFilePath(string $configFilePath): array
$configCallable = require $configFilePath;
$configCallable($rectorConfig);

// get tagged class-names
$tagsReflectionProperty = new ReflectionProperty($rectorConfig, 'tags');
$tags = $tagsReflectionProperty->getValue($rectorConfig);

$rectorClasses = $tags[RectorInterface::class] ?? [];

// avoid sorting to keep original natural order for levels

return array_unique($rectorClasses);
return $rectorConfig;
}
}
20 changes: 19 additions & 1 deletion src/Config/RectorConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
final class RectorConfig extends Container
{
/**
* @var array<class-string<RectorInterface>, mixed[]>>
* @var array<class-string<ConfigurableRectorInterface>, mixed[]>>
*/
private array $ruleConfigurations = [];

Expand Down Expand Up @@ -418,4 +418,22 @@ public function reportingRealPath(bool $absolute = true): void
{
SimpleParameterProvider::setParameter(Option::ABSOLUTE_FILE_PATH, $absolute);
}

/**
* @internal Used only for bridge
* @return array<class-string<ConfigurableRectorInterface>, mixed>
*/
public function getRuleConfigurations(): array
{
return $this->ruleConfigurations;
}

/**
* @internal Used only for bridge
* @return array<class-string<RectorInterface>>
*/
public function getRectorClasses(): array
{
return $this->tags[RectorInterface::class] ?? [];
}
}
8 changes: 2 additions & 6 deletions src/Configuration/Levels/LevelRulesResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ final class LevelRulesResolver
*/
public static function resolve(int $level, array $availableRules, string $methodName): array
{
Assert::natural($level);
// level < 0 is not allowed
Assert::natural($level, sprintf('Level must be >= 0 on %s', $methodName));

Assert::allIsAOf($availableRules, RectorInterface::class);

Expand All @@ -29,9 +30,6 @@ public static function resolve(int $level, array $availableRules, string $method
));
}

// level < 0 is not allowed
Assert::natural($level, sprintf('Level must be >= 0 on %s', $methodName));

// start with 0
$maxLevel = $rulesCount - 1;
if ($level > $maxLevel) {
Expand All @@ -44,8 +42,6 @@ public static function resolve(int $level, array $availableRules, string $method
$levelRules[] = $availableRules[$i];
}

Assert::allIsAOf($levelRules, RectorInterface::class);

return $levelRules;
}
}
Loading

0 comments on commit 91122f1

Please sign in to comment.