1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Fix #4349 - improve types for suggested unions

This commit is contained in:
Matt Brown 2020-10-16 17:56:31 -04:00 committed by Daniil Gentili
parent 426a1ce47e
commit da79106a6a
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
8 changed files with 42 additions and 36 deletions

View File

@ -305,7 +305,7 @@ class ReturnTypeAnalyzer
if (IssueBuffer::accepts( if (IssueBuffer::accepts(
new MissingClosureReturnType( new MissingClosureReturnType(
'Closure does not have a return type, expecting ' . $inferred_return_type, 'Closure does not have a return type, expecting ' . $inferred_return_type->getId(),
new CodeLocation($function_like_analyzer, $function, null, true) new CodeLocation($function_like_analyzer, $function, null, true)
), ),
$suppressed_issues, $suppressed_issues,
@ -345,7 +345,7 @@ class ReturnTypeAnalyzer
if (IssueBuffer::accepts( if (IssueBuffer::accepts(
new MissingReturnType( new MissingReturnType(
'Method ' . $cased_method_id . ' does not have a return type' . 'Method ' . $cased_method_id . ' does not have a return type' .
(!$inferred_return_type->hasMixed() ? ', expecting ' . $inferred_return_type : ''), (!$inferred_return_type->hasMixed() ? ', expecting ' . $inferred_return_type->getId() : ''),
new CodeLocation($function_like_analyzer, $function->name, null, true) new CodeLocation($function_like_analyzer, $function->name, null, true)
), ),
$suppressed_issues, $suppressed_issues,

View File

@ -44,6 +44,6 @@ class TLiteralInt extends TInt
?string $this_class, ?string $this_class,
bool $use_phpdoc_format bool $use_phpdoc_format
): string { ): string {
return 'int'; return $use_phpdoc_format ? 'int' : $this->value;
} }
} }

View File

@ -8,6 +8,11 @@ class TPositiveInt extends TInt
return 'positive-int'; return 'positive-int';
} }
public function __toString(): string
{
return 'positive-int';
}
/** /**
* @return false * @return false
*/ */
@ -15,4 +20,17 @@ class TPositiveInt extends TInt
{ {
return false; return false;
} }
/**
* @param array<string> $aliased_classes
*
*/
public function toNamespacedString(
?string $namespace,
array $aliased_classes,
?string $this_class,
bool $use_phpdoc_format
): string {
return 'positive-int';
}
} }

View File

@ -402,40 +402,28 @@ class Union implements TypeNode
?string $this_class, ?string $this_class,
bool $use_phpdoc_format bool $use_phpdoc_format
): string { ): string {
$printed_int = false;
$printed_float = false;
$printed_string = false;
$types = []; $types = [];
$multi_ints = count($this->literal_int_types) > 1;
$multi_strings = count($this->literal_string_types) > 1;
$multi_floats = count($this->literal_float_types) > 1;
foreach ($this->types as $type) { foreach ($this->types as $type) {
$type_string = $type->toNamespacedString($namespace, $aliased_classes, $this_class, $use_phpdoc_format); $type_string = $type->toNamespacedString($namespace, $aliased_classes, $this_class, $use_phpdoc_format);
if ($type instanceof TLiteralFloat && $type_string === 'float') { if ($type instanceof TLiteralInt && !$multi_ints) {
if ($printed_float) { $type_string = 'int';
continue; } elseif ($type instanceof TLiteralFloat && !$multi_floats) {
} $type_string = 'float';
} elseif ($type instanceof TLiteralString && !$multi_strings) {
$printed_float = true; $type_string = 'string';
} elseif ($type instanceof TLiteralString && $type_string === 'string') {
if ($printed_string) {
continue;
}
$printed_string = true;
} elseif ($type instanceof TLiteralInt && $type_string === 'int') {
if ($printed_int) {
continue;
}
$printed_int = true;
} }
$types[] = $type_string; $types[] = $type_string;
} }
sort($types); sort($types);
return implode('|', $types); return implode('|', array_unique($types));
} }
/** /**

View File

@ -174,9 +174,9 @@ class BinaryOperationTest extends TestCase
'assertions' => [ 'assertions' => [
'$a' => 'int', '$a' => 'int',
'$b' => 'int', '$b' => 'int',
'$c' => 'int', '$c' => 'positive-int',
'$d' => 'int', '$d' => 'positive-int',
'$e' => 'int', '$e' => 'positive-int',
'$f' => 'string', '$f' => 'string',
], ],
], ],
@ -187,8 +187,8 @@ class BinaryOperationTest extends TestCase
$c = (true xor false); $c = (true xor false);
$d = (false xor false);', $d = (false xor false);',
'assertions' => [ 'assertions' => [
'$a' => 'int', '$a' => 'positive-int',
'$b' => 'int', '$b' => 'positive-int',
'$c' => 'bool', '$c' => 'bool',
'$d' => 'bool', '$d' => 'bool',
], ],
@ -220,7 +220,7 @@ class BinaryOperationTest extends TestCase
$b = 4 ^ 5;', $b = 4 ^ 5;',
'assertions' => [ 'assertions' => [
'$a' => 'string', '$a' => 'string',
'$b' => 'int', '$b' => 'positive-int',
], ],
], ],
'bitwiseNot' => [ 'bitwiseNot' => [

View File

@ -98,7 +98,7 @@ class JsonOutputTest extends TestCase
function fooFoo() { function fooFoo() {
return "hello"; return "hello";
}', }',
'message' => 'Method fooFoo does not have a return type, expecting string', 'message' => 'Method fooFoo does not have a return type, expecting string(hello)',
'line' => 2, 'line' => 2,
'error' => 'fooFoo', 'error' => 'fooFoo',
], ],

View File

@ -49,8 +49,8 @@ class Php56Test extends TestCase
$c4 = (new C)->four;', $c4 = (new C)->four;',
'assertions' => [ 'assertions' => [
'$c1' => 'int', '$c1' => 'int',
'$c2' => 'int', '$c2' => 'positive-int',
'$c3' => 'int', '$c3' => 'positive-int',
'$c1_3rd' => 'float|int', '$c1_3rd' => 'float|int',
'$c_sentence' => 'string', '$c_sentence' => 'string',
'$cf' => 'int', '$cf' => 'int',

View File

@ -863,7 +863,7 @@ class TypeTest extends \Psalm\Tests\TestCase
$a = 0; $a = 0;
$b = $a++;', $b = $a++;',
'assertions' => [ 'assertions' => [
'$a' => 'int', '$a' => 'positive-int',
], ],
], ],
'typedValueAssertion' => [ 'typedValueAssertion' => [