Updated Rector to commit c8c3e82a05436c4c128fd6a5bb2a7207c24a7c53

c8c3e82a05 Move Nette extension from the core to the community (#2746)
This commit is contained in:
Tomas Votruba 2022-08-09 20:03:15 +00:00
parent 8885e287b6
commit 9348cb36bc
78 changed files with 41 additions and 5557 deletions

View File

@ -17,12 +17,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'b9cc90c058942d82f84a68f3d1971b2db6b1601d';
public const PACKAGE_VERSION = 'c8c3e82a05436c4c128fd6a5bb2a7207c24a7c53';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2022-08-09 21:31:52';
public const RELEASE_DATE = '2022-08-09 21:58:33';
/**
* @var int
*/

2
vendor/autoload.php vendored
View File

@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit428bba4eabdf26c6ab915326a9e8aa28::getLoader();
return ComposerAutoloaderInit41fa121b744436092d6f0a792b949afa::getLoader();

View File

@ -2040,57 +2040,6 @@ return array(
'Rector\\Naming\\ValueObject\\VariableAndCallAssign' => $baseDir . '/rules/Naming/ValueObject/VariableAndCallAssign.php',
'Rector\\Naming\\ValueObject\\VariableAndCallForeach' => $baseDir . '/rules/Naming/ValueObject/VariableAndCallForeach.php',
'Rector\\Naming\\VariableRenamer' => $baseDir . '/rules/Naming/VariableRenamer.php',
'Rector\\Nette\\Contract\\Rector\\LatteRectorInterface' => $vendorDir . '/rector/rector-nette/src/Contract/Rector/LatteRectorInterface.php',
'Rector\\Nette\\FileProcessor\\LatteFileProcessor' => $vendorDir . '/rector/rector-nette/src/FileProcessor/LatteFileProcessor.php',
'Rector\\Nette\\Latte\\Parser\\TemplateTypeParser' => $vendorDir . '/rector/rector-nette/src/Latte/Parser/TemplateTypeParser.php',
'Rector\\Nette\\Latte\\Parser\\VarTypeParser' => $vendorDir . '/rector/rector-nette/src/Latte/Parser/VarTypeParser.php',
'Rector\\Nette\\NodeAnalyzer\\ConditionalTemplateAssignReplacer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/ConditionalTemplateAssignReplacer.php',
'Rector\\Nette\\NodeAnalyzer\\MethodCallArgMerger' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/MethodCallArgMerger.php',
'Rector\\Nette\\NodeAnalyzer\\NetteClassAnalyzer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/NetteClassAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\NetteInjectPropertyAnalyzer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/NetteInjectPropertyAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\PregMatchAllAnalyzer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/PregMatchAllAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\PropertyUsageAnalyzer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/PropertyUsageAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\RenderMethodAnalyzer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/RenderMethodAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\ReturnAnalyzer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/ReturnAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\StaticCallAnalyzer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/StaticCallAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\TemplatePropertyAssignCollector' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/TemplatePropertyAssignCollector.php',
'Rector\\Nette\\NodeAnalyzer\\TemplatePropertyParametersReplacer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/TemplatePropertyParametersReplacer.php',
'Rector\\Nette\\NodeAnalyzer\\ThisTemplatePropertyFetchAnalyzer' => $vendorDir . '/rector/rector-nette/src/NodeAnalyzer/ThisTemplatePropertyFetchAnalyzer.php',
'Rector\\Nette\\NodeFactory\\ClassWithPublicPropertiesFactory' => $vendorDir . '/rector/rector-nette/src/NodeFactory/ClassWithPublicPropertiesFactory.php',
'Rector\\Nette\\NodeFactory\\RenderParameterArrayFactory' => $vendorDir . '/rector/rector-nette/src/NodeFactory/RenderParameterArrayFactory.php',
'Rector\\Nette\\NodeFinder\\FormFieldsFinder' => $vendorDir . '/rector/rector-nette/src/NodeFinder/FormFieldsFinder.php',
'Rector\\Nette\\NodeFinder\\FormOnSuccessCallbackFinder' => $vendorDir . '/rector/rector-nette/src/NodeFinder/FormOnSuccessCallbackFinder.php',
'Rector\\Nette\\NodeFinder\\FormOnSuccessCallbackValuesParamFinder' => $vendorDir . '/rector/rector-nette/src/NodeFinder/FormOnSuccessCallbackValuesParamFinder.php',
'Rector\\Nette\\NodeFinder\\FormVariableFinder' => $vendorDir . '/rector/rector-nette/src/NodeFinder/FormVariableFinder.php',
'Rector\\Nette\\NodeFinder\\ParamFinder' => $vendorDir . '/rector/rector-nette/src/NodeFinder/ParamFinder.php',
'Rector\\Nette\\Rector\\ClassMethod\\MergeTemplateSetFileToTemplateRenderRector' => $vendorDir . '/rector/rector-nette/src/Rector/ClassMethod/MergeTemplateSetFileToTemplateRenderRector.php',
'Rector\\Nette\\Rector\\ClassMethod\\RemoveParentAndNameFromComponentConstructorRector' => $vendorDir . '/rector/rector-nette/src/Rector/ClassMethod/RemoveParentAndNameFromComponentConstructorRector.php',
'Rector\\Nette\\Rector\\ClassMethod\\TemplateMagicAssignToExplicitVariableArrayRector' => $vendorDir . '/rector/rector-nette/src/Rector/ClassMethod/TemplateMagicAssignToExplicitVariableArrayRector.php',
'Rector\\Nette\\Rector\\ClassMethod\\TranslateClassMethodToVariadicsRector' => $vendorDir . '/rector/rector-nette/src/Rector/ClassMethod/TranslateClassMethodToVariadicsRector.php',
'Rector\\Nette\\Rector\\Class_\\FormDataRector' => $vendorDir . '/rector/rector-nette/src/Rector/Class_/FormDataRector.php',
'Rector\\Nette\\Rector\\Class_\\LatteVarTypesBasedOnPresenterTemplateParametersRector' => $vendorDir . '/rector/rector-nette/src/Rector/Class_/LatteVarTypesBasedOnPresenterTemplateParametersRector.php',
'Rector\\Nette\\Rector\\Class_\\MoveInjectToExistingConstructorRector' => $vendorDir . '/rector/rector-nette/src/Rector/Class_/MoveInjectToExistingConstructorRector.php',
'Rector\\Nette\\Rector\\Class_\\TemplateTypeBasedOnPresenterTemplateParametersRector' => $vendorDir . '/rector/rector-nette/src/Rector/Class_/TemplateTypeBasedOnPresenterTemplateParametersRector.php',
'Rector\\Nette\\Rector\\FuncCall\\JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector' => $vendorDir . '/rector/rector-nette/src/Rector/FuncCall/JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector.php',
'Rector\\Nette\\Rector\\FuncCall\\PregFunctionToNetteUtilsStringsRector' => $vendorDir . '/rector/rector-nette/src/Rector/FuncCall/PregFunctionToNetteUtilsStringsRector.php',
'Rector\\Nette\\Rector\\FuncCall\\PregMatchFunctionToNetteUtilsStringsRector' => $vendorDir . '/rector/rector-nette/src/Rector/FuncCall/PregMatchFunctionToNetteUtilsStringsRector.php',
'Rector\\Nette\\Rector\\FuncCall\\SubstrStrlenFunctionToNetteUtilsStringsRector' => $vendorDir . '/rector/rector-nette/src/Rector/FuncCall/SubstrStrlenFunctionToNetteUtilsStringsRector.php',
'Rector\\Nette\\Rector\\LNumber\\ReplaceTimeNumberWithDateTimeConstantRector' => $vendorDir . '/rector/rector-nette/src/Rector/LNumber/ReplaceTimeNumberWithDateTimeConstantRector.php',
'Rector\\Nette\\Rector\\Latte\\RenameMethodLatteRector' => $vendorDir . '/rector/rector-nette/src/Rector/Latte/RenameMethodLatteRector.php',
'Rector\\Nette\\Rector\\MethodCall\\BuilderExpandToHelperExpandRector' => $vendorDir . '/rector/rector-nette/src/Rector/MethodCall/BuilderExpandToHelperExpandRector.php',
'Rector\\Nette\\Rector\\MethodCall\\ContextGetByTypeToConstructorInjectionRector' => $vendorDir . '/rector/rector-nette/src/Rector/MethodCall/ContextGetByTypeToConstructorInjectionRector.php',
'Rector\\Nette\\Rector\\MethodCall\\ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector' => $vendorDir . '/rector/rector-nette/src/Rector/MethodCall/ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector.php',
'Rector\\Nette\\Rector\\MethodCall\\MagicHtmlCallToAppendAttributeRector' => $vendorDir . '/rector/rector-nette/src/Rector/MethodCall/MagicHtmlCallToAppendAttributeRector.php',
'Rector\\Nette\\Rector\\MethodCall\\MergeDefaultsInGetConfigCompilerExtensionRector' => $vendorDir . '/rector/rector-nette/src/Rector/MethodCall/MergeDefaultsInGetConfigCompilerExtensionRector.php',
'Rector\\Nette\\Rector\\MethodCall\\RequestGetCookieDefaultArgumentToCoalesceRector' => $vendorDir . '/rector/rector-nette/src/Rector/MethodCall/RequestGetCookieDefaultArgumentToCoalesceRector.php',
'Rector\\Nette\\Rector\\MethodCall\\SetClassWithArgumentToSetFactoryRector' => $vendorDir . '/rector/rector-nette/src/Rector/MethodCall/SetClassWithArgumentToSetFactoryRector.php',
'Rector\\Nette\\Rector\\Property\\NetteInjectToConstructorInjectionRector' => $vendorDir . '/rector/rector-nette/src/Rector/Property/NetteInjectToConstructorInjectionRector.php',
'Rector\\Nette\\Set\\NetteSetList' => $vendorDir . '/rector/rector-nette/src/Set/NetteSetList.php',
'Rector\\Nette\\ValueObject\\AlwaysTemplateParameterAssign' => $vendorDir . '/rector/rector-nette/src/ValueObject/AlwaysTemplateParameterAssign.php',
'Rector\\Nette\\ValueObject\\FormField' => $vendorDir . '/rector/rector-nette/src/ValueObject/FormField.php',
'Rector\\Nette\\ValueObject\\LatteVariableType' => $vendorDir . '/rector/rector-nette/src/ValueObject/LatteVariableType.php',
'Rector\\Nette\\ValueObject\\ParameterAssign' => $vendorDir . '/rector/rector-nette/src/ValueObject/ParameterAssign.php',
'Rector\\Nette\\ValueObject\\TemplateParametersAssigns' => $vendorDir . '/rector/rector-nette/src/ValueObject/TemplateParametersAssigns.php',
'Rector\\NodeCollector\\BinaryOpConditionsCollector' => $baseDir . '/packages/NodeCollector/BinaryOpConditionsCollector.php',
'Rector\\NodeCollector\\BinaryOpTreeRootLocator' => $baseDir . '/packages/NodeCollector/BinaryOpTreeRootLocator.php',
'Rector\\NodeCollector\\NodeAnalyzer\\ArrayCallableMethodMatcher' => $baseDir . '/packages/NodeCollector/NodeAnalyzer/ArrayCallableMethodMatcher.php',

View File

@ -16,7 +16,6 @@ return array(
'Rector\\RectorGenerator\\' => array($vendorDir . '/rector/rector-generator/src'),
'Rector\\PHPUnit\\' => array($vendorDir . '/rector/rector-phpunit/src'),
'Rector\\PHPOffice\\' => array($vendorDir . '/rector/rector-phpoffice/src'),
'Rector\\Nette\\' => array($vendorDir . '/rector/rector-nette/src'),
'Rector\\Laravel\\' => array($vendorDir . '/rector/rector-laravel/src'),
'Rector\\Doctrine\\' => array($vendorDir . '/rector/rector-doctrine/src'),
'Rector\\Core\\' => array($baseDir . '/src'),

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit428bba4eabdf26c6ab915326a9e8aa28
class ComposerAutoloaderInit41fa121b744436092d6f0a792b949afa
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInit428bba4eabdf26c6ab915326a9e8aa28
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit428bba4eabdf26c6ab915326a9e8aa28', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit41fa121b744436092d6f0a792b949afa', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit428bba4eabdf26c6ab915326a9e8aa28', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit41fa121b744436092d6f0a792b949afa', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit41fa121b744436092d6f0a792b949afa::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInit41fa121b744436092d6f0a792b949afa::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire428bba4eabdf26c6ab915326a9e8aa28($fileIdentifier, $file);
composerRequire41fa121b744436092d6f0a792b949afa($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInit428bba4eabdf26c6ab915326a9e8aa28
* @param string $file
* @return void
*/
function composerRequire428bba4eabdf26c6ab915326a9e8aa28($fileIdentifier, $file)
function composerRequire41fa121b744436092d6f0a792b949afa($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28
class ComposerStaticInit41fa121b744436092d6f0a792b949afa
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@ -35,7 +35,6 @@ class ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28
'Rector\\RectorGenerator\\' => 23,
'Rector\\PHPUnit\\' => 15,
'Rector\\PHPOffice\\' => 17,
'Rector\\Nette\\' => 13,
'Rector\\Laravel\\' => 15,
'Rector\\Doctrine\\' => 16,
'Rector\\Core\\' => 12,
@ -127,10 +126,6 @@ class ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28
array (
0 => __DIR__ . '/..' . '/rector/rector-phpoffice/src',
),
'Rector\\Nette\\' =>
array (
0 => __DIR__ . '/..' . '/rector/rector-nette/src',
),
'Rector\\Laravel\\' =>
array (
0 => __DIR__ . '/..' . '/rector/rector-laravel/src',
@ -2346,57 +2341,6 @@ class ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28
'Rector\\Naming\\ValueObject\\VariableAndCallAssign' => __DIR__ . '/../..' . '/rules/Naming/ValueObject/VariableAndCallAssign.php',
'Rector\\Naming\\ValueObject\\VariableAndCallForeach' => __DIR__ . '/../..' . '/rules/Naming/ValueObject/VariableAndCallForeach.php',
'Rector\\Naming\\VariableRenamer' => __DIR__ . '/../..' . '/rules/Naming/VariableRenamer.php',
'Rector\\Nette\\Contract\\Rector\\LatteRectorInterface' => __DIR__ . '/..' . '/rector/rector-nette/src/Contract/Rector/LatteRectorInterface.php',
'Rector\\Nette\\FileProcessor\\LatteFileProcessor' => __DIR__ . '/..' . '/rector/rector-nette/src/FileProcessor/LatteFileProcessor.php',
'Rector\\Nette\\Latte\\Parser\\TemplateTypeParser' => __DIR__ . '/..' . '/rector/rector-nette/src/Latte/Parser/TemplateTypeParser.php',
'Rector\\Nette\\Latte\\Parser\\VarTypeParser' => __DIR__ . '/..' . '/rector/rector-nette/src/Latte/Parser/VarTypeParser.php',
'Rector\\Nette\\NodeAnalyzer\\ConditionalTemplateAssignReplacer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/ConditionalTemplateAssignReplacer.php',
'Rector\\Nette\\NodeAnalyzer\\MethodCallArgMerger' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/MethodCallArgMerger.php',
'Rector\\Nette\\NodeAnalyzer\\NetteClassAnalyzer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/NetteClassAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\NetteInjectPropertyAnalyzer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/NetteInjectPropertyAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\PregMatchAllAnalyzer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/PregMatchAllAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\PropertyUsageAnalyzer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/PropertyUsageAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\RenderMethodAnalyzer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/RenderMethodAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\ReturnAnalyzer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/ReturnAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\StaticCallAnalyzer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/StaticCallAnalyzer.php',
'Rector\\Nette\\NodeAnalyzer\\TemplatePropertyAssignCollector' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/TemplatePropertyAssignCollector.php',
'Rector\\Nette\\NodeAnalyzer\\TemplatePropertyParametersReplacer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/TemplatePropertyParametersReplacer.php',
'Rector\\Nette\\NodeAnalyzer\\ThisTemplatePropertyFetchAnalyzer' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeAnalyzer/ThisTemplatePropertyFetchAnalyzer.php',
'Rector\\Nette\\NodeFactory\\ClassWithPublicPropertiesFactory' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeFactory/ClassWithPublicPropertiesFactory.php',
'Rector\\Nette\\NodeFactory\\RenderParameterArrayFactory' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeFactory/RenderParameterArrayFactory.php',
'Rector\\Nette\\NodeFinder\\FormFieldsFinder' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeFinder/FormFieldsFinder.php',
'Rector\\Nette\\NodeFinder\\FormOnSuccessCallbackFinder' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeFinder/FormOnSuccessCallbackFinder.php',
'Rector\\Nette\\NodeFinder\\FormOnSuccessCallbackValuesParamFinder' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeFinder/FormOnSuccessCallbackValuesParamFinder.php',
'Rector\\Nette\\NodeFinder\\FormVariableFinder' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeFinder/FormVariableFinder.php',
'Rector\\Nette\\NodeFinder\\ParamFinder' => __DIR__ . '/..' . '/rector/rector-nette/src/NodeFinder/ParamFinder.php',
'Rector\\Nette\\Rector\\ClassMethod\\MergeTemplateSetFileToTemplateRenderRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/ClassMethod/MergeTemplateSetFileToTemplateRenderRector.php',
'Rector\\Nette\\Rector\\ClassMethod\\RemoveParentAndNameFromComponentConstructorRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/ClassMethod/RemoveParentAndNameFromComponentConstructorRector.php',
'Rector\\Nette\\Rector\\ClassMethod\\TemplateMagicAssignToExplicitVariableArrayRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/ClassMethod/TemplateMagicAssignToExplicitVariableArrayRector.php',
'Rector\\Nette\\Rector\\ClassMethod\\TranslateClassMethodToVariadicsRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/ClassMethod/TranslateClassMethodToVariadicsRector.php',
'Rector\\Nette\\Rector\\Class_\\FormDataRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/Class_/FormDataRector.php',
'Rector\\Nette\\Rector\\Class_\\LatteVarTypesBasedOnPresenterTemplateParametersRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/Class_/LatteVarTypesBasedOnPresenterTemplateParametersRector.php',
'Rector\\Nette\\Rector\\Class_\\MoveInjectToExistingConstructorRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/Class_/MoveInjectToExistingConstructorRector.php',
'Rector\\Nette\\Rector\\Class_\\TemplateTypeBasedOnPresenterTemplateParametersRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/Class_/TemplateTypeBasedOnPresenterTemplateParametersRector.php',
'Rector\\Nette\\Rector\\FuncCall\\JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/FuncCall/JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector.php',
'Rector\\Nette\\Rector\\FuncCall\\PregFunctionToNetteUtilsStringsRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/FuncCall/PregFunctionToNetteUtilsStringsRector.php',
'Rector\\Nette\\Rector\\FuncCall\\PregMatchFunctionToNetteUtilsStringsRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/FuncCall/PregMatchFunctionToNetteUtilsStringsRector.php',
'Rector\\Nette\\Rector\\FuncCall\\SubstrStrlenFunctionToNetteUtilsStringsRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/FuncCall/SubstrStrlenFunctionToNetteUtilsStringsRector.php',
'Rector\\Nette\\Rector\\LNumber\\ReplaceTimeNumberWithDateTimeConstantRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/LNumber/ReplaceTimeNumberWithDateTimeConstantRector.php',
'Rector\\Nette\\Rector\\Latte\\RenameMethodLatteRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/Latte/RenameMethodLatteRector.php',
'Rector\\Nette\\Rector\\MethodCall\\BuilderExpandToHelperExpandRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/MethodCall/BuilderExpandToHelperExpandRector.php',
'Rector\\Nette\\Rector\\MethodCall\\ContextGetByTypeToConstructorInjectionRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/MethodCall/ContextGetByTypeToConstructorInjectionRector.php',
'Rector\\Nette\\Rector\\MethodCall\\ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/MethodCall/ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector.php',
'Rector\\Nette\\Rector\\MethodCall\\MagicHtmlCallToAppendAttributeRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/MethodCall/MagicHtmlCallToAppendAttributeRector.php',
'Rector\\Nette\\Rector\\MethodCall\\MergeDefaultsInGetConfigCompilerExtensionRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/MethodCall/MergeDefaultsInGetConfigCompilerExtensionRector.php',
'Rector\\Nette\\Rector\\MethodCall\\RequestGetCookieDefaultArgumentToCoalesceRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/MethodCall/RequestGetCookieDefaultArgumentToCoalesceRector.php',
'Rector\\Nette\\Rector\\MethodCall\\SetClassWithArgumentToSetFactoryRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/MethodCall/SetClassWithArgumentToSetFactoryRector.php',
'Rector\\Nette\\Rector\\Property\\NetteInjectToConstructorInjectionRector' => __DIR__ . '/..' . '/rector/rector-nette/src/Rector/Property/NetteInjectToConstructorInjectionRector.php',
'Rector\\Nette\\Set\\NetteSetList' => __DIR__ . '/..' . '/rector/rector-nette/src/Set/NetteSetList.php',
'Rector\\Nette\\ValueObject\\AlwaysTemplateParameterAssign' => __DIR__ . '/..' . '/rector/rector-nette/src/ValueObject/AlwaysTemplateParameterAssign.php',
'Rector\\Nette\\ValueObject\\FormField' => __DIR__ . '/..' . '/rector/rector-nette/src/ValueObject/FormField.php',
'Rector\\Nette\\ValueObject\\LatteVariableType' => __DIR__ . '/..' . '/rector/rector-nette/src/ValueObject/LatteVariableType.php',
'Rector\\Nette\\ValueObject\\ParameterAssign' => __DIR__ . '/..' . '/rector/rector-nette/src/ValueObject/ParameterAssign.php',
'Rector\\Nette\\ValueObject\\TemplateParametersAssigns' => __DIR__ . '/..' . '/rector/rector-nette/src/ValueObject/TemplateParametersAssigns.php',
'Rector\\NodeCollector\\BinaryOpConditionsCollector' => __DIR__ . '/../..' . '/packages/NodeCollector/BinaryOpConditionsCollector.php',
'Rector\\NodeCollector\\BinaryOpTreeRootLocator' => __DIR__ . '/../..' . '/packages/NodeCollector/BinaryOpTreeRootLocator.php',
'Rector\\NodeCollector\\NodeAnalyzer\\ArrayCallableMethodMatcher' => __DIR__ . '/../..' . '/packages/NodeCollector/NodeAnalyzer/ArrayCallableMethodMatcher.php',
@ -3306,9 +3250,9 @@ class ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit428bba4eabdf26c6ab915326a9e8aa28::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit41fa121b744436092d6f0a792b949afa::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit41fa121b744436092d6f0a792b949afa::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit41fa121b744436092d6f0a792b949afa::$classMap;
}, null, ClassLoader::class);
}

View File

@ -2123,75 +2123,6 @@
},
"install-path": "..\/rector\/rector-laravel"
},
{
"name": "rector\/rector-nette",
"version": "dev-main",
"version_normalized": "dev-main",
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-nette.git",
"reference": "0e8e9338c52b5b1a8a8dc1fc6dcd641e02a2f443"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-nette\/zipball\/0e8e9338c52b5b1a8a8dc1fc6dcd641e02a2f443",
"reference": "0e8e9338c52b5b1a8a8dc1fc6dcd641e02a2f443",
"shasum": ""
},
"require": {
"php": ">=8.0",
"rector\/rector": "^0.13.8"
},
"require-dev": {
"nette\/application": "^3.1",
"nette\/di": "^3.0",
"nette\/forms": "3.0.*",
"phpstan\/extension-installer": "^1.1",
"phpstan\/phpstan": "^1.8",
"phpstan\/phpstan-nette": "^1.0",
"phpstan\/phpstan-strict-rules": "^1.3",
"phpstan\/phpstan-webmozart-assert": "^1.2",
"phpunit\/phpunit": "^9.5",
"rector\/phpstan-rules": "^0.5.12",
"symplify\/easy-ci": "^11.1",
"symplify\/easy-coding-standard": "^11.1",
"symplify\/monorepo-builder": "^11.1",
"symplify\/phpstan-extensions": "^11.1",
"symplify\/phpstan-rules": "^11.1.2",
"symplify\/rule-doc-generator": "^11.1",
"symplify\/vendor-patches": "^11.1"
},
"time": "2022-08-09T10:12:59+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {
"enable-patching": true,
"branch-alias": {
"dev-main": "0.11-dev"
},
"rector": {
"includes": [
"config\/config.php"
]
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Rector\\Nette\\": "src"
}
},
"notification-url": "https:\/\/packagist.org\/downloads\/",
"license": [
"MIT"
],
"description": "Rector upgrades rules for Nette Framework",
"support": {
"issues": "https:\/\/github.com\/rectorphp\/rector-nette\/issues",
"source": "https:\/\/github.com\/rectorphp\/rector-nette\/tree\/main"
},
"install-path": "..\/rector\/rector-nette"
},
{
"name": "rector\/rector-phpoffice",
"version": "dev-main",
@ -2266,12 +2197,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-phpunit.git",
"reference": "c4caecafa38f3d6f09147f2f07700a44c4e099f1"
"reference": "528d3135a2e565220a7e0b8fc85132e772693026"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-phpunit\/zipball\/c4caecafa38f3d6f09147f2f07700a44c4e099f1",
"reference": "c4caecafa38f3d6f09147f2f07700a44c4e099f1",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-phpunit\/zipball\/528d3135a2e565220a7e0b8fc85132e772693026",
"reference": "528d3135a2e565220a7e0b8fc85132e772693026",
"shasum": ""
},
"require": {
@ -2296,7 +2227,7 @@
"symplify\/rule-doc-generator": "^11.0",
"symplify\/vendor-patches": "^11.0"
},
"time": "2022-08-09T13:51:17+00:00",
"time": "2022-08-09T19:43:15+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {
@ -2323,7 +2254,7 @@
"description": "Rector upgrades rules for PHPUnit",
"support": {
"issues": "https:\/\/github.com\/rectorphp\/rector-phpunit\/issues",
"source": "https:\/\/github.com\/rectorphp\/rector-phpunit\/tree\/main"
"source": "https:\/\/github.com\/rectorphp\/rector-phpunit\/tree\/0.13.4"
},
"install-path": "..\/rector\/rector-phpunit"
},

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
*/
final class GeneratedConfig
{
public const EXTENSIONS = array('rector/rector-cakephp' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-cakephp', 'relative_install_path' => '../../rector-cakephp', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main c2ec06c'), 'rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main d6ae1b1'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 7ee4e58'), 'rector/rector-generator' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-generator', 'relative_install_path' => '../../rector-generator', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 38440b9'), 'rector/rector-laravel' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-laravel', 'relative_install_path' => '../../rector-laravel', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 1712a30'), 'rector/rector-nette' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-nette', 'relative_install_path' => '../../rector-nette', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 0e8e933'), 'rector/rector-phpoffice' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpoffice', 'relative_install_path' => '../../rector-phpoffice', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main ad7cfce'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main c4caeca'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main f88fb13'));
public const EXTENSIONS = array('rector/rector-cakephp' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-cakephp', 'relative_install_path' => '../../rector-cakephp', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main c2ec06c'), 'rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main d6ae1b1'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 7ee4e58'), 'rector/rector-generator' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-generator', 'relative_install_path' => '../../rector-generator', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 38440b9'), 'rector/rector-laravel' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-laravel', 'relative_install_path' => '../../rector-laravel', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 1712a30'), 'rector/rector-phpoffice' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpoffice', 'relative_install_path' => '../../rector-phpoffice', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main ad7cfce'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 528d313'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main f88fb13'));
private function __construct()
{
}

View File

@ -1,25 +0,0 @@
The MIT License
---------------
Copyright (c) 2017-present Tomáš Votruba (https://tomasvotruba.cz)
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,37 +0,0 @@
# Rector Rules for Nette
See available [Nette rules](/docs/rector_rules_overview.md)
## Install
This package is a Rector extension developed by community around Nette. To add it, install package as dependency:
```bash
composer require <todo>/rector-nette --dev
```
## Use Sets
To add a set to your config, use `Rector\Nette\Set\NetteSetList` class and pick one of constants:
```php
use Rector\Nette\Set\NetteSetList;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([
NetteSetList::NETTE_24,
]);
};
```
<br>
## Learn Rector Faster
Rector is a tool that [we develop](https://getrector.org/) and share for free, so anyone can save hundreds of hours on refactoring. But not everyone has time to understand Rector and AST complexity. You have 2 ways to speed this process up:
* read a book - <a href="https://leanpub.com/rector-the-power-of-automated-refactoring">The Power of Automated Refactoring</a>
* hire our experienced team to <a href="https://getrector.org/contact">improve your code base</a>
Both ways support us to and improve Rector in sustainable way by learning from practical projects.

View File

@ -1,72 +0,0 @@
{
"name": "rector\/rector-nette",
"type": "rector-extension",
"license": "MIT",
"description": "Rector upgrades rules for Nette Framework",
"require": {
"php": ">=8.0",
"rector\/rector": "^0.13.8"
},
"require-dev": {
"phpunit\/phpunit": "^9.5",
"symplify\/phpstan-extensions": "^11.1",
"rector\/phpstan-rules": "^0.5.12",
"symplify\/phpstan-rules": "^11.1.2",
"symplify\/easy-coding-standard": "^11.1",
"symplify\/monorepo-builder": "^11.1",
"phpstan\/phpstan": "^1.8",
"phpstan\/phpstan-nette": "^1.0",
"nette\/application": "^3.1",
"nette\/di": "^3.0",
"nette\/forms": "3.0.*",
"symplify\/rule-doc-generator": "^11.1",
"phpstan\/extension-installer": "^1.1",
"phpstan\/phpstan-webmozart-assert": "^1.2",
"phpstan\/phpstan-strict-rules": "^1.3",
"symplify\/vendor-patches": "^11.1",
"symplify\/easy-ci": "^11.1"
},
"autoload": {
"psr-4": {
"Rector\\Nette\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Rector\\Nette\\Tests\\": "tests"
},
"classmap": [
"stubs"
]
},
"scripts": {
"release": "vendor\/bin\/monorepo-builder release patch --ansi",
"phpstan": "vendor\/bin\/phpstan analyse --ansi --error-format symplify",
"check-cs": "vendor\/bin\/ecs check --ansi",
"fix-cs": "vendor\/bin\/ecs check --fix --ansi",
"docs": [
"vendor\/bin\/rule-doc-generator generate src --output-file docs\/rector_rules_overview.md --ansi",
"vendor\/bin\/ecs check-markdown docs\/rector_rules_overview.md --ansi --fix"
]
},
"extra": {
"enable-patching": true,
"branch-alias": {
"dev-main": "0.11-dev"
},
"rector": {
"includes": [
"config\/config.php"
]
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"allow-plugins": {
"cweagans\/composer-patches": true,
"rector\/extension-installer": true,
"phpstan\/extension-installer": true
}
}
}

View File

@ -1,15 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use Rector\Config\RectorConfig;
use Rector\Core\NonPhpFile\Rector\RenameClassNonPhpRector;
use Rector\Nette\Rector\Latte\RenameMethodLatteRector;
return static function (RectorConfig $rectorConfig) : void {
$services = $rectorConfig->services();
$services->defaults()->public()->autowire()->autoconfigure();
$services->load('Rector\\Nette\\', __DIR__ . '/../src')->exclude([__DIR__ . '/../src/Contract', __DIR__ . '/../src/Rector', __DIR__ . '/../src/ValueObject', __DIR__ . '/../src/Kdyby/Rector', __DIR__ . '/../src/Kdyby/ValueObject']);
$rectorConfig->rule(RenameClassNonPhpRector::class);
$rectorConfig->rule(RenameMethodLatteRector::class);
};

View File

@ -1,12 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use Rector\Config\RectorConfig;
use Rector\Transform\Rector\Class_\ParentClassToTraitsRector;
use Rector\Transform\ValueObject\ParentClassToTraits;
// @see https://doc.nette.org/en/2.4/migration-2-4#toc-nette-smartobject
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->ruleWithConfiguration(ParentClassToTraitsRector::class, [new ParentClassToTraits('Nette\\Object', ['Nette\\SmartObject'])]);
};

View File

@ -1,61 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use Rector\Arguments\Rector\ClassMethod\ReplaceArgumentDefaultValueRector;
use Rector\Arguments\ValueObject\ReplaceArgumentDefaultValue;
use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector;
use Rector\Nette\Rector\ClassMethod\RemoveParentAndNameFromComponentConstructorRector;
use Rector\Nette\Rector\MethodCall\ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector;
use Rector\Nette\Rector\MethodCall\MagicHtmlCallToAppendAttributeRector;
use Rector\Nette\Rector\MethodCall\MergeDefaultsInGetConfigCompilerExtensionRector;
use Rector\Nette\Rector\MethodCall\RequestGetCookieDefaultArgumentToCoalesceRector;
use Rector\Renaming\Rector\ClassConstFetch\RenameClassConstFetchRector;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Renaming\ValueObject\MethodCallRename;
use Rector\Renaming\ValueObject\RenameClassConstFetch;
use Rector\Transform\Rector\StaticCall\StaticCallToMethodCallRector;
use Rector\Transform\ValueObject\StaticCallToMethodCall;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->sets([__DIR__ . '/nette-30/nette-30-composer.php', __DIR__ . '/nette-30/nette-30-dependency-injection.php', __DIR__ . '/nette-30/nette-30-return-types.php', __DIR__ . '/nette-30/nette-30-param-types.php']);
$rectorConfig->rule(MergeDefaultsInGetConfigCompilerExtensionRector::class);
// Control class has remove __construct(), e.g. https://github.com/Pixidos/GPWebPay/pull/16/files#diff-fdc8251950f85c5467c63c249df05786
$rectorConfig->rule(RemoveParentCallWithoutParentRector::class);
$rectorConfig->ruleWithConfiguration(StaticCallToMethodCallRector::class, [new StaticCallToMethodCall('Nette\\Security\\Passwords', 'hash', 'Nette\\Security\\Passwords', 'hash'), new StaticCallToMethodCall('Nette\\Security\\Passwords', 'verify', 'Nette\\Security\\Passwords', 'verify'), new StaticCallToMethodCall('Nette\\Security\\Passwords', 'needsRehash', 'Nette\\Security\\Passwords', 'needsRehash')]);
// https://github.com/contributte/event-dispatcher-extra/tree/v0.4.3 and higher
$rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [new RenameClassConstFetch('Contributte\\Events\\Extra\\Event\\Security\\LoggedInEvent', 'NAME', 'class'), new RenameClassConstFetch('Contributte\\Events\\Extra\\Event\\Security\\LoggedOutEvent', 'NAME', 'class'), new RenameClassConstFetch('Contributte\\Events\\Extra\\Event\\Application\\ShutdownEvent', 'NAME', 'class')]);
$rectorConfig->ruleWithConfiguration(RenameClassRector::class, [
# nextras/forms was split into 2 packages
'Nextras\\FormComponents\\Controls\\DatePicker' => 'Nextras\\FormComponents\\Controls\\DateControl',
# @see https://github.com/nette/di/commit/a0d361192f8ac35f1d9f82aab7eb351e4be395ea
'Nette\\DI\\ServiceDefinition' => 'Nette\\DI\\Definitions\\ServiceDefinition',
'Nette\\DI\\Statement' => 'Nette\\DI\\Definitions\\Statement',
'WebChemistry\\Forms\\Controls\\Multiplier' => 'Contributte\\FormMultiplier\\Multiplier',
]);
$rectorConfig->ruleWithConfiguration(ReplaceArgumentDefaultValueRector::class, [
// json 2nd argument is now `int` typed
new ReplaceArgumentDefaultValue('Nette\\Utils\\Json', 'decode', 1, \true, 'Nette\\Utils\\Json::FORCE_ARRAY'),
// @see https://github.com/nette/forms/commit/574b97f9d5e7a902a224e57d7d584e7afc9fefec
new ReplaceArgumentDefaultValue('Nette\\Forms\\Form', 'decode', 0, \true, 'array'),
]);
$rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [
// see https://github.com/nette/forms/commit/b99385aa9d24d729a18f6397a414ea88eab6895a
new MethodCallRename('Nette\\Forms\\Controls\\BaseControl', 'setType', 'setHtmlType'),
new MethodCallRename('Nette\\Forms\\Controls\\BaseControl', 'setAttribute', 'setHtmlAttribute'),
new MethodCallRename(
'Nette\\DI\\Definitions\\ServiceDefinition',
# see https://github.com/nette/di/commit/1705a5db431423fc610a6f339f88dead1b5dc4fb
'setClass',
'setType'
),
new MethodCallRename('Nette\\DI\\Definitions\\ServiceDefinition', 'getClass', 'getType'),
new MethodCallRename('Nette\\DI\\Definitions\\Definition', 'isAutowired', 'getAutowired'),
]);
$rectorConfig->rule(MagicHtmlCallToAppendAttributeRector::class);
$rectorConfig->rule(RequestGetCookieDefaultArgumentToCoalesceRector::class);
$rectorConfig->rule(RemoveParentAndNameFromComponentConstructorRector::class);
$rectorConfig->rule(ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector::class);
};

