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

Fix #2139 - allow comprehension of constant ternaries

This commit is contained in:
Brown 2019-09-17 11:29:41 -04:00
parent 6423a5e68a
commit 0ac9108814
4 changed files with 84 additions and 0 deletions

View File

@ -38,6 +38,7 @@ use function strlen;
use function strrpos; use function strrpos;
use function strtolower; use function strtolower;
use function substr; use function substr;
use Psalm\Internal\Scanner\UnresolvedConstantComponent;
/** /**
* @internal * @internal
@ -1557,6 +1558,25 @@ class ClassLikes
return new Type\Atomic\TMixed; return new Type\Atomic\TMixed;
} }
if ($c instanceof UnresolvedConstant\UnresolvedTernary) {
$cond = $this->resolveConstantType($c->cond, $statements_analyzer);
$if = $c->if ? $this->resolveConstantType($c->if, $statements_analyzer) : null;
$else = $this->resolveConstantType($c->else, $statements_analyzer);
if ($cond instanceof Type\Atomic\TLiteralFloat
|| $cond instanceof Type\Atomic\TLiteralInt
|| $cond instanceof Type\Atomic\TLiteralString
) {
if ($cond->value) {
return $if ? $if : $cond;
}
} elseif ($cond instanceof Type\Atomic\TFalse || $cond instanceof Type\Atomic\TNull) {
return $else;
} elseif ($cond instanceof Type\Atomic\TTrue) {
return $if ? $if : $cond;
}
}
if ($c instanceof UnresolvedConstant\ArrayValue) { if ($c instanceof UnresolvedConstant\ArrayValue) {
$properties = []; $properties = [];

View File

@ -0,0 +1,22 @@
<?php
namespace Psalm\Internal\Scanner\UnresolvedConstant;
use Psalm\Internal\Scanner\UnresolvedConstantComponent;
class UnresolvedTernary extends UnresolvedConstantComponent
{
public $cond;
public $if;
public $else;
public function __construct(
UnresolvedConstantComponent $cond,
?UnresolvedConstantComponent $if,
UnresolvedConstantComponent $else
) {
$this->cond = $cond;
$this->if = $if;
$this->else = $else;
}
}

View File

@ -3283,6 +3283,38 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
} }
} }
if ($stmt instanceof PhpParser\Node\Expr\Ternary) {
$cond = self::getUnresolvedClassConstExpr(
$stmt->cond,
$aliases,
$fq_classlike_name
);
$if = null;
if ($stmt->if) {
$if = self::getUnresolvedClassConstExpr(
$stmt->if,
$aliases,
$fq_classlike_name
);
if ($if === null) {
$if = false;
}
}
$else = self::getUnresolvedClassConstExpr(
$stmt->else,
$aliases,
$fq_classlike_name
);
if ($cond && $else && $if !== false) {
return new UnresolvedConstant\UnresolvedTernary($cond, $if, $else);
}
}
if ($stmt instanceof PhpParser\Node\Expr\ConstFetch) { if ($stmt instanceof PhpParser\Node\Expr\ConstFetch) {
if (strtolower($stmt->name->parts[0]) === 'false') { if (strtolower($stmt->name->parts[0]) === 'false') {
return new UnresolvedConstant\ScalarValue(false); return new UnresolvedConstant\ScalarValue(false);

View File

@ -429,6 +429,16 @@ class ConstantTest extends TestCase
const Z = self::X; const Z = self::X;
}' }'
], ],
'supportTernaries' => [
'<?php
const cons1 = true;
class Clazz {
const cons2 = (cons1) ? 1 : 0;
}
echo Clazz::cons2;',
]
]; ];
} }