mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-19 07:40:49 +01:00
Take tabs indent into account
This commit is contained in:
parent
b56cd04af1
commit
97d9f0de91
@ -5,7 +5,7 @@ services:
|
||||
|
||||
Rector\BetterPhpDocParser\:
|
||||
resource: '../src'
|
||||
exclude: '../src/{HttpKernel,Data,*/*Info.php,*Info.php,Attributes/Ast/PhpDoc/*,Ast/PhpDoc/*}'
|
||||
exclude: '../src/{HttpKernel,ValueObject/*,*/*Info.php,*Info.php,Attributes/Ast/PhpDoc/*,Ast/PhpDoc/*}'
|
||||
|
||||
PHPStan\PhpDocParser\Lexer\Lexer: ~
|
||||
PHPStan\PhpDocParser\Parser\TypeParser: ~
|
||||
|
@ -20,8 +20,8 @@ use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\AttributeAwareParamTagValueN
|
||||
use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\AttributeAwarePhpDocNode;
|
||||
use Rector\BetterPhpDocParser\Attributes\Attribute\Attribute;
|
||||
use Rector\BetterPhpDocParser\Contract\PhpDocParserExtensionInterface;
|
||||
use Rector\BetterPhpDocParser\Data\StartEndInfo;
|
||||
use Rector\BetterPhpDocParser\Printer\MultilineSpaceFormatPreserver;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartEndInfo;
|
||||
use Symplify\PackageBuilder\Reflection\PrivatesAccessor;
|
||||
use Symplify\PackageBuilder\Reflection\PrivatesCaller;
|
||||
|
||||
|
@ -6,7 +6,7 @@ use Nette\Utils\Arrays;
|
||||
use Nette\Utils\Strings;
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use Rector\BetterPhpDocParser\Data\StartEndInfo;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartEndInfo;
|
||||
use Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc\DoctrineTagNodeInterface;
|
||||
|
||||
final class OriginalSpacingRestorer
|
||||
|
@ -11,8 +11,8 @@ use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\AttributeAwarePhpDocNode;
|
||||
use Rector\BetterPhpDocParser\Attributes\Attribute\Attribute;
|
||||
use Rector\BetterPhpDocParser\Attributes\Contract\Ast\AttributeAwareNodeInterface;
|
||||
use Rector\BetterPhpDocParser\Data\StartEndInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartEndInfo;
|
||||
|
||||
/**
|
||||
* @see \Rector\BetterPhpDocParser\Tests\PhpDocInfo\PhpDocInfoPrinter\PhpDocInfoPrinterTest
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\BetterPhpDocParser\Data;
|
||||
namespace Rector\BetterPhpDocParser\ValueObject;
|
||||
|
||||
final class StartEndInfo
|
||||
{
|
@ -54,7 +54,7 @@ final class PhpDocClassRenamer
|
||||
$this->procesDoctrineRelationTagValueNode($oldToNewClasses, $phpDocInfo);
|
||||
$this->processSerializerTypeTagValueNode($oldToNewClasses, $phpDocInfo);
|
||||
|
||||
if ($this->shouldUpdate === null) {
|
||||
if ($this->shouldUpdate === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ use PhpParser\Node\Expr\Yield_;
|
||||
use PhpParser\Node\Scalar\DNumber;
|
||||
use PhpParser\Node\Scalar\EncapsedStringPart;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Declare_;
|
||||
@ -18,12 +19,19 @@ use PhpParser\Node\Stmt\Nop;
|
||||
use PhpParser\Node\Stmt\TraitUse;
|
||||
use PhpParser\PrettyPrinter\Standard;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\PhpParser\Printer\BetterStandardPrinterTest
|
||||
*/
|
||||
final class BetterStandardPrinter extends Standard
|
||||
{
|
||||
/**
|
||||
* Use space by default
|
||||
* @var string
|
||||
*/
|
||||
private $tabOrSpaceIndentCharacter = ' ';
|
||||
|
||||
/**
|
||||
* @param mixed[] $options
|
||||
*/
|
||||
@ -38,6 +46,14 @@ final class BetterStandardPrinter extends Standard
|
||||
$this->insertionMap['Expr_Closure->returnType'] = [')', false, ': ', null];
|
||||
}
|
||||
|
||||
public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens): string
|
||||
{
|
||||
// detect per print
|
||||
$this->detectTabOrSpaceIndentCharacter($stmts);
|
||||
|
||||
return parent::printFormatPreserving($stmts, $origStmts, $origTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node|Node[]|null $node
|
||||
*/
|
||||
@ -73,6 +89,50 @@ final class BetterStandardPrinter extends Standard
|
||||
return $this->print($firstNode) === $this->print($secondNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows to use both spaces and tabs vs. original space-only
|
||||
*/
|
||||
protected function setIndentLevel(int $level): void
|
||||
{
|
||||
$this->indentLevel = $level;
|
||||
$this->nl = "\n" . str_repeat($this->tabOrSpaceIndentCharacter, $level);
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows to use both spaces and tabs vs. original space-only
|
||||
*/
|
||||
protected function indent(): void
|
||||
{
|
||||
if ($this->tabOrSpaceIndentCharacter === ' ') {
|
||||
// 4 spaces
|
||||
$multiplier = 4;
|
||||
} else {
|
||||
// 1 tab
|
||||
$multiplier = 1;
|
||||
}
|
||||
|
||||
$this->indentLevel += $multiplier;
|
||||
$this->nl .= str_repeat($this->tabOrSpaceIndentCharacter, $multiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows to use both spaces and tabs vs. original space-only
|
||||
*/
|
||||
protected function outdent(): void
|
||||
{
|
||||
if ($this->tabOrSpaceIndentCharacter === ' ') {
|
||||
// - 4 spaces
|
||||
assert($this->indentLevel >= 4);
|
||||
$this->indentLevel -= 4;
|
||||
} else {
|
||||
// - 1 tab
|
||||
assert($this->indentLevel >= 1);
|
||||
--$this->indentLevel;
|
||||
}
|
||||
|
||||
$this->nl = "\n" . str_repeat($this->tabOrSpaceIndentCharacter, $this->indentLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $nodes
|
||||
* @param mixed[] $origNodes
|
||||
@ -249,4 +309,36 @@ final class BetterStandardPrinter extends Standard
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Solves https://github.com/rectorphp/rector/issues/1964
|
||||
*
|
||||
* Some files have spaces, some have tabs. Keep the original indent if possible.
|
||||
*
|
||||
* @param Stmt[] $stmts
|
||||
*/
|
||||
private function detectTabOrSpaceIndentCharacter(array $stmts): void
|
||||
{
|
||||
// use space by default
|
||||
$this->tabOrSpaceIndentCharacter = ' ';
|
||||
|
||||
foreach ($stmts as $stmt) {
|
||||
if (! $stmt instanceof Node) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var SmartFileInfo|null $fileInfo */
|
||||
$fileInfo = $stmt->getAttribute(AttributeKey::FILE_INFO);
|
||||
if ($fileInfo === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$whitespacesChars = Strings::matchAll($fileInfo->getContents(), '#^( |\t)#m');
|
||||
foreach ($whitespacesChars as $whitespacesChar) {
|
||||
// let the first win
|
||||
$this->tabOrSpaceIndentCharacter = $whitespacesChar[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user