View File

@ -1,47 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use Rector\Composer\Rector\ChangePackageVersionComposerRector;
use Rector\Composer\Rector\RemovePackageComposerRector;
use Rector\Composer\Rector\ReplacePackageAndVersionComposerRector;
use Rector\Composer\ValueObject\PackageAndVersion;
use Rector\Composer\ValueObject\ReplacePackageAndVersion;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->ruleWithConfiguration(ChangePackageVersionComposerRector::class, [
new PackageAndVersion('nette/nette', '^3.0'),
// https://github.com/nette/nette/blob/v2.4.0/composer.json vs https://github.com/nette/nette/blob/v3.0.0/composer.json
// older versions have security issues
new PackageAndVersion('nette/application', '^3.0.6'),
new PackageAndVersion('nette/bootstrap', '^3.0'),
new PackageAndVersion('nette/caching', '^3.0'),
new PackageAndVersion('nette/component-model', '^3.0'),
new PackageAndVersion('nette/database', '^3.0'),
new PackageAndVersion('nette/di', '^3.0'),
new PackageAndVersion('nette/finder', '^2.5'),
new PackageAndVersion('nette/forms', '^3.0'),
new PackageAndVersion('nette/http', '^3.0'),
new PackageAndVersion('nette/mail', '^3.0'),
new PackageAndVersion('nette/neon', '^3.0'),
new PackageAndVersion('nette/php-generator', '^3.0'),
new PackageAndVersion('nette/robot-loader', '^3.0'),
new PackageAndVersion('nette/safe-stream', '^2.4'),
new PackageAndVersion('nette/security', '^3.0'),
new PackageAndVersion('nette/tokenizer', '^3.0'),
new PackageAndVersion('nette/utils', '^3.0'),
new PackageAndVersion('latte/latte', '^2.5'),
new PackageAndVersion('tracy/tracy', '^2.6'),
// contributte packages
new PackageAndVersion('contributte/event-dispatcher-extra', '^0.8'),
new PackageAndVersion('contributte/forms-multiplier', '3.1.x-dev'),
// other packages
new PackageAndVersion('radekdostal/nette-datetimepicker', '^3.0'),
]);
$rectorConfig->ruleWithConfiguration(RemovePackageComposerRector::class, ['nette/deprecated', 'nette/reflection']);
$rectorConfig->ruleWithConfiguration(ReplacePackageAndVersionComposerRector::class, [
// webchemistry to contributte
new ReplacePackageAndVersion('webchemistry/forms-multiplier', 'contributte/forms-multiplier', '3.1.x-dev'),
]);
};

View File

@ -1,12 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use Rector\Config\RectorConfig;
use Rector\Nette\Rector\MethodCall\BuilderExpandToHelperExpandRector;
use Rector\Nette\Rector\MethodCall\SetClassWithArgumentToSetFactoryRector;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rule(SetClassWithArgumentToSetFactoryRector::class);
$rectorConfig->rule(BuilderExpandToHelperExpandRector::class);
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,123 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use PHPStan\Type\NullType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\UnionType;
use Rector\Composer\Rector\ChangePackageVersionComposerRector;
use Rector\Composer\Rector\RemovePackageComposerRector;
use Rector\Composer\ValueObject\PackageAndVersion;
use Rector\Config\RectorConfig;
use Rector\Nette\Rector\MethodCall\ContextGetByTypeToConstructorInjectionRector;
use Rector\Nette\Set\NetteSetList;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Renaming\Rector\StaticCall\RenameStaticMethodRector;
use Rector\Renaming\ValueObject\MethodCallRename;
use Rector\Renaming\ValueObject\RenameStaticMethod;
use Rector\Transform\Rector\Assign\DimFetchAssignToMethodCallRector;
use Rector\Transform\Rector\Assign\PropertyFetchToMethodCallRector;
use Rector\Transform\ValueObject\DimFetchAssignToMethodCall;
use Rector\Transform\ValueObject\PropertyFetchToMethodCall;
use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeDeclarationRector;
use Rector\TypeDeclaration\ValueObject\AddParamTypeDeclaration;
return static function (RectorConfig $rectorConfig) : void {
// forms 3.1
$rectorConfig->ruleWithConfiguration(PropertyFetchToMethodCallRector::class, [new PropertyFetchToMethodCall('Nette\\Application\\UI\\Form', 'values', 'getValues')]);
// some attributes were added in nette 3.0, but only in one of latest patch versions; it's is safer to add them in 3.1
$rectorConfig->sets([NetteSetList::ANNOTATIONS_TO_ATTRIBUTES]);
$rectorConfig->ruleWithConfiguration(RenameClassRector::class, [
'Nette\\Bridges\\ApplicationLatte\\Template' => 'Nette\\Bridges\\ApplicationLatte\\DefaultTemplate',
// https://github.com/nette/application/compare/v3.0.7...v3.1.0
'Nette\\Application\\IRouter' => 'Nette\\Routing\\Router',
'Nette\\Application\\IResponse' => 'Nette\\Application\\Response',
'Nette\\Application\\UI\\IRenderable' => 'Nette\\Application\\UI\\Renderable',
'Nette\\Application\\UI\\ISignalReceiver' => 'Nette\\Application\\UI\\SignalReceiver',
'Nette\\Application\\UI\\IStatePersistent' => 'Nette\\Application\\UI\\StatePersistent',
'Nette\\Application\\UI\\ITemplate' => 'Nette\\Application\\UI\\Template',
'Nette\\Application\\UI\\ITemplateFactory' => 'Nette\\Application\\UI\\TemplateFactory',
'Nette\\Bridges\\ApplicationLatte\\ILatteFactory' => 'Nette\\Bridges\\ApplicationLatte\\LatteFactory',
// https://github.com/nette/bootstrap/compare/v3.0.2...v3.1.0
'Nette\\Configurator' => 'Nette\\Bootstrap\\Configurator',
// https://github.com/nette/caching/compare/v3.0.2...v3.1.0
'Nette\\Caching\\IBulkReader' => 'Nette\\Caching\\BulkReader',
'Nette\\Caching\\IStorage' => 'Nette\\Caching\\Storage',
'Nette\\Caching\\Storages\\IJournal' => 'Nette\\Caching\\Storages\\Journal',
// https://github.com/nette/database/compare/v3.0.7...v3.1.1
'Nette\\Database\\ISupplementalDriver' => 'Nette\\Database\\Driver',
'Nette\\Database\\IConventions' => 'Nette\\Database\\Conventions',
'Nette\\Database\\Context' => 'Nette\\Database\\Explorer',
'Nette\\Database\\IRow' => 'Nette\\Database\\Row',
'Nette\\Database\\IRowContainer' => 'Nette\\Database\\ResultSet',
'Nette\\Database\\Table\\IRow' => 'Nette\\Database\\Table\\ActiveRow',
'Nette\\Database\\Table\\IRowContainer' => 'Nette\\Database\\Table\\Selection',
// https://github.com/nette/forms/compare/v3.0.7...v3.1.0-RC2
'Nette\\Forms\\IControl' => 'Nette\\Forms\\Control',
'Nette\\Forms\\IFormRenderer' => 'Nette\\Forms\\FormRenderer',
'Nette\\Forms\\ISubmitterControl' => 'Nette\\Forms\\SubmitterControl',
// https://github.com/nette/mail/compare/v3.0.1...v3.1.5
'Nette\\Mail\\IMailer' => 'Nette\\Mail\\Mailer',
// https://github.com/nette/security/compare/v3.0.5...v3.1.2
'Nette\\Security\\IAuthorizator' => 'Nette\\Security\\Authorizator',
'Nette\\Security\\Identity' => 'Nette\\Security\\SimpleIdentity',
'Nette\\Security\\IResource' => 'Nette\\Security\\Resource',
'Nette\\Security\\IRole' => 'Nette\\Security\\Role',
// https://github.com/nette/utils/compare/v3.1.4...v3.2.1
'Nette\\Utils\\IHtmlString' => 'Nette\\HtmlStringable',
'Nette\\Localization\\ITranslator' => 'Nette\\Localization\\Translator',
// https://github.com/nette/latte/compare/v2.5.5...v2.9.2
'Latte\\ILoader' => 'Latte\\Loader',
'Latte\\IMacro' => 'Latte\\Macro',
'Latte\\Runtime\\IHtmlString' => 'Latte\\Runtime\\HtmlStringable',
'Latte\\Runtime\\ISnippetBridge' => 'Latte\\Runtime\\SnippetBridge',
]);
$rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [
// https://github.com/nette/caching/commit/60281abf366c4ab76e9436dc1bfe2e402db18b67
new MethodCallRename('Nette\\Caching\\Cache', 'start', 'capture'),
// https://github.com/nette/forms/commit/faaaf8b8fd3408a274a9de7ca3f342091010ad5d
new MethodCallRename('Nette\\Forms\\Container', 'addImage', 'addImageButton'),
// https://github.com/nette/utils/commit/d0427c1811462dbb6c503143eabe5478b26685f7
new MethodCallRename('Nette\\Utils\\Arrays', 'searchKey', 'getKeyOffset'),
new MethodCallRename('Nette\\Configurator', 'addParameters', 'addStaticParameters'),
]);
$rectorConfig->ruleWithConfiguration(RenameStaticMethodRector::class, [
// https://github.com/nette/utils/commit/8a4b795acd00f3f6754c28a73a7e776b60350c34
new RenameStaticMethod('Nette\\Utils\\Callback', 'closure', 'Closure', 'fromCallable'),
]);
$rectorConfig->ruleWithConfiguration(DimFetchAssignToMethodCallRector::class, [new DimFetchAssignToMethodCall('Nette\\Application\\Routers\\RouteList', 'Nette\\Application\\Routers\\Route', 'addRoute')]);
$nullableTemplateType = new UnionType([new ObjectType('Nette\\Application\\UI\\Template'), new NullType()]);
$rectorConfig->ruleWithConfiguration(AddParamTypeDeclarationRector::class, [new AddParamTypeDeclaration('Nette\\Application\\UI\\Presenter', 'sendTemplate', 0, $nullableTemplateType)]);
$rectorConfig->rule(ContextGetByTypeToConstructorInjectionRector::class);
$rectorConfig->ruleWithConfiguration(ChangePackageVersionComposerRector::class, [
// meta package
new PackageAndVersion('nette/nette', '^3.1'),
// https://github.com/nette/nette/blob/v3.0.0/composer.json vs https://github.com/nette/nette/blob/v3.1.0/composer.json
new PackageAndVersion('nette/application', '^3.1'),
new PackageAndVersion('nette/bootstrap', '^3.1'),
new PackageAndVersion('nette/caching', '^3.1'),
new PackageAndVersion('nette/database', '^3.1'),
new PackageAndVersion('nette/di', '^3.0'),
new PackageAndVersion('nette/finder', '^2.5'),
new PackageAndVersion('nette/forms', '^3.1'),
new PackageAndVersion('nette/http', '^3.1'),
new PackageAndVersion('nette/mail', '^3.1'),
new PackageAndVersion('nette/php-generator', '^3.5'),
new PackageAndVersion('nette/robot-loader', '^3.3'),
new PackageAndVersion('nette/safe-stream', '^2.4'),
new PackageAndVersion('nette/security', '^3.1'),
new PackageAndVersion('nette/tokenizer', '^3.0'),
new PackageAndVersion('nette/utils', '^3.2'),
new PackageAndVersion('latte/latte', '^2.9'),
new PackageAndVersion('tracy/tracy', '^2.8'),
// contributte
new PackageAndVersion('contributte/console', '^0.9'),
new PackageAndVersion('contributte/event-dispatcher', '^0.8'),
new PackageAndVersion('contributte/event-dispatcher-extra', '^0.8'),
// nettrine
new PackageAndVersion('nettrine/annotations', '^0.7'),
new PackageAndVersion('nettrine/cache', '^0.3'),
]);
$rectorConfig->ruleWithConfiguration(RemovePackageComposerRector::class, ['nette/component-model', 'nette/neon']);
};

