Move package to 1st position in recipe (#4882)

* add alias

* [recipe] enable set by default, most contributors are core

* move package to 1st place, close to rule name where we think about package

* [ci-review] Rector Rectify

* fix recipe test

Co-authored-by: rector-bot <tomas@getrector.org>
This commit is contained in:
Tomas Votruba 2020-12-14 17:24:33 +01:00 committed by GitHub
parent c5a15d559a
commit a8a0030bf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 60 deletions

View File

@ -27,6 +27,7 @@ final class InitRecipeCommand extends Command
protected function configure(): void protected function configure(): void
{ {
$this->setDescription('[DEV] Initialize "rector-recipe.php" config'); $this->setDescription('[DEV] Initialize "rector-recipe.php" config');
$this->setAliases(['recipe-init']);
} }
protected function execute(InputInterface $input, OutputInterface $output): int protected function execute(InputInterface $input, OutputInterface $output): int

View File

@ -88,6 +88,7 @@ final class RectorRecipe
* @param class-string[] $nodeTypes * @param class-string[] $nodeTypes
*/ */
public function __construct( public function __construct(
string $package,
string $name, string $name,
array $nodeTypes, array $nodeTypes,
string $description, string $description,
@ -96,6 +97,7 @@ final class RectorRecipe
) { ) {
$this->isRectorRepository = file_exists(__DIR__ . '/../../../../vendor'); $this->isRectorRepository = file_exists(__DIR__ . '/../../../../vendor');
$this->setPackage($package);
$this->setName($name); $this->setName($name);
$this->setNodeTypes($nodeTypes); $this->setNodeTypes($nodeTypes);
@ -204,23 +206,6 @@ final class RectorRecipe
return StaticRectorStrings::camelCaseToDashes($this->getPackage()); return StaticRectorStrings::camelCaseToDashes($this->getPackage());
} }
/**
* @api
*/
public function setPackage(string $package): void
{
if (is_file($package)) {
$message = sprintf(
'The "%s()" method only accepts package name, file path "%s" given',
__METHOD__,
$package
);
throw new ShouldNotHappenException($message);
}
$this->package = $package;
}
/** /**
* @api * @api
*/ */
@ -257,6 +242,24 @@ final class RectorRecipe
$this->isRectorRepository = $isRectorRepository; $this->isRectorRepository = $isRectorRepository;
} }
/**
* For tests
* @api
*/
public function setPackage(string $package): void
{
if (is_file($package)) {
$message = sprintf(
'The "%s()" method only accepts package name, file path "%s" given',
__METHOD__,
$package
);
throw new ShouldNotHappenException($message);
}
$this->package = $package;
}
private function setName(string $name): void private function setName(string $name): void
{ {
if (! Strings::endsWith($name, 'Rector')) { if (! Strings::endsWith($name, 'Rector')) {

View File

@ -13,6 +13,7 @@ final class StaticRectorRecipeFactory
public static function createRectorRecipe(bool $isRectorRepository): RectorRecipe public static function createRectorRecipe(bool $isRectorRepository): RectorRecipe
{ {
$rectorRecipe = new RectorRecipe( $rectorRecipe = new RectorRecipe(
'Utils',
'WhateverRector', 'WhateverRector',
[MethodCall::class], [MethodCall::class],
'Change $service->arg(...) to $service->call(...)', 'Change $service->arg(...) to $service->call(...)',

View File

@ -5,13 +5,13 @@ declare(strict_types=1);
namespace Rector\DowngradePhp80\Rector\ClassMethod; namespace Rector\DowngradePhp80\Rector\ClassMethod;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Closure; use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ClosureUse; use PhpParser\Node\Expr\ClosureUse;
use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_; use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Arg;
use PhpParser\Node\Param; use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_; use PhpParser\Node\Stmt\Function_;

View File

@ -20,15 +20,28 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/ */
final class ReflectionExtractorEnableMagicCallExtractorRector extends AbstractRector final class ReflectionExtractorEnableMagicCallExtractorRector extends AbstractRector
{ {
/**
* @var string
*/
private const OLD_OPTION_NAME = 'enable_magic_call_extraction'; private const OLD_OPTION_NAME = 'enable_magic_call_extraction';
/**
* @var string
*/
private const NEW_OPTION_NAME = 'enable_magic_methods_extraction'; private const NEW_OPTION_NAME = 'enable_magic_methods_extraction';
/**
* @var string[]
*/
private const METHODS_WITH_OPTION = ['getWriteInfo', 'getReadInfo']; private const METHODS_WITH_OPTION = ['getWriteInfo', 'getReadInfo'];
public function getRuleDefinition(): RuleDefinition public function getRuleDefinition(): RuleDefinition
{ {
return new RuleDefinition('Migrates from deprecated enable_magic_call_extraction context option in ReflectionExtractor', [ return new RuleDefinition(
new CodeSample( 'Migrates from deprecated enable_magic_call_extraction context option in ReflectionExtractor',
<<<'PHP' [
new CodeSample(
<<<'CODE_SAMPLE'
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
class SomeClass class SomeClass
@ -41,9 +54,9 @@ class SomeClass
]); ]);
} }
} }
PHP CODE_SAMPLE
, ,
<<<'PHP' <<<'CODE_SAMPLE'
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
class SomeClass class SomeClass
@ -56,9 +69,9 @@ class SomeClass
]); ]);
} }
} }
PHP CODE_SAMPLE
), ),
]); ]);
} }
/** /**
@ -93,21 +106,24 @@ PHP
return $node; return $node;
} }
private function prepareEnableMagicMethodsExtractionFlags(bool $enableMagicCallExtractionValue): BitwiseOr private function shouldSkip(MethodCall $methodCall): bool
{ {
$magicGet = $this->createClassConstFetch('Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor', 'MAGIC_GET'); if (! $this->isObjectType($methodCall, 'Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor')) {
$magicSet = $this->createClassConstFetch('Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor', 'MAGIC_SET'); return true;
if (! $enableMagicCallExtractionValue) {
return new BitwiseOr($magicGet, $magicSet);
} }
return new BitwiseOr( if (! $this->isNames($methodCall->name, self::METHODS_WITH_OPTION)) {
new BitwiseOr( return true;
$this->createClassConstFetch('Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor', 'MAGIC_CALL'), }
$magicGet,
), if (count((array) $methodCall->args) < 3) {
$magicSet, return true;
); }
/** @var Array_ $contextOptions */
$contextOptions = $methodCall->args[2]->value;
return $contextOptions->items === [];
} }
private function getContextOptionValue(MethodCall $methodCall): ?bool private function getContextOptionValue(MethodCall $methodCall): ?bool
@ -137,23 +153,29 @@ PHP
return $contextOptionValue; return $contextOptionValue;
} }
private function shouldSkip(MethodCall $methodCall): bool private function prepareEnableMagicMethodsExtractionFlags(bool $enableMagicCallExtractionValue): BitwiseOr
{ {
if (! $this->isObjectType($methodCall, 'Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor')) { $classConstFetch = $this->createClassConstFetch(
return true; 'Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor',
'MAGIC_GET'
);
$magicSet = $this->createClassConstFetch(
'Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor',
'MAGIC_SET'
);
if (! $enableMagicCallExtractionValue) {
return new BitwiseOr($classConstFetch, $magicSet);
} }
if (! $this->isNames($methodCall->name, self::METHODS_WITH_OPTION)) { return new BitwiseOr(
return true; new BitwiseOr(
} $this->createClassConstFetch(
'Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor',
if (count((array) $methodCall->args) < 3) { 'MAGIC_CALL'
return true; ),
} $classConstFetch,
),
/** @var Array_ $contextOptions */ $magicSet,
$contextOptions = $methodCall->args[2]->value; );
return count($contextOptions->items) === 0;
} }
} }

