mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +01:00
Improve accuracy of optional example
This commit is contained in:
parent
e6dad6e65f
commit
37659445f0
@ -229,7 +229,8 @@ class TemplateInferredTypeReplacer
|
|||||||
? clone $inferred_upper_bounds[$atomic_type->param_name][$atomic_type->defining_class]->type
|
? clone $inferred_upper_bounds[$atomic_type->param_name][$atomic_type->defining_class]->type
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
$class_template_type = null;
|
$if_template_type = null;
|
||||||
|
$else_template_type = null;
|
||||||
|
|
||||||
$atomic_type = clone $atomic_type;
|
$atomic_type = clone $atomic_type;
|
||||||
|
|
||||||
@ -270,37 +271,53 @@ class TemplateInferredTypeReplacer
|
|||||||
$else_candidate_type = $matching_else_types ? new Type\Union($matching_else_types) : null;
|
$else_candidate_type = $matching_else_types ? new Type\Union($matching_else_types) : null;
|
||||||
|
|
||||||
if ($if_candidate_type
|
if ($if_candidate_type
|
||||||
&& !$else_candidate_type
|
|
||||||
&& UnionTypeComparator::isContainedBy(
|
&& UnionTypeComparator::isContainedBy(
|
||||||
$codebase,
|
$codebase,
|
||||||
$if_candidate_type,
|
$if_candidate_type,
|
||||||
$atomic_type->conditional_type
|
$atomic_type->conditional_type
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
$class_template_type = clone $atomic_type->if_type;
|
$if_template_type = clone $atomic_type->if_type;
|
||||||
|
|
||||||
|
$refined_template_result = clone $template_result;
|
||||||
|
|
||||||
|
$refined_template_result->upper_bounds[$atomic_type->param_name][$atomic_type->defining_class]
|
||||||
|
= new \Psalm\Internal\Type\TemplateBound(
|
||||||
|
$if_candidate_type
|
||||||
|
);
|
||||||
|
|
||||||
self::replace(
|
self::replace(
|
||||||
$class_template_type,
|
$if_template_type,
|
||||||
$template_result,
|
$refined_template_result,
|
||||||
$codebase
|
$codebase
|
||||||
);
|
);
|
||||||
} elseif (!$if_candidate_type
|
}
|
||||||
&& $else_candidate_type
|
|
||||||
|
if ($else_candidate_type
|
||||||
&& UnionTypeComparator::isContainedBy(
|
&& UnionTypeComparator::isContainedBy(
|
||||||
$codebase,
|
$codebase,
|
||||||
$else_candidate_type,
|
$else_candidate_type,
|
||||||
$atomic_type->as_type
|
$atomic_type->as_type
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
$class_template_type = clone $atomic_type->else_type;
|
$else_template_type = clone $atomic_type->else_type;
|
||||||
|
|
||||||
|
$refined_template_result = clone $template_result;
|
||||||
|
|
||||||
|
$refined_template_result->upper_bounds[$atomic_type->param_name][$atomic_type->defining_class]
|
||||||
|
= new \Psalm\Internal\Type\TemplateBound(
|
||||||
|
$else_candidate_type
|
||||||
|
);
|
||||||
|
|
||||||
self::replace(
|
self::replace(
|
||||||
$class_template_type,
|
$else_template_type,
|
||||||
$template_result,
|
$refined_template_result,
|
||||||
$codebase
|
$codebase
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$class_template_type) {
|
if (!$if_template_type && !$else_template_type) {
|
||||||
self::replace(
|
self::replace(
|
||||||
$atomic_type->if_type,
|
$atomic_type->if_type,
|
||||||
$template_result,
|
$template_result,
|
||||||
@ -318,6 +335,16 @@ class TemplateInferredTypeReplacer
|
|||||||
$atomic_type->else_type,
|
$atomic_type->else_type,
|
||||||
$codebase
|
$codebase
|
||||||
);
|
);
|
||||||
|
} elseif ($if_template_type && !$else_template_type) {
|
||||||
|
$class_template_type = $if_template_type;
|
||||||
|
} elseif (!$if_template_type) {
|
||||||
|
$class_template_type = $else_template_type;
|
||||||
|
} else {
|
||||||
|
$class_template_type = Type::combineUnionTypes(
|
||||||
|
$if_template_type,
|
||||||
|
$else_template_type,
|
||||||
|
$codebase
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$keys_to_unset[] = $key;
|
$keys_to_unset[] = $key;
|
||||||
|
@ -674,9 +674,9 @@ class ConditionalReturnTypeTest extends TestCase
|
|||||||
public string $name = "Dave";
|
public string $name = "Dave";
|
||||||
}
|
}
|
||||||
|
|
||||||
function takesNullableUser(?User $user) : void {
|
/** @return User|NullObject */
|
||||||
$name = optional($user);
|
function takesNullableUser(?User $user) {
|
||||||
if ($name instanceof NullObject) {}
|
return optional($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
class NullObject {
|
class NullObject {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user