View File

@ -1,23 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use Rector\Config\RectorConfig;
use Rector\Nette\Rector\ClassMethod\TemplateMagicAssignToExplicitVariableArrayRector;
use Rector\Nette\Rector\FuncCall\JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector;
use Rector\Nette\Rector\FuncCall\PregFunctionToNetteUtilsStringsRector;
use Rector\Nette\Rector\FuncCall\PregMatchFunctionToNetteUtilsStringsRector;
use Rector\Nette\Rector\FuncCall\SubstrStrlenFunctionToNetteUtilsStringsRector;
use Rector\Nette\Rector\LNumber\ReplaceTimeNumberWithDateTimeConstantRector;
use Rector\Transform\Rector\FuncCall\FuncCallToStaticCallRector;
use Rector\Transform\ValueObject\FuncCallToStaticCall;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rule(TemplateMagicAssignToExplicitVariableArrayRector::class);
$rectorConfig->ruleWithConfiguration(FuncCallToStaticCallRector::class, [new FuncCallToStaticCall('file_get_contents', 'Nette\\Utils\\FileSystem', 'read'), new FuncCallToStaticCall('unlink', 'Nette\\Utils\\FileSystem', 'delete'), new FuncCallToStaticCall('rmdir', 'Nette\\Utils\\FileSystem', 'delete')]);
$rectorConfig->rule(SubstrStrlenFunctionToNetteUtilsStringsRector::class);
$rectorConfig->rule(PregMatchFunctionToNetteUtilsStringsRector::class);
$rectorConfig->rule(PregFunctionToNetteUtilsStringsRector::class);
$rectorConfig->rule(JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector::class);
$rectorConfig->rule(ReplaceTimeNumberWithDateTimeConstantRector::class);
};

View File

@ -1,10 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use Rector\Config\RectorConfig;
use Rector\Nette\Rector\Property\NetteInjectToConstructorInjectionRector;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rule(NetteInjectToConstructorInjectionRector::class);
};

View File

@ -1,16 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use Rector\Config\RectorConfig;
use Rector\Php80\Rector\Class_\AnnotationToAttributeRector;
use Rector\Php80\ValueObject\AnnotationToAttribute;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->ruleWithConfiguration(AnnotationToAttributeRector::class, [
// nette 3.0+, see https://github.com/nette/application/commit/d2471134ed909210de8a3e8559931902b1bee67b#diff-457507a8bdc046dd4f3a4aa1ca51794543fbb1e06f03825ab69ee864549a570c
new AnnotationToAttribute('inject', 'Nette\\DI\\Attributes\\Inject'),
new AnnotationToAttribute('persistent', 'Nette\\Application\\Attributes\\Persistent'),
new AnnotationToAttribute('crossOrigin', 'Nette\\Application\\Attributes\\CrossOrigin'),
]);
};

View File

@ -1,561 +0,0 @@
# 22 Rules Overview
## BuilderExpandToHelperExpandRector
Change `containerBuilder->expand()` to static call with parameters
- class: [`Rector\Nette\Rector\MethodCall\BuilderExpandToHelperExpandRector`](../src/Rector/MethodCall/BuilderExpandToHelperExpandRector.php)
```diff
use Nette\DI\CompilerExtension;
final class SomeClass extends CompilerExtension
{
public function loadConfiguration()
{
- $value = $this->getContainerBuilder()->expand('%value');
+ $value = \Nette\DI\Helpers::expand('%value', $this->getContainerBuilder()->parameters);
}
}
```
<br>
## ContextGetByTypeToConstructorInjectionRector
Move dependency get via `$context->getByType()` to constructor injection
- class: [`Rector\Nette\Rector\MethodCall\ContextGetByTypeToConstructorInjectionRector`](../src/Rector/MethodCall/ContextGetByTypeToConstructorInjectionRector.php)
```diff
class SomeClass
{
/**
* @var \Nette\DI\Container
*/
private $context;
+ public function __construct(private SomeTypeToInject $someTypeToInject)
+ {
+ }
+
public function run()
{
- $someTypeToInject = $this->context->getByType(SomeTypeToInject::class);
+ $someTypeToInject = $this->someTypeToInject;
}
}
```
<br>
## ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector
convert `addUpload()` with 3rd argument true to `addMultiUpload()`
- class: [`Rector\Nette\Rector\MethodCall\ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector`](../src/Rector/MethodCall/ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector.php)
```diff
$form = new Nette\Forms\Form();
-$form->addUpload('...', '...', true);
+$form->addMultiUpload('...', '...');
```
<br>
## FormDataRector
Create form data class with all fields of Form
:wrench: **configure it!**
- class: [`Rector\Nette\Rector\Class_\FormDataRector`](../src/Rector/Class_/FormDataRector.php)
```php
use Rector\Config\RectorConfig;
use Rector\Nette\Rector\Class_\FormDataRector;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->ruleWithConfiguration(FormDataRector::class, [
FormDataRector::FORM_DATA_CLASS_PARENT => '',
FormDataRector::FORM_DATA_CLASS_TRAITS => [],
]);
};
```
```diff
+class MyFormFactoryFormData
+{
+ public string $foo;
+ public string $bar;
+}
+
class MyFormFactory
{
public function create()
{
$form = new Form();
$form->addText('foo', 'Foo');
$form->addText('bar', 'Bar')->setRequired();
- $form->onSuccess[] = function (Form $form, ArrayHash $values) {
+ $form->onSuccess[] = function (Form $form, MyFormFactoryFormData $values) {
// do something
}
}
}
```
<br>
## JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector
Changes `json_encode()/json_decode()` to safer and more verbose `Nette\Utils\Json::encode()/decode()` calls
- class: [`Rector\Nette\Rector\FuncCall\JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector`](../src/Rector/FuncCall/JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector.php)
```diff
class SomeClass
{
public function decodeJson(string $jsonString)
{
- $stdClass = json_decode($jsonString);
+ $stdClass = \Nette\Utils\Json::decode($jsonString);
- $array = json_decode($jsonString, true);
- $array = json_decode($jsonString, false);
+ $array = \Nette\Utils\Json::decode($jsonString, \Nette\Utils\Json::FORCE_ARRAY);
+ $array = \Nette\Utils\Json::decode($jsonString);
}
public function encodeJson(array $data)
{
- $jsonString = json_encode($data);
+ $jsonString = \Nette\Utils\Json::encode($data);
- $prettyJsonString = json_encode($data, JSON_PRETTY_PRINT);
+ $prettyJsonString = \Nette\Utils\Json::encode($data, \Nette\Utils\Json::PRETTY);
}
}
```
<br>
## LatteVarTypesBasedOnPresenterTemplateParametersRector
Adds latte {varType}s based on presenter `$this->template` parameters
- class: [`Rector\Nette\Rector\Class_\LatteVarTypesBasedOnPresenterTemplateParametersRector`](../src/Rector/Class_/LatteVarTypesBasedOnPresenterTemplateParametersRector.php)
```diff
// presenters/SomePresenter.php
<?php
use Nette\Application\UI\Presenter;
class SomePresenter extends Presenter
{
public function renderDefault(): void
{
$this->template->title = 'My title';
$this->template->count = 123;
}
}
// templates/Some/default.latte
+{varType string $title}
+{varType int $count}
+
<h1>{$title}</h1>
<span class="count">{$count}</span>
```
<br>
## MagicHtmlCallToAppendAttributeRector
Change magic `addClass()` etc. calls on Html to explicit methods
- class: [`Rector\Nette\Rector\MethodCall\MagicHtmlCallToAppendAttributeRector`](../src/Rector/MethodCall/MagicHtmlCallToAppendAttributeRector.php)
```diff
use Nette\Utils\Html;
final class SomeClass
{
public function run()
{
$html = Html::el();
- $html->setClass('first');
+ $html->appendAttribute('class', 'first');
}
}
```
<br>
## MergeDefaultsInGetConfigCompilerExtensionRector
Change `$this->getConfig($defaults)` to array_merge
- class: [`Rector\Nette\Rector\MethodCall\MergeDefaultsInGetConfigCompilerExtensionRector`](../src/Rector/MethodCall/MergeDefaultsInGetConfigCompilerExtensionRector.php)
```diff
use Nette\DI\CompilerExtension;
final class SomeExtension extends CompilerExtension
{
private $defaults = [
'key' => 'value'
];
public function loadConfiguration()
{
- $config = $this->getConfig($this->defaults);
+ $config = array_merge($this->defaults, $this->getConfig());
}
}
```
<br>
## MergeTemplateSetFileToTemplateRenderRector
Change `$this->template->setFile()` `$this->template->render()`
- class: [`Rector\Nette\Rector\ClassMethod\MergeTemplateSetFileToTemplateRenderRector`](../src/Rector/ClassMethod/MergeTemplateSetFileToTemplateRenderRector.php)
```diff
use Nette\Application\UI\Control;
final class SomeControl extends Control
{
public function render()
{
- $this->template->setFile(__DIR__ . '/someFile.latte');
- $this->template->render();
+ $this->template->render(__DIR__ . '/someFile.latte');
}
}
```
<br>
## MoveInjectToExistingConstructorRector
Move `@inject` properties to constructor, if there already is one
- class: [`Rector\Nette\Rector\Class_\MoveInjectToExistingConstructorRector`](../src/Rector/Class_/MoveInjectToExistingConstructorRector.php)
```diff
final class SomeClass
{
/**
* @var SomeDependency
- * @inject
*/
- public $someDependency;
+ private $someDependency;
/**
* @var OtherDependency
*/
private $otherDependency;
- public function __construct(OtherDependency $otherDependency)
+ public function __construct(OtherDependency $otherDependency, SomeDependency $someDependency)
{
$this->otherDependency = $otherDependency;
+ $this->someDependency = $someDependency;
}
}
```
<br>
## NetteInjectToConstructorInjectionRector
Turns properties with `@inject` to private properties and constructor injection
- class: [`Rector\Nette\Rector\Property\NetteInjectToConstructorInjectionRector`](../src/Rector/Property/NetteInjectToConstructorInjectionRector.php)
```diff
/**
* @var SomeService
- * @inject
*/
-public $someService;
+private $someService;
+
+public function __construct(SomeService $someService)
+{
+ $this->someService = $someService;
+}
```
<br>
## PregFunctionToNetteUtilsStringsRector
Use `Nette\Utils\Strings` over bare `preg_split()` and `preg_replace()` functions
- class: [`Rector\Nette\Rector\FuncCall\PregFunctionToNetteUtilsStringsRector`](../src/Rector/FuncCall/PregFunctionToNetteUtilsStringsRector.php)
```diff
+use Nette\Utils\Strings;
+
class SomeClass
{
public function run()
{
$content = 'Hi my name is Tom';
- $splitted = preg_split('#Hi#', $content);
+ $splitted = \Nette\Utils\Strings::split($content, '#Hi#');
}
}
```
<br>
## PregMatchFunctionToNetteUtilsStringsRector
Use `Nette\Utils\Strings` over bare `preg_match()` and `preg_match_all()` functions
- class: [`Rector\Nette\Rector\FuncCall\PregMatchFunctionToNetteUtilsStringsRector`](../src/Rector/FuncCall/PregMatchFunctionToNetteUtilsStringsRector.php)
```diff
+use Nette\Utils\Strings;
+
class SomeClass
{
public function run()
{
$content = 'Hi my name is Tom';
- preg_match('#Hi#', $content, $matches);
+ $matches = Strings::match($content, '#Hi#');
}
}
```
<br>
## RemoveParentAndNameFromComponentConstructorRector
Remove `$parent` and `$name` in control constructor
- class: [`Rector\Nette\Rector\ClassMethod\RemoveParentAndNameFromComponentConstructorRector`](../src/Rector/ClassMethod/RemoveParentAndNameFromComponentConstructorRector.php)
```diff
use Nette\Application\UI\Control;
class SomeControl extends Control
{
- public function __construct(IContainer $parent = null, $name = null, int $value)
+ public function __construct(int $value)
{
- parent::__construct($parent, $name);
$this->value = $value;
}
}
```
<br>
## RenameMethodLatteRector
Renames method calls in LATTE templates
- class: [`Rector\Nette\Rector\Latte\RenameMethodLatteRector`](../src/Rector/Latte/RenameMethodLatteRector.php)
```diff
{varType SomeClass $someClass}
-<div n:foreach="$someClass->oldCall() as $item"></div>
+<div n:foreach="$someClass->newCall() as $item"></div>
```
<br>
## ReplaceTimeNumberWithDateTimeConstantRector
Replace time numbers with `Nette\Utils\DateTime` constants
- class: [`Rector\Nette\Rector\LNumber\ReplaceTimeNumberWithDateTimeConstantRector`](../src/Rector/LNumber/ReplaceTimeNumberWithDateTimeConstantRector.php)
```diff
final class SomeClass
{
public function run()
{
- return 86400;
+ return \Nette\Utils\DateTime::DAY;
}
}
```
<br>
## RequestGetCookieDefaultArgumentToCoalesceRector
Add removed `Nette\Http\Request::getCookies()` default value as coalesce
- class: [`Rector\Nette\Rector\MethodCall\RequestGetCookieDefaultArgumentToCoalesceRector`](../src/Rector/MethodCall/RequestGetCookieDefaultArgumentToCoalesceRector.php)
```diff
use Nette\Http\Request;
class SomeClass
{
public function run(Request $request)
{
- return $request->getCookie('name', 'default');
+ return $request->getCookie('name') ?? 'default';
}
}
```
<br>
## SetClassWithArgumentToSetFactoryRector
Change setClass with class and arguments to separated methods
- class: [`Rector\Nette\Rector\MethodCall\SetClassWithArgumentToSetFactoryRector`](../src/Rector/MethodCall/SetClassWithArgumentToSetFactoryRector.php)
```diff
use Nette\DI\ContainerBuilder;
class SomeClass
{
public function run(ContainerBuilder $containerBuilder)
{
$containerBuilder->addDefinition('...')
- ->setClass('SomeClass', [1, 2]);
+ ->setFactory('SomeClass', [1, 2]);
}
}
```
<br>
## SubstrStrlenFunctionToNetteUtilsStringsRector
Use `Nette\Utils\Strings` over bare string-functions
- class: [`Rector\Nette\Rector\FuncCall\SubstrStrlenFunctionToNetteUtilsStringsRector`](../src/Rector/FuncCall/SubstrStrlenFunctionToNetteUtilsStringsRector.php)
```diff
class SomeClass
{
public function run()
{
- return substr($value, 0, 3);
+ return \Nette\Utils\Strings::substring($value, 0, 3);
}
}
```
<br>
## TemplateMagicAssignToExplicitVariableArrayRector
Change `$this->templates->{magic}` to `$this->template->render(..., $values)` in components
- class: [`Rector\Nette\Rector\ClassMethod\TemplateMagicAssignToExplicitVariableArrayRector`](../src/Rector/ClassMethod/TemplateMagicAssignToExplicitVariableArrayRector.php)
```diff
use Nette\Application\UI\Control;
class SomeControl extends Control
{
public function render()
{
- $this->template->param = 'some value';
- $this->template->render(__DIR__ . '/poll.latte');
+ $this->template->render(__DIR__ . '/poll.latte', ['param' => 'some value']);
}
}
```
<br>
## TemplateTypeBasedOnPresenterTemplateParametersRector
Creates Template class and adds latte {templateType} based on presenter `$this->template` parameters
:wrench: **configure it!**
- class: [`Rector\Nette\Rector\Class_\TemplateTypeBasedOnPresenterTemplateParametersRector`](../src/Rector/Class_/TemplateTypeBasedOnPresenterTemplateParametersRector.php)
```php
use Rector\Config\RectorConfig;
use Rector\Nette\Rector\Class_\TemplateTypeBasedOnPresenterTemplateParametersRector;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->ruleWithConfiguration(TemplateTypeBasedOnPresenterTemplateParametersRector::class, [
TemplateTypeBasedOnPresenterTemplateParametersRector::TEMPLATE_CLASS_PARENT => '',
TemplateTypeBasedOnPresenterTemplateParametersRector::TEMPLATE_CLASS_TRAITS => [],
]);
};
```
```diff
// presenters/SomePresenter.php
<?php
use Nette\Application\UI\Presenter;
class SomePresenter extends Presenter
{
public function renderDefault(): void
{
$this->template->title = 'My title';
$this->template->count = 123;
}
}
+// presenters/SomeDefaultTemplate.php
+<?php
+
+use Nette\Bridges\ApplicationLatte\Template;
+
+class SomeDefaultTemplate extends Template
+{
+ public string $title;
+ public int $count;
+}
+
// templates/Some/default.latte
+{templateType SomeDefaultTemplate}
+
<h1>{$title}</h1>
<span class="count">{$count}</span>
```
<br>
## TranslateClassMethodToVariadicsRector
Change `translate()` method call 2nd arg to variadic
- class: [`Rector\Nette\Rector\ClassMethod\TranslateClassMethodToVariadicsRector`](../src/Rector/ClassMethod/TranslateClassMethodToVariadicsRector.php)
```diff
use Nette\Localization\ITranslator;
final class SomeClass implements ITranslator
{
- public function translate($message, $count = null)
+ public function translate($message, ... $parameters)
{
+ $count = $parameters[0] ?? null;
return [$message, $count];
}
}
```
<br>

View File

@ -1,15 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use RectorPrefix202208\Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use RectorPrefix202208\Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker;
use RectorPrefix202208\Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker;
return static function (ContainerConfigurator $containerConfigurator) : void {
$services = $containerConfigurator->services();
$services->defaults()->autowire();
// @see https://github.com/symplify/monorepo-builder#6-release-flow
$services->set(TagVersionReleaseWorker::class);
$services->set(PushTagReleaseWorker::class);
};

View File

@ -1,28 +0,0 @@
<?php
declare (strict_types=1);
namespace RectorPrefix202208;
use Rector\Config\RectorConfig;
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->importNames();
$rectorConfig->parallel();
$rectorConfig->paths([__DIR__ . '/src', __DIR__ . '/tests']);
$rectorConfig->skip([
// for tests
'*/Source/*',
'*/Fixture/*',
]);
$rectorConfig->ruleWithConfiguration(StringClassNameToClassConstantRector::class, ['Nette\\*', 'Symfony\\Component\\Translation\\TranslatorInterface', 'Symfony\\Contracts\\EventDispatcher\\Event', 'Kdyby\\Events\\Subscriber']);
// needed for DEAD_CODE list, just in split package like this
$rectorConfig->sets([
__DIR__ . '/config/config.php',
// LevelSetList::UP_TO_PHP_80,
\Rector\Set\ValueObject\DowngradeLevelSetList::DOWN_TO_PHP_80,
SetList::DEAD_CODE,
SetList::CODE_QUALITY,
]);
};

View File

@ -1,10 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Contract\Rector;
use Rector\Core\Contract\Rector\RectorInterface;
interface LatteRectorInterface extends RectorInterface
{
public function changeContent(string $content) : string;
}

View File

