Skip to content

Commit

Permalink
feat: add coding style levels
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-granados committed Jan 26, 2025
1 parent a1170ac commit c76e006
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 58 deletions.
65 changes: 7 additions & 58 deletions config/set/coding-style.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,15 @@

declare(strict_types=1);

use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector;
use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector;
use Rector\CodingStyle\Rector\ClassConst\RemoveFinalFromConstRector;
use Rector\CodingStyle\Rector\ClassConst\SplitGroupedClassConstantsRector;
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector;
use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector;
use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
use Rector\CodingStyle\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector;
use Rector\CodingStyle\Rector\FuncCall\CallUserFuncArrayToVariadicRector;
use Rector\CodingStyle\Rector\FuncCall\CallUserFuncToMethodCallRector;
use Rector\CodingStyle\Rector\FuncCall\ConsistentImplodeRector;
use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
use Rector\CodingStyle\Rector\FuncCall\StrictArraySearchRector;
use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector;
use Rector\CodingStyle\Rector\If_\NullableCompareToNullRector;
use Rector\CodingStyle\Rector\Property\SplitGroupedPropertiesRector;
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
use Rector\CodingStyle\Rector\Stmt\RemoveUselessAliasInUseStatementRector;
use Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector;
use Rector\CodingStyle\Rector\String_\UseClassKeywordForClassNameResolutionRector;
use Rector\CodingStyle\Rector\Ternary\TernaryConditionVariableAssignmentRector;
use Rector\CodingStyle\Rector\Use_\SeparateMultiUseImportsRector;
use Rector\Config\Level\CodingStyleLevel;
use Rector\Config\RectorConfig;
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
use Rector\Transform\Rector\FuncCall\FuncCallToConstFetchRector;
use Rector\Visibility\Rector\ClassMethod\ExplicitPublicClassMethodRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig
->ruleWithConfiguration(FuncCallToConstFetchRector::class, [
'php_sapi_name' => 'PHP_SAPI',
'pi' => 'M_PI',
]);
foreach (CodingStyleLevel::RULES_WITH_CONFIGURATION as $rectorClass => $configuration) {
$rectorConfig->ruleWithConfiguration($rectorClass, $configuration);
}

$rectorConfig->rules([
SeparateMultiUseImportsRector::class,
NewlineAfterStatementRector::class,
RemoveFinalFromConstRector::class,
NullableCompareToNullRector::class,
ConsistentImplodeRector::class,
TernaryConditionVariableAssignmentRector::class,
SymplifyQuoteEscapeRector::class,
StringClassNameToClassConstantRector::class,
CatchExceptionNameMatchingTypeRector::class,
SplitDoubleAssignRector::class,
EncapsedStringsToSprintfRector::class,
WrapEncapsedVariableInCurlyBracesRector::class,
NewlineBeforeNewAssignSetRector::class,
MakeInheritedMethodVisibilitySameAsParentRector::class,
CallUserFuncArrayToVariadicRector::class,
VersionCompareFuncCallToConstantRector::class,
CountArrayToEmptyArrayComparisonRector::class,
CallUserFuncToMethodCallRector::class,
FuncGetArgsToVariadicParamRector::class,
StrictArraySearchRector::class,
UseClassKeywordForClassNameResolutionRector::class,
SplitGroupedPropertiesRector::class,
SplitGroupedClassConstantsRector::class,
ExplicitPublicClassMethodRector::class,
RemoveUselessAliasInUseStatementRector::class,
]);
// the rule order matters, as its used in withCodingStyleLevel() method
// place the safest rules first, follow by more complex ones
$rectorConfig->rules(CodingStyleLevel::RULES);
};
91 changes: 91 additions & 0 deletions src/Config/Level/CodingStyleLevel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

declare(strict_types=1);

namespace Rector\Config\Level;

use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector;
use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector;
use Rector\CodingStyle\Rector\ClassConst\RemoveFinalFromConstRector;
use Rector\CodingStyle\Rector\ClassConst\SplitGroupedClassConstantsRector;
use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector;
use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector;
use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector;
use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
use Rector\CodingStyle\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector;
use Rector\CodingStyle\Rector\FuncCall\CallUserFuncArrayToVariadicRector;
use Rector\CodingStyle\Rector\FuncCall\CallUserFuncToMethodCallRector;
use Rector\CodingStyle\Rector\FuncCall\ConsistentImplodeRector;
use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
use Rector\CodingStyle\Rector\FuncCall\StrictArraySearchRector;
use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector;
use Rector\CodingStyle\Rector\If_\NullableCompareToNullRector;
use Rector\CodingStyle\Rector\Property\SplitGroupedPropertiesRector;
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
use Rector\CodingStyle\Rector\Stmt\RemoveUselessAliasInUseStatementRector;
use Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector;
use Rector\CodingStyle\Rector\String_\UseClassKeywordForClassNameResolutionRector;
use Rector\CodingStyle\Rector\Ternary\TernaryConditionVariableAssignmentRector;
use Rector\CodingStyle\Rector\Use_\SeparateMultiUseImportsRector;
use Rector\Contract\Rector\RectorInterface;
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
use Rector\Transform\Rector\FuncCall\FuncCallToConstFetchRector;
use Rector\Visibility\Rector\ClassMethod\ExplicitPublicClassMethodRector;

