1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Improve rendering of tuples

This commit is contained in:
Brown 2020-05-11 09:08:53 -04:00
parent 8bfe91787d
commit 813302206a
4 changed files with 46 additions and 29 deletions

View File

@ -74,8 +74,12 @@ class ObjectLike extends \Psalm\Type\Atomic
public function __toString()
{
$union_type_parts = array_map(
$property_strings = array_map(
function ($name, Union $type) {
if ($this->is_list && $this->sealed) {
return (string) $type;
}
if (\is_string($name) && \preg_match('/[ "\'\\\\.\n]/', $name)) {
$name = '\'' . \str_replace("\n", '\n', \addslashes($name)) . '\'';
}
@ -85,15 +89,23 @@ class ObjectLike extends \Psalm\Type\Atomic
array_keys($this->properties),
$this->properties
);
sort($union_type_parts);
if (!$this->is_list) {
sort($property_strings);
}
/** @psalm-suppress MixedOperand */
return static::KEY . '{' . implode(', ', $union_type_parts) . '}';
return static::KEY . '{' . implode(', ', $property_strings) . '}';
}
public function getId(bool $nested = false)
{
$union_type_parts = array_map(
$property_strings = array_map(
function ($name, Union $type) {
if ($this->is_list && $this->sealed) {
return $type->getId();
}
if (\is_string($name) && \preg_match('/[ "\'\\\\.\n]/', $name)) {
$name = '\'' . \str_replace("\n", '\n', \addslashes($name)) . '\'';
}
@ -103,10 +115,14 @@ class ObjectLike extends \Psalm\Type\Atomic
array_keys($this->properties),
$this->properties
);
sort($union_type_parts);
if (!$this->is_list) {
sort($property_strings);
}
/** @psalm-suppress MixedOperand */
return static::KEY . '{' .
implode(', ', $union_type_parts) .
implode(', ', $property_strings) .
'}'
. ($this->previous_value_type
? '<' . ($this->previous_key_type ? $this->previous_key_type->getId() . ', ' : '')

View File

@ -64,7 +64,7 @@ class ArrayAssignmentTest extends TestCase
$out[] = [4];
}',
'assertions' => [
'$out' => 'non-empty-list<array{0: int}>',
'$out' => 'non-empty-list<array{int}>',
],
],
'generic2dArrayCreationAddedInIf' => [
@ -193,7 +193,7 @@ class ArrayAssignmentTest extends TestCase
}',
'assertions' => [
'$foo' => 'array{0: string, 1: string, 2: string}',
'$bar' => 'array{0: int, 1: int, 2: int}',
'$bar' => 'array{int, int, int}',
'$bat' => 'non-empty-array<string, int>',
],
],
@ -257,7 +257,7 @@ class ArrayAssignmentTest extends TestCase
"baz" => [1]
];',
'assertions' => [
'$foo' => 'array{bar: array{a: string}, baz: array{0: int}}',
'$foo' => 'array{bar: array{a: string}, baz: array{int}}',
],
],
'implicitObjectLikeCreation' => [
@ -278,7 +278,7 @@ class ArrayAssignmentTest extends TestCase
];
$foo["bar"]["bam"]["baz"] = "hello";',
'assertions' => [
'$foo' => 'array{bar: array{a: string, bam: array{baz: string}}, baz: array{0: int}}',
'$foo' => 'array{bar: array{a: string, bam: array{baz: string}}, baz: array{int}}',
],
],
'conflictingTypesWithAssignment2' => [
@ -436,7 +436,7 @@ class ArrayAssignmentTest extends TestCase
$foo["a"] = 1;
$foo += ["b" => [2, 3]];',
'assertions' => [
'$foo' => 'array{a: int, b: array{0: int, 1: int}}',
'$foo' => 'array{a: int, b: array{int, int}}',
],
],
'nestedObjectLikeArrayAddition' => [
@ -445,7 +445,7 @@ class ArrayAssignmentTest extends TestCase
$foo["root"]["a"] = 1;
$foo["root"] += ["b" => [2, 3]];',
'assertions' => [
'$foo' => 'array{root: array{a: int, b: array{0: int, 1: int}}}',
'$foo' => 'array{root: array{a: int, b: array{int, int}}}',
],
],
'updateStringIntKey1' => [
@ -812,7 +812,7 @@ class ArrayAssignmentTest extends TestCase
$a_values = array_values($a);
$a_keys = array_keys($a);',
'assertions' => [
'$a' => 'array{0: string, 1: int}',
'$a' => 'array{string, int}',
'$a_values' => 'non-empty-list<int|string>',
'$a_keys' => 'non-empty-list<int>',
],
@ -822,7 +822,7 @@ class ArrayAssignmentTest extends TestCase
$b = ["hello", 5];
$b[0] = 3;',
'assertions' => [
'$b' => 'array{0: int, 1: int}',
'$b' => 'array{int, int}',
],
],
'changeIntOffsetKeyValuesAfterCopy' => [
@ -831,8 +831,8 @@ class ArrayAssignmentTest extends TestCase
$c = $b;
$c[0] = 3;',
'assertions' => [
'$b' => 'array{0: string, 1: int}',
'$c' => 'array{0: int, 1: int}',
'$b' => 'array{string, int}',
'$c' => 'array{int, int}',
],
],
'mergeIntOffsetValues' => [
@ -1196,8 +1196,8 @@ class ArrayAssignmentTest extends TestCase
$b[] = rand(0, 10);',
'assertions' => [
'$a' => 'array{0: int, 1: int, 2: int}',
'$b' => 'array{0: int, 1: int, 2: int, 3: int}',
'$a' => 'array{int, int, int}',
'$b' => 'array{int, int, int, int}',
],
],
'listMergedWithObjectLikeList' => [
@ -1281,8 +1281,8 @@ class ArrayAssignmentTest extends TestCase
$arr2 = [...$arr1];
$arr3 = [1 => 0, ...$arr1];',
[
'$result' => 'array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int}',
'$arr2' => 'array{0: int, 1: int, 2: int}',
'$result' => 'array{int, int, int, int, int, int, int, int}',
'$arr2' => 'array{int, int, int}',
'$arr3' => 'array{1: int, 2: int, 3: int, 4: int}',
]
],