@ -1,63 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\FileProcessor;
use Rector\ChangesReporting\ValueObjectFactory\FileDiffFactory;
use Rector\Core\Contract\Processor\FileProcessorInterface;
use Rector\Core\ValueObject\Application\File;
use Rector\Core\ValueObject\Configuration;
use Rector\Core\ValueObject\Error\SystemError;
use Rector\Core\ValueObject\Reporting\FileDiff;
use Rector\Nette\Contract\Rector\LatteRectorInterface;
use Rector\Parallel\ValueObject\Bridge;
final class LatteFileProcessor implements FileProcessorInterface
{
/**
* @var LatteRectorInterface[]
*/
private $latteRectors;
/**
* @var \Rector\ChangesReporting\ValueObjectFactory\FileDiffFactory
*/
private $fileDiffFactory;
/**
* @param LatteRectorInterface[] $latteRectors
*/
public function __construct(array $latteRectors, FileDiffFactory $fileDiffFactory)
{
$this->latteRectors = $latteRectors;
$this->fileDiffFactory = $fileDiffFactory;
}
/**
* @return array{system_errors: SystemError[], file_diffs: FileDiff[]}
*/
public function process(File $file, Configuration $configuration) : array
{
$systemErrorsAndFileDiffs = [Bridge::SYSTEM_ERRORS => [], Bridge::FILE_DIFFS => []];
$oldFileContent = $file->getFileContent();
$fileContent = $file->getFileContent();
foreach ($this->latteRectors as $latteRector) {
$fileContent = $latteRector->changeContent($fileContent);
}
$file->changeFileContent($fileContent);
if ($oldFileContent === $fileContent) {
return $systemErrorsAndFileDiffs;
}
$fileDiff = $this->fileDiffFactory->createFileDiff($file, $oldFileContent, $fileContent);
$systemErrorsAndFileDiffs[Bridge::FILE_DIFFS][] = $fileDiff;
return $systemErrorsAndFileDiffs;
}
public function supports(File $file, Configuration $configuration) : bool
{
$fileInfo = $file->getSmartFileInfo();
return $fileInfo->hasSuffixes($this->getSupportedFileExtensions());
}
/**
* @return string[]
*/
public function getSupportedFileExtensions() : array
{
return ['latte'];
}
}

View File

@ -1,40 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Latte\Parser;
use RectorPrefix202208\Nette\Utils\Strings;
use PHPStan\BetterReflection\Reflection\ReflectionClass;
use PHPStan\BetterReflection\Reflection\ReflectionNamedType;
use PHPStan\BetterReflection\Reflector\Exception\IdentifierNotFound;
use Rector\Nette\ValueObject\LatteVariableType;
final class TemplateTypeParser
{
/**
* @var string
* @see https://regex101.com/r/R06TTK/1
*/
private const TEMPLATE_TYPE_REGEX = '#{templateType (?P<template>.*?)}#';
/**
* @return LatteVariableType[]
*/
public function parse(string $content) : array
{
$templateTypeMatch = Strings::match($content, self::TEMPLATE_TYPE_REGEX);
if (!isset($templateTypeMatch['template'])) {
return [];
}
try {
$reflectionClass = ReflectionClass::createFromName($templateTypeMatch['template']);
} catch (IdentifierNotFound $exception) {
return [];
}
$variableTypes = [];
foreach ($reflectionClass->getProperties() as $property) {
/** @var ReflectionNamedType $type */
$type = $property->getType();
$variableTypes[] = new LatteVariableType($property->getName(), (string) $type);
}
return $variableTypes;
}
}

View File

@ -1,27 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Latte\Parser;
use RectorPrefix202208\Nette\Utils\Strings;
use Rector\Nette\ValueObject\LatteVariableType;
final class VarTypeParser
{
/**
* @var string
* @see https://regex101.com/r/vYlxWm/1
*/
private const VAR_TYPE_REGEX = '#{varType (?P<type>.*?) \\$(?P<variable>.*?)}#';
/**
* @return LatteVariableType[]
*/
public function parse(string $content) : array
{
$matches = Strings::matchAll($content, self::VAR_TYPE_REGEX);
$variableTypes = [];
foreach ($matches as $match) {
$variableTypes[] = new LatteVariableType($match['variable'], $match['type']);
}
return $variableTypes;
}
}

View File

@ -1,26 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node\Expr\Variable;
use Rector\Nette\ValueObject\TemplateParametersAssigns;
/**
* Replaces:
*
* if (...) { $this->template->key = 'some'; } else { $this->template->key = 'another'; }
*
*
*
* if (...) { $key = 'some'; } else { $key = 'another'; }
*/
final class ConditionalTemplateAssignReplacer
{
public function processClassMethod(TemplateParametersAssigns $templateParametersAssigns) : void
{
foreach ($templateParametersAssigns->getNonSingleParameterAssigns() as $parameterAssign) {
$assign = $parameterAssign->getAssign();
$assign->var = new Variable($parameterAssign->getParameterName());
}
}
}

View File

@ -1,26 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\MethodCall;
use Rector\Core\Exception\NotImplementedYetException;
final class MethodCallArgMerger
{
public function mergeOrApendArray(MethodCall $methodCall, int $argumentPosition, Array_ $array) : void
{
$methodCallArgs = $methodCall->getArgs();
if (!isset($methodCallArgs[$argumentPosition])) {
$methodCall->args[$argumentPosition] = new Arg($array);
return;
}
$existingParameterArgValue = $methodCallArgs[$argumentPosition]->value;
if (!$existingParameterArgValue instanceof Array_) {
// another parameters than array are not suported yet
throw new NotImplementedYetException();
}
$existingParameterArgValue->items = \array_merge($existingParameterArgValue->items, $array->items);
}
}

View File

@ -1,37 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PHPStan\Type\ObjectType;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\NodeTypeResolver;
final class NetteClassAnalyzer
{
/**
* @var \Rector\NodeTypeResolver\NodeTypeResolver
*/
private $nodeTypeResolver;
/**
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
public function __construct(NodeTypeResolver $nodeTypeResolver, BetterNodeFinder $betterNodeFinder)
{
$this->nodeTypeResolver = $nodeTypeResolver;
$this->betterNodeFinder = $betterNodeFinder;
}
public function isInComponent(Node $node) : bool
{
$class = $node instanceof Class_ ? $node : $this->betterNodeFinder->findParentType($node, Class_::class);
if (!$class instanceof Class_) {
return \false;
}
if (!$this->nodeTypeResolver->isObjectType($class, new ObjectType('Nette\\Application\\UI\\Control'))) {
return \false;
}
return !$this->nodeTypeResolver->isObjectType($class, new ObjectType('Nette\\Application\\UI\\Presenter'));
}
}

View File

@ -1,75 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node\Stmt\Property;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\MethodName;
use Rector\FamilyTree\NodeAnalyzer\ClassChildAnalyzer;
final class NetteInjectPropertyAnalyzer
{
/**
* @var \Rector\FamilyTree\NodeAnalyzer\ClassChildAnalyzer
*/
private $classChildAnalyzer;
/**
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
public function __construct(ClassChildAnalyzer $classChildAnalyzer, ReflectionResolver $reflectionResolver)
{
$this->classChildAnalyzer = $classChildAnalyzer;
$this->reflectionResolver = $reflectionResolver;
}
public function canBeRefactored(Property $property, PhpDocInfo $phpDocInfo) : bool
{
if (!$phpDocInfo->hasByName('inject')) {
throw new ShouldNotHappenException();
}
// it needs @var tag as well, to get the type - faster, put first :)
if (!$this->isKnownPropertyType($phpDocInfo, $property)) {
return \false;
}
$classReflection = $this->reflectionResolver->resolveClassReflection($property);
if (!$classReflection instanceof ClassReflection) {
return \false;
}
if ($classReflection->isAbstract()) {
return \false;
}
if ($classReflection->isAnonymous()) {
return \false;
}
if ($this->classChildAnalyzer->hasChildClassMethod($classReflection, MethodName::CONSTRUCT)) {
return \false;
}
return $this->hasNoOrEmptyParamParentConstructor($classReflection);
}
public function hasNoOrEmptyParamParentConstructor(ClassReflection $classReflection) : bool
{
$parentClassMethods = $this->classChildAnalyzer->resolveParentClassMethods($classReflection, MethodName::CONSTRUCT);
if ($parentClassMethods === []) {
return \true;
}
// are there parent ctors? - has empty constructor params? it can be refactored
foreach ($parentClassMethods as $parentClassMethod) {
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($parentClassMethod->getVariants());
if ($parametersAcceptor->getParameters() !== []) {
return \false;
}
}
return \true;
}
private function isKnownPropertyType(PhpDocInfo $phpDocInfo, Property $property) : bool
{
if ($phpDocInfo->getVarTagValueNode() !== null) {
return \true;
}
return $property->type !== null;
}
}

View File

@ -1,35 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\BinaryOp\Minus;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\LNumber;
final class PregMatchAllAnalyzer
{
/**
* Compensate enforced flag
* https://github.com/nette/utils/blob/e3dd1853f56ee9a68bfbb2e011691283c2ed420d/src/Utils/Strings.php#L487 See
* https://stackoverflow.com/a/61424319/1348344
*
* @param Arg[] $args
* @return Arg[]
*/
public function compensateEnforcedFlag(string $methodName, FuncCall $funcCall, array $args) : array
{
if ($methodName !== 'matchAll') {
return $args;
}
if (\count($funcCall->args) !== 3) {
return $args;
}
$constFetch = new ConstFetch(new Name('PREG_SET_ORDER'));
$minus = new Minus($constFetch, new LNumber(1));
$args[] = new Arg($minus);
return $args;
}
}

View File

@ -1,77 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PHPStan\Reflection\ClassReflection;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer;
use Rector\NodeNameResolver\NodeNameResolver;
final class PropertyUsageAnalyzer
{
/**
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @var \Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer
*/
private $familyRelationsAnalyzer;
/**
* @var \Rector\NodeNameResolver\NodeNameResolver
*/
private $nodeNameResolver;
/**
* @var \Rector\Core\PhpParser\AstResolver
*/
private $astResolver;
/**
* @var \Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer
*/
private $propertyFetchAnalyzer;
/**
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
public function __construct(BetterNodeFinder $betterNodeFinder, FamilyRelationsAnalyzer $familyRelationsAnalyzer, NodeNameResolver $nodeNameResolver, AstResolver $astResolver, PropertyFetchAnalyzer $propertyFetchAnalyzer, ReflectionResolver $reflectionResolver)
{
$this->betterNodeFinder = $betterNodeFinder;
$this->familyRelationsAnalyzer = $familyRelationsAnalyzer;
$this->nodeNameResolver = $nodeNameResolver;
$this->astResolver = $astResolver;
$this->propertyFetchAnalyzer = $propertyFetchAnalyzer;
$this->reflectionResolver = $reflectionResolver;
}
public function isPropertyFetchedInChildClass(Property $property) : bool
{
$classReflection = $this->reflectionResolver->resolveClassReflection($property);
if (!$classReflection instanceof ClassReflection) {
throw new ShouldNotHappenException();
}
if ($classReflection->isClass() && $classReflection->isFinal()) {
return \false;
}
$propertyName = $this->nodeNameResolver->getName($property);
$childrenClassReflections = $this->familyRelationsAnalyzer->getChildrenOfClassReflection($classReflection);
foreach ($childrenClassReflections as $childClassReflection) {
$childClass = $this->astResolver->resolveClassFromName($childClassReflection->getName());
if (!$childClass instanceof Class_) {
continue;
}
$isPropertyFetched = (bool) $this->betterNodeFinder->findFirst($childClass->stmts, function (Node $node) use($propertyName) : bool {
return $this->propertyFetchAnalyzer->isLocalPropertyFetchName($node, $propertyName);
});
if ($isPropertyFetched) {
return \true;
}
}
return \false;
}
}

View File

@ -1,40 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
final class RenderMethodAnalyzer
{
/**
* @var \Rector\NodeNameResolver\NodeNameResolver
*/
private $nodeNameResolver;
/**
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
public function __construct(NodeNameResolver $nodeNameResolver, BetterNodeFinder $betterNodeFinder)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->betterNodeFinder = $betterNodeFinder;
}
/**
* @return MethodCall[]
*/
public function machRenderMethodCalls(ClassMethod $classMethod) : array
{
/** @var MethodCall[] $methodsCalls */
$methodsCalls = $this->betterNodeFinder->findInstanceOf((array) $classMethod->stmts, MethodCall::class);
$renderMethodCalls = [];
foreach ($methodsCalls as $methodCall) {
if ($this->nodeNameResolver->isName($methodCall->name, 'render')) {
$renderMethodCalls[] = $methodCall;
}
}
return $renderMethodCalls;
}
}

View File

@ -1,46 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNestingScope\ScopeNestingComparator;
final class ReturnAnalyzer
{
/**
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @var \Rector\NodeNestingScope\ScopeNestingComparator
*/
private $scopeNestingComparator;
public function __construct(BetterNodeFinder $betterNodeFinder, ScopeNestingComparator $scopeNestingComparator)
{
$this->betterNodeFinder = $betterNodeFinder;
$this->scopeNestingComparator = $scopeNestingComparator;
}
public function findLastClassMethodReturn(ClassMethod $classMethod) : ?Return_
{
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->findInstanceOf($classMethod, Return_::class);
// put the latest first
$returns = \array_reverse($returns);
foreach ($returns as $return) {
if ($this->scopeNestingComparator->areReturnScopeNested($return, $classMethod)) {
return $return;
}
}
return null;
}
public function isBeforeLastReturn(Assign $assign, ?Return_ $lastReturn) : bool
{
if (!$lastReturn instanceof Return_) {
return \true;
}
return $lastReturn->getStartTokenPos() < $assign->getStartTokenPos();
}
}

View File

@ -1,36 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\StaticCall;
use Rector\NodeNameResolver\NodeNameResolver;
final class StaticCallAnalyzer
{
/**
* @var \Rector\NodeNameResolver\NodeNameResolver
*/
private $nodeNameResolver;
public function __construct(NodeNameResolver $nodeNameResolver)
{
$this->nodeNameResolver = $nodeNameResolver;
}
public function isParentCallNamed(Node $node, string $desiredMethodName) : bool
{
if (!$node instanceof StaticCall) {
return \false;
}
if ($node->class instanceof Expr) {
return \false;
}
if (!$this->nodeNameResolver->isName($node->class, 'parent')) {
return \false;
}
if ($node->name instanceof Expr) {
return \false;
}
return $this->nodeNameResolver->isName($node->name, $desiredMethodName);
}
}

View File

@ -1,201 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Match_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\Case_;
use PhpParser\Node\Stmt\Catch_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Do_;
use PhpParser\Node\Stmt\Else_;
use PhpParser\Node\Stmt\Foreach_;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Return_;
use PhpParser\Node\Stmt\Switch_;
use PhpParser\Node\Stmt\While_;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Nette\ValueObject\AlwaysTemplateParameterAssign;
use Rector\Nette\ValueObject\ParameterAssign;
use Rector\Nette\ValueObject\TemplateParametersAssigns;
use Rector\NodeNestingScope\ScopeNestingComparator;
final class TemplatePropertyAssignCollector
{
/**
* @var array<class-string<Node>>
*/
private const NODE_TYPES = [
// these situations happens only if condition is met
If_::class,
While_::class,
Do_::class,
Catch_::class,
Case_::class,
Match_::class,
Switch_::class,
Foreach_::class,
// FunctionLike must be last, so we know the variable is defined in main stmt
FunctionLike::class,
];
/**
* @var \PhpParser\Node\Stmt\Return_|null
*/
private $lastReturn;
/**
* @var AlwaysTemplateParameterAssign[]
*/
private $alwaysTemplateParameterAssigns = [];
/**
* @var AlwaysTemplateParameterAssign[]
*/
private $defaultChangeableTemplateParameterAssigns = [];
/**
* @var ParameterAssign[]
*/
private $conditionalTemplateParameterAssigns = [];
/**
* @var \Rector\NodeNestingScope\ScopeNestingComparator
*/
private $scopeNestingComparator;
/**
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @var \Rector\Nette\NodeAnalyzer\ThisTemplatePropertyFetchAnalyzer
*/
private $thisTemplatePropertyFetchAnalyzer;
/**
* @var \Rector\Nette\NodeAnalyzer\ReturnAnalyzer
*/
private $returnAnalyzer;
public function __construct(ScopeNestingComparator $scopeNestingComparator, BetterNodeFinder $betterNodeFinder, \Rector\Nette\NodeAnalyzer\ThisTemplatePropertyFetchAnalyzer $thisTemplatePropertyFetchAnalyzer, \Rector\Nette\NodeAnalyzer\ReturnAnalyzer $returnAnalyzer)
{
$this->scopeNestingComparator = $scopeNestingComparator;
$this->betterNodeFinder = $betterNodeFinder;
$this->thisTemplatePropertyFetchAnalyzer = $thisTemplatePropertyFetchAnalyzer;
$this->returnAnalyzer = $returnAnalyzer;
}
public function collect(ClassMethod $classMethod) : TemplateParametersAssigns
{
$this->alwaysTemplateParameterAssigns = [];
$this->conditionalTemplateParameterAssigns = [];
$this->defaultChangeableTemplateParameterAssigns = [];
$this->lastReturn = $this->returnAnalyzer->findLastClassMethodReturn($classMethod);
$assignsOfPropertyFetches = $this->findAssignToPropertyFetches($classMethod);
$this->collectVariableFromAssign($assignsOfPropertyFetches);
return new TemplateParametersAssigns($this->alwaysTemplateParameterAssigns, $this->conditionalTemplateParameterAssigns, $this->defaultChangeableTemplateParameterAssigns);
}
/**
* @return Node[]
*/
private function getFoundParents(PropertyFetch $propertyFetch) : array
{
$foundParents = [];
/** @var class-string<Node> $nodeType */
foreach (self::NODE_TYPES as $nodeType) {
$parentType = $this->betterNodeFinder->findParentType($propertyFetch->var, $nodeType);
if ($parentType instanceof Node) {
$foundParents[] = $parentType;
$parentParentType = $this->betterNodeFinder->findParentType($parentType, $nodeType);
if ($parentParentType instanceof Node) {
$foundParents[] = $parentParentType;
}
}
}
return $foundParents;
}
/**
* @param Assign[] $assigns
*/
private function collectVariableFromAssign(array $assigns) : void
{
if ($assigns === []) {
return;
}
$fistAssign = $assigns[0];
/** @var PropertyFetch $propertyFetch */
$propertyFetch = $fistAssign->var;
$foundParents = $this->getFoundParents($propertyFetch);
$isDefaultValueDefined = $this->isDefaultValueDefined($foundParents);
foreach ($assigns as $assign) {
$this->processAssign($assign, $isDefaultValueDefined);
}
}
/**
* @param Node[] $nodes
*/
private function isDefaultValueDefined(array $nodes) : bool
{
if (!isset($nodes[0])) {
return \false;
}
return $nodes[0] instanceof ClassMethod;
}
private function processAssign(Assign $assign, bool $isDefaultValueDefined) : void
{
$parameterName = $this->thisTemplatePropertyFetchAnalyzer->resolveTemplateParameterNameFromAssign($assign);
if ($parameterName === null) {
return;
}
$propertyFetch = $assign->var;
if (!$propertyFetch instanceof PropertyFetch) {
throw new ShouldNotHappenException();
}
$foundParents = $this->getFoundParents($propertyFetch);
// nested conditions, unreliable, might not be defined
if (\count($foundParents) >= 3) {
return;
}
foreach ($foundParents as $foundParent) {
if ($this->scopeNestingComparator->isInBothIfElseBranch($foundParent, $propertyFetch)) {
$this->conditionalTemplateParameterAssigns[] = new ParameterAssign($assign, $parameterName);
return;
}
if ($foundParent instanceof If_) {
if ($isDefaultValueDefined) {
$this->defaultChangeableTemplateParameterAssigns[] = new AlwaysTemplateParameterAssign($assign, $parameterName, new Variable($parameterName));
// remove it from always template variables
foreach ($this->alwaysTemplateParameterAssigns as $key => $alwaysTemplateParameterAssigns) {
if ($alwaysTemplateParameterAssigns->getParameterName() === $parameterName) {
unset($this->alwaysTemplateParameterAssigns[$key]);
}
}
}
return;
}
// only defined in else branch, nothing we can do
if ($foundParent instanceof Else_) {
return;
}
}
// there is a return before this assign, to do not remove it and keep ti
if (!$this->returnAnalyzer->isBeforeLastReturn($assign, $this->lastReturn)) {
return;
}
$this->alwaysTemplateParameterAssigns[] = new AlwaysTemplateParameterAssign($assign, $parameterName, $assign->expr);
}
/**
* @return Assign[]
*/
private function findAssignToPropertyFetches(ClassMethod $classMethod) : array
{
/** @var Assign[] $assigns */
$assigns = $this->betterNodeFinder->findInstanceOf((array) $classMethod->stmts, Assign::class);
$assignsOfPropertyFetches = [];
foreach ($assigns as $assign) {
if (!$assign->var instanceof PropertyFetch) {
continue;
}
$assignsOfPropertyFetches[] = $assign;
}
// re-index from 0
return \array_values($assignsOfPropertyFetches);
}
}

View File

@ -1,20 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;
use Rector\Nette\ValueObject\TemplateParametersAssigns;
final class TemplatePropertyParametersReplacer
{
public function replace(TemplateParametersAssigns $magicTemplateParametersAssigns, Variable $variable) : void
{
foreach ($magicTemplateParametersAssigns->getTemplateParameterAssigns() as $alwaysTemplateParameterAssign) {
$arrayDimFetch = new ArrayDimFetch($variable, new String_($alwaysTemplateParameterAssign->getParameterName()));
$assign = $alwaysTemplateParameterAssign->getAssign();
$assign->var = $arrayDimFetch;
}
}
}

View File

@ -1,50 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use Rector\NodeNameResolver\NodeNameResolver;
final class ThisTemplatePropertyFetchAnalyzer
{
/**
* @var \Rector\NodeNameResolver\NodeNameResolver
*/
private $nodeNameResolver;
public function __construct(NodeNameResolver $nodeNameResolver)
{
$this->nodeNameResolver = $nodeNameResolver;
}
public function resolveTemplateParameterNameFromAssign(Assign $assign) : ?string
{
if (!$assign->var instanceof PropertyFetch) {
return null;
}
$propertyFetch = $assign->var;
if (!$this->isTemplatePropertyFetch($propertyFetch->var)) {
return null;
}
return $this->nodeNameResolver->getName($propertyFetch);
}
/**
* Looks for: $this->template
*
* $template
*/
private function isTemplatePropertyFetch(Expr $expr) : bool
{
if (!$expr instanceof PropertyFetch) {
return \false;
}
if (!$expr->var instanceof Variable) {
return \false;
}
if (!$this->nodeNameResolver->isName($expr->var, 'this')) {
return \false;
}
return $this->nodeNameResolver->isName($expr->name, 'template');
}
}

View File

