1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-15 10:57:08 +01:00
psalm/src/Psalm/Internal/PhpVisitor/ParamReplacementVisitor.php

118 lines
3.7 KiB
PHP
Raw Normal View History

2020-08-14 21:25:21 +02:00
<?php
namespace Psalm\Internal\PhpVisitor;
use PhpParser;
use Psalm\FileManipulation;
2021-12-03 20:11:20 +01:00
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Scanner\DocblockParser;
2020-08-14 21:25:21 +02:00
/**
* @internal
*/
class ParamReplacementVisitor extends PhpParser\NodeVisitorAbstract
2020-08-14 21:25:21 +02:00
{
/** @var string */
private $old_name;
/** @var string */
private $new_name;
/** @var list<FileManipulation> */
private $replacements = [];
/** @var bool */
private $new_name_replaced = false;
/** @var bool */
private $new_new_name_used = false;
public function __construct(string $old_name, string $new_name)
{
$this->old_name = $old_name;
$this->new_name = $new_name;
}
public function enterNode(PhpParser\Node $node): ?int
2020-08-14 21:25:21 +02:00
{
if ($node instanceof PhpParser\Node\Expr\Variable) {
if ($node->name === $this->old_name) {
$this->replacements[] = new FileManipulation(
(int) $node->getAttribute('startFilePos') + 1,
(int) $node->getAttribute('endFilePos') + 1,
$this->new_name
);
} elseif ($node->name === $this->new_name) {
if ($this->new_new_name_used) {
$this->replacements = [];
return PhpParser\NodeTraverser::STOP_TRAVERSAL;
}
$this->replacements[] = new FileManipulation(
(int) $node->getAttribute('startFilePos') + 1,
(int) $node->getAttribute('endFilePos') + 1,
$this->new_name . '_new'
);
$this->new_name_replaced = true;
} elseif ($node->name === $this->new_name . '_new') {
if ($this->new_name_replaced) {
$this->replacements = [];
return PhpParser\NodeTraverser::STOP_TRAVERSAL;
}
$this->new_new_name_used = true;
}
2020-08-14 22:26:55 +02:00
} elseif ($node instanceof PhpParser\Node\Stmt\ClassMethod
&& ($docblock = $node->getDocComment())
) {
2021-12-03 20:11:20 +01:00
$parsed_docblock = DocblockParser::parse(
2021-08-06 22:00:37 +02:00
$docblock->getText(),
$docblock->getStartFilePos()
);
2020-08-14 22:26:55 +02:00
$replaced = false;
foreach ($parsed_docblock->tags as $tag_name => $tags) {
foreach ($tags as $i => $tag) {
if ($tag_name === 'param'
|| $tag_name === 'psalm-param'
|| $tag_name === 'phpstan-param'
|| $tag_name === 'phan-param'
) {
2021-12-03 20:11:20 +01:00
$parts = CommentAnalyzer::splitDocLine($tag);
2020-08-14 22:26:55 +02:00
if (($parts[1] ?? '') === '$' . $this->old_name) {
$parsed_docblock->tags[$tag_name][$i] = \str_replace(
'$' . $this->old_name,
'$' . $this->new_name,
$tag
);
$replaced = true;
}
}
}
}
if ($replaced) {
$this->replacements[] = new FileManipulation(
$docblock->getStartFilePos(),
$docblock->getStartFilePos() + \strlen($docblock->getText()),
2020-08-14 22:26:55 +02:00
\rtrim($parsed_docblock->render($parsed_docblock->first_line_padding)),
false,
false
);
}
2020-08-14 21:25:21 +02:00
}
return null;
2020-08-14 21:25:21 +02:00
}
/**
* @return list<FileManipulation>
*/
public function getReplacements(): array
2020-08-14 21:25:21 +02:00
{
return $this->replacements;
}
}