rectorphp / rector

Instant Upgrades and Automated Refactoring of any PHP 5.3+ code
https://getrector.com
MIT License
8.42k stars 673 forks source link

AddParamBasedOnParentClassMethodRector causes "System error" #8712

Open RuesimOfCode opened 4 days ago

RuesimOfCode commented 4 days ago

Bug Report

Subject Details
Rector version 1.2.0
nikic/php-parser version v5.0.2
php version 8.2.20

When using AddParamBasedOnParentClassMethodRector with a parent class having properties and a new optional method parameter, a system error occurres with the following stack trace:

[ERROR] Could not process "/var/www/xxx/ExtendingTestClass.php" file, due to:
         "System error: "PhpParser\Internal\TokenStream::getIndentationBefore(): Return value must be of type int, null 
         returned"

         Stack trace:
         #0 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(530):
         PhpParser\Internal\TokenStream->getIndentationBefore(31)
         #1 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(117):
         PhpParser\PrettyPrinterAbstract->p(Object(PhpParser\Node\Identifier), false)
         #2 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php(37):
         Rector\PhpParser\Printer\BetterStandardPrinter->p(Object(PhpParser\Node\Identifier))
         #3 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(490):
         PhpParser\PrettyPrinter\Standard->pNullableType(Object(PhpParser\Node\NullableType))
         #4 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(511):
         PhpParser\PrettyPrinterAbstract->pFallback(Object(PhpParser\Node\NullableType))
         #5 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(117):
         PhpParser\PrettyPrinterAbstract->p(Object(PhpParser\Node\NullableType), false)
         #6 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(381):
         Rector\PhpParser\Printer\BetterStandardPrinter->p(Object(PhpParser\Node\NullableType))
         #7 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(490):
         Rector\PhpParser\Printer\BetterStandardPrinter->pParam(Object(PhpParser\Node\Param))
         #8 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(511):
         PhpParser\PrettyPrinterAbstract->pFallback(Object(PhpParser\Node\Param))
         #9 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(117):
         PhpParser\PrettyPrinterAbstract->p(Object(PhpParser\Node\Param), true)
         #10 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(841):
         Rector\PhpParser\Printer\BetterStandardPrinter->p(Object(PhpParser\Node\Param), true)
         #11 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(191):
         PhpParser\PrettyPrinterAbstract->pArray(Array, Array, 20, 0, 'Stmt_ClassMetho...', 'params', NULL)
         #12 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(545):
         Rector\PhpParser\Printer\BetterStandardPrinter->pArray(Array, Array, 20, 0, 'Stmt_ClassMetho...', 'params',    
         NULL)
         #13 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(117):
         PhpParser\PrettyPrinterAbstract->p(Object(PhpParser\Node\Stmt\ClassMethod), true)
         #14 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(812):
         Rector\PhpParser\Printer\BetterStandardPrinter->p(Object(PhpParser\Node\Stmt\ClassMethod), true)
         #15 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(191):
         PhpParser\PrettyPrinterAbstract->pArray(Array, Array, 9, 0, 'Stmt_Class', 'stmts', NULL)
         #16 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(545):
         Rector\PhpParser\Printer\BetterStandardPrinter->pArray(Array, Array, 9, 0, 'Stmt_Class', 'stmts', NULL)        
         #17 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(117):
         PhpParser\PrettyPrinterAbstract->p(Object(PhpParser\Node\Stmt\Class_), true)
         #18 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(812):
         Rector\PhpParser\Printer\BetterStandardPrinter->p(Object(PhpParser\Node\Stmt\Class_), true)
         #19 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(191):
         PhpParser\PrettyPrinterAbstract->pArray(Array, Array, 0, 0, 'File', 'stmts', NULL)
         #20 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php(478):
         Rector\PhpParser\Printer\BetterStandardPrinter->pArray(Array, Array, 0, 0, 'File', 'stmts', NULL)
         #21 vendor/rector/rector/src/PhpParser/Printer/BetterStandardPrinter.php(75):
         PhpParser\PrettyPrinterAbstract->printFormatPreserving(Array, Array, Array)
         #22 vendor/rector/rector/src/Application/FileProcessor.php(160):
         Rector\PhpParser\Printer\BetterStandardPrinter->printFormatPreserving(Array, Array, Array)
         #23 vendor/rector/rector/src/Application/FileProcessor.php(118):
         Rector\Application\FileProcessor->printFile(Object(Rector\ValueObject\Application\File),
         Object(Rector\ValueObject\Configuration), '/var/www/xxx...')
         #24 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(182):
         Rector\Application\FileProcessor->processFile(Object(Rector\ValueObject\Application\File),
         Object(Rector\ValueObject\Configuration))
         #25 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(159):
         Rector\Application\ApplicationFileProcessor->processFile(Object(Rector\ValueObject\Application\File),
         Object(Rector\ValueObject\Configuration))
         #26 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(136):
         Rector\Application\ApplicationFileProcessor->processFiles(Array, Object(Rector\ValueObject\Configuration),     
         Object(Closure), Object(Closure))
         #27 vendor/rector/rector/src/Console/Command/ProcessCommand.php(131):
         Rector\Application\ApplicationFileProcessor->run(Object(Rector\ValueObject\Configuration),
         Object(RectorPrefix202407\Symfony\Component\Console\Input\ArgvInput))
         #28 vendor/rector/rector/vendor/symfony/console/Command/Command.php(327):
         Rector\Console\Command\ProcessCommand->execute(Object(RectorPrefix202407\Symfony\Component\Console\Input\ArgvI 
         nput), Object(RectorPrefix202407\Symfony\Component\Console\Output\ConsoleOutput))
         #29 vendor/rector/rector/vendor/symfony/console/Application.php(960):
         RectorPrefix202407\Symfony\Component\Console\Command\Command->run(Object(RectorPrefix202407\Symfony\Component\ 
         Console\Input\ArgvInput), Object(RectorPrefix202407\Symfony\Component\Console\Output\ConsoleOutput))
         #30 vendor/rector/rector/vendor/symfony/console/Application.php(333):
         RectorPrefix202407\Symfony\Component\Console\Application->doRunCommand(Object(Rector\Console\Command\ProcessCo 
         mmand), Object(RectorPrefix202407\Symfony\Component\Console\Input\ArgvInput),
         Object(RectorPrefix202407\Symfony\Component\Console\Output\ConsoleOutput))
         #31 vendor/rector/rector/src/Console/ConsoleApplication.php(53):
         RectorPrefix202407\Symfony\Component\Console\Application->doRun(Object(RectorPrefix202407\Symfony\Component\Co 
         nsole\Input\ArgvInput), Object(RectorPrefix202407\Symfony\Component\Console\Output\ConsoleOutput))
         #32 vendor/rector/rector/vendor/symfony/console/Application.php(216):
         Rector\Console\ConsoleApplication->doRun(Object(RectorPrefix202407\Symfony\Component\Console\Input\ArgvInput), 
         Object(RectorPrefix202407\Symfony\Component\Console\Output\ConsoleOutput))
         #33 vendor/rector/rector/bin/rector.php(130): RectorPrefix202407\Symfony\Component\Console\Application->run()  
         #34 vendor/rector/rector/bin/rector(5): require_once('/var/www/xxx...')
         #35 vendor/bin/rector(119): include('/var/www/xxx...')
         #36 {main}". On line: 209