@ -1,60 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeFactory;
use PhpParser\Builder\Class_ as ClassBuilder;
use PhpParser\Builder\Property;
use PhpParser\Builder\TraitUse;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Namespace_;
/**
* @see \Rector\Nette\Tests\NodeFactory\ClassWithPublicPropertiesFactory\ClassWithPublicPropertiesFactoryTest
*/
final class ClassWithPublicPropertiesFactory
{
/**
* @param string $fullyQualifiedName fully qualified name of new class
* @param array<string, array{type: string, nullable?: bool}> $properties
* @param string|null $parent fully qualified name of parent class
* @param string[] $traits list of fully qualified names of traits used in class
* @return \PhpParser\Node\Stmt\Namespace_|\PhpParser\Node\Stmt\Class_
*/
public function createNode(string $fullyQualifiedName, array $properties, ?string $parent, array $traits)
{
$namespaceParts = \explode('\\', \ltrim($fullyQualifiedName, '\\'));
$className = \array_pop($namespaceParts);
$namespace = \implode('\\', $namespaceParts);
$namespaceBuilder = null;
if ($namespace !== '') {
$namespaceBuilder = new \PhpParser\Builder\Namespace_($namespace);
}
$classBuilder = new ClassBuilder($className);
if ($parent !== null && $parent !== '') {
$classBuilder->extend($this->fixFullyQualifiedName($parent));
}
foreach ($traits as $trait) {
$classBuilder->addStmt(new TraitUse($this->fixFullyQualifiedName($trait)));
}
foreach ($properties as $propertyName => $propertySettings) {
$propertyType = $propertySettings['type'];
$nullable = $propertySettings['nullable'] ?? \false;
if ($nullable) {
$propertyType = new NullableType($propertyType);
}
$propertyBuilder = new Property($propertyName);
$propertyBuilder->setType($propertyType);
$classBuilder->addStmt($propertyBuilder);
}
if ($namespaceBuilder !== null) {
$namespaceBuilder->addStmt($classBuilder);
return $namespaceBuilder->getNode();
}
return $classBuilder->getNode();
}
private function fixFullyQualifiedName(string $fullyQualifiedName) : string
{
return '\\' . \ltrim($fullyQualifiedName, '\\');
}
}

View File

@ -1,27 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeFactory;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;
use Rector\Nette\ValueObject\TemplateParametersAssigns;
final class RenderParameterArrayFactory
{
public function createArray(TemplateParametersAssigns $templateParametersAssigns) : ?Array_
{
$arrayItems = [];
foreach ($templateParametersAssigns->getTemplateVariables() as $name => $expr) {
$arrayItems[] = new ArrayItem($expr, new String_($name));
}
foreach ($templateParametersAssigns->getConditionalVariableNames() as $variableName) {
$arrayItems[] = new ArrayItem(new Variable($variableName), new String_($variableName));
}
if ($arrayItems === []) {
return null;
}
return new Array_($arrayItems);
}
}

View File

@ -1,157 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeFinder;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Expression;
use PHPStan\Type\ObjectType;
use Rector\Nette\ValueObject\FormField;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\NodeTypeResolver;
/**
* @see \Rector\Nette\Tests\NodeFinder\FormFinder\FormFinderTest
*/
final class FormFieldsFinder
{
/**
* @var \Rector\NodeTypeResolver\NodeTypeResolver
*/
private $nodeTypeResolver;
/**
* @var \Rector\NodeNameResolver\NodeNameResolver
*/
private $nodeNameResolver;
public function __construct(NodeTypeResolver $nodeTypeResolver, NodeNameResolver $nodeNameResolver)
{
$this->nodeTypeResolver = $nodeTypeResolver;
$this->nodeNameResolver = $nodeNameResolver;
}
/**
* @return FormField[]
*/
public function find(Class_ $class, Variable $form) : array
{
$formFields = [];
foreach ($class->getMethods() as $classMethod) {
$stmts = $classMethod->getStmts();
if ($stmts === null) {
continue;
}
foreach ($stmts as $stmt) {
if (!$stmt instanceof Expression) {
continue;
}
$methodCall = $this->findMethodCall($stmt);
if (!$methodCall instanceof MethodCall) {
continue;
}
$addFieldMethodCall = $this->findAddFieldMethodCall($methodCall);
if (!$addFieldMethodCall instanceof MethodCall) {
continue;
}
if (!$this->isFormAddFieldMethodCall($addFieldMethodCall, $form)) {
continue;
}
$formFields = $this->addFormField($formFields, $addFieldMethodCall, $methodCall);
}
}
return $formFields;
}
private function findMethodCall(Expression $expression) : ?MethodCall
{
$methodCall = null;
if ($expression->expr instanceof MethodCall) {
$methodCall = $expression->expr;
} elseif ($expression->expr instanceof Assign && $expression->expr->expr instanceof MethodCall) {
$methodCall = $expression->expr->expr;
}
return $methodCall;
}
private function findAddFieldMethodCall(MethodCall $methodCall) : ?MethodCall
{
if ($methodCall->var instanceof Variable) {
// skip submit buttons
if ($this->nodeTypeResolver->isObjectType($methodCall, new ObjectType('Nette\\Forms\\Controls\\SubmitButton'))) {
return null;
}
if ($this->nodeTypeResolver->isObjectType($methodCall, new ObjectType('Nette\\Forms\\Container'))) {
return $methodCall;
}
// skip groups, renderers, translator etc.
if ($this->nodeTypeResolver->isObjectType($methodCall, new ObjectType('Nette\\Forms\\Controls\\BaseControl'))) {
return $methodCall;
}
return null;
}
if ($methodCall->var instanceof MethodCall) {
return $this->findAddFieldMethodCall($methodCall->var);
}
return null;
}
private function isFormAddFieldMethodCall(MethodCall $addFieldMethodCall, Variable $form) : bool
{
$methodCallVariable = $this->findMethodCallVariable($addFieldMethodCall);
if (!$methodCallVariable instanceof Variable) {
return \false;
}
return $methodCallVariable->name === $form->name;
}
private function findMethodCallVariable(MethodCall $methodCall) : ?Variable
{
if ($methodCall->var instanceof Variable) {
return $methodCall->var;
}
if ($methodCall->var instanceof MethodCall) {
return $this->findMethodCallVariable($methodCall->var);
}
return null;
}
/**
* @param FormField[] $formFields
* @return FormField[]
*/
private function addFormField(array $formFields, MethodCall $addFieldMethodCall, MethodCall $methodCall) : array
{
$arg = $addFieldMethodCall->getArgs()[0] ?? null;
if (!$arg instanceof Arg) {
return $formFields;
}
$name = $arg->value;
if (!$name instanceof String_) {
return $formFields;
}
$formFields[] = new FormField($name->value, $this->resolveFieldType($this->nodeNameResolver->getName($addFieldMethodCall->name)), $this->isFieldRequired($methodCall));
return $formFields;
}
private function isFieldRequired(MethodCall $methodCall) : bool
{
if ($methodCall->name instanceof Identifier && $methodCall->name->name === 'setRequired') {
// TODO addRule(Form:FILLED) is also required
return \true;
}
if ($methodCall->var instanceof MethodCall) {
return $this->isFieldRequired($methodCall->var);
}
return \false;
}
private function resolveFieldType(?string $methodName) : string
{
switch ($methodName) {
case 'addInteger':
return 'int';
case 'addContainer':
return 'array';
case 'addCheckbox':
return 'bool';
default:
return 'string';
}
}
}

View File

@ -1,59 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeFinder;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Expression;
final class FormOnSuccessCallbackFinder
{
public function find(Class_ $class, Variable $form) : ?Expr
{
foreach ($class->getMethods() as $classMethod) {
$stmts = $classMethod->getStmts();
if ($stmts === null) {
continue;
}
foreach ($stmts as $stmt) {
if (!$stmt instanceof Expression) {
continue;
}
if (!$stmt->expr instanceof Assign) {
continue;
}
if (!$stmt->expr->var instanceof ArrayDimFetch) {
continue;
}
/** @var ArrayDimFetch $arrayDimFetch */
$arrayDimFetch = $stmt->expr->var;
if (!$this->isFormOnSuccess($arrayDimFetch, $form)) {
continue;
}
return $stmt->expr->expr;
}
}
return null;
}
private function isFormOnSuccess(ArrayDimFetch $arrayDimFetch, Variable $form) : bool
{
if (!$arrayDimFetch->var instanceof PropertyFetch) {
return \false;
}
if (!$arrayDimFetch->var->var instanceof Variable) {
return \false;
}
if ($arrayDimFetch->var->var->name !== $form->name) {
return \false;
}
if (!$arrayDimFetch->var->name instanceof Identifier) {
return \false;
}
return $arrayDimFetch->var->name->name === 'onSuccess';
}
}

View File

@ -1,49 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeFinder;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
final class FormOnSuccessCallbackValuesParamFinder
{
public function find(Class_ $class, Expr $onSuccessCallback) : ?Param
{
if ($onSuccessCallback instanceof Closure) {
return $onSuccessCallback->params[1] ?? null;
}
$methodName = null;
if ($onSuccessCallback instanceof Array_) {
$varPart = $onSuccessCallback->items[0] ?? null;
$methodNamePart = $onSuccessCallback->items[1] ?? null;
if (!$varPart instanceof ArrayItem || !$methodNamePart instanceof ArrayItem) {
return null;
}
if (!$varPart->value instanceof Variable) {
return null;
}
if ($varPart->value->name !== 'this') {
return null;
}
if (!$methodNamePart->value instanceof String_) {
return null;
}
$methodName = $methodNamePart->value->value;
}
if ($methodName === null) {
return null;
}
$classMethod = $class->getMethod($methodName);
if (!$classMethod instanceof ClassMethod) {
return null;
}
return $classMethod->params[1] ?? null;
}
}

View File

@ -1,52 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeFinder;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Expression;
use PHPStan\Type\ObjectType;
use Rector\NodeTypeResolver\NodeTypeResolver;
/**
* @see \Rector\Nette\Tests\NodeFinder\FormFinder\FormFinderTest
*/
final class FormVariableFinder
{
/**
* @var \Rector\NodeTypeResolver\NodeTypeResolver
*/
private $nodeTypeResolver;
public function __construct(NodeTypeResolver $nodeTypeResolver)
{
$this->nodeTypeResolver = $nodeTypeResolver;
}
public function find(Class_ $class) : ?Variable
{
foreach ($class->getMethods() as $classMethod) {
$classMethodStmts = $classMethod->getStmts();
if ($classMethodStmts === null) {
continue;
}
foreach ($classMethodStmts as $classMethodStmt) {
if (!$classMethodStmt instanceof Expression) {
continue;
}
if (!$classMethodStmt->expr instanceof Assign) {
continue;
}
$var = $classMethodStmt->expr->var;
$expr = $classMethodStmt->expr->expr;
if (!$var instanceof Variable) {
continue;
}
if (!$this->nodeTypeResolver->isObjectType($expr, new ObjectType('Nette\\Forms\\Form'))) {
continue;
}
return $var;
}
}
return null;
}
}

View File

@ -1,41 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\NodeFinder;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Param;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ParamFinder
{
/**
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @var \Rector\Core\PhpParser\Comparing\NodeComparator
*/
private $nodeComparator;
public function __construct(BetterNodeFinder $betterNodeFinder, NodeComparator $nodeComparator)
{
$this->betterNodeFinder = $betterNodeFinder;
$this->nodeComparator = $nodeComparator;
}
/**
* @param \PhpParser\Node|mixed[] $nodeHaystack
*/
public function isInAssign($nodeHaystack, Param $param) : bool
{
$variable = $param->var;
return (bool) $this->betterNodeFinder->find($nodeHaystack, function (Node $node) use($variable) : bool {
$parent = $node->getAttribute(AttributeKey::PARENT_NODE);
if (!$parent instanceof Assign) {
return \false;
}
return $this->nodeComparator->areNodesEqual($node, $variable);
});
}
}

View File