/**
* Key 0 = level 0
* Key 50 = level 50
*
* Start at 0, go slowly higher, one level per PR, and improve your rule coverage
*
* From the safest rules to more changing ones.
*
* @experimental This list can change in time, based on community feedback,
* what rules are safer than other. The safest rules will be always in the top.
*/
final class CodingStyleLevel
{
/**
* The rule order matters, as its used in withCodingStyleLevel() method
* Place the safest rules first, followed by more complex ones
*
* @var array<class-string<RectorInterface>>
*/
public const RULES = [
SeparateMultiUseImportsRector::class,
NewlineAfterStatementRector::class,
RemoveFinalFromConstRector::class,
NullableCompareToNullRector::class,
ConsistentImplodeRector::class,
TernaryConditionVariableAssignmentRector::class,
SymplifyQuoteEscapeRector::class,
StringClassNameToClassConstantRector::class,
CatchExceptionNameMatchingTypeRector::class,
SplitDoubleAssignRector::class,
EncapsedStringsToSprintfRector::class,
WrapEncapsedVariableInCurlyBracesRector::class,
NewlineBeforeNewAssignSetRector::class,
MakeInheritedMethodVisibilitySameAsParentRector::class,
CallUserFuncArrayToVariadicRector::class,
VersionCompareFuncCallToConstantRector::class,
CountArrayToEmptyArrayComparisonRector::class,
CallUserFuncToMethodCallRector::class,
FuncGetArgsToVariadicParamRector::class,
StrictArraySearchRector::class,
UseClassKeywordForClassNameResolutionRector::class,
SplitGroupedPropertiesRector::class,
SplitGroupedClassConstantsRector::class,
ExplicitPublicClassMethodRector::class,
RemoveUselessAliasInUseStatementRector::class,
];

/**
* @var array<class-string<RectorInterface>, mixed[]>
*/
public const RULES_WITH_CONFIGURATION = [
FuncCallToConstFetchRector::class => [
'php_sapi_name' => 'PHP_SAPI',
'pi' => 'M_PI',
],
];
}
31 changes: 31 additions & 0 deletions src/Configuration/RectorConfigBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Rector\Caching\Contract\ValueObject\Storage\CacheStorageInterface;
use Rector\Composer\InstalledPackageResolver;
use Rector\Config\Level\CodeQualityLevel;
use Rector\Config\Level\CodingStyleLevel;
use Rector\Config\Level\DeadCodeLevel;
use Rector\Config\Level\TypeDeclarationLevel;
use Rector\Config\RectorConfig;
Expand Down Expand Up @@ -137,6 +138,8 @@ final class RectorConfigBuilder

private ?bool $isCodeQualityLevelUsed = null;

private ?bool $isCodingStyleLevelUsed = null;

private ?bool $isFluentNewLine = null;

/**
Expand Down Expand Up @@ -221,6 +224,13 @@ public function __invoke(RectorConfig $rectorConfig): void
));
}

if (in_array(SetList::CODING_STYLE, $uniqueSets, true) && $this->isCodingStyleLevelUsed === true) {
throw new InvalidConfigurationException(sprintf(
'Your config already enables coding style set.%sRemove "->withCodingStyleLevel()" as it only duplicates it, or remove coding style set.',
PHP_EOL
));
}

if ($uniqueSets !== []) {
$rectorConfig->sets($uniqueSets);
}
Expand Down Expand Up @@ -1010,6 +1020,27 @@ public function withCodeQualityLevel(int $level): self
return $this;
}

/**
* @experimental Raise your coding style from the safest rules
* to more affecting ones, one level at a time
*/
public function withCodingStyleLevel(int $level): self
{
Assert::natural($level);

$this->isCodingStyleLevelUsed = true;

$levelRules = LevelRulesResolver::resolve($level, CodingStyleLevel::RULES, __METHOD__);

$this->rules = array_merge($this->rules, $levelRules);

foreach (CodingStyleLevel::RULES_WITH_CONFIGURATION as $rectorClass => $configuration) {
$this->rulesWithConfigurations[$rectorClass][] = $configuration;
}

return $this;
}

public function withFluentCallNewLine(bool $isFluentNewLine = true): self
{
$this->isFluentNewLine = $isFluentNewLine;
Expand Down

0 comments on commit c76e006

Please sign in to comment.