Skip to content

Commit

Permalink
Fix #1398 - improve casting rules for resource
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Mar 1, 2019
1 parent 42d4156 commit d1cf9d6
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 24 deletions.
50 changes: 26 additions & 24 deletions src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php
Expand Up @@ -416,33 +416,35 @@ public static function analyze(
return false;
}

$container_type = Type::getString();

if (isset($stmt->expr->inferredType)
&& !$stmt->expr->inferredType->hasMixed()
&& !isset($stmt->expr->inferredType->getTypes()['resource'])
&& !TypeAnalyzer::isContainedBy(
$statements_analyzer->getCodebase(),
$stmt->expr->inferredType,
$container_type,
true,
false,
$has_scalar_match
)
&& !$has_scalar_match
) {
if (IssueBuffer::accepts(
new InvalidCast(
$stmt->expr->inferredType->getId() . ' cannot be cast to ' . $container_type,
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
return false;
if (isset($stmt->expr->inferredType)) {
foreach ($stmt->expr->inferredType->getTypes() as $atomic_type) {
if (!$atomic_type instanceof TMixed
&& !$atomic_type instanceof Type\Atomic\TResource
&& !$atomic_type instanceof TNull
&& !TypeAnalyzer::isAtomicContainedBy(
$statements_analyzer->getCodebase(),
$atomic_type,
new TString(),
true,
false,
$has_scalar_match
)
&& !$has_scalar_match
) {
if (IssueBuffer::accepts(
new InvalidCast(
$atomic_type->getId() . ' cannot be cast to string',
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
return false;
}
}
}
}

$stmt->inferredType = $container_type;
$stmt->inferredType = Type::getString();
} elseif ($stmt instanceof PhpParser\Node\Expr\Cast\Object_) {
if (self::analyze($statements_analyzer, $stmt->expr, $context) === false) {
return false;
Expand Down
9 changes: 9 additions & 0 deletions tests/ToStringTest.php
Expand Up @@ -186,6 +186,15 @@ function takesString(string $s) : void {}
takesString($a);',
'error_message' => 'InvalidArgument',
],
'resourceOrFalseToString' => [
'<?php
$a = fopen("php://memory", "r");
if (rand(0, 1)) {
$a = [];
}
$b = (string) $a;',
'error_message' => 'InvalidCast',
],
];
}
}

0 comments on commit d1cf9d6

Please sign in to comment.