View File

@ -459,7 +459,7 @@ class ArrayFunctionCallTest extends TestCase
'$vars' => 'array{x: string, y: string}',
'$c' => 'string',
'$d' => 'string',
'$more_vars' => 'array{0: string, 1: string}',
'$more_vars' => 'array{string, string}',
'$e' => 'int',
],
],
@ -909,11 +909,12 @@ class ArrayFunctionCallTest extends TestCase
$b = ["a", "b", "c"];
array_splice($a, -1, 1, $b);
$d = [1, 2, 3];
array_splice($d, -1, 1);',
$e = array_splice($d, -1, 1);',
'assertions' => [
'$a' => 'non-empty-list<int|string>',
'$b' => 'array{0: string, 1: string, 2: string}',
'$c' => 'array{0: int, 1: int, 2: int}',
'$b' => 'array{string, string, string}',
'$c' => 'array{int, int, int}',
'$e' => 'array<array-key, mixed>'
],
],
'arraySpliceOtherType' => [
@ -921,7 +922,7 @@ class ArrayFunctionCallTest extends TestCase
$d = [["red"], ["green"], ["blue"]];
array_splice($d, -1, 1, "foo");',
'assertions' => [
'$d' => 'array<int, array{0: string}|string>',
'$d' => 'array<int, array{string}|string>',
],
],
'ksortPreserveShape' => [

View File

@ -289,7 +289,7 @@ class TypeParseTest extends TestCase
public function testIterableContainingObjectLike() : void
{
$this->assertSame('iterable<string, array{0: int}>', Type::parseString('iterable<string, array{int}>')->getId());
$this->assertSame('iterable<string, array{int}>', Type::parseString('iterable<string, array{int}>')->getId());
}
/**
@ -488,7 +488,7 @@ class TypeParseTest extends TestCase
public function testObjectLikeWithIntKeysAndUnionArgs()
{
$this->assertSame(
'array{0: null|stdClass}',
'array{null|stdClass}',
(string)Type::parseString('array{stdClass|null}')
);
}
@ -499,12 +499,12 @@ class TypeParseTest extends TestCase
public function testObjectLikeWithIntKeysAndGenericArgs()
{
$this->assertSame(
'array{0: array<array-key, mixed>}',
'array{array<array-key, mixed>}',
(string)Type::parseString('array{array}')
);
$this->assertSame(
'array{0: array<int, string>}',
'array{array<int, string>}',
(string)Type::parseString('array{array<int, string>}')
);
}