Skip to content
Permalink
Browse files

Improve behaviour of templated template assertions

Fixes #1956
  • Loading branch information...
muglug committed Jul 21, 2019
1 parent 3516b48 commit 76508e6d645bbbf0dcd397c4f4f35491c6f7e713
@@ -2972,39 +2972,43 @@ protected static function applyAssertionsToContext(
$rule = substr($rule, 1);
}
if (isset($template_type_map[$rule][''])) {
if ($template_type_map[$rule][''][0]->hasMixed()) {
continue;
}
$replacement_atomic_types = $template_type_map[$rule][''][0]->getTypes();
if (count($replacement_atomic_types) > 1) {
continue;
}
if (isset($template_type_map[$rule])) {
foreach ($template_type_map[$rule] as $template_map) {
if ($template_map[0]->hasMixed()) {
continue 2;
}
$ored_type_assertions = [];
$replacement_atomic_types = $template_map[0]->getTypes();
foreach ($replacement_atomic_types as $replacement_atomic_type) {
if ($replacement_atomic_type instanceof Type\Atomic\TMixed) {
if (count($replacement_atomic_types) > 1) {
continue 2;
}
if ($replacement_atomic_type instanceof Type\Atomic\TArray
|| $replacement_atomic_type instanceof Type\Atomic\ObjectLike
) {
$ored_type_assertions[] = $prefix . 'array';
} elseif ($replacement_atomic_type instanceof Type\Atomic\TNamedObject) {
$ored_type_assertions[] = $prefix . $replacement_atomic_type->value;
} elseif ($replacement_atomic_type instanceof Type\Atomic\Scalar) {
$ored_type_assertions[] = $prefix . $replacement_atomic_type->getId();
} elseif ($replacement_atomic_type instanceof Type\Atomic\TNull) {
$ored_type_assertions[] = $prefix . 'null';
$ored_type_assertions = [];
foreach ($replacement_atomic_types as $replacement_atomic_type) {
if ($replacement_atomic_type instanceof Type\Atomic\TMixed) {
continue 3;
}
if ($replacement_atomic_type instanceof Type\Atomic\TArray
|| $replacement_atomic_type instanceof Type\Atomic\ObjectLike
) {
$ored_type_assertions[] = $prefix . 'array';
} elseif ($replacement_atomic_type instanceof Type\Atomic\TNamedObject) {
$ored_type_assertions[] = $prefix . $replacement_atomic_type->value;
} elseif ($replacement_atomic_type instanceof Type\Atomic\Scalar) {
$ored_type_assertions[] = $prefix . $replacement_atomic_type->getId();
} elseif ($replacement_atomic_type instanceof Type\Atomic\TNull) {
$ored_type_assertions[] = $prefix . 'null';
} elseif ($replacement_atomic_type instanceof Type\Atomic\TTemplateParam) {
$ored_type_assertions[] = $prefix . $replacement_atomic_type->param_name;
}
}
}
if ($ored_type_assertions) {
$type_assertions[$assertion_var_id] = [$ored_type_assertions];
if ($ored_type_assertions) {
$type_assertions[$assertion_var_id] = [$ored_type_assertions];
}
}
} else {
$type_assertions[$assertion_var_id] = $assertion->rule;
@@ -50,7 +50,8 @@ function (array $rules) use ($template_type_map) : array {
if (isset($template_type_map[$rule_token[0]])) {
foreach ($template_type_map[$rule_token[0]] as list($type)) {
$substitute = true;
$rule_token[0] = $type->getId();
$rule_token[0] = $type->getKey();
}
}
}
@@ -173,7 +173,7 @@ public function bat(): void {
'$f' => 'Foo',
],
],
'suppressRedundantCondition' => [
'suppressRedundantCondition' => [
'<?php
namespace Bar;
@@ -449,6 +449,69 @@ function consume2($value)
return $value;
}'
],
'assertTemplatedTemplateSimple' => [
'<?php
/**
* @template T1
*/
class Clazz
{
/**
* @param mixed $x
*
* @psalm-assert T1 $x
*/
public function is($x) : void {}
}
/**
* @template T2
*
* @param Clazz<T2> $c
*
* @return T2
* @psalm-suppress MixedAssignment
*/
function example(Clazz $c) {
/** @var mixed */
$x = 0;
$c->is($x);
return $x;
}'
],
'assertTemplatedTemplateIfTrue' => [
'<?php
/**
* @template T1
*/
class Clazz
{
/**
* @param mixed $x
*
* @return bool
*
* @psalm-assert-if-true T1 $x
*/
public function is($x) : bool {
return true;
}
}
/**
* @template T2
*
* @param Clazz<T2> $c
*
* @return T2|false
* @psalm-suppress MixedAssignment
*/
function example(Clazz $c) {
/** @var mixed */
$x = 0;
return $c->is($x) ? $x : false;
}'
],
];
}

0 comments on commit 76508e6

Please sign in to comment.
You can’t perform that action at this time.