mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Fix manipulation of intersection types, arrow functions, foreign static types, T|false|null unions.
This commit is contained in:
parent
1574751aef
commit
1c99af205b
@ -8,6 +8,7 @@ use Psalm\Type\Atomic;
|
||||
|
||||
use function array_map;
|
||||
use function implode;
|
||||
use function strrpos;
|
||||
use function substr;
|
||||
|
||||
/**
|
||||
@ -127,7 +128,14 @@ class TNamedObject extends Atomic
|
||||
return $php_major_version >= 8 ? 'static' : 'self';
|
||||
}
|
||||
|
||||
return $this->toNamespacedString($namespace, $aliased_classes, $this_class, false);
|
||||
$result = $this->toNamespacedString($namespace, $aliased_classes, $this_class, false);
|
||||
$intersection = strrpos($result, '&');
|
||||
if ($intersection === false ||
|
||||
($intersection !== false && $php_major_version >= 8 && $php_minor_version >= 1)
|
||||
) {
|
||||
return $result;
|
||||
}
|
||||
return substr($result, $intersection+1);
|
||||
}
|
||||
|
||||
public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool
|
||||
|
@ -23,6 +23,7 @@ use function array_values;
|
||||
use function count;
|
||||
use function get_class;
|
||||
use function implode;
|
||||
use function ksort;
|
||||
use function reset;
|
||||
use function sort;
|
||||
use function strpos;
|
||||
@ -497,7 +498,7 @@ class Union implements TypeNode
|
||||
|
||||
$nullable = false;
|
||||
|
||||
if (isset($types['null']) && count($types) === 2) {
|
||||
if (isset($types['null']) && count($types) > 1) {
|
||||
unset($types['null']);
|
||||
|
||||
$nullable = true;
|
||||
@ -530,7 +531,12 @@ class Union implements TypeNode
|
||||
}
|
||||
|
||||
if ($falsable) {
|
||||
return ($nullable ? '?' : '') . implode('|', array_unique($php_types)) . '|false';
|
||||
if ($nullable) {
|
||||
$php_types['null'] = 'null';
|
||||
}
|
||||
$php_types['false'] = 'false';
|
||||
ksort($php_types);
|
||||
return implode('|', array_unique($php_types));
|
||||
}
|
||||
|
||||
return ($nullable ? '?' : '') . implode('|', array_unique($php_types));
|
||||
|
@ -731,7 +731,111 @@ class ReturnTypeManipulationTest extends FileManipulationTestCase
|
||||
['MissingReturnType'],
|
||||
false,
|
||||
true,
|
||||
]
|
||||
],
|
||||
'OrFalseNullInReturn' => [
|
||||
'<?php
|
||||
function a() {
|
||||
/** @var array|false|null $a */
|
||||
$a = false;
|
||||
return $a;
|
||||
}',
|
||||
'<?php
|
||||
function a(): array|false|null {
|
||||
/** @var array|false|null $a */
|
||||
$a = false;
|
||||
return $a;
|
||||
}',
|
||||
'8.0',
|
||||
['MissingReturnType'],
|
||||
false,
|
||||
true,
|
||||
],
|
||||
'OrFalseNullInReturn' => [
|
||||
'<?php
|
||||
function a() {
|
||||
/** @var array|false|null $a */
|
||||
$a = false;
|
||||
return $a;
|
||||
}',
|
||||
'<?php
|
||||
function a(): array|false|null {
|
||||
/** @var array|false|null $a */
|
||||
$a = false;
|
||||
return $a;
|
||||
}',
|
||||
'8.0',
|
||||
['MissingReturnType'],
|
||||
false,
|
||||
true,
|
||||
],
|
||||
'ForeignStatic' => [
|
||||
'<?php
|
||||
class a {
|
||||
public function g(): static { return $this; }
|
||||
}
|
||||
class b extends a {}
|
||||
|
||||
class c {
|
||||
public function a() { return (new a)->g(); }
|
||||
public function b() { return (new b)->g(); }
|
||||
}
|
||||
',
|
||||
'<?php
|
||||
class a {
|
||||
public function g(): static { return $this; }
|
||||
}
|
||||
class b extends a {}
|
||||
|
||||
class c {
|
||||
public function a(): a { return (new a)->g(); }
|
||||
public function b(): b { return (new b)->g(); }
|
||||
}
|
||||
',
|
||||
'8.0',
|
||||
['MissingReturnType'],
|
||||
false,
|
||||
true,
|
||||
],
|
||||
'ForeignStaticIntersection' => [
|
||||
'<?php
|
||||
class a {
|
||||
public function g(): static { return $this; }
|
||||
}
|
||||
class b extends a {}
|
||||
|
||||
class c {
|
||||
public function a() { return (new a)->g(); }
|
||||
public function b() { return (new b)->g(); }
|
||||
}
|
||||
',
|
||||
'<?php
|
||||
class a {
|
||||
public function g(): static { return $this; }
|
||||
}
|
||||
class b extends a {}
|
||||
|
||||
class c {
|
||||
public function a(): a { return (new a)->g(); }
|
||||
public function b(): a&b { return (new b)->g(); }
|
||||
}
|
||||
',
|
||||
'8.1',
|
||||
['MissingReturnType'],
|
||||
false,
|
||||
true,
|
||||
],
|
||||
'ArrowFunction' => [
|
||||
'<?php
|
||||
fn () => 0;
|
||||
',
|
||||
'<?php
|
||||
fn (): int => 0;
|
||||
',
|
||||
'8.0',
|
||||
['MissingClosureReturnType'],
|
||||
false,
|
||||
true,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user