@ -1,105 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Rector\AbstractRector;
use Rector\Nette\NodeAnalyzer\NetteClassAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\ClassMethod\MergeTemplateSetFileToTemplateRenderRector\MergeTemplateSetFileToTemplateRenderRectorTest
*/
final class MergeTemplateSetFileToTemplateRenderRector extends AbstractRector
{
/**
* @var \Rector\Nette\NodeAnalyzer\NetteClassAnalyzer
*/
private $netteClassAnalyzer;
public function __construct(NetteClassAnalyzer $netteClassAnalyzer)
{
$this->netteClassAnalyzer = $netteClassAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change $this->template->setFile() $this->template->render()', [new CodeSample(<<<'CODE_SAMPLE'
use Nette\Application\UI\Control;
final class SomeControl extends Control
{
public function render()
{
$this->template->setFile(__DIR__ . '/someFile.latte');
$this->template->render();
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\Application\UI\Control;
final class SomeControl extends Control
{
public function render()
{
$this->template->render(__DIR__ . '/someFile.latte');
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class];
}
/**
* @param ClassMethod $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->netteClassAnalyzer->isInComponent($node)) {
return null;
}
/** @var MethodCall[] $methodCalls */
$methodCalls = $this->betterNodeFinder->findInstanceOf((array) $node->stmts, MethodCall::class);
$setFileMethodCall = $this->resolveSingleSetFileMethodCall($methodCalls);
if (!$setFileMethodCall instanceof MethodCall) {
return null;
}
foreach ($methodCalls as $methodCall) {
if (!$this->isName($methodCall->name, 'render')) {
continue;
}
$methodCallArgs = $methodCall->getArgs();
if (isset($methodCallArgs[0])) {
continue;
}
$this->removeNode($setFileMethodCall);
$methodCall->args[0] = $setFileMethodCall->getArgs()[0];
return $node;
}
return null;
}
/**
* @param MethodCall[] $methodCalls
*/
private function resolveSingleSetFileMethodCall(array $methodCalls) : ?MethodCall
{
$singleSetFileMethodCall = null;
foreach ($methodCalls as $methodCall) {
if (!$this->isName($methodCall->name, 'setFile')) {
continue;
}
if ($singleSetFileMethodCall instanceof MethodCall) {
return null;
}
$singleSetFileMethodCall = $methodCall;
}
return $singleSetFileMethodCall;
}
}

View File

@ -1,201 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParameterReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\MethodName;
use Rector\Nette\NodeAnalyzer\StaticCallAnalyzer;
use Rector\Nette\NodeFinder\ParamFinder;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/nette/component-model/commit/1fb769f4602cf82694941530bac1111b3c5cd11b
* This only applied to child of \Nette\Application\UI\Control, not Forms! Forms still need to be attached to their parents
*
* @see \Rector\Nette\Tests\Rector\ClassMethod\RemoveParentAndNameFromComponentConstructorRector\RemoveParentAndNameFromComponentConstructorRectorTest
*/
final class RemoveParentAndNameFromComponentConstructorRector extends AbstractRector
{
/**
* @var string
*/
private const PARENT = 'parent';
/**
* @var string
*/
private const NAME = 'name';
/**
* @readonly
* @var \PHPStan\Type\ObjectType
*/
private $controlObjectType;
/**
* @var \Rector\Nette\NodeFinder\ParamFinder
*/
private $paramFinder;
/**
* @var \Rector\Nette\NodeAnalyzer\StaticCallAnalyzer
*/
private $staticCallAnalyzer;
/**
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
public function __construct(ParamFinder $paramFinder, StaticCallAnalyzer $staticCallAnalyzer, ReflectionResolver $reflectionResolver)
{
$this->paramFinder = $paramFinder;
$this->staticCallAnalyzer = $staticCallAnalyzer;
$this->reflectionResolver = $reflectionResolver;
$this->controlObjectType = new ObjectType('Nette\\Application\\UI\\Control');
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Remove $parent and $name in control constructor', [new CodeSample(<<<'CODE_SAMPLE'
use Nette\Application\UI\Control;
class SomeControl extends Control
{
public function __construct(IContainer $parent = null, $name = null, int $value)
{
parent::__construct($parent, $name);
$this->value = $value;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\Application\UI\Control;
class SomeControl extends Control
{
public function __construct(int $value)
{
$this->value = $value;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class, StaticCall::class, New_::class];
}
/**
* @param ClassMethod|StaticCall|New_ $node
*/
public function refactor(Node $node) : ?Node
{
if ($node instanceof ClassMethod) {
return $this->refactorClassMethod($node);
}
if ($node instanceof StaticCall) {
return $this->refactorStaticCall($node);
}
if ($this->isObjectType($node->class, new ObjectType('Nette\\Application\\UI\\Control'))) {
$this->refactorNew($node);
return $node;
}
return null;
}
private function refactorClassMethod(ClassMethod $classMethod) : ?ClassMethod
{
if (!$this->isInsideNetteComponentClass($classMethod)) {
return null;
}
if (!$this->isName($classMethod, MethodName::CONSTRUCT)) {
return null;
}
$this->removeClassMethodParams($classMethod);
return $classMethod;
}
private function refactorStaticCall(StaticCall $staticCall) : ?StaticCall
{
if (!$this->isInsideNetteComponentClass($staticCall)) {
return null;
}
if (!$this->staticCallAnalyzer->isParentCallNamed($staticCall, MethodName::CONSTRUCT)) {
return null;
}
foreach ($staticCall->getArgs() as $position => $staticCallArg) {
if (!$staticCallArg->value instanceof Variable) {
continue;
}
/** @var Variable $variable */
$variable = $staticCallArg->value;
if (!$this->isNames($variable, [self::NAME, self::PARENT])) {
continue;
}
unset($staticCall->args[$position]);
}
if ($staticCall->args === []) {
$this->removeNode($staticCall);
return null;
}
return $staticCall;
}
private function refactorNew(New_ $new) : void
{
$methodReflection = $this->reflectionResolver->resolveMethodReflectionFromNew($new);
if (!$methodReflection instanceof MethodReflection) {
return;
}
$parameterNames = [];
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());
foreach ($parametersAcceptor->getParameters() as $parameterReflection) {
/** @var ParameterReflection $parameterReflection */
$parameterNames[] = $parameterReflection->getName();
}
foreach (\array_keys($new->args) as $position) {
// is on position of $parent or $name?
if (!isset($parameterNames[$position])) {
continue;
}
$parameterName = $parameterNames[$position];
if (!\in_array($parameterName, [self::PARENT, self::NAME], \true)) {
continue;
}
unset($new->args[$position]);
}
}
private function isInsideNetteComponentClass(Node $node) : bool
{
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
if (!$classReflection instanceof ClassReflection) {
return \false;
}
// presenter is not a component
if ($classReflection->isSubclassOf('Nette\\Application\\UI\\Presenter')) {
return \false;
}
return $classReflection->isSubclassOf($this->controlObjectType->getClassName());
}
private function removeClassMethodParams(ClassMethod $classMethod) : void
{
foreach ($classMethod->params as $param) {
if ($this->paramFinder->isInAssign((array) $classMethod->stmts, $param)) {
continue;
}
if ($this->isObjectType($param, new ObjectType('Nette\\ComponentModel\\IContainer'))) {
$this->removeNode($param);
continue;
}
if ($this->isName($param, self::NAME)) {
$this->removeNode($param);
}
}
}
}

View File

@ -1,196 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\Rector\AbstractRector;
use Rector\Nette\NodeAnalyzer\ConditionalTemplateAssignReplacer;
use Rector\Nette\NodeAnalyzer\MethodCallArgMerger;
use Rector\Nette\NodeAnalyzer\NetteClassAnalyzer;
use Rector\Nette\NodeAnalyzer\RenderMethodAnalyzer;
use Rector\Nette\NodeAnalyzer\TemplatePropertyAssignCollector;
use Rector\Nette\NodeAnalyzer\TemplatePropertyParametersReplacer;
use Rector\Nette\NodeFactory\RenderParameterArrayFactory;
use Rector\Nette\ValueObject\TemplateParametersAssigns;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\ClassMethod\TemplateMagicAssignToExplicitVariableArrayRector\TemplateMagicAssignToExplicitVariableArrayRectorTest
*/
final class TemplateMagicAssignToExplicitVariableArrayRector extends AbstractRector
{
/**
* @var \Rector\Nette\NodeAnalyzer\TemplatePropertyAssignCollector
*/
private $templatePropertyAssignCollector;
/**
* @var \Rector\Nette\NodeAnalyzer\RenderMethodAnalyzer
*/
private $renderMethodAnalyzer;
/**
* @var \Rector\Nette\NodeAnalyzer\NetteClassAnalyzer
*/
private $netteClassAnalyzer;
/**
* @var \Rector\Nette\NodeFactory\RenderParameterArrayFactory
*/
private $renderParameterArrayFactory;
/**
* @var \Rector\Nette\NodeAnalyzer\ConditionalTemplateAssignReplacer
*/
private $conditionalTemplateAssignReplacer;
/**
* @var \Rector\Nette\NodeAnalyzer\TemplatePropertyParametersReplacer
*/
private $templatePropertyParametersReplacer;
/**
* @var \Rector\Nette\NodeAnalyzer\MethodCallArgMerger
*/
private $methodCallArgMerger;
public function __construct(TemplatePropertyAssignCollector $templatePropertyAssignCollector, RenderMethodAnalyzer $renderMethodAnalyzer, NetteClassAnalyzer $netteClassAnalyzer, RenderParameterArrayFactory $renderParameterArrayFactory, ConditionalTemplateAssignReplacer $conditionalTemplateAssignReplacer, TemplatePropertyParametersReplacer $templatePropertyParametersReplacer, MethodCallArgMerger $methodCallArgMerger)
{
$this->templatePropertyAssignCollector = $templatePropertyAssignCollector;
$this->renderMethodAnalyzer = $renderMethodAnalyzer;
$this->netteClassAnalyzer = $netteClassAnalyzer;
$this->renderParameterArrayFactory = $renderParameterArrayFactory;
$this->conditionalTemplateAssignReplacer = $conditionalTemplateAssignReplacer;
$this->templatePropertyParametersReplacer = $templatePropertyParametersReplacer;
$this->methodCallArgMerger = $methodCallArgMerger;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change `$this->templates->{magic}` to `$this->template->render(..., $values)` in components', [new CodeSample(<<<'CODE_SAMPLE'
use Nette\Application\UI\Control;
class SomeControl extends Control
{
public function render()
{
$this->template->param = 'some value';
$this->template->render(__DIR__ . '/poll.latte');
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\Application\UI\Control;
class SomeControl extends Control
{
public function render()
{
$this->template->render(__DIR__ . '/poll.latte', ['param' => 'some value']);
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class];
}
/**
* @param ClassMethod $node
*/
public function refactor(Node $node) : ?Node
{
if ($this->shouldSkip($node)) {
return null;
}
$renderMethodCalls = $this->renderMethodAnalyzer->machRenderMethodCalls($node);
if ($renderMethodCalls === []) {
return null;
}
if (!$this->haveMethodCallsFirstArgument($renderMethodCalls)) {
return null;
}
// initialize $parameters variable for multiple renders
if (\count($renderMethodCalls) > 1) {
return $this->refactorForMultipleRenderMethodCalls($node, $renderMethodCalls);
}
return $this->refactorForSingleRenderMethodCall($node, $renderMethodCalls[0]);
}
private function shouldSkip(ClassMethod $classMethod) : bool
{
return !$this->netteClassAnalyzer->isInComponent($classMethod);
}
/**
* @param MethodCall[] $methodCalls
*/
private function haveMethodCallsFirstArgument(array $methodCalls) : bool
{
foreach ($methodCalls as $methodCall) {
if (!isset($methodCall->args[0])) {
return \false;
}
}
return \true;
}
private function refactorForSingleRenderMethodCall(ClassMethod $classMethod, MethodCall $renderMethodCall) : ?ClassMethod
{
$templateParametersAssigns = $this->templatePropertyAssignCollector->collect($classMethod);
$array = $this->renderParameterArrayFactory->createArray($templateParametersAssigns);
if (!$array instanceof Array_) {
return null;
}
$this->traverseNodesWithCallable($classMethod, function (Node $node) use($templateParametersAssigns) {
if (!$node instanceof Assign) {
return null;
}
foreach ($templateParametersAssigns->getTemplateParameterAssigns() as $alwaysTemplateParameterAssign) {
if ($this->nodeComparator->areNodesEqual($node->var, $alwaysTemplateParameterAssign->getAssignVar())) {
$this->removeNode($node);
return null;
}
}
return $this->replaceThisTemplateAssignWithVariable($templateParametersAssigns, $node);
});
$this->conditionalTemplateAssignReplacer->processClassMethod($templateParametersAssigns);
// has already an array?
$this->methodCallArgMerger->mergeOrApendArray($renderMethodCall, 1, $array);
return $classMethod;
}
/**
* @param MethodCall[] $renderMethodCalls
*/
private function refactorForMultipleRenderMethodCalls(ClassMethod $classMethod, array $renderMethodCalls) : ?ClassMethod
{
$magicTemplateParametersAssigns = $this->templatePropertyAssignCollector->collect($classMethod);
if ($magicTemplateParametersAssigns->getTemplateParameterAssigns() === []) {
return null;
}
$parametersVariable = new Variable('parameters');
$parametersAssign = new Assign($parametersVariable, new Array_());
$assignExpression = new Expression($parametersAssign);
$classMethod->stmts = \array_merge([$assignExpression], (array) $classMethod->stmts);
$this->templatePropertyParametersReplacer->replace($magicTemplateParametersAssigns, $parametersVariable);
foreach ($renderMethodCalls as $renderMethodCall) {
$renderMethodCall->args[1] = new Arg($parametersVariable);
}
return $classMethod;
}
/**
* @return null|\PhpParser\Node\Expr\Assign
*/
private function replaceThisTemplateAssignWithVariable(TemplateParametersAssigns $templateParametersAssigns, Assign $assign)
{
foreach ($templateParametersAssigns->getDefaultChangeableTemplateParameterAssigns() as $alwaysTemplateParameterAssign) {
if (!$this->nodeComparator->areNodesEqual($assign->var, $alwaysTemplateParameterAssign->getAssignVar())) {
continue;
}
$assign->var = new Variable($alwaysTemplateParameterAssign->getParameterName());
return $assign;
}
return null;
}
}

View File

@ -1,143 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\Coalesce;
use PhpParser\Node\Expr\Error;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\NodeTraverser;
use PHPStan\Reflection\ClassReflection;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\PostRector\Collector\NodesToAddCollector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://github.com/nette/utils/pull/178
* @changelog https://github.com/contributte/translation/commit/d374c4c05b57dff1e5b327bb9bf98c392769806c
*
* @see \Rector\Nette\Tests\Rector\ClassMethod\TranslateClassMethodToVariadicsRector\TranslateClassMethodToVariadicsRectorTest
*
* @note must be run before "composer update nette/utils:^3.0", because param contract break causes fatal error
*/
final class TranslateClassMethodToVariadicsRector extends AbstractRector
{
/**
* @var string
*/
private const PARAMETERS = 'parameters';
/**
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
/**
* @var \Rector\PostRector\Collector\NodesToAddCollector
*/
private $nodesToAddCollector;
public function __construct(ReflectionResolver $reflectionResolver, NodesToAddCollector $nodesToAddCollector)
{
$this->reflectionResolver = $reflectionResolver;
$this->nodesToAddCollector = $nodesToAddCollector;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change translate() method call 2nd arg to variadic', [new CodeSample(<<<'CODE_SAMPLE'
use Nette\Localization\ITranslator;
final class SomeClass implements ITranslator
{
public function translate($message, $count = null)
{
return [$message, $count];
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\Localization\ITranslator;
final class SomeClass implements ITranslator
{
public function translate($message, ... $parameters)
{
$count = $parameters[0] ?? null;
return [$message, $count];
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class];
}
/**
* @param ClassMethod $node
*/
public function refactor(Node $node) : ?Node
{
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
if (!$classReflection instanceof ClassReflection) {
return null;
}
if (!$classReflection->isSubclassOf('Nette\\Localization\\ITranslator')) {
return null;
}
if (!$this->isName($node->name, 'translate')) {
return null;
}
if (!isset($node->params[1])) {
return null;
}
$secondParam = $node->params[1];
if (!$secondParam->var instanceof Variable) {
return null;
}
if ($secondParam->variadic) {
return null;
}
$this->replaceSecondParamInClassMethodBody($node, $secondParam);
$secondParam->default = null;
$secondParam->variadic = \true;
if ($secondParam->var instanceof Error) {
throw new ShouldNotHappenException();
}
$secondParam->var->name = self::PARAMETERS;
return $node;
}
private function replaceSecondParamInClassMethodBody(ClassMethod $classMethod, Param $param) : void
{
$paramName = $this->getName($param->var);
if ($paramName === null) {
return;
}
$this->traverseNodesWithCallable((array) $classMethod->stmts, function (Node $node) use($paramName) : ?int {
if (!$node instanceof Variable) {
return null;
}
if (!$this->isName($node, $paramName)) {
return null;
}
// instantiate
$assign = $this->createCoalesceAssign($node);
$this->nodesToAddCollector->addNodeBeforeNode($assign, $node);
return NodeTraverser::STOP_TRAVERSAL;
});
}
private function createCoalesceAssign(Variable $variable) : Assign
{
$arrayDimFetch = new ArrayDimFetch(new Variable(self::PARAMETERS), new LNumber(0));
$coalesce = new Coalesce($arrayDimFetch, $this->nodeFactory->createNull());
return new Assign(new Variable($variable->name), $coalesce);
}
}

View File

@ -1,181 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector;
use Rector\Core\Contract\PhpParser\NodePrinterInterface;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
use Rector\Nette\NodeFactory\ClassWithPublicPropertiesFactory;
use Rector\Nette\NodeFinder\FormFieldsFinder;
use Rector\Nette\NodeFinder\FormOnSuccessCallbackFinder;
use Rector\Nette\NodeFinder\FormOnSuccessCallbackValuesParamFinder;
use Rector\Nette\NodeFinder\FormVariableFinder;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix202208\Webmozart\Assert\Assert;
/**
* @see https://doc.nette.org/en/3.1/form-presenter#toc-mapping-to-classes
* @see \Rector\Nette\Tests\Rector\Class_\FormDataRector\FormDataRectorTest
*/
final class FormDataRector extends AbstractRector implements ConfigurableRectorInterface
{
public const FORM_DATA_CLASS_PARENT = 'form_data_class_parent';
public const FORM_DATA_CLASS_TRAITS = 'form_data_class_traits';
/**
* @var string
*/
private $formDataClassParent = 'Nette\\Utils\\ArrayHash';
/**
* @var string[]
*/
private $formDataClassTraits = ['Nette\\SmartObject'];
/**
* @var \Rector\Nette\NodeFinder\FormVariableFinder
*/
private $formVariableFinder;
/**
* @var \Rector\Nette\NodeFinder\FormFieldsFinder
*/
private $formFieldsFinder;
/**
* @var \Rector\Nette\NodeFinder\FormOnSuccessCallbackFinder
*/
private $formOnSuccessCallbackFinder;
/**
* @var \Rector\Nette\NodeFinder\FormOnSuccessCallbackValuesParamFinder
*/
private $formOnSuccessCallbackValuesParamFinder;
/**
* @var \Rector\Nette\NodeFactory\ClassWithPublicPropertiesFactory
*/
private $classWithPublicPropertiesFactory;
/**
* @var \Rector\Core\Contract\PhpParser\NodePrinterInterface
*/
private $nodePrinter;
/**
* @var \Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector
*/
private $removedAndAddedFilesCollector;
public function __construct(FormVariableFinder $formVariableFinder, FormFieldsFinder $formFieldsFinder, FormOnSuccessCallbackFinder $formOnSuccessCallbackFinder, FormOnSuccessCallbackValuesParamFinder $formOnSuccessCallbackValuesParamFinder, ClassWithPublicPropertiesFactory $classWithPublicPropertiesFactory, NodePrinterInterface $nodePrinter, RemovedAndAddedFilesCollector $removedAndAddedFilesCollector)
{
$this->formVariableFinder = $formVariableFinder;
$this->formFieldsFinder = $formFieldsFinder;
$this->formOnSuccessCallbackFinder = $formOnSuccessCallbackFinder;
$this->formOnSuccessCallbackValuesParamFinder = $formOnSuccessCallbackValuesParamFinder;
$this->classWithPublicPropertiesFactory = $classWithPublicPropertiesFactory;
$this->nodePrinter = $nodePrinter;
$this->removedAndAddedFilesCollector = $removedAndAddedFilesCollector;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Create form data class with all fields of Form', [new ConfiguredCodeSample(<<<'CODE_SAMPLE'
class MyFormFactory
{
public function create()
{
$form = new Form();
$form->addText('foo', 'Foo');
$form->addText('bar', 'Bar')->setRequired();
$form->onSuccess[] = function (Form $form, ArrayHash $values) {
// do something
}
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class MyFormFactoryFormData
{
public string $foo;
public string $bar;
}
class MyFormFactory
{
public function create()
{
$form = new Form();
$form->addText('foo', 'Foo');
$form->addText('bar', 'Bar')->setRequired();
$form->onSuccess[] = function (Form $form, MyFormFactoryFormData $values) {
// do something
}
}
}
CODE_SAMPLE
, [self::FORM_DATA_CLASS_PARENT => '', self::FORM_DATA_CLASS_TRAITS => []])]);
}
public function getNodeTypes() : array
{
return [Class_::class];
}
/**
* @param mixed[] $configuration
*/
public function configure(array $configuration) : void
{
if (isset($configuration[self::FORM_DATA_CLASS_PARENT])) {
$formDataClassParent = $configuration[self::FORM_DATA_CLASS_PARENT];
Assert::string($formDataClassParent);
$this->formDataClassParent = $formDataClassParent;
}
if (isset($configuration[self::FORM_DATA_CLASS_TRAITS])) {
$formDataClassTraits = $configuration[self::FORM_DATA_CLASS_TRAITS];
Assert::isArray($formDataClassTraits);
Assert::allString($formDataClassTraits);
$this->formDataClassTraits = $formDataClassTraits;
}
}
/**
* @param Class_ $node
*/
public function refactor(Node $node) : ?Node
{
if ($node->name === null) {
return null;
}
$shortClassName = $this->nodeNameResolver->getShortName($node);
$fullClassName = $this->getName($node);
$form = $this->formVariableFinder->find($node);
if (!$form instanceof Variable) {
return null;
}
$formFields = $this->formFieldsFinder->find($node, $form);
if ($formFields === []) {
return null;
}
$properties = [];
foreach ($formFields as $formField) {
$properties[$formField->getName()] = ['type' => $formField->getType(), 'nullable' => $formField->getType() === 'int' && !$formField->isRequired()];
}
$formDataClassName = $shortClassName . 'FormData';
$fullFormDataClassName = '\\' . $fullClassName . 'FormData';
$formDataClass = $this->classWithPublicPropertiesFactory->createNode($fullFormDataClassName, $properties, $this->formDataClassParent, $this->formDataClassTraits);
$printedClassContent = "<?php\n\n" . $this->nodePrinter->print($formDataClass) . "\n";
$smartFileInfo = $this->file->getSmartFileInfo();
$targetFilePath = $smartFileInfo->getRealPathDirectory() . '/' . $formDataClassName . '.php';
$addedFileWithContent = new AddedFileWithContent($targetFilePath, $printedClassContent);
$this->removedAndAddedFilesCollector->addAddedFile($addedFileWithContent);
$onSuccessCallback = $this->formOnSuccessCallbackFinder->find($node, $form);
if (!$onSuccessCallback instanceof Expr) {
return null;
}
$valuesParam = $this->formOnSuccessCallbackValuesParamFinder->find($node, $onSuccessCallback);
if (!$valuesParam instanceof Param) {
return null;
}
$valuesParam->type = new Identifier($fullFormDataClassName);
return $node;
}
}

View File

@ -1,177 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PHPStan\Type\ObjectType;
use PHPStan\Type\VerbosityLevel;
use Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector;
use Rector\Core\Rector\AbstractRector;
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
use Rector\Nette\ValueObject\LatteVariableType;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\Class_\LatteVarTypesBasedOnPresenterTemplateParametersRector\LatteVarTypesBasedOnPresenterTemplateParametersRectorTest
*/
final class LatteVarTypesBasedOnPresenterTemplateParametersRector extends AbstractRector
{
/**
* @var \Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector
*/
private $removedAndAddedFilesCollector;
public function __construct(RemovedAndAddedFilesCollector $removedAndAddedFilesCollector)
{
$this->removedAndAddedFilesCollector = $removedAndAddedFilesCollector;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Adds latte {varType}s based on presenter $this->template parameters', [new CodeSample(<<<'CODE_SAMPLE'
// presenters/SomePresenter.php
<?php
use Nette\Application\UI\Presenter;
class SomePresenter extends Presenter
{
public function renderDefault(): void
{
$this->template->title = 'My title';
$this->template->count = 123;
}
}
// templates/Some/default.latte
<h1>{$title}</h1>
<span class="count">{$count}</span>
CODE_SAMPLE
, <<<'CODE_SAMPLE'
// presenters/SomePresenter.php
<?php
use Nette\Application\UI\Presenter;
class SomePresenter extends Presenter
{
public function renderDefault(): void
{
$this->template->title = 'My title';
$this->template->count = 123;
}
}
// templates/Some/default.latte
{varType string $title}
{varType int $count}
<h1>{$title}</h1>
<span class="count">{$count}</span>
CODE_SAMPLE
)]);
}
public function getNodeTypes() : array
{
return [Class_::class];
}
/**
* @param Class_ $node
*/
public function refactor(Node $node)
{
if (!$this->nodeTypeResolver->isObjectType($node, new ObjectType('Nette\\Application\\UI\\Presenter'))) {
return null;
}
if ($node->name === null) {
return null;
}
$shortClassName = $this->nodeNameResolver->getShortName($node);
$presenterName = \str_replace('Presenter', '', $shortClassName);
$actionVarTypes = [];
foreach ($node->getMethods() as $method) {
$fullActionName = $method->name->name;
if (\strncmp($fullActionName, 'action', \strlen('action')) !== 0 && \strncmp($fullActionName, 'render', \strlen('render')) !== 0) {
continue;
}
$actionName = \str_replace(['action', 'render'], '', $fullActionName);
$actionName = \lcfirst($actionName);
if (!isset($actionVarTypes[$actionName])) {
$actionVarTypes[$actionName] = [];
}
$actionVarTypes[$actionName] = \array_merge($actionVarTypes[$actionName], $this->findVarTypesForAction($method));
}
$this->printVarTypesToTemplateFiles($actionVarTypes, $presenterName);
return null;
}
/**
* @return LatteVariableType[]
*/
private function findVarTypesForAction(ClassMethod $method) : array
{
$varTypes = [];
$stmts = $method->getStmts();
if ($stmts === null) {
return [];
}
foreach ($stmts as $stmt) {
if (!$stmt instanceof Expression) {
continue;
}
if (!$stmt->expr instanceof Assign) {
continue;
}
if (!$stmt->expr->var instanceof PropertyFetch) {
continue;
}
/** @var PropertyFetch $propertyFetch */
$propertyFetch = $stmt->expr->var;
if (!$this->isName($propertyFetch->var, 'template')) {
continue;
}
$staticType = $this->getType($stmt->expr->expr);
$varTypes[] = new LatteVariableType((string) $this->getName($propertyFetch->name), $staticType->describe(VerbosityLevel::typeOnly()));
}
return $varTypes;
}
/**
* @param array<string, LatteVariableType[]> $actionVarTypes
*/
private function printVarTypesToTemplateFiles(array $actionVarTypes, string $presenterName) : void
{
foreach ($actionVarTypes as $actionName => $varTypes) {
if ($varTypes === []) {
continue;
}
$templateFilePath = $this->findTemplateFilePath($presenterName, $actionName);
if ($templateFilePath === null) {
continue;
}
$content = \file_get_contents($templateFilePath);
$varTypeContentParts = [];
foreach ($varTypes as $varType) {
$varTypeContentParts[] = '{varType ' . $varType->getType() . ' $' . $varType->getName() . '}';
}
$content = \implode("\n", $varTypeContentParts) . "\n\n" . $content;
$addedFileWithContent = new AddedFileWithContent($templateFilePath, $content);
$this->removedAndAddedFilesCollector->addAddedFile($addedFileWithContent);
}
}
private function findTemplateFilePath(string $presenterName, string $actionName) : ?string
{
$smartFileInfo = $this->file->getSmartFileInfo();
$dir = $smartFileInfo->getRealPathDirectory();
$dir = \is_dir("{$dir}/templates") ? $dir : \dirname($dir);
$templateFileCandidates = ["{$dir}/templates/{$presenterName}/{$actionName}.latte", "{$dir}/templates/{$presenterName}.{$actionName}.latte"];
foreach ($templateFileCandidates as $templateFileCandidate) {
if (\file_exists($templateFileCandidate)) {
return $templateFileCandidate;
}
}
return null;
}
}

View File

@ -1,164 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\Nette\NodeAnalyzer\PropertyUsageAnalyzer;
use Rector\PostRector\Collector\PropertyToAddCollector;
use Rector\PostRector\ValueObject\PropertyMetadata;
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\Class_\MoveInjectToExistingConstructorRector\MoveInjectToExistingConstructorRectorTest
*/
final class MoveInjectToExistingConstructorRector extends AbstractRector
{
/**
* @var \Rector\Nette\NodeAnalyzer\PropertyUsageAnalyzer
*/
private $propertyUsageAnalyzer;
/**
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover
*/
private $phpDocTagRemover;
/**
* @var \Rector\PostRector\Collector\PropertyToAddCollector
*/
private $propertyToAddCollector;
/**
* @var \Rector\Privatization\NodeManipulator\VisibilityManipulator
*/
private $visibilityManipulator;
/**
* @var \Rector\Core\Php\PhpVersionProvider
*/
private $phpVersionProvider;
public function __construct(PropertyUsageAnalyzer $propertyUsageAnalyzer, PhpDocTagRemover $phpDocTagRemover, PropertyToAddCollector $propertyToAddCollector, VisibilityManipulator $visibilityManipulator, PhpVersionProvider $phpVersionProvider)
{
$this->propertyUsageAnalyzer = $propertyUsageAnalyzer;
$this->phpDocTagRemover = $phpDocTagRemover;
$this->propertyToAddCollector = $propertyToAddCollector;
$this->visibilityManipulator = $visibilityManipulator;
$this->phpVersionProvider = $phpVersionProvider;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Move @inject properties to constructor, if there already is one', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
/**
* @var SomeDependency
* @inject
*/
public $someDependency;
/**
* @var OtherDependency
*/
private $otherDependency;
public function __construct(OtherDependency $otherDependency)
{
$this->otherDependency = $otherDependency;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
/**
* @var SomeDependency
*/
private $someDependency;
/**
* @var OtherDependency
*/
private $otherDependency;
public function __construct(OtherDependency $otherDependency, SomeDependency $someDependency)
{
$this->otherDependency = $otherDependency;
$this->someDependency = $someDependency;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [Class_::class];
}
/**
* @param Class_ $node
*/
public function refactor(Node $node) : ?Node
{
$injectProperties = $this->getInjectProperties($node);
if ($injectProperties === []) {
return null;
}
$constructClassMethod = $node->getMethod(MethodName::CONSTRUCT);
if (!$constructClassMethod instanceof ClassMethod) {
return null;
}
foreach ($injectProperties as $injectProperty) {
$this->removeInjectAnnotation($injectProperty);
$this->changePropertyVisibility($injectProperty);
$propertyName = $injectProperty->props[0]->name->toString();
$propertyType = $this->nodeTypeResolver->getType($injectProperty);
$propertyMetadata = new PropertyMetadata($propertyName, $propertyType, $injectProperty->flags);
$this->propertyToAddCollector->addPropertyToClass($node, $propertyMetadata);
if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::PROPERTY_PROMOTION)) {
$this->removeNode($injectProperty);
}
}
return $node;
}
/**
* @return Property[]
*/
private function getInjectProperties(Class_ $class) : array
{
return \array_filter($class->getProperties(), function (Property $property) : bool {
return $this->isInjectProperty($property);
});
}
private function removeInjectAnnotation(Property $property) : void
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$injectTagValueNode = $phpDocInfo->getByName('inject');
if ($injectTagValueNode instanceof \PHPStan\PhpDocParser\Ast\Node) {
$this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $injectTagValueNode);
}
}
private function changePropertyVisibility(Property $injectProperty) : void
{
if ($this->propertyUsageAnalyzer->isPropertyFetchedInChildClass($injectProperty)) {
$this->visibilityManipulator->makeProtected($injectProperty);
} else {
$this->visibilityManipulator->makePrivate($injectProperty);
}
}
private function isInjectProperty(Property $property) : bool
{
if (!$property->isPublic()) {
return \false;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
return $phpDocInfo->hasByName('inject');
}
}

View File

@ -1,250 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\Class_;
use RectorPrefix202208\Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PHPStan\Type\ObjectType;
use PHPStan\Type\VerbosityLevel;
use Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector;
use Rector\Core\Contract\PhpParser\NodePrinterInterface;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
use Rector\Nette\NodeFactory\ClassWithPublicPropertiesFactory;
use Rector\Nette\ValueObject\LatteVariableType;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix202208\Webmozart\Assert\Assert;
/**
* @see \Rector\Nette\Tests\Rector\Class_\TemplateTypeBasedOnPresenterTemplateParametersRector\TemplateTypeBasedOnPresenterTemplateParametersRectorTest
*/
final class TemplateTypeBasedOnPresenterTemplateParametersRector extends AbstractRector implements ConfigurableRectorInterface
{
public const TEMPLATE_CLASS_PARENT = 'template_class_parent';
public const TEMPLATE_CLASS_TRAITS = 'template_class_traits';
/**
* @var string
*/
private $templateClassParent = 'Nette\\Bridges\\ApplicationLatte\\Template';
/**
* @var string[]
*/
private $templateClassTraits = [];
/**
* @var \Rector\Nette\NodeFactory\ClassWithPublicPropertiesFactory
*/
private $classWithPublicPropertiesFactory;
/**
* @var \Rector\Core\Contract\PhpParser\NodePrinterInterface
*/
private $nodePrinter;
/**
* @var \Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector
*/
private $removedAndAddedFilesCollector;
public function __construct(ClassWithPublicPropertiesFactory $classWithPublicPropertiesFactory, NodePrinterInterface $nodePrinter, RemovedAndAddedFilesCollector $removedAndAddedFilesCollector)
{
$this->classWithPublicPropertiesFactory = $classWithPublicPropertiesFactory;
$this->nodePrinter = $nodePrinter;
$this->removedAndAddedFilesCollector = $removedAndAddedFilesCollector;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Creates Template class and adds latte {templateType} based on presenter $this->template parameters', [new ConfiguredCodeSample(<<<'CODE_SAMPLE'
// presenters/SomePresenter.php
<?php
use Nette\Application\UI\Presenter;
class SomePresenter extends Presenter
{
public function renderDefault(): void
{
$this->template->title = 'My title';
$this->template->count = 123;
}
}
// templates/Some/default.latte
<h1>{$title}</h1>
<span class="count">{$count}</span>
CODE_SAMPLE
, <<<'CODE_SAMPLE'
// presenters/SomePresenter.php
<?php
use Nette\Application\UI\Presenter;
class SomePresenter extends Presenter
{
public function renderDefault(): void
{
$this->template->title = 'My title';
$this->template->count = 123;
}
}
// presenters/SomeDefaultTemplate.php
<?php
use Nette\Bridges\ApplicationLatte\Template;
class SomeDefaultTemplate extends Template
{
public string $title;
public int $count;
}
// templates/Some/default.latte
{templateType SomeDefaultTemplate}
<h1>{$title}</h1>
<span class="count">{$count}</span>
CODE_SAMPLE
, [self::TEMPLATE_CLASS_PARENT => '', self::TEMPLATE_CLASS_TRAITS => []])]);
}
public function getNodeTypes() : array
{
return [Class_::class];
}
/**
* @param mixed[] $configuration
*/
public function configure(array $configuration) : void
{
if (isset($configuration[self::TEMPLATE_CLASS_PARENT])) {
$templateClassParent = $configuration[self::TEMPLATE_CLASS_PARENT];
Assert::string($templateClassParent);
$this->templateClassParent = $templateClassParent;
}
if (isset($configuration[self::TEMPLATE_CLASS_TRAITS])) {
$templateClassTraits = $configuration[self::TEMPLATE_CLASS_TRAITS];
Assert::isArray($templateClassTraits);
$this->templateClassTraits = $templateClassTraits;
}
}
/**
* @param Class_ $node
*/
public function refactor(Node $node)
{
if (!$this->nodeTypeResolver->isObjectType($node, new ObjectType('Nette\\Application\\UI\\Presenter'))) {
return null;
}
if ($node->name === null) {
return null;
}
$shortClassName = $this->nodeNameResolver->getShortName($node);
$fullClassName = $this->nodeNameResolver->getName($node);
if (!\is_string($fullClassName)) {
return null;
}
$presenterName = \str_replace('Presenter', '', $shortClassName);
$actionVarTypes = [];
foreach ($node->getMethods() as $method) {
$fullActionName = $method->name->name;
if (\strncmp($fullActionName, 'action', \strlen('action')) !== 0 && \strncmp($fullActionName, 'render', \strlen('render')) !== 0) {
continue;
}
$actionName = \str_replace(['action', 'render'], '', $fullActionName);
$actionName = \lcfirst($actionName);
if (!isset($actionVarTypes[$actionName])) {
$actionVarTypes[$actionName] = [];
}
$actionVarTypes[$actionName] = \array_merge($actionVarTypes[$actionName], $this->findVarTypesForAction($method));
}
$this->printTemplateTypeToTemplateFiles($actionVarTypes, $presenterName, $fullClassName);
return null;
}
/**
* @return LatteVariableType[]
*/
private function findVarTypesForAction(ClassMethod $method) : array
{
$varTypes = [];
$stmts = $method->getStmts();
if ($stmts === null) {
return [];
}
foreach ($stmts as $stmt) {
if (!$stmt instanceof Expression) {
continue;
}
if (!$stmt->expr instanceof Assign) {
continue;
}
if (!$stmt->expr->var instanceof PropertyFetch) {
continue;
}
/** @var PropertyFetch $propertyFetch */
$propertyFetch = $stmt->expr->var;
if (!$this->isName($propertyFetch->var, 'template')) {
continue;
}
$staticType = $this->getType($stmt->expr->expr);
$varTypes[] = new LatteVariableType((string) $this->getName($propertyFetch->name), $staticType->describe(VerbosityLevel::typeOnly()));
}
return $varTypes;
}
/**
* @param array<string, LatteVariableType[]> $actionVarTypes
*/
private function printTemplateTypeToTemplateFiles(array $actionVarTypes, string $presenterName, string $fullPresenterName) : void
{
foreach ($actionVarTypes as $actionName => $varTypes) {
if ($varTypes === []) {
continue;
}
$templateFilePath = $this->findTemplateFilePath($presenterName, $actionName);
if ($templateFilePath === null) {
continue;
}
$templateClassName = $this->createTemplateClass($presenterName, $fullPresenterName, $actionName, $varTypes);
$content = \file_get_contents($templateFilePath);
$content = '{templateType ' . \ltrim($templateClassName, '\\') . "}\n\n" . $content;
$addedFileWithContent = new AddedFileWithContent($templateFilePath, $content);
$this->removedAndAddedFilesCollector->addAddedFile($addedFileWithContent);
}
}
/**
* @param LatteVariableType[] $varTypes
*/
private function createTemplateClass(string $presenterName, string $fullPresenterName, string $actionName, array $varTypes) : string
{
$properties = [];
foreach ($varTypes as $varType) {
$properties[$varType->getName()] = ['type' => $varType->getType()];
}
$upperCasedActionName = \ucfirst($actionName);
$templateClassName = $presenterName . $upperCasedActionName . 'Template';
$presenterPattern = '#Presenter$#';
$fullTemplateClassName = '\\' . Strings::replace($fullPresenterName, $presenterPattern, $upperCasedActionName . 'Template');
$templateClass = $this->classWithPublicPropertiesFactory->createNode($fullTemplateClassName, $properties, $this->templateClassParent, $this->templateClassTraits);
$printedClassContent = "<?php\n\n" . $this->nodePrinter->print($templateClass) . "\n";
$smartFileInfo = $this->file->getSmartFileInfo();
$targetFilePath = $smartFileInfo->getRealPathDirectory() . '/' . $templateClassName . '.php';
$addedFileWithContent = new AddedFileWithContent($targetFilePath, $printedClassContent);
$this->removedAndAddedFilesCollector->addAddedFile($addedFileWithContent);
return $fullTemplateClassName;
}
private function findTemplateFilePath(string $presenterName, string $actionName) : ?string
{
$smartFileInfo = $this->file->getSmartFileInfo();
$dir = $smartFileInfo->getRealPathDirectory();
$dir = \is_dir("{$dir}/templates") ? $dir : \dirname($dir);
$templateFileCandidates = ["{$dir}/templates/{$presenterName}/{$actionName}.latte", "{$dir}/templates/{$presenterName}.{$actionName}.latte"];
foreach ($templateFileCandidates as $templateFileCandidate) {
if (\file_exists($templateFileCandidate)) {
return $templateFileCandidate;
}
}
return null;
}
}

