Skip to content

Commit

Permalink
Closes #5042
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Sep 12, 2022
1 parent ef3f40b commit 7768084
Showing 1 changed file with 38 additions and 29 deletions.
67 changes: 38 additions & 29 deletions src/Framework/MockObject/Invocation.php
Expand Up @@ -121,12 +121,17 @@ public function generateReturnValue()
return null;
}

$intersection = false;
$union = false;
$intersection = false;
$union = false;
$unionContainsIntersections = false;

if (strpos($this->returnType, '|') !== false) {
$types = explode('|', $this->returnType);
$union = true;

if (strpos($this->returnType, '(') !== false) {
$unionContainsIntersections = true;
}
} elseif (strpos($this->returnType, '&') !== false) {
$types = explode('&', $this->returnType);
$intersection = true;
Expand All @@ -136,7 +141,7 @@ public function generateReturnValue()

$types = array_map('strtolower', $types);

if (!$intersection) {
if (!$intersection && !$unionContainsIntersections) {
if (in_array('', $types, true) ||
in_array('null', $types, true) ||
in_array('mixed', $types, true) ||
Expand Down Expand Up @@ -220,38 +225,28 @@ public function generateReturnValue()
}
}

if ($intersection && $this->onlyInterfaces($types)) {
try {
return (new Generator)->getMockForInterfaces($types);
} catch (Throwable $t) {
throw new RuntimeException(
sprintf(
'Return value for %s::%s() cannot be generated: %s',
$this->className,
$this->methodName,
$t->getMessage(),
),
(int) $t->getCode(),
);
}
}

$reason = '';

if ($union) {
$reason = ' because the declared return type is a union';
} elseif ($intersection) {
$reason = ' because the declared return type is an intersection';

$onlyInterfaces = true;

foreach ($types as $type) {
if (!interface_exists($type)) {
$onlyInterfaces = false;

break;
}
}

if ($onlyInterfaces) {
try {
return (new Generator)->getMockForInterfaces($types);
} catch (Throwable $t) {
throw new RuntimeException(
sprintf(
'Return value for %s::%s() cannot be generated: %s',
$this->className,
$this->methodName,
$t->getMessage(),
),
(int) $t->getCode(),
);
}
}
}

throw new RuntimeException(
Expand Down Expand Up @@ -287,4 +282,18 @@ public function getObject(): object
{
return $this->object;
}

/**
* @psalm-param non-empty-list<string> $types
*/
private function onlyInterfaces(array $types): bool
{
foreach ($types as $type) {
if (!interface_exists($type)) {
return false;
}
}

return true;
}
}

0 comments on commit 7768084

Please sign in to comment.