mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Allow updating of params
This commit is contained in:
parent
5bae869dc6
commit
0e67aae21b
@ -380,7 +380,7 @@ class CommentChecker
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
protected static function splitDocLine($return_block)
|
||||
public static function splitDocLine($return_block)
|
||||
{
|
||||
$brackets = '';
|
||||
|
||||
|
@ -305,6 +305,14 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
|
||||
$signature_type
|
||||
)
|
||||
) {
|
||||
if ($project_checker->alter_code
|
||||
&& isset($project_checker->getIssuesToFix()['MismatchingDocblockParamType'])
|
||||
) {
|
||||
$this->addOrUpdateParamType($project_checker, $function_param->name, $signature_type, true);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (IssueBuffer::accepts(
|
||||
new MismatchingDocblockParamType(
|
||||
'Parameter $' . $function_param->name . ' has wrong type \'' . $param_type .
|
||||
@ -1423,6 +1431,47 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $param_name
|
||||
* @param bool $docblock_only
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addOrUpdateParamType(
|
||||
ProjectChecker $project_checker,
|
||||
$param_name,
|
||||
Type\Union $inferred_return_type,
|
||||
$docblock_only = false
|
||||
) {
|
||||
$manipulator = FunctionDocblockManipulator::getForFunction(
|
||||
$project_checker,
|
||||
$this->source->getFilePath(),
|
||||
$this->getMethodId(),
|
||||
$this->function
|
||||
);
|
||||
$manipulator->setParamType(
|
||||
$param_name,
|
||||
!$docblock_only && $project_checker->php_major_version >= 7
|
||||
? $inferred_return_type->toPhpString(
|
||||
$this->source->getAliasedClassesFlipped(),
|
||||
$this->source->getFQCLN(),
|
||||
$project_checker->php_major_version,
|
||||
$project_checker->php_minor_version
|
||||
) : null,
|
||||
$inferred_return_type->toNamespacedString(
|
||||
$this->source->getAliasedClassesFlipped(),
|
||||
$this->source->getFQCLN(),
|
||||
false
|
||||
),
|
||||
$inferred_return_type->toNamespacedString(
|
||||
$this->source->getAliasedClassesFlipped(),
|
||||
$this->source->getFQCLN(),
|
||||
true
|
||||
),
|
||||
$inferred_return_type->canBeFullyExpressedInPhp()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $docblock_only
|
||||
*
|
||||
|
@ -50,6 +50,27 @@ class FunctionDocblockManipulator
|
||||
/** @var ?string */
|
||||
private $new_psalm_return_type;
|
||||
|
||||
/** @var array<string, int> */
|
||||
private $param_typehint_area_starts = [];
|
||||
|
||||
/** @var array<string, int> */
|
||||
private $param_typehint_starts = [];
|
||||
|
||||
/** @var array<string, int> */
|
||||
private $param_typehint_ends = [];
|
||||
|
||||
/** @var array<string, string> */
|
||||
private $new_php_param_types = [];
|
||||
|
||||
/** @var array<string, bool> */
|
||||
private $param_type_is_php_compatible = [];
|
||||
|
||||
/** @var array<string, string> */
|
||||
private $new_phpdoc_param_types = [];
|
||||
|
||||
/** @var array<string, string> */
|
||||
private $new_psalm_param_types = [];
|
||||
|
||||
/** @var string */
|
||||
private $indentation;
|
||||
|
||||
@ -92,6 +113,8 @@ class FunctionDocblockManipulator
|
||||
|
||||
$file_contents = $project_checker->getFileContents($file_path);
|
||||
|
||||
|
||||
|
||||
$last_arg_position = $stmt->params
|
||||
? (int) $stmt->params[count($stmt->params) - 1]->getAttribute('endFilePos')
|
||||
: null;
|
||||
@ -158,7 +181,7 @@ class FunctionDocblockManipulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new docblock return type
|
||||
* Sets the new return type
|
||||
*
|
||||
* @param ?string $php_type
|
||||
* @param string $new_type
|
||||
@ -177,6 +200,30 @@ class FunctionDocblockManipulator
|
||||
$this->return_type_is_php_compatible = $is_php_compatible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new param type
|
||||
*
|
||||
* @param string $param_name
|
||||
* @param ?string $php_type
|
||||
* @param string $new_type
|
||||
* @param string $phpdoc_type
|
||||
* @param bool $is_php_compatible
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setParamType($param_name, $php_type, $new_type, $phpdoc_type, $is_php_compatible)
|
||||
{
|
||||
|
||||
$new_type = str_replace(['<mixed, mixed>', '<empty, empty>'], '', $new_type);
|
||||
|
||||
if ($php_type) {
|
||||
$this->new_php_param_types[$param_name] = $php_type;
|
||||
}
|
||||
$this->new_phpdoc_param_types[$param_name] = $phpdoc_type;
|
||||
$this->new_psalm_param_types[$param_name] = $new_type;
|
||||
$this->param_type_is_php_compatible[$param_name] = $is_php_compatible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new docblock given the existing docblock, if one exists, and the updated return types
|
||||
* and/or parameters
|
||||
@ -193,6 +240,27 @@ class FunctionDocblockManipulator
|
||||
$parsed_docblock = ['description' => ''];
|
||||
}
|
||||
|
||||
foreach ($this->new_phpdoc_param_types as $param_name => $phpdoc_type) {
|
||||
$found_in_params = false;
|
||||
$new_param_block = $phpdoc_type . ' ' . '$' . $param_name;
|
||||
|
||||
if (isset($parsed_docblock['specials']['param'])) {
|
||||
foreach ($parsed_docblock['specials']['param'] as &$param_block) {
|
||||
$doc_parts = CommentChecker::splitDocLine($param_block);
|
||||
|
||||
if ($doc_parts[1] === '$' . $param_name) {
|
||||
$param_block = $new_param_block;
|
||||
$found_in_params = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found_in_params) {
|
||||
$parsed_docblock['specials']['params'][] = $new_param_block;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->new_phpdoc_return_type) {
|
||||
$parsed_docblock['specials']['return'] = [$this->new_phpdoc_return_type];
|
||||
}
|
||||
|
@ -257,6 +257,42 @@ class FileManipulationTest extends TestCase
|
||||
'7.0',
|
||||
['InvalidReturnType'],
|
||||
],
|
||||
'fixMismatchingDocblockReturnType70' => [
|
||||
'<?php
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
function foo() : string {
|
||||
return "hello";
|
||||
}',
|
||||
'<?php
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function foo() : string {
|
||||
return "hello";
|
||||
}',
|
||||
'7.0',
|
||||
['MismatchingDocblockReturnType'],
|
||||
],
|
||||
'fixMismatchingDocblockParamType70' => [
|
||||
'<?php
|
||||
/**
|
||||
* @param int $s
|
||||
*/
|
||||
function foo(string $s) : string {
|
||||
return "hello";
|
||||
}',
|
||||
'<?php
|
||||
/**
|
||||
* @param string $s
|
||||
*/
|
||||
function foo(string $s) : string {
|
||||
return "hello";
|
||||
}',
|
||||
'7.0',
|
||||
['MismatchingDocblockParamType'],
|
||||
],
|
||||
'useUnqualifierPlugin' => [
|
||||
'<?php
|
||||
namespace A\B\C {
|
||||
|
Loading…
Reference in New Issue
Block a user