View File

@ -1,106 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\StaticCall;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\FuncCall\JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector\JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRectorTest
*/
final class JsonDecodeEncodeToNetteUtilsJsonDecodeEncodeRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Changes json_encode()/json_decode() to safer and more verbose Nette\\Utils\\Json::encode()/decode() calls', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function decodeJson(string $jsonString)
{
$stdClass = json_decode($jsonString);
$array = json_decode($jsonString, true);
$array = json_decode($jsonString, false);
}
public function encodeJson(array $data)
{
$jsonString = json_encode($data);
$prettyJsonString = json_encode($data, JSON_PRETTY_PRINT);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function decodeJson(string $jsonString)
{
$stdClass = \Nette\Utils\Json::decode($jsonString);
$array = \Nette\Utils\Json::decode($jsonString, \Nette\Utils\Json::FORCE_ARRAY);
$array = \Nette\Utils\Json::decode($jsonString);
}
public function encodeJson(array $data)
{
$jsonString = \Nette\Utils\Json::encode($data);
$prettyJsonString = \Nette\Utils\Json::encode($data, \Nette\Utils\Json::PRETTY);
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [FuncCall::class];
}
/**
* @param FuncCall $node
*/
public function refactor(Node $node) : ?Node
{
if ($this->isName($node, 'json_encode')) {
return $this->refactorJsonEncode($node);
}
if ($this->isName($node, 'json_decode')) {
return $this->refactorJsonDecode($node);
}
return null;
}
private function refactorJsonEncode(FuncCall $funcCall) : StaticCall
{
$args = $funcCall->getArgs();
if (isset($args[1])) {
$secondArgumentValue = $args[1]->value;
if ($this->isName($secondArgumentValue, 'JSON_PRETTY_PRINT')) {
$classConstFetch = $this->nodeFactory->createClassConstFetch('Nette\\Utils\\Json', 'PRETTY');
$args[1] = new Arg($classConstFetch);
}
}
return $this->nodeFactory->createStaticCall('Nette\\Utils\\Json', 'encode', $args);
}
private function refactorJsonDecode(FuncCall $funcCall) : StaticCall
{
$args = $funcCall->getArgs();
if (isset($args[1])) {
$secondArgumentValue = $args[1]->value;
if ($this->valueResolver->isFalse($secondArgumentValue)) {
unset($args[1]);
} elseif ($this->valueResolver->isTrue($secondArgumentValue)) {
$classConstFetch = $this->nodeFactory->createClassConstFetch('Nette\\Utils\\Json', 'FORCE_ARRAY');
$args[1] = new Arg($classConstFetch);
}
}
return $this->nodeFactory->createStaticCall('Nette\\Utils\\Json', 'decode', $args);
}
}

View File

@ -1,193 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\FuncCall;
use RectorPrefix202208\Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\BitwiseAnd;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BitwiseNot;
use PhpParser\Node\Expr\Cast\Bool_;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://tomasvotruba.com/blog/2019/02/07/what-i-learned-by-using-thecodingmachine-safe/#is-there-a-better-way
*
* @see \Rector\Nette\Tests\Rector\FuncCall\PregFunctionToNetteUtilsStringsRector\PregFunctionToNetteUtilsStringsRectorTest
*/
final class PregFunctionToNetteUtilsStringsRector extends AbstractRector
{
/**
* @var array<string, string>
*/
private const FUNCTION_NAME_TO_METHOD_NAME = ['preg_split' => 'split', 'preg_replace' => 'replace', 'preg_replace_callback' => 'replace'];
/**
* @see https://regex101.com/r/05MPWa/1/
* @var string
*/
private const SLASH_REGEX = '#[^\\\\]\\(#';
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Use Nette\\Utils\\Strings over bare preg_split() and preg_replace() functions', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$content = 'Hi my name is Tom';
$splitted = preg_split('#Hi#', $content);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\Utils\Strings;
class SomeClass
{
public function run()
{
$content = 'Hi my name is Tom';
$splitted = \Nette\Utils\Strings::split($content, '#Hi#');
}
}
CODE_SAMPLE
)]);
}
/**
* @param FuncCall|Identical $node
*/
public function refactor(Node $node) : ?Node
{
if ($node instanceof Identical) {
return $this->refactorIdentical($node);
}
return $this->refactorFuncCall($node);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [FuncCall::class, Identical::class];
}
public function refactorIdentical(Identical $identical) : ?Bool_
{
$parent = $identical->getAttribute(AttributeKey::PARENT_NODE);
if (!$parent instanceof Node) {
return null;
}
if ($identical->left instanceof FuncCall) {
$refactoredFuncCall = $this->refactorFuncCall($identical->left);
if ($refactoredFuncCall !== null && $this->valueResolver->isValue($identical->right, 1)) {
return $this->createBoolCast($parent, $refactoredFuncCall);
}
}
if ($identical->right instanceof FuncCall) {
$refactoredFuncCall = $this->refactorFuncCall($identical->right);
if ($refactoredFuncCall !== null && $this->valueResolver->isValue($identical->left, 1)) {
return new Bool_($refactoredFuncCall);
}
}
return null;
}
/**
* @return FuncCall|StaticCall|Assign|null
*/
public function refactorFuncCall(FuncCall $funcCall) : ?Expr
{
$methodName = $this->nodeNameResolver->matchNameFromMap($funcCall, self::FUNCTION_NAME_TO_METHOD_NAME);
if ($methodName === null) {
return null;
}
$matchStaticCall = $this->createMatchStaticCall($funcCall, $methodName);
// skip assigns, might be used with different return value
$parentNode = $funcCall->getAttribute(AttributeKey::PARENT_NODE);
if ($parentNode instanceof Assign) {
if ($methodName === 'split') {
return $this->processSplit($funcCall, $matchStaticCall);
}
if ($methodName === 'replace') {
return $matchStaticCall;
}
return null;
}
$currentFunctionName = $this->getName($funcCall);
$args = $funcCall->getArgs();
// assign
if (isset($args[2]) && $currentFunctionName !== 'preg_replace') {
return new Assign($args[2]->value, $matchStaticCall);
}
return $matchStaticCall;
}
/**
* @param Expr $expr
*/
private function createBoolCast(?Node $node, Node $expr) : Bool_
{
if ($node instanceof Return_ && $expr instanceof Assign) {
$expr = $expr->expr;
}
return new Bool_($expr);
}
private function createMatchStaticCall(FuncCall $funcCall, string $methodName) : StaticCall
{
$args = [];
if ($methodName === 'replace') {
$args[] = $funcCall->args[2];
$args[] = $funcCall->args[0];
$args[] = $funcCall->args[1];
} else {
$args[] = $funcCall->args[1];
$args[] = $funcCall->args[0];
}
return $this->nodeFactory->createStaticCall('Nette\\Utils\\Strings', $methodName, $args);
}
/**
* @return FuncCall|StaticCall
*/
private function processSplit(FuncCall $funcCall, StaticCall $matchStaticCall) : Expr
{
$this->compensateNetteUtilsSplitDelimCapture($matchStaticCall);
$funcCallArgs = $funcCall->getArgs();
if (!isset($funcCallArgs[2])) {
return $matchStaticCall;
}
$thirdArg = $funcCallArgs[2];
if ($this->valueResolver->isValue($thirdArg->value, -1)) {
if (isset($funcCallArgs[3])) {
$matchStaticCall->args[] = $funcCallArgs[3];
}
return $matchStaticCall;
}
return $funcCall;
}
/**
* Handles https://github.com/rectorphp/rector/issues/2348
*/
private function compensateNetteUtilsSplitDelimCapture(StaticCall $staticCall) : void
{
$args = $staticCall->getArgs();
$patternValue = $this->valueResolver->getValue($args[1]->value);
if (!\is_string($patternValue)) {
return;
}
$match = Strings::match($patternValue, self::SLASH_REGEX);
if ($match === null) {
return;
}
$constFetch = new ConstFetch(new Name('PREG_SPLIT_DELIM_CAPTURE'));
$bitwiseAnd = new BitwiseAnd(new LNumber(0), new BitwiseNot($constFetch));
$staticCall->args[2] = new Arg($bitwiseAnd);
}
}

View File

@ -1,148 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\Cast\Bool_;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\Rector\AbstractRector;
use Rector\Nette\NodeAnalyzer\PregMatchAllAnalyzer;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://tomasvotruba.com/blog/2019/02/07/what-i-learned-by-using-thecodingmachine-safe/#is-there-a-better-way
*
* @see \Rector\Nette\Tests\Rector\FuncCall\PregMatchFunctionToNetteUtilsStringsRector\PregMatchFunctionToNetteUtilsStringsRectorTest
*/
final class PregMatchFunctionToNetteUtilsStringsRector extends AbstractRector
{
/**
* @var array<string, string>
*/
private const FUNCTION_NAME_TO_METHOD_NAME = ['preg_match' => 'match', 'preg_match_all' => 'matchAll'];
/**
* @var \Rector\Nette\NodeAnalyzer\PregMatchAllAnalyzer
*/
private $pregMatchAllAnalyzer;
public function __construct(PregMatchAllAnalyzer $pregMatchAllAnalyzer)
{
$this->pregMatchAllAnalyzer = $pregMatchAllAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Use Nette\\Utils\\Strings over bare preg_match() and preg_match_all() functions', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$content = 'Hi my name is Tom';
preg_match('#Hi#', $content, $matches);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\Utils\Strings;
class SomeClass
{
public function run()
{
$content = 'Hi my name is Tom';
$matches = Strings::match($content, '#Hi#');
}
}
CODE_SAMPLE
)]);
}
/**
* @param FuncCall|Identical $node
*/
public function refactor(Node $node) : ?Node
{
if ($node instanceof Identical) {
return $this->refactorIdentical($node);
}
return $this->refactorFuncCall($node);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [FuncCall::class, Identical::class];
}
public function refactorIdentical(Identical $identical) : ?Bool_
{
$parent = $identical->getAttribute(AttributeKey::PARENT_NODE);
if (!$parent instanceof Node) {
return null;
}
if ($identical->left instanceof FuncCall) {
$refactoredFuncCall = $this->refactorFuncCall($identical->left);
if ($refactoredFuncCall !== null && $this->valueResolver->isValue($identical->right, 1)) {
return $this->createBoolCast($parent, $refactoredFuncCall);
}
}
if ($identical->right instanceof FuncCall) {
$refactoredFuncCall = $this->refactorFuncCall($identical->right);
if ($refactoredFuncCall !== null && $this->valueResolver->isValue($identical->left, 1)) {
return $this->createBoolCast($parent, $refactoredFuncCall);
}
}
return null;
}
/**
* @return FuncCall|StaticCall|Assign|null
*/
public function refactorFuncCall(FuncCall $funcCall) : ?Expr
{
$methodName = $this->nodeNameResolver->matchNameFromMap($funcCall, self::FUNCTION_NAME_TO_METHOD_NAME);
if ($methodName === null) {
return null;
}
$matchStaticCall = $this->createMatchStaticCall($funcCall, $methodName);
// skip assigns, might be used with different return value
$parentNode = $funcCall->getAttribute(AttributeKey::PARENT_NODE);
if ($parentNode instanceof Assign) {
if ($methodName === 'matchAll') {
// use count
return new FuncCall(new Name('count'), [new Arg($matchStaticCall)]);
}
return null;
}
$args = $funcCall->getArgs();
// assign
if (isset($args[2])) {
return new Assign($args[2]->value, $matchStaticCall);
}
return $matchStaticCall;
}
/**
* @param Expr $expr
*/
private function createBoolCast(?Node $node, Node $expr) : Bool_
{
if ($node instanceof Return_ && $expr instanceof Assign) {
$expr = $expr->expr;
}
return new Bool_($expr);
}
private function createMatchStaticCall(FuncCall $funcCall, string $methodName) : StaticCall
{
$originalArgs = $funcCall->getArgs();
$args = [];
$args[] = $originalArgs[1];
$args[] = $originalArgs[0];
$args = $this->pregMatchAllAnalyzer->compensateEnforcedFlag($methodName, $funcCall, $args);
return $this->nodeFactory->createStaticCall('Nette\\Utils\\Strings', $methodName, $args);
}
}

View File

@ -1,63 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/nette/utils/blob/master/src/Utils/Strings.php
* @see \Rector\Nette\Tests\Rector\FuncCall\SubstrStrlenFunctionToNetteUtilsStringsRector\SubstrStrlenFunctionToNetteUtilsStringsRectorTest
*/
final class SubstrStrlenFunctionToNetteUtilsStringsRector extends AbstractRector
{
/**
* @var array<string, string>
*/
private const FUNCTION_TO_STATIC_METHOD = ['substr' => 'substring'];
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Use Nette\\Utils\\Strings over bare string-functions', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
return substr($value, 0, 3);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
return \Nette\Utils\Strings::substring($value, 0, 3);
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [FuncCall::class];
}
/**
* @param FuncCall $node
*/
public function refactor(Node $node) : ?Node
{
foreach (self::FUNCTION_TO_STATIC_METHOD as $function => $staticMethod) {
if (!$this->isName($node, $function)) {
continue;
}
return $this->nodeFactory->createStaticCall('Nette\\Utils\\Strings', $staticMethod, $node->args);
}
return null;
}
}

View File

@ -1,63 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\LNumber;
use RectorPrefix202208\Nette\Utils\DateTime;
use PhpParser\Node;
use PhpParser\Node\Scalar\LNumber;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\LNumber\ReplaceTimeNumberWithDateTimeConstantRector\ReplaceTimeNumberWithDateTimeConstantRectorTest
*/
final class ReplaceTimeNumberWithDateTimeConstantRector extends AbstractRector
{
/**
* @noRector
* @var array<int, string>
*/
private const NUMBER_TO_CONSTANT_NAME = [DateTime::HOUR => 'HOUR', DateTime::DAY => 'DAY', DateTime::WEEK => 'WEEK', DateTime::MONTH => 'MONTH', DateTime::YEAR => 'YEAR'];
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Replace time numbers with Nette\\Utils\\DateTime constants', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
public function run()
{
return 86400;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
public function run()
{
return \Nette\Utils\DateTime::DAY;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [LNumber::class];
}
/**
* @param LNumber $node
*/
public function refactor(Node $node) : ?Node
{
$number = $node->value;
$constantName = self::NUMBER_TO_CONSTANT_NAME[$number] ?? null;
if ($constantName === null) {
return null;
}
return $this->nodeFactory->createClassConstFetch('Nette\\Utils\\DateTime', $constantName);
}
}

View File

@ -1,78 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\Latte;
use Rector\Nette\Contract\Rector\LatteRectorInterface;
use Rector\Nette\Latte\Parser\TemplateTypeParser;
use Rector\Nette\Latte\Parser\VarTypeParser;
use Rector\Renaming\Collector\MethodCallRenameCollector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\Latte\RenameMethodLatteRector\RenameMethodLatteRectorTest
*/
final class RenameMethodLatteRector implements LatteRectorInterface
{
/**
* @var \Rector\Renaming\Collector\MethodCallRenameCollector
*/
private $methodCallRenameCollector;
/**
* @var \Rector\Nette\Latte\Parser\TemplateTypeParser
*/
private $templateTypeParser;
/**
* @var \Rector\Nette\Latte\Parser\VarTypeParser
*/
private $varTypeParser;
public function __construct(MethodCallRenameCollector $methodCallRenameCollector, TemplateTypeParser $templateTypeParser, VarTypeParser $varTypeParser)
{
$this->methodCallRenameCollector = $methodCallRenameCollector;
$this->templateTypeParser = $templateTypeParser;
$this->varTypeParser = $varTypeParser;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Renames method calls in LATTE templates', [new CodeSample(<<<'CODE_SAMPLE'
{varType SomeClass $someClass}
<div n:foreach="$someClass->oldCall() as $item"></div>
CODE_SAMPLE
, <<<'CODE_SAMPLE'
{varType SomeClass $someClass}
<div n:foreach="$someClass->newCall() as $item"></div>
CODE_SAMPLE
)]);
}
public function changeContent(string $content) : string
{
$typesToVariables = $this->findTypesForVariables($content);
foreach ($this->methodCallRenameCollector->getMethodCallRenames() as $methodCallRename) {
$className = $methodCallRename->getClass();
if (!isset($typesToVariables[$className])) {
continue;
}
foreach ($typesToVariables[$className] as $variableName) {
$content = \str_replace('$' . $variableName . '->' . $methodCallRename->getOldMethod() . '(', '$' . $variableName . '->' . $methodCallRename->getNewMethod() . '(', $content);
}
}
return $content;
}
/**
* @return array<string, string[]> list of types with all variables of this type
*/
private function findTypesForVariables(string $content) : array
{
$typesToVariables = [];
$latteVariableTypes = \array_merge($this->templateTypeParser->parse($content), $this->varTypeParser->parse($content));
foreach ($latteVariableTypes as $latteVariableType) {
if (!isset($typesToVariables[$latteVariableType->getType()])) {
$typesToVariables[$latteVariableType->getType()] = [];
}
$typesToVariables[$latteVariableType->getType()][] = $latteVariableType->getName();
}
return $typesToVariables;
}
}

