1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Fix #594 - support intersection types (and catch errors)

This commit is contained in:
Matthew Brown 2018-03-20 20:56:33 -04:00
parent 3f90bceabf
commit 837f5d7096
2 changed files with 43 additions and 35 deletions

View File

@ -216,45 +216,53 @@ class TypeChecker
) {
$intersection_input_types = $input_type_part->extra_types ?: [];
$intersection_input_types[] = $input_type_part;
$container_type_lower = strtolower($container_type_part->value);
foreach ($intersection_input_types as $intersection_input_type) {
if ($intersection_input_type->value === $container_type_part->value) {
return true;
$intersection_container_types = $container_type_part->extra_types ?: [];
$intersection_container_types[] = $container_type_part;
foreach ($intersection_container_types as $intersection_container_type) {
$intersection_container_type_lower = strtolower($intersection_container_type->value);
foreach ($intersection_input_types as $intersection_input_type) {
$intersection_input_type_lower = strtolower($intersection_input_type->value);
if ($intersection_container_type_lower === $intersection_input_type_lower) {
continue 2;
}
if ($intersection_input_type_lower === 'generator'
&& in_array($intersection_container_type_lower, ['iterator', 'traversable', 'iterable'], true)
) {
continue 2;
}
if ($codebase->classExists($intersection_input_type->value)
&& $codebase->classExtendsOrImplements(
$intersection_input_type->value,
$intersection_container_type->value
)
) {
continue 2;
}
if ($codebase->interfaceExists($intersection_input_type->value)
&& $codebase->interfaceExtends(
$intersection_input_type->value,
$intersection_container_type->value
)
) {
continue 2;
}
if (ExpressionChecker::isMock($intersection_input_type->value)) {
return true;
}
}
$intersection_input_type_lower = strtolower($intersection_input_type->value);
if ($intersection_input_type_lower === 'generator'
&& in_array($container_type_lower, ['iterator', 'traversable', 'iterable'], true)
) {
return true;
}
if ($codebase->classExists($intersection_input_type->value)
&& $codebase->classExtendsOrImplements(
$intersection_input_type->value,
$container_type_part->value
)
) {
return true;
}
if ($codebase->interfaceExists($intersection_input_type->value)
&& $codebase->interfaceExtends(
$intersection_input_type->value,
$container_type_part->value
)
) {
return true;
}
if (ExpressionChecker::isMock($intersection_input_type->value)) {
return true;
}
return false;
}
return false;
return true;
}
/**

View File

@ -838,7 +838,7 @@ class TypeReconciliationTest extends TestCase
}',
'error_message' => 'PossiblyInvalidArgument',
],
'SKIPPED-intersection' => [
'intersectionIncorrect' => [
'<?php
interface I {
public function bat(): void;