Skip to content

Commit

Permalink
ConstantArrayType - toPhpDocNode without keys if they are not necessary
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed May 17, 2023
1 parent 9592e9f commit 413079d
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
19 changes: 17 additions & 2 deletions src/Type/Constant/ConstantArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -1559,7 +1559,12 @@ public function makeOffsetRequired(Type $offsetType): self
public function toPhpDocNode(): TypeNode
{
$items = [];
$values = [];
$exportValuesOnly = true;
foreach ($this->keyTypes as $i => $keyType) {
if ($keyType->getValue() !== $i) {
$exportValuesOnly = false;
}
$keyPhpDocNode = $keyType->toPhpDocNode();
if (!$keyPhpDocNode instanceof ConstTypeNode) {
continue;
Expand All @@ -1574,14 +1579,24 @@ public function toPhpDocNode(): TypeNode
$keyNode = new IdentifierTypeNode($value);
}
}

$isOptional = $this->isOptionalKey($i);
if ($isOptional) {
$exportValuesOnly = false;
}
$items[] = new ArrayShapeItemNode(
$keyNode,
$this->isOptionalKey($i),
$isOptional,
$valueType->toPhpDocNode(),
);
$values[] = new ArrayShapeItemNode(
null,
$isOptional,
$valueType->toPhpDocNode(),
);
}

return new ArrayShapeNode($items);
return new ArrayShapeNode($exportValuesOnly ? $values : $items);
}

public static function isValidIdentifier(string $value): bool
Expand Down
33 changes: 33 additions & 0 deletions tests/PHPStan/Type/TypeToPhpDocNodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,39 @@ public function dataToPhpDocNode(): iterable
]),
'non-empty-list<mixed>',
];

yield [
new ConstantArrayType([
new ConstantIntegerType(0),
new ConstantIntegerType(1),
], [
new ConstantStringType('foo'),
new ConstantStringType('bar'),
]),
"array{'foo', 'bar'}",
];

yield [
new ConstantArrayType([
new ConstantIntegerType(0),
new ConstantIntegerType(2),
], [
new ConstantStringType('foo'),
new ConstantStringType('bar'),
]),
"array{0: 'foo', 2: 'bar'}",
];

yield [
new ConstantArrayType([
new ConstantIntegerType(0),
new ConstantIntegerType(1),
], [
new ConstantStringType('foo'),
new ConstantStringType('bar'),
], [2], [1]),
"array{0: 'foo', 1?: 'bar'}",
];
}

/**
Expand Down

0 comments on commit 413079d

Please sign in to comment.