1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

allow Psalter to fix RedundantCast (#5948)

* allow Psalter to fix RedundantCast

* fix test
This commit is contained in:
orklah 2021-06-18 00:15:45 +02:00 committed by GitHub
parent c2f7422e80
commit 872f1c232c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 75 deletions

View File

@ -32,6 +32,8 @@ use Psalm\Issue\PossiblyUndefinedGlobalVariable;
use Psalm\Issue\PossiblyUndefinedVariable;
use Psalm\Issue\PossiblyUnusedMethod;
use Psalm\Issue\PossiblyUnusedProperty;
use Psalm\Issue\RedundantCast;
use Psalm\Issue\RedundantCastGivenDocblockType;
use Psalm\Issue\UnnecessaryVarAnnotation;
use Psalm\Issue\UnusedMethod;
use Psalm\Issue\UnusedProperty;
@ -229,6 +231,8 @@ class ProjectAnalyzer
PossiblyUndefinedVariable::class,
PossiblyUnusedMethod::class,
PossiblyUnusedProperty::class,
RedundantCast::class,
RedundantCastGivenDocblockType::class,
UnusedMethod::class,
UnusedProperty::class,
UnusedVariable::class,

View File

@ -7,6 +7,7 @@ use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodCallReturnTypeFetcher;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Issue\InvalidCast;
use Psalm\Issue\PossiblyInvalidCast;
@ -52,21 +53,7 @@ class CastAnalyzer
if ($maybe_type->isInt()) {
$valid_int_type = $maybe_type;
if (!$maybe_type->from_calculation) {
if ($maybe_type->from_docblock) {
$issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $maybe_type->getKey() . ' given docblock-provided type',
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
} else {
$issue = new RedundantCast(
'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
}
if (IssueBuffer::accepts($issue, $statements_analyzer->getSuppressedIssues())) {
// fall through
}
self::handleRedundantCast($maybe_type, $statements_analyzer, $stmt);
}
}
@ -113,21 +100,7 @@ class CastAnalyzer
if ($maybe_type) {
if ($maybe_type->isFloat()) {
if ($maybe_type->from_docblock) {
$issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $maybe_type->getKey() . ' given docblock-provided type',
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
} else {
$issue = new RedundantCast(
'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
}
if (IssueBuffer::accepts($issue, $statements_analyzer->getSuppressedIssues())) {
// fall through
}
self::handleRedundantCast($maybe_type, $statements_analyzer, $stmt);
}
}
@ -153,21 +126,7 @@ class CastAnalyzer
if ($maybe_type) {
if ($maybe_type->isBool()) {
if ($maybe_type->from_docblock) {
$issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $maybe_type->getKey() . ' given docblock-provided type',
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
} else {
$issue = new RedundantCast(
'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
}
if (IssueBuffer::accepts($issue, $statements_analyzer->getSuppressedIssues())) {
// fall through
}
self::handleRedundantCast($maybe_type, $statements_analyzer, $stmt);
}
}
@ -193,21 +152,7 @@ class CastAnalyzer
if ($stmt_expr_type) {
if ($stmt_expr_type->isString()) {
if ($stmt_expr_type->from_docblock) {
$issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $stmt_expr_type->getKey() . ' given docblock-provided type',
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
} else {
$issue = new RedundantCast(
'Redundant cast to ' . $stmt_expr_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
}
if (IssueBuffer::accepts($issue, $statements_analyzer->getSuppressedIssues())) {
// fall through
}
self::handleRedundantCast($stmt_expr_type, $statements_analyzer, $stmt);
}
$stmt_type = self::castStringAttempt(
@ -262,21 +207,7 @@ class CastAnalyzer
if ($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) {
if ($stmt_expr_type->isArray()) {
if ($stmt_expr_type->from_docblock) {
$issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $stmt_expr_type->getKey() . ' given docblock-provided type',
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
} else {
$issue = new RedundantCast(
'Redundant cast to ' . $stmt_expr_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
}
if (IssueBuffer::accepts($issue, $statements_analyzer->getSuppressedIssues())) {
// fall through
}
self::handleRedundantCast($stmt_expr_type, $statements_analyzer, $stmt);
}
$all_permissible = true;
@ -518,4 +449,55 @@ class CastAnalyzer
return $str_type;
}
private static function handleRedundantCast(
Type\Union $maybe_type,
StatementsAnalyzer $statements_analyzer,
PhpParser\Node\Expr\Cast $stmt
): void {
$codebase = $statements_analyzer->getCodebase();
$project_analyzer = $statements_analyzer->getProjectAnalyzer();
$file_manipulation = null;
if ($maybe_type->from_docblock) {
$issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $maybe_type->getKey() . ' given docblock-provided type',
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
if ($codebase->alter_code
&& isset($project_analyzer->getIssuesToFix()['RedundantCastGivenDocblockType'])
) {
$file_manipulation = new \Psalm\FileManipulation(
(int) $stmt->getAttribute('startFilePos'),
(int) $stmt->expr->getAttribute('startFilePos'),
''
);
}
} else {
$issue = new RedundantCast(
'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt)
);
if ($codebase->alter_code
&& isset($project_analyzer->getIssuesToFix()['RedundantCast'])
) {
$file_manipulation = new \Psalm\FileManipulation(
(int) $stmt->getAttribute('startFilePos'),
(int) $stmt->expr->getAttribute('startFilePos'),
''
);
}
}
if ($file_manipulation) {
FileManipulationBuffer::add($statements_analyzer->getFilePath(), [$file_manipulation]);
}
if (IssueBuffer::accepts($issue, $statements_analyzer->getSuppressedIssues())) {
// fall through
}
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace Psalm\Tests\FileManipulation;
class RedundantCastManipulationTest extends FileManipulationTestCase
{
/**
* @return array<string,array{string,string,string,string[],bool,5?:bool}>
*/
public function providerValidCodeParse(): array
{
return [
'RemoveRedundantCast' => [
'<?php
$test = 1;
(int)$test;
',
'<?php
$test = 1;
$test;
',
'5.6',
['RedundantCast'],
true,
],
'RemoveRedundantCastGivenDocblockType' => [
'<?php
/** @param int $test */
function a($test){
(int)$test;
}
',
'<?php
/** @param int $test */
function a($test){
$test;
}
',
'5.6',
['RedundantCastGivenDocblockType'],
true,
],
];
}
}