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

Break out RedundantCast issues

This commit is contained in:
Matt Brown 2020-12-01 17:25:45 -05:00 committed by Daniil Gentili
parent 2a30e49d88
commit 06d69ba5f3
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
11 changed files with 84 additions and 44 deletions

View File

@ -369,6 +369,8 @@
<xs:element name="PropertyNotSetInConstructor" type="PropertyIssueHandlerType" minOccurs="0" /> <xs:element name="PropertyNotSetInConstructor" type="PropertyIssueHandlerType" minOccurs="0" />
<xs:element name="PropertyTypeCoercion" type="PropertyIssueHandlerType" minOccurs="0" /> <xs:element name="PropertyTypeCoercion" type="PropertyIssueHandlerType" minOccurs="0" />
<xs:element name="RawObjectIteration" type="IssueHandlerType" minOccurs="0" /> <xs:element name="RawObjectIteration" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantCast" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantCastGivenDocblockType" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantCondition" type="IssueHandlerType" minOccurs="0" /> <xs:element name="RedundantCondition" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantConditionGivenDocblockType" type="IssueHandlerType" minOccurs="0" /> <xs:element name="RedundantConditionGivenDocblockType" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantPropertyInitializationCheck" type="IssueHandlerType" minOccurs="0" /> <xs:element name="RedundantPropertyInitializationCheck" type="IssueHandlerType" minOccurs="0" />

View File

@ -0,0 +1,10 @@
# RedundantCast
Emitted when a cast (string, int, float etc.) is redundant
```php
<?php
function foo(string $s) : string {
return (string) $s;
}
```

View File

@ -0,0 +1,13 @@
# RedundantCastGivenDocblockType
Emitted when a cast (string, int, float etc.) is redundant given the docblock-provided type
```php
<?php
/**
* @param string $s
*/
function foo($s) : string {
return (string) $s;
}
```

View File

