Skip to content

Commit

Permalink
allow Psalter to fix RedundantCast (#5948)
Browse files Browse the repository at this point in the history
* allow Psalter to fix RedundantCast

* fix test
  • Loading branch information
orklah authored Jun 17, 2021
1 parent c2f7422 commit 872f1c2
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 75 deletions.
4 changes: 4 additions & 0 deletions src/Psalm/Internal/Analyzer/ProjectAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
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;
Expand Down Expand Up @@ -229,6 +231,8 @@ class ProjectAnalyzer
PossiblyUndefinedVariable::class,
PossiblyUnusedMethod::class,
PossiblyUnusedProperty::class,
RedundantCast::class,
RedundantCastGivenDocblockType::class,
UnusedMethod::class,
UnusedProperty::class,
UnusedVariable::class,
Expand Down
132 changes: 57 additions & 75 deletions src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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;
Expand Down Expand Up @@ -52,21 +53,7 @@ public static function analyze(
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);
}
}

Expand Down Expand Up @@ -113,21 +100,7 @@ public static function analyze(

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);
}
}

Expand All @@ -153,21 +126,7 @@ public static function analyze(

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);
}
}

Expand All @@ -193,21 +152,7 @@ public static function analyze(

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(
Expand Down Expand Up @@ -262,21 +207,7 @@ public static function analyze(

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;
Expand Down Expand Up @@ -518,4 +449,55 @@ public static function castStringAttempt(

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
}
}
}
46 changes: 46 additions & 0 deletions tests/FileManipulation/RedundantCastManipulationTest.php
Original file line number Diff line number Diff line change
@@ -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,
],
];
}
}

0 comments on commit 872f1c2

Please sign in to comment.