diff --git a/bin/simple-downgrade b/bin/simple-downgrade index 23566e1..9b8fa76 100755 --- a/bin/simple-downgrade +++ b/bin/simple-downgrade @@ -20,7 +20,6 @@ foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php $lexer = new \PhpParser\Lexer\Emulative(); $parser = new Php7($lexer); -$printer = new PhpPrinter(); $phpDocParserConfig = new ParserConfig(['lines' => true, 'indexes' => true]); $constExprParser = new ConstExprParser($phpDocParserConfig); @@ -29,6 +28,6 @@ $phpDocParser = new PhpDocParser($phpDocParserConfig, $typeParser, $constExprPar $phpDocLexer = new PHPStan\PhpDocParser\Lexer\Lexer($phpDocParserConfig); $app = new Application(); -$app->add(new DowngradeCommand($parser, $printer, $phpDocLexer, $phpDocParser)); +$app->add(new DowngradeCommand($parser, $phpDocLexer, $phpDocParser)); $app->setCatchExceptions(false); $app->run(); diff --git a/composer.json b/composer.json index 97ed937..e8d52f7 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "license": ["MIT"], "require": { "php": "^7.4|^8.0", - "nikic/php-parser": "^5.0", + "nikic/php-parser": "^5.3.0", "symfony/console": "^5.4", "nette/utils": "^3.2.5", "symfony/finder": "^5.4", diff --git a/src/Console/DowngradeCommand.php b/src/Console/DowngradeCommand.php index acde871..65504fe 100644 --- a/src/Console/DowngradeCommand.php +++ b/src/Console/DowngradeCommand.php @@ -4,6 +4,7 @@ use Exception; use Nette\Utils\Strings; +use PhpParser\Internal\TokenStream; use PhpParser\Node\Stmt; use PhpParser\NodeTraverser; use PhpParser\NodeVisitor; @@ -14,6 +15,7 @@ use PHPStan\PhpDocParser\Printer\Printer; use SimpleDowngrader\Php\FollowedByCommaAnalyser; use SimpleDowngrader\Php\PhpPrinter; +use SimpleDowngrader\Php\PhpPrinterIndentationDetectorVisitor; use SimpleDowngrader\PhpDoc\PhpDocEditor; use SimpleDowngrader\Visitor\DowngradeMixedTypeVisitor; use SimpleDowngrader\Visitor\DowngradeNonCapturingCatchesVisitor; @@ -47,6 +49,7 @@ use function is_string; use function preg_quote; use function sprintf; +use function str_repeat; use function str_replace; class DowngradeCommand extends Command @@ -57,19 +60,16 @@ class DowngradeCommand extends Command private Parser $parser; - private PhpPrinter $printer; - private Lexer $phpDocLexer; private PhpDocParser $phpDocParser; private NodeTraverser $cloningTraverser; - public function __construct(Parser $parser, PhpPrinter $printer, Lexer $phpDocLexer, PhpDocParser $phpDocParser) + public function __construct(Parser $parser, Lexer $phpDocLexer, PhpDocParser $phpDocParser) { parent::__construct(); $this->parser = $parser; - $this->printer = $printer; $this->phpDocLexer = $phpDocLexer; $this->phpDocParser = $phpDocParser; $this->cloningTraverser = new NodeTraverser(); @@ -142,6 +142,11 @@ private function processFile(string $file, array $visitors): void /** @var Stmt[] $newStmts */ $newStmts = $this->cloningTraverser->traverse($oldStmts); + $indentTraverser = new NodeTraverser(); + $indentDetector = new PhpPrinterIndentationDetectorVisitor(new TokenStream($oldTokens, PhpPrinter::TAB_WIDTH)); + $indentTraverser->addVisitor($indentDetector); + $indentTraverser->traverse($oldStmts); + foreach ($visitors as $visitor) { $traverser = new NodeTraverser(); $traverser->addVisitor($visitor); @@ -154,7 +159,8 @@ private function processFile(string $file, array $visitors): void $newStmts = $traverser->traverse($newStmts); } - $newCode = $this->printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens); + $printer = new PhpPrinter(['indent' => str_repeat($indentDetector->indentCharacter, $indentDetector->indentSize)]); + $newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens); $result = file_put_contents($file, $newCode); if ($result === false) { throw new Exception(sprintf('%s could not be written', $file)); diff --git a/src/Php/PhpPrinter.php b/src/Php/PhpPrinter.php index 1fc871f..bc3d5e4 100644 --- a/src/Php/PhpPrinter.php +++ b/src/Php/PhpPrinter.php @@ -3,63 +3,16 @@ namespace SimpleDowngrader\Php; use PhpParser\Node; -use PhpParser\NodeTraverser; use PhpParser\PrettyPrinter\Standard; use function count; use function rtrim; -use function str_repeat; class PhpPrinter extends Standard { + public const TAB_WIDTH = 4; public const FUNC_ARGS_TRAILING_COMMA_ATTRIBUTE = 'trailing_comma'; - private string $indentCharacter = ' '; - - private int $indentSize = 4; - - protected function resetState(): void - { - parent::resetState(); - $this->indentCharacter = ' '; - $this->indentSize = 4; - } - - protected function preprocessNodes(array $nodes): void - { - parent::preprocessNodes($nodes); - if ($this->origTokens === null) { - return; - } - - $traverser = new NodeTraverser(); - - $visitor = new PhpPrinterIndentationDetectorVisitor($this->origTokens); - $traverser->addVisitor($visitor); - $traverser->traverse($nodes); - - $this->indentCharacter = $visitor->indentCharacter; - $this->indentSize = $visitor->indentSize; - } - - protected function setIndentLevel(int $level): void - { - $this->indentLevel = $level; - $this->nl = "\n" . str_repeat($this->indentCharacter, $level); - } - - protected function indent(): void - { - $this->indentLevel += $this->indentSize; - $this->nl = "\n" . str_repeat($this->indentCharacter, $this->indentLevel); - } - - protected function outdent(): void - { - $this->indentLevel -= $this->indentSize; - $this->nl = "\n" . str_repeat($this->indentCharacter, $this->indentLevel); - } - /** * @param Node[] $nodes */ diff --git a/tests/Visitor/AbstractVisitorTestCase.php b/tests/Visitor/AbstractVisitorTestCase.php index c62874e..d8a5970 100644 --- a/tests/Visitor/AbstractVisitorTestCase.php +++ b/tests/Visitor/AbstractVisitorTestCase.php @@ -2,6 +2,7 @@ namespace SimpleDowngrader\Visitor; +use PhpParser\Internal\TokenStream; use PhpParser\Lexer\Emulative; use PhpParser\Node\Stmt; use PhpParser\NodeTraverser; @@ -16,7 +17,9 @@ use PHPStan\PhpDocParser\Printer\Printer; use PHPUnit\Framework\TestCase; use SimpleDowngrader\Php\PhpPrinter; +use SimpleDowngrader\Php\PhpPrinterIndentationDetectorVisitor; use SimpleDowngrader\PhpDoc\PhpDocEditor; +use function str_repeat; abstract class AbstractVisitorTestCase extends TestCase { @@ -38,6 +41,11 @@ public function testVisitor(string $codeBefore, string $codeAfter): void $oldStmts = $parser->parse($codeBefore); $oldTokens = $parser->getTokens(); + $indentTraverser = new NodeTraverser(); + $indentDetector = new PhpPrinterIndentationDetectorVisitor(new TokenStream($oldTokens, PhpPrinter::TAB_WIDTH)); + $indentTraverser->addVisitor($indentDetector); + $indentTraverser->traverse($oldStmts); + $cloningTraverser = new NodeTraverser(); $cloningTraverser->addVisitor(new CloningVisitor()); @@ -54,7 +62,7 @@ public function testVisitor(string $codeBefore, string $codeAfter): void /** @var Stmt[] $newStmts */ $newStmts = $traverser->traverse($newStmts); - $printer = new PhpPrinter(); + $printer = new PhpPrinter(['indent' => str_repeat($indentDetector->indentCharacter, $indentDetector->indentSize)]); $newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens); $this->assertSame($codeAfter, $newCode);