View File

@ -1,74 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name\FullyQualified;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/Kdyby/Doctrine/commit/db80bf77c0b68af88dfe7eddb2cb2db94aedb04a#diff-ccc8ba07edfa3a425ddfe564acb50656R291
*
* @see \Rector\Nette\Tests\Rector\MethodCall\BuilderExpandToHelperExpandRector\BuilderExpandToHelperExpandRectorTest
*/
final class BuilderExpandToHelperExpandRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change containerBuilder->expand() to static call with parameters', [new CodeSample(<<<'CODE_SAMPLE'
use Nette\DI\CompilerExtension;
final class SomeClass extends CompilerExtension
{
public function loadConfiguration()
{
$value = $this->getContainerBuilder()->expand('%value');
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\DI\CompilerExtension;
final class SomeClass extends CompilerExtension
{
public function loadConfiguration()
{
$value = \Nette\DI\Helpers::expand('%value', $this->getContainerBuilder()->parameters);
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isObjectType($node->var, new ObjectType('Nette\\DI\\ContainerBuilder'))) {
return null;
}
if (!$this->isName($node->name, 'expand')) {
return null;
}
$args = $node->args;
$getContainerBuilderMethodCall = new MethodCall(new Variable('this'), 'getContainerBuilder');
$parametersPropertyFetch = new PropertyFetch($getContainerBuilderMethodCall, 'parameters');
$args[] = new Arg($parametersPropertyFetch);
return new StaticCall(new FullyQualified('Nette\\DI\\Helpers'), 'expand', $args);
}
}

View File

@ -1,93 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
use Rector\Symfony\NodeAnalyzer\DependencyInjectionMethodCallAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\MethodCall\ContextGetByTypeToConstructorInjectionRector\ContextGetByTypeToConstructorInjectionRectorTest
*/
final class ContextGetByTypeToConstructorInjectionRector extends AbstractRector
{
/**
* @var \Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer
*/
private $testsNodeAnalyzer;
/**
* @var \Rector\Symfony\NodeAnalyzer\DependencyInjectionMethodCallAnalyzer
*/
private $dependencyInjectionMethodCallAnalyzer;
public function __construct(TestsNodeAnalyzer $testsNodeAnalyzer, DependencyInjectionMethodCallAnalyzer $dependencyInjectionMethodCallAnalyzer)
{
$this->testsNodeAnalyzer = $testsNodeAnalyzer;
$this->dependencyInjectionMethodCallAnalyzer = $dependencyInjectionMethodCallAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Move dependency get via $context->getByType() to constructor injection', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
/**
* @var \Nette\DI\Container
*/
private $context;
public function run()
{
$someTypeToInject = $this->context->getByType(SomeTypeToInject::class);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
/**
* @var \Nette\DI\Container
*/
private $context;
public function __construct(private SomeTypeToInject $someTypeToInject)
{
}
public function run()
{
$someTypeToInject = $this->someTypeToInject;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node) : ?Node
{
if ($this->testsNodeAnalyzer->isInTestClass($node)) {
return null;
}
$callerType = $this->nodeTypeResolver->getType($node->var);
$containerObjectType = new ObjectType('Nette\\DI\\Container');
if (!$containerObjectType->isSuperTypeOf($callerType)->yes()) {
return null;
}
if (!$this->isName($node->name, 'getByType')) {
return null;
}
return $this->dependencyInjectionMethodCallAnalyzer->replaceMethodCallWithPropertyFetchAndDependency($node);
}
}

View File

@ -1,60 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Identifier;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\MethodCall\ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector\ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRectorTest
*/
final class ConvertAddUploadWithThirdArgumentTrueToAddMultiUploadRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('convert addUpload() with 3rd argument true to addMultiUpload()', [new CodeSample(<<<'CODE_SAMPLE'
$form = new Nette\Forms\Form();
$form->addUpload('...', '...', true);
CODE_SAMPLE
, <<<'CODE_SAMPLE'
$form = new Nette\Forms\Form();
$form->addMultiUpload('...', '...');
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isObjectType($node->var, new ObjectType('Nette\\Forms\\Form'))) {
return null;
}
if (!$this->isName($node->name, 'addUpload')) {
return null;
}
$args = $node->getArgs();
if (!isset($args[2])) {
return null;
}
$thirdArg = $args[2];
if ($this->valueResolver->isTrue($thirdArg->value)) {
$node->name = new Identifier('addMultiUpload');
unset($node->args[2]);
return $node;
}
return null;
}
}

View File

@ -1,74 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\String_;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/nette/utils/commit/75abe7c6aa472fd023aa49ba1a4d6c6eca0eaaa6
* @see https://github.com/nette/utils/issues/88
*
* @see \Rector\Nette\Tests\Rector\MethodCall\MagicHtmlCallToAppendAttributeRector\MagicHtmlCallToAppendAttributeRectorTest
*/
final class MagicHtmlCallToAppendAttributeRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change magic addClass() etc. calls on Html to explicit methods', [new CodeSample(<<<'CODE_SAMPLE'
use Nette\Utils\Html;
final class SomeClass
{
public function run()
{
$html = Html::el();
$html->setClass('first');
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\Utils\Html;
final class SomeClass
{
public function run()
{
$html = Html::el();
$html->appendAttribute('class', 'first');
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isObjectType($node->var, new ObjectType('Nette\\Utils\\Html'))) {
return null;
}
// @todo posibly extends by more common names
if ($this->isName($node->name, 'setClass')) {
$node->name = new Identifier('appendAttribute');
$node->args = \array_merge([new Arg(new String_('class'))], $node->args);
return $node;
}
return null;
}
}

View File

@ -1,78 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\MethodCall\MergeDefaultsInGetConfigCompilerExtensionRector\MergeDefaultsInGetConfigCompilerExtensionRectorTest
*/
final class MergeDefaultsInGetConfigCompilerExtensionRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change $this->getConfig($defaults) to array_merge', [new CodeSample(<<<'CODE_SAMPLE'
use Nette\DI\CompilerExtension;
final class SomeExtension extends CompilerExtension
{
private $defaults = [
'key' => 'value'
];
public function loadConfiguration()
{
$config = $this->getConfig($this->defaults);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\DI\CompilerExtension;
final class SomeExtension extends CompilerExtension
{
private $defaults = [
'key' => 'value'
];
public function loadConfiguration()
{
$config = array_merge($this->defaults, $this->getConfig());
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isObjectType($node->var, new ObjectType('Nette\\DI\\CompilerExtension'))) {
return null;
}
if (!$this->isName($node->name, 'getConfig')) {
return null;
}
$args = $node->getArgs();
if (\count($args) !== 1) {
return null;
}
$getConfigMethodCall = new MethodCall(new Variable('this'), 'getConfig');
$firstArgValue = $args[0]->value;
return $this->nodeFactory->createFuncCall('array_merge', [$firstArgValue, $getConfigMethodCall]);
}
}

View File

@ -1,71 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\Coalesce;
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Nette\Tests\Rector\MethodCall\RequestGetCookieDefaultArgumentToCoalesceRector\RequestGetCookieDefaultArgumentToCoalesceRectorTest
*/
final class RequestGetCookieDefaultArgumentToCoalesceRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add removed Nette\\Http\\Request::getCookies() default value as coalesce', [new CodeSample(<<<'CODE_SAMPLE'
use Nette\Http\Request;
class SomeClass
{
public function run(Request $request)
{
return $request->getCookie('name', 'default');
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\Http\Request;
class SomeClass
{
public function run(Request $request)
{
return $request->getCookie('name') ?? 'default';
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isObjectType($node->var, new ObjectType('Nette\\Http\\Request'))) {
return null;
}
if (!$this->isName($node->name, 'getCookie')) {
return null;
}
$args = $node->getArgs();
// no default value
if (!isset($args[1])) {
return null;
}
$defaultValue = $args[1]->value;
unset($node->args[1]);
return new Coalesce($node, $defaultValue);
}
}

View File

@ -1,72 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Identifier;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://github.com/nette/di/pull/146/files
*
* @see \Rector\Nette\Tests\Rector\MethodCall\SetClassWithArgumentToSetFactoryRector\SetClassWithArgumentToSetFactoryRectorTest
*/
final class SetClassWithArgumentToSetFactoryRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change setClass with class and arguments to separated methods', [new CodeSample(<<<'CODE_SAMPLE'
use Nette\DI\ContainerBuilder;
class SomeClass
{
public function run(ContainerBuilder $containerBuilder)
{
$containerBuilder->addDefinition('...')
->setClass('SomeClass', [1, 2]);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Nette\DI\ContainerBuilder;
class SomeClass
{
public function run(ContainerBuilder $containerBuilder)
{
$containerBuilder->addDefinition('...')
->setFactory('SomeClass', [1, 2]);
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isName($node->name, 'setClass')) {
return null;
}
if (\count($node->args) !== 2) {
return null;
}
if (!$this->isObjectType($node->var, new ObjectType('Nette\\DI\\Definitions\\ServiceDefinition'))) {
return null;
}
$node->name = new Identifier('setFactory');
return $node;
}
}

View File

@ -1,139 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Rector\Property;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\Nette\NodeAnalyzer\NetteInjectPropertyAnalyzer;
use Rector\Nette\NodeAnalyzer\PropertyUsageAnalyzer;
use Rector\PostRector\Collector\PropertyToAddCollector;
use Rector\PostRector\ValueObject\PropertyMetadata;
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* Covers these cases:
* - https://doc.nette.org/en/2.4/di-usage#toc-inject-annotations
* - https://github.com/Kdyby/Autowired/blob/master/docs/en/index.md#autowired-properties
*
* @see \Rector\Nette\Tests\Rector\Property\NetteInjectToConstructorInjectionRector\NetteInjectToConstructorInjectionRectorTest
*/
final class NetteInjectToConstructorInjectionRector extends AbstractRector
{
/**
* @var \Rector\Nette\NodeAnalyzer\PropertyUsageAnalyzer
*/
private $propertyUsageAnalyzer;
/**
* @var \Rector\Nette\NodeAnalyzer\NetteInjectPropertyAnalyzer
*/
private $netteInjectPropertyAnalyzer;
/**
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover
*/
private $phpDocTagRemover;
/**
* @var \Rector\PostRector\Collector\PropertyToAddCollector
*/
private $propertyToAddCollector;
/**
* @var \Rector\Privatization\NodeManipulator\VisibilityManipulator
*/
private $visibilityManipulator;
/**
* @var \Rector\Core\Php\PhpVersionProvider
*/
private $phpVersionProvider;
public function __construct(PropertyUsageAnalyzer $propertyUsageAnalyzer, NetteInjectPropertyAnalyzer $netteInjectPropertyAnalyzer, PhpDocTagRemover $phpDocTagRemover, PropertyToAddCollector $propertyToAddCollector, VisibilityManipulator $visibilityManipulator, PhpVersionProvider $phpVersionProvider)
{
$this->propertyUsageAnalyzer = $propertyUsageAnalyzer;
$this->netteInjectPropertyAnalyzer = $netteInjectPropertyAnalyzer;
$this->phpDocTagRemover = $phpDocTagRemover;
$this->propertyToAddCollector = $propertyToAddCollector;
$this->visibilityManipulator = $visibilityManipulator;
$this->phpVersionProvider = $phpVersionProvider;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Turns properties with `@inject` to private properties and constructor injection', [new CodeSample(<<<'CODE_SAMPLE'
/**
* @var SomeService
* @inject
*/
public $someService;
CODE_SAMPLE
, <<<'CODE_SAMPLE'
/**
* @var SomeService
*/
private $someService;
public function __construct(SomeService $someService)
{
$this->someService = $someService;
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [Property::class];
}
/**
* @param Property $node
*/
public function refactor(Node $node) : ?Node
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($node);
if (!$phpDocInfo instanceof PhpDocInfo) {
return null;
}
if (!$phpDocInfo->hasByName('inject')) {
return null;
}
if (!$this->netteInjectPropertyAnalyzer->canBeRefactored($node, $phpDocInfo)) {
return null;
}
return $this->refactorNetteInjectProperty($phpDocInfo, $node);
}
private function refactorNetteInjectProperty(PhpDocInfo $phpDocInfo, Property $property) : ?Property
{
$injectTagNode = $phpDocInfo->getByName('inject');
if ($injectTagNode instanceof \PHPStan\PhpDocParser\Ast\Node) {
$this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $injectTagNode);
}
$this->changePropertyVisibility($property);
$class = $this->betterNodeFinder->findParentType($property, Class_::class);
if (!$class instanceof Class_) {
throw new ShouldNotHappenException();
}
$propertyName = $this->nodeNameResolver->getName($property);
$propertyType = $this->nodeTypeResolver->getType($property);
$propertyMetadata = new PropertyMetadata($propertyName, $propertyType, $property->flags);
$this->propertyToAddCollector->addPropertyToClass($class, $propertyMetadata);
if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::PROPERTY_PROMOTION)) {
$this->removeNode($property);
return null;
}
return $property;
}
private function changePropertyVisibility(Property $property) : void
{
if ($this->propertyUsageAnalyzer->isPropertyFetchedInChildClass($property)) {
$this->visibilityManipulator->makeProtected($property);
} else {
$this->visibilityManipulator->makePrivate($property);
}
}
}

View File

@ -1,33 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\Set;
use Rector\Set\Contract\SetListInterface;
final class NetteSetList implements SetListInterface
{
/**
* @var string
*/
public const NETTE_REMOVE_INJECT = __DIR__ . '/../../config/sets/nette-remove-inject.php';
/**
* @var string
*/
public const NETTE_24 = __DIR__ . '/../../config/sets/nette-24.php';
/**
* @var string
*/
public const NETTE_30 = __DIR__ . '/../../config/sets/nette-30.php';
/**
* @var string
*/
public const NETTE_31 = __DIR__ . '/../../config/sets/nette-31.php';
/**
* @var string
*/
public const NETTE_CODE_QUALITY = __DIR__ . '/../../config/sets/nette-code-quality.php';
/**
* @var string
*/
public const ANNOTATIONS_TO_ATTRIBUTES = __DIR__ . '/../../config/sets/nette/annotations-to-attributes.php';
}

View File

@ -1,44 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\ValueObject;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
final class AlwaysTemplateParameterAssign
{
/**
* @var \PhpParser\Node\Expr\Assign
*/
private $assign;
/**
* @var string
*/
private $parameterName;
/**
* @var \PhpParser\Node\Expr
*/
private $assignedExpr;
public function __construct(Assign $assign, string $parameterName, Expr $assignedExpr)
{
$this->assign = $assign;
$this->parameterName = $parameterName;
$this->assignedExpr = $assignedExpr;
}
public function getAssign() : Assign
{
return $this->assign;
}
public function getAssignVar() : Expr
{
return $this->assign->var;
}
public function getParameterName() : string
{
return $this->parameterName;
}
public function getAssignedExpr() : Expr
{
return $this->assignedExpr;
}
}

View File

@ -1,38 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\ValueObject;
final class FormField
{
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $type;
/**
* @var bool
*/
private $isRequired;
public function __construct(string $name, string $type, bool $isRequired)
{
$this->name = $name;
$this->type = $type;
$this->isRequired = $isRequired;
}
public function getName() : string
{
return $this->name;
}
public function getType() : string
{
return $this->type;
}
public function isRequired() : bool
{
return $this->isRequired;
}
}

View File

@ -1,29 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\ValueObject;
final class LatteVariableType
{
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $type;
public function __construct(string $name, string $type)
{
$this->name = $name;
$this->type = $type;
}
public function getName() : string
{
return $this->name;
}
public function getType() : string
{
return $this->type;
}
}

View File

@ -1,30 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\ValueObject;
use PhpParser\Node\Expr\Assign;
final class ParameterAssign
{
/**
* @var \PhpParser\Node\Expr\Assign
*/
private $assign;
/**
* @var string
*/
private $parameterName;
public function __construct(Assign $assign, string $parameterName)
{
$this->assign = $assign;
$this->parameterName = $parameterName;
}
public function getAssign() : Assign
{
return $this->assign;
}
public function getParameterName() : string
{
return $this->parameterName;
}
}

View File

@ -1,88 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Nette\ValueObject;
use PhpParser\Node\Expr;
final class TemplateParametersAssigns
{
/**
* @var AlwaysTemplateParameterAssign[]
*/
private $templateParameterAssigns;
/**
* @var ParameterAssign[]
*/
private $conditionalTemplateParameterAssign;
/**
* @var AlwaysTemplateParameterAssign[]
*/
private $defaultChangeableTemplateParameterAssigns;
/**
* @param AlwaysTemplateParameterAssign[] $templateParameterAssigns
* @param ParameterAssign[] $conditionalTemplateParameterAssign
* @param AlwaysTemplateParameterAssign[] $defaultChangeableTemplateParameterAssigns
*/
public function __construct(array $templateParameterAssigns, array $conditionalTemplateParameterAssign, array $defaultChangeableTemplateParameterAssigns)
{
$this->templateParameterAssigns = $templateParameterAssigns;
$this->conditionalTemplateParameterAssign = $conditionalTemplateParameterAssign;
$this->defaultChangeableTemplateParameterAssigns = $defaultChangeableTemplateParameterAssigns;
}
/**
* These parameters are not defined just once. They can change later or they defined based on if/else/while
* conditions.
*
* @return array<ParameterAssign|AlwaysTemplateParameterAssign>
*/
public function getNonSingleParameterAssigns() : array
{
return \array_merge($this->conditionalTemplateParameterAssign, $this->defaultChangeableTemplateParameterAssigns);
}
/**
* @return ParameterAssign[]
*/
public function getConditionalTemplateParameterAssign() : array
{
return $this->conditionalTemplateParameterAssign;
}
/**
* @return string[]
*/
public function getConditionalVariableNames() : array
{
$conditionalVariableNames = [];
foreach ($this->conditionalTemplateParameterAssign as $conditionalTemplateParameterAssign) {
$conditionalVariableNames[] = $conditionalTemplateParameterAssign->getParameterName();
}
return \array_unique($conditionalVariableNames);
}
/**
* @return AlwaysTemplateParameterAssign[]
*/
public function getTemplateParameterAssigns() : array
{
return $this->templateParameterAssigns;
}
/**
* @return array<string, Expr>
*/
public function getTemplateVariables() : array
{
$templateVariables = [];
foreach ($this->templateParameterAssigns as $templateParameterAssign) {
$templateVariables[$templateParameterAssign->getParameterName()] = $templateParameterAssign->getAssignedExpr();
}
foreach ($this->defaultChangeableTemplateParameterAssigns as $alwaysTemplateParameterAssign) {
$templateVariables[$alwaysTemplateParameterAssign->getParameterName()] = $alwaysTemplateParameterAssign->getAssignedExpr();
}
return $templateVariables;
}
/**
* @return AlwaysTemplateParameterAssign[]
*/
public function getDefaultChangeableTemplateParameterAssigns() : array
{
return $this->defaultChangeableTemplateParameterAssigns;
}
}

View File

@ -4,6 +4,8 @@ declare (strict_types=1);
namespace Rector\PHPUnit\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Class_;
@ -12,7 +14,6 @@ use PhpParser\Node\Stmt\Expression;
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\Nette\NodeAnalyzer\StaticCallAnalyzer;
use Rector\PHPUnit\NodeAnalyzer\SetUpMethodDecorator;
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
@ -25,11 +26,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class ConstructClassMethodToSetUpTestCaseRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\Nette\NodeAnalyzer\StaticCallAnalyzer
*/
private $staticCallAnalyzer;
/**
* @readonly
* @var \Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer
@ -50,9 +46,8 @@ final class ConstructClassMethodToSetUpTestCaseRector extends AbstractRector
* @var \Rector\PHPUnit\NodeAnalyzer\SetUpMethodDecorator
*/
private $setUpMethodDecorator;
public function __construct(StaticCallAnalyzer $staticCallAnalyzer, TestsNodeAnalyzer $testsNodeAnalyzer, ClassAnalyzer $classAnalyzer, VisibilityManipulator $visibilityManipulator, SetUpMethodDecorator $setUpMethodDecorator)
public function __construct(TestsNodeAnalyzer $testsNodeAnalyzer, ClassAnalyzer $classAnalyzer, VisibilityManipulator $visibilityManipulator, SetUpMethodDecorator $setUpMethodDecorator)
{
$this->staticCallAnalyzer = $staticCallAnalyzer;
$this->testsNodeAnalyzer = $testsNodeAnalyzer;
$this->classAnalyzer = $classAnalyzer;
$this->visibilityManipulator = $visibilityManipulator;
@ -139,11 +134,27 @@ CODE_SAMPLE
if ($constructorStmt instanceof Expression) {
$constructorStmt = clone $constructorStmt->expr;
}
if (!$this->staticCallAnalyzer->isParentCallNamed($constructorStmt, MethodName::CONSTRUCT)) {
if (!$this->isParentCallNamed($constructorStmt, MethodName::CONSTRUCT)) {
continue;
}
unset($constructorStmts[$key]);
}
return $constructorStmts;
}
private function isParentCallNamed(Node $node, string $desiredMethodName) : bool
{
if (!$node instanceof StaticCall) {
return \false;
}
if ($node->class instanceof Expr) {
return \false;
}
if (!$this->nodeNameResolver->isName($node->class, 'parent')) {
return \false;
}
if ($node->name instanceof Expr) {
return \false;
}
return $this->nodeNameResolver->isName($node->name, $desiredMethodName);
}
}