Server : nginx/1.18.0 System : Linux localhost 6.14.3-x86_64-linode168 #1 SMP PREEMPT_DYNAMIC Mon Apr 21 19:47:55 EDT 2025 x86_64 User : www-data ( 33) PHP Version : 8.0.16 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /var/www/ecommerce/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/ |
<?php
declare(strict_types=1);
/*
* This file is part of PHP CS Fixer.
*
* (c) Fabien Potencier <fabien@symfony.com>
* Dariusz RumiĆski <dariusz.ruminski@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace PhpCsFixer\Fixer\Phpdoc;
use PhpCsFixer\AbstractFixer;
use PhpCsFixer\DocBlock\Annotation;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\DocBlock\TagComparator;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
/**
* @author Graham Campbell <hello@gjcampbell.co.uk>
*/
final class PhpdocSeparationFixer extends AbstractFixer
{
/**
* {@inheritdoc}
*/
public function getDefinition(): FixerDefinitionInterface
{
return new FixerDefinition(
'Annotations in PHPDoc should be grouped together so that annotations of the same type immediately follow each other, and annotations of a different type are separated by a single blank line.',
[
new CodeSample(
'<?php
/**
* Description.
* @param string $foo
*
*
* @param bool $bar Bar
* @throws Exception|RuntimeException
* @return bool
*/
function fnc($foo, $bar) {}
'
),
]
);
}
/**
* {@inheritdoc}
*
* Must run before PhpdocAlignFixer.
* Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, PhpdocIndentFixer, PhpdocNoAccessFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocOrderFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer.
*/
public function getPriority(): int
{
return -3;
}
/**
* {@inheritdoc}
*/
public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_DOC_COMMENT);
}
/**
* {@inheritdoc}
*/
protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
{
foreach ($tokens as $index => $token) {
if (!$token->isGivenKind(T_DOC_COMMENT)) {
continue;
}
$doc = new DocBlock($token->getContent());
$this->fixDescription($doc);
$this->fixAnnotations($doc);
$tokens[$index] = new Token([T_DOC_COMMENT, $doc->getContent()]);
}
}
/**
* Make sure the description is separated from the annotations.
*/
private function fixDescription(DocBlock $doc): void
{
foreach ($doc->getLines() as $index => $line) {
if ($line->containsATag()) {
break;
}
if ($line->containsUsefulContent()) {
$next = $doc->getLine($index + 1);
if (null !== $next && $next->containsATag()) {
$line->addBlank();
break;
}
}
}
}
/**
* Make sure the annotations are correctly separated.
*/
private function fixAnnotations(DocBlock $doc): void
{
foreach ($doc->getAnnotations() as $index => $annotation) {
$next = $doc->getAnnotation($index + 1);
if (null === $next) {
break;
}
if (true === $next->getTag()->valid()) {
if (TagComparator::shouldBeTogether($annotation->getTag(), $next->getTag())) {
$this->ensureAreTogether($doc, $annotation, $next);
} else {
$this->ensureAreSeparate($doc, $annotation, $next);
}
}
}
}
/**
* Force the given annotations to immediately follow each other.
*/
private function ensureAreTogether(DocBlock $doc, Annotation $first, Annotation $second): void
{
$pos = $first->getEnd();
$final = $second->getStart();
for ($pos = $pos + 1; $pos < $final; ++$pos) {
$doc->getLine($pos)->remove();
}
}
/**
* Force the given annotations to have one empty line between each other.
*/
private function ensureAreSeparate(DocBlock $doc, Annotation $first, Annotation $second): void
{
$pos = $first->getEnd();
$final = $second->getStart() - 1;
// check if we need to add a line, or need to remove one or more lines
if ($pos === $final) {
$doc->getLine($pos)->addBlank();
return;
}
for ($pos = $pos + 1; $pos < $final; ++$pos) {
$doc->getLine($pos)->remove();
}
}
}