Minimal PHP Code Causing Issue

use Rector\Config\RectorConfig; use Rector\Php80\Rector\ClassMethod\AddParamBasedOnParentClassMethodRector;

return static function (RectorConfig $rectorConfig): void { $rectorConfig->paths([ DIR . '/TestClass.php', DIR . '/ExtendingTestClass.php', ]);

// register a single rule
$rectorConfig->rule(AddParamBasedOnParentClassMethodRector::class);

};


* TestClass.php

<?php

class TestClass { private string $string1; private string $string2;

public function test(?string $string3 = '')
{
}

}


* ExtendingTestClass.php

<?php

class ExtendingTestClass extends TestClass { public function test() { } }


## Expected Behaviour

ExtendingTestClass.php updated content is

<?php

class ExtendingTestClass extends TestClass { public function test(?string $string3 = '') { } }


## Additional information

* Only reproducible with two different files for classes
* Removing the property `private string $string2;` from `TestClass` results in 
`ExtendingTestClass.php` having invalid code:

<?php

class ExtendingTestClass extends TestClass { public function test(?} $string3 = '') { } }


* EDIT: removed 'static' keywords from code samples (reproducible with static and non-static method calls).
samsonasik commented 4 days ago

Reproduced

Screenshot 2024-07-03 at 21 05 24