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

Fix #4643 - use PHP8 union types when possible

This commit is contained in:
Matt Brown 2020-11-21 22:50:56 -05:00 committed by Daniil Gentili
parent 169dbf2545
commit 56918001a8
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
2 changed files with 57 additions and 23 deletions

View File

@ -437,10 +437,11 @@ class Union implements TypeNode
int $php_major_version, int $php_major_version,
int $php_minor_version int $php_minor_version
): ?string { ): ?string {
$nullable = false; if (!$this->isSingleAndMaybeNullable()) {
if ($php_major_version < 8) {
if (!$this->isSingleAndMaybeNullable() return null;
|| $php_major_version < 7 }
} elseif ($php_major_version < 7
|| (isset($this->types['null']) && $php_major_version === 7 && $php_minor_version < 1) || (isset($this->types['null']) && $php_major_version === 7 && $php_minor_version < 1)
) { ) {
return null; return null;
@ -448,36 +449,38 @@ class Union implements TypeNode
$types = $this->types; $types = $this->types;
if (isset($types['null'])) { $nullable = false;
if (count($types) === 1) {
return null;
}
if (isset($types['null']) && count($types) === 2) {
unset($types['null']); unset($types['null']);
$nullable = true; $nullable = true;
} }
$atomic_type = array_values($types)[0]; $php_types = [];
$atomic_type_string = $atomic_type->toPhpString( foreach ($types as $atomic_type) {
$namespace, $php_type = $atomic_type->toPhpString(
$aliased_classes, $namespace,
$this_class, $aliased_classes,
$php_major_version, $this_class,
$php_minor_version $php_major_version,
); $php_minor_version
);
if ($atomic_type_string) { if (!$php_type) {
return ($nullable ? '?' : '') . $atomic_type_string; return null;
}
$php_types[] = $php_type;
} }
return null; return ($nullable ? '?' : '') . implode('|', array_unique($php_types));
} }
public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool
{ {
if (!$this->isSingleAndMaybeNullable()) { if (!$this->isSingleAndMaybeNullable() && $php_major_version < 8) {
return false; return false;
} }
@ -491,9 +494,12 @@ class Union implements TypeNode
} }
} }
$atomic_type = array_values($types)[0]; return !array_filter(
$types,
return $atomic_type->canBeFullyExpressedInPhp($php_major_version, $php_minor_version); function ($atomic_type) use ($php_major_version, $php_minor_version) {
return !$atomic_type->canBeFullyExpressedInPhp($php_major_version, $php_minor_version);
}
);
} }
public function removeType(string $type_string): bool public function removeType(string $type_string): bool

View File

@ -984,6 +984,34 @@ class MissingReturnTypeTest extends FileManipulationTest
false, false,
true, true,
], ],
'returnIntOrString' => [
'<?php
function scope(int $i, string $s) {
return rand(0, 1) ? $i : $s;
}',
'<?php
function scope(int $i, string $s): int|string {
return rand(0, 1) ? $i : $s;
}',
'8.0',
['MissingReturnType'],
false,
true,
],
'returnIntOrString80' => [
'<?php
function scope(int $i, string $s) {
return rand(0, 1) ? $i : $s;
}',
'<?php
function scope(int $i, string $s): int|string {
return rand(0, 1) ? $i : $s;
}',
'8.0',
['MissingReturnType'],
false,
true,
],
]; ];
} }
} }