From 9026b891a4eeea1ccae8bc3cd6c270e1a019b9eb Mon Sep 17 00:00:00 2001 From: Junaid Hussnain <84363665+Junaid-PK@users.noreply.github.com> Date: Tue, 4 Aug 2026 02:54:13 +0500 Subject: [PATCH 1/3] Skip constructor defaults on extensible classes --- .../Fixture/skip_non_final_class.php.inc | 23 +++++++++++++++++++ ...lineConstructorDefaultToPropertyRector.php | 5 ++++ 2 files changed, 28 insertions(+) create mode 100644 rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_non_final_class.php.inc diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_non_final_class.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_non_final_class.php.inc new file mode 100644 index 00000000000..9b1adad7b09 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_non_final_class.php.inc @@ -0,0 +1,23 @@ +validate(); + $this->validated = true; + } + + private function validate(): void + { + } +} + +final class SkipsParentConstructor extends ValidatedBase +{ + public function __construct() + { + } +} diff --git a/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php b/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php index 83ef9f3b268..5ab4ee0e4e1 100644 --- a/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php +++ b/rules/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector.php @@ -82,6 +82,11 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { + // A child class may bypass the constructor and depend on the declared property default + if (! $node->isFinal()) { + return null; + } + $hasChanged = false; $constructClassMethod = $node->getMethod(MethodName::CONSTRUCT); From 56c899880298c116a1cc1f14921751ed8b5f406d Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 6 Aug 2026 17:17:28 +0200 Subject: [PATCH 2/3] [Testing] Move ValidatedBase to Source/, namespace the skip fixture --- .../Fixture/skip_non_final_class.php.inc | 19 ++++++------------- .../Source/ValidatedBase.php | 12 ++++++++++++ 2 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Source/ValidatedBase.php diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_non_final_class.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_non_final_class.php.inc index 9b1adad7b09..48dc3be73b6 100644 --- a/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_non_final_class.php.inc +++ b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/skip_non_final_class.php.inc @@ -1,23 +1,16 @@ validate(); $this->validated = true; } - - private function validate(): void - { - } -} - -final class SkipsParentConstructor extends ValidatedBase -{ - public function __construct() - { - } } diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Source/ValidatedBase.php b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Source/ValidatedBase.php new file mode 100644 index 00000000000..d48c323415a --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Source/ValidatedBase.php @@ -0,0 +1,12 @@ + Date: Thu, 6 Aug 2026 22:06:00 +0200 Subject: [PATCH 3/3] fixup! [Testing] Move ValidatedBase to Source/, namespace the skip fixture --- tests/Bin/RectorTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Bin/RectorTest.php b/tests/Bin/RectorTest.php index 11f37ff522e..bd9e85de090 100644 --- a/tests/Bin/RectorTest.php +++ b/tests/Bin/RectorTest.php @@ -17,15 +17,15 @@ final class RectorTest extends TestCase public static function outputProvider(): Iterator { yield 'Version' => [ - 'command' => PHP_BINARY . ' bin/rector --version', - 'expectedOutput' => "Rector @package_version@" . PHP_EOL, + 'command' => PHP_BINARY . ' bin/rector --version', + 'expectedOutput' => 'Rector @package_version@' . PHP_EOL, ]; yield 'Exception with previous console output' => [ - 'command' => PHP_BINARY . ' bin/rector -c tests/Bin/config/incorrect-phpstan-files.php', - 'expectedOutput' => PHP_EOL . " [ERROR] Rector\\NodeTypeResolver\\DependencyInjection\\PHPStanServicesFactory " . PHP_EOL . PHP_EOL . " [ERROR] Unexpected item 'parameters › invalidParameters'. " . PHP_EOL . PHP_EOL, + 'command' => PHP_BINARY . ' bin/rector -c tests/Bin/config/incorrect-phpstan-files.php', + 'expectedOutput' => PHP_EOL . ' [ERROR] Rector\\NodeTypeResolver\\DependencyInjection\\PHPStanServicesFactory ' . PHP_EOL . PHP_EOL . " [ERROR] Unexpected item 'parameters › invalidParameters'. " . PHP_EOL . PHP_EOL, ]; yield 'Exception with previous console output in JSON format' => [ - 'command' => PHP_BINARY . ' bin/rector -c tests/Bin/config/incorrect-phpstan-files.php --output-format json', + 'command' => PHP_BINARY . ' bin/rector -c tests/Bin/config/incorrect-phpstan-files.php --output-format json', 'expectedOutput' => '{"fatal_errors":["Rector\\\\NodeTypeResolver\\\\DependencyInjection\\\\PHPStanServicesFactory","Unexpected item \'parameters › invalidParameters\'."]}', ]; } @@ -35,6 +35,6 @@ public function testConsoleOutput(string $command, string $expectedOutput): void { $process = Process::fromShellCommandline($command); $process->run(); - $this->assertSame($expectedOutput, preg_replace("/ +/", " ", $process->getOutput())); + $this->assertSame($expectedOutput, preg_replace('/ +/', ' ', $process->getOutput())); } }