@ -761,7 +761,7 @@ class InstancePropertyAssignmentAnalyzer
$context_type = $context_type ?: $assignment_value_type; $context_type = $context_type ?: $assignment_value_type;
if ($var_id && $context_type) { if ($var_id) {
if ($context->collect_initializations if ($context->collect_initializations
&& $lhs_var_id === '$this' && $lhs_var_id === '$this'
) { ) {

View File

@ -377,10 +377,9 @@ class NamedFunctionCallHandler
) { ) {
if ($first_arg_type->from_docblock) { if ($first_arg_type->from_docblock) {
if (IssueBuffer::accepts( if (IssueBuffer::accepts(
new \Psalm\Issue\RedundantConditionGivenDocblockType( new \Psalm\Issue\RedundantCastGivenDocblockType(
'The call to strtolower is unnecessary given the docblock type', 'The call to strtolower is unnecessary given the docblock type',
new CodeLocation($statements_analyzer, $function_name), new CodeLocation($statements_analyzer, $function_name)
null
), ),
$statements_analyzer->getSuppressedIssues() $statements_analyzer->getSuppressedIssues()
)) { )) {
@ -388,10 +387,9 @@ class NamedFunctionCallHandler
} }
} else { } else {
if (IssueBuffer::accepts( if (IssueBuffer::accepts(
new \Psalm\Issue\RedundantCondition( new \Psalm\Issue\RedundantCast(
'The call to strtolower is unnecessary', 'The call to strtolower is unnecessary',
new CodeLocation($statements_analyzer, $function_name), new CodeLocation($statements_analyzer, $function_name)
null
), ),
$statements_analyzer->getSuppressedIssues() $statements_analyzer->getSuppressedIssues()
)) { )) {

View File

@ -9,8 +9,8 @@ use Psalm\CodeLocation;
use Psalm\Context; use Psalm\Context;
use Psalm\Issue\InvalidCast; use Psalm\Issue\InvalidCast;
use Psalm\Issue\PossiblyInvalidCast; use Psalm\Issue\PossiblyInvalidCast;
use Psalm\Issue\RedundantCondition; use Psalm\Issue\RedundantCast;
use Psalm\Issue\RedundantConditionGivenDocblockType; use Psalm\Issue\RedundantCastGivenDocblockType;
use Psalm\Issue\UnrecognizedExpression; use Psalm\Issue\UnrecognizedExpression;
use Psalm\IssueBuffer; use Psalm\IssueBuffer;
use Psalm\Type; use Psalm\Type;
@ -49,16 +49,14 @@ class CastAnalyzer
if ($maybe_type) { if ($maybe_type) {
if ($maybe_type->isInt()) { if ($maybe_type->isInt()) {
if ($maybe_type->from_docblock) { if ($maybe_type->from_docblock) {
$issue = new RedundantConditionGivenDocblockType( $issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $maybe_type->getKey(), 'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$maybe_type->getKey()
); );
} else { } else {
$issue = new RedundantCondition( $issue = new RedundantCast(
'Redundant cast to ' . $maybe_type->getKey(), 'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$maybe_type->getKey()
); );
} }
@ -103,16 +101,14 @@ class CastAnalyzer
if ($maybe_type) { if ($maybe_type) {
if ($maybe_type->isFloat()) { if ($maybe_type->isFloat()) {
if ($maybe_type->from_docblock) { if ($maybe_type->from_docblock) {
$issue = new RedundantConditionGivenDocblockType( $issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $maybe_type->getKey(), 'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$maybe_type->getKey()
); );
} else { } else {
$issue = new RedundantCondition( $issue = new RedundantCast(
'Redundant cast to ' . $maybe_type->getKey(), 'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$maybe_type->getKey()
); );
} }
@ -145,16 +141,14 @@ class CastAnalyzer
if ($maybe_type) { if ($maybe_type) {
if ($maybe_type->isBool()) { if ($maybe_type->isBool()) {
if ($maybe_type->from_docblock) { if ($maybe_type->from_docblock) {
$issue = new RedundantConditionGivenDocblockType( $issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $maybe_type->getKey(), 'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$maybe_type->getKey()
); );
} else { } else {
$issue = new RedundantCondition( $issue = new RedundantCast(
'Redundant cast to ' . $maybe_type->getKey(), 'Redundant cast to ' . $maybe_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$maybe_type->getKey()
); );
} }
@ -187,16 +181,14 @@ class CastAnalyzer
if ($stmt_expr_type) { if ($stmt_expr_type) {
if ($stmt_expr_type->isString()) { if ($stmt_expr_type->isString()) {
if ($stmt_expr_type->from_docblock) { if ($stmt_expr_type->from_docblock) {
$issue = new RedundantConditionGivenDocblockType( $issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $stmt_expr_type->getKey(), 'Redundant cast to ' . $stmt_expr_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$stmt_expr_type->getKey()
); );
} else { } else {
$issue = new RedundantCondition( $issue = new RedundantCast(
'Redundant cast to ' . $stmt_expr_type->getKey(), 'Redundant cast to ' . $stmt_expr_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$stmt_expr_type->getKey()
); );
} }
@ -258,16 +250,14 @@ class CastAnalyzer
if ($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) { if ($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) {
if ($stmt_expr_type->isArray()) { if ($stmt_expr_type->isArray()) {
if ($stmt_expr_type->from_docblock) { if ($stmt_expr_type->from_docblock) {
$issue = new RedundantConditionGivenDocblockType( $issue = new RedundantCastGivenDocblockType(
'Redundant cast to ' . $stmt_expr_type->getKey(), 'Redundant cast to ' . $stmt_expr_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$stmt_expr_type->getKey()
); );
} else { } else {
$issue = new RedundantCondition( $issue = new RedundantCast(
'Redundant cast to ' . $stmt_expr_type->getKey(), 'Redundant cast to ' . $stmt_expr_type->getKey(),
new CodeLocation($statements_analyzer->getSource(), $stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)
$stmt_expr_type->getKey()
); );
} }

View File

@ -0,0 +1,8 @@
<?php
namespace Psalm\Issue;
class RedundantCast extends CodeIssue
{
public const ERROR_LEVEL = 4;
public const SHORTCODE = 262;
}

View File

@ -0,0 +1,8 @@
<?php
namespace Psalm\Issue;
class RedundantCastGivenDocblockType extends CodeIssue
{
public const ERROR_LEVEL = 2;
public const SHORTCODE = 263;
}

View File

@ -1890,8 +1890,10 @@ class ArrayAssignmentTest extends TestCase
/** /**
* @param list<int> $bar * @param list<int> $bar
*/ */
function baz(array $bar) : void { foo((array) $bar); }', function baz(array $bar) : void {
'error_message' => 'RedundantCondition', foo((array) $bar);
}',
'error_message' => 'RedundantCast',
], ],
]; ];
} }

View File

@ -2169,6 +2169,16 @@ class PropertyTypeTest extends TestCase
} }
}', }',
], ],
'memoizePropertyAfterSetting' => [
'<?php
class A {
public function foo() : void {
/** @psalm-suppress UndefinedThisPropertyAssignment */
$this->b = "c";
echo strlen($this->b);
}
}'
],
]; ];
} }

View File

@ -69,16 +69,15 @@ class RedundantConditionTest extends \Psalm\Tests\TestCase
'<?php '<?php
/** @param int $i */ /** @param int $i */
function foo($i): void { function foo($i): void {
/** @psalm-suppress RedundantConditionGivenDocblockType */
if ($i !== null) { if ($i !== null) {
/** @psalm-suppress RedundantCastGivenDocblockType */
$i = (int) $i; $i = (int) $i;
if ($i) {} if ($i) {}
} }
}', }',
'assertions' => [], 'assertions' => [],
'error_levels' => [
'RedundantConditionGivenDocblockType',
],
], ],
'noRedundantConditionAfterDocblockTypeNullCheck' => [ 'noRedundantConditionAfterDocblockTypeNullCheck' => [
'<?php '<?php