View File

@ -13,6 +13,10 @@ return static function (ContainerConfigurator $containerConfigurator): void {
// [REQUIRED] // [REQUIRED]
$rectorRecipe = new RectorRecipe( $rectorRecipe = new RectorRecipe(
// [RECTOR CORE CONTRIBUTION - REQUIRED]
// package name, basically namespace part in `rules/<package>/src`, use PascalCase
'Naming',
// name, basically short class name; use PascalCase // name, basically short class name; use PascalCase
'RenameMethodCallRector', 'RenameMethodCallRector',
@ -65,12 +69,6 @@ CODE_SAMPLE
// is the rule configurable? add default configuration here // is the rule configurable? add default configuration here
// $rectorRecipe->setConfiguration(['SOME_CONSTANT_KEY' => ['before' => 'after']]); // $rectorRecipe->setConfiguration(['SOME_CONSTANT_KEY' => ['before' => 'after']]);
// [RECTOR CORE CONTRIBUTION]
// [RECTOR CORE CONTRIBUTION - REQUIRED]
// package name, basically part namespace in `rule/<package>/src`, use PascalCase
// $rectorRecipe->setPackage('Generic');
// [RECTOR CORE CONTRIBUTION - OPTIONAL] // [RECTOR CORE CONTRIBUTION - OPTIONAL]
// set the rule belongs to; is optional, because e.g. generic rules don't need a specific set to belong to // set the rule belongs to; is optional, because e.g. generic rules don't need a specific set to belong to
// $rectorRecipe->setSet(\Rector\Set\ValueObject\SetList::NAMING); // $rectorRecipe->setSet(\Rector\Set\ValueObject\SetList::NAMING);