try to fix broken indent in param description

This commit is contained in:
Tomas Votruba 2019-06-02 11:01:01 +03:00
parent cbfa9e1676
commit 86c39fc98a
8 changed files with 91 additions and 15 deletions

View File

@ -101,6 +101,7 @@ parameters:
Symplify\CodingStandard\Sniffs\CleanCode\CognitiveComplexitySniff:
# tough logic
- 'packages/BetterPhpDocParser/src/'
- 'packages/Symfony/src/Rector/Class_/MakeCommandLazyRector.php'
- 'packages/Legacy/src/Rector/ClassMethod/ChangeSingletonToServiceRector.php'
- 'src/Rector/Psr4/MultipleClassFileToPsr4ClassesRector.php'

View File

@ -4,6 +4,11 @@ namespace Rector\BetterPhpDocParser\Attributes\Attribute;
final class Attribute
{
/**
* @var string
*/
public const HAS_DESCRIPTION_WITH_ORIGINAL_SPACES = 'has_description_with_restored_spaces';
/**
* Fully-qualified name
*

View File

@ -6,6 +6,7 @@ use Nette\Utils\Strings;
use PHPStan\PhpDocParser\Ast\Node;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
@ -108,14 +109,23 @@ final class BetterPhpDocParser extends PhpDocParser
$attributeAwareNode = $this->attributeAwareNodeFactory->createFromNode($node);
$attributeAwareNode->setAttribute(Attribute::PHP_DOC_NODE_INFO, new StartEndInfo($tokenStart, $tokenEnd));
// add original text, for keeping trimmed spaces
$possibleMultilineText = null;
if ($attributeAwareNode instanceof PhpDocTagNode) {
if (property_exists($attributeAwareNode->value, 'description')) {
$possibleMultilineText = $attributeAwareNode->value->description;
}
}
if ($attributeAwareNode instanceof PhpDocTextNode) {
$possibleMultilineText = $attributeAwareNode->text;
}
if ($possibleMultilineText) {
// add original text, for keeping trimmed spaces
$originalContent = $this->getOriginalContentFromTokenIterator($tokenIterator);
$currentText = $attributeAwareNode->text;
// we try to match original content without trimmed spaces
$currentTextPattern = '#' . preg_quote($currentText, '#') . '#s';
$currentTextPattern = '#' . preg_quote($possibleMultilineText, '#') . '#s';
$currentTextPattern = Strings::replace($currentTextPattern, '#\s#', '\s+');
$match = Strings::match($originalContent, $currentTextPattern);

View File

@ -128,6 +128,7 @@ final class PhpDocInfoPrinter
/** @var StartEndInfo|null $tokenStartEndInfo */
$startEndInfo = $attributeAwareNode->getAttribute(Attribute::PHP_DOC_NODE_INFO) ?: $startEndInfo;
$attributeAwareNode = $this->fixMultilineDescriptions($attributeAwareNode);
if ($startEndInfo) {
$isLastToken = ($nodeCount === $i);
@ -158,11 +159,6 @@ final class PhpDocInfoPrinter
);
}
// fix multiline BC break - https://github.com/phpstan/phpdoc-parser/pull/26/files
if ($attributeAwareNode->getAttribute(Attribute::ORIGINAL_CONTENT)) {
$this->restoreOriginalSpacingInText($attributeAwareNode);
}
$content = (string) $attributeAwareNode;
$content = explode(PHP_EOL, $content);
$content = implode(PHP_EOL . ' * ', $content);
@ -209,6 +205,9 @@ final class PhpDocInfoPrinter
return $this->appendToOutput($output, $from, $to, $positionJumpSet);
}
/**
* @param PhpDocTagNode|AttributeAwareNodeInterface $phpDocTagNode
*/
private function printPhpDocTagNode(
PhpDocTagNode $phpDocTagNode,
StartEndInfo $startEndInfo,
@ -222,6 +221,17 @@ final class PhpDocInfoPrinter
$output .= ' ';
}
if ($phpDocTagNode->getAttribute(Attribute::HAS_DESCRIPTION_WITH_ORIGINAL_SPACES)) {
if (property_exists($phpDocTagNode->value, 'description') && $phpDocTagNode->value->description) {
$pattern = Strings::replace($phpDocTagNode->value->description, '#[\s]+#', '\s+');
$nodeOutput = Strings::replace($nodeOutput, '#' . $pattern . '#', $phpDocTagNode->value->description);
if (substr_count($nodeOutput, "\n")) {
$nodeOutput = Strings::replace($nodeOutput, "#\n#", PHP_EOL . ' * ');
}
}
}
return $output . $nodeOutput;
}
@ -290,17 +300,29 @@ final class PhpDocInfoPrinter
/**
* @param PhpDocTextNode|AttributeAwareNodeInterface $attributeAwareNode
*/
private function restoreOriginalSpacingInText(AttributeAwareNodeInterface $attributeAwareNode): void
{
private function restoreOriginalSpacingInText(
AttributeAwareNodeInterface $attributeAwareNode
): ?AttributeAwareNodeInterface {
/** @var string $originalContent */
$originalContent = $attributeAwareNode->getAttribute(Attribute::ORIGINAL_CONTENT);
$oldSpaces = Strings::matchAll($originalContent, '#\s+#ms');
$newParts = Strings::split($attributeAwareNode->text, '#\s+#');
$currentText = null;
if ($attributeAwareNode instanceof PhpDocTagNode) {
if (property_exists($attributeAwareNode->value, 'description')) {
$currentText = $attributeAwareNode->value->description;
}
}
if ($attributeAwareNode instanceof PhpDocTextNode) {
$currentText = $attributeAwareNode->text;
}
$newParts = Strings::split($currentText, '#\s+#');
// we can't do this!
if (count($oldSpaces) + 1 !== count($newParts)) {
return;
return null;
}
$newText = '';
@ -317,7 +339,36 @@ final class PhpDocInfoPrinter
}
if ($newText) {
$attributeAwareNode->text = $newText;
if ($attributeAwareNode instanceof PhpDocTagNode) {
if (property_exists($attributeAwareNode->value, 'description')) {
$attributeAwareNode->value->description = $newText;
return $attributeAwareNode;
}
}
if ($attributeAwareNode instanceof PhpDocTextNode) {
$attributeAwareNode->text = $newText;
return $attributeAwareNode;
}
}
return null;
}
/**
* Fix multiline BC break - https://github.com/phpstan/phpdoc-parser/pull/26/files
*/
private function fixMultilineDescriptions(AttributeAwareNodeInterface $attributeAwareNode): AttributeAwareNodeInterface
{
if (! $attributeAwareNode->getAttribute(Attribute::ORIGINAL_CONTENT)) {
return $attributeAwareNode;
}
$nodeWithRestoredSpaces = $this->restoreOriginalSpacingInText($attributeAwareNode);
if ($nodeWithRestoredSpaces !== null) {
$attributeAwareNode = $nodeWithRestoredSpaces;
$attributeAwareNode->setAttribute(Attribute::HAS_DESCRIPTION_WITH_ORIGINAL_SPACES, true);
}
return $attributeAwareNode;
}
}

View File

@ -1,5 +1,4 @@
/**
* @param string $orderSrcId
* @param string|null $channelId Also if we do the check in the self::execute method,
* allow for null to make PHPStan pass
*/

View File

@ -0,0 +1,4 @@
/**
* @return string|null Also if we do the check in the self::execute method,
* allow for null to make PHPStan pass
*/

View File

@ -0,0 +1,4 @@
/**
* @deprecated Also if we do the check in the self::execute method,
* allow for null to make PHPStan pass
*/

View File

@ -73,6 +73,8 @@ final class PhpDocInfoPrinterTest extends AbstractKernelTestCase
yield [__DIR__ . '/PhpDocInfoPrinterSource/multiline1.txt'];
yield [__DIR__ . '/PhpDocInfoPrinterSource/multiline2.txt'];
yield [__DIR__ . '/PhpDocInfoPrinterSource/multiline3.txt'];
yield [__DIR__ . '/PhpDocInfoPrinterSource/multiline4.txt'];
yield [__DIR__ . '/PhpDocInfoPrinterSource/multiline5.txt'];
}
/**