fix: allow trailing comma in shaped array

Allows the following syntax:

```php
/**
 * @var array{
 * 	   foo: string,
 *     bar: int,
 * }
 */
 ```
This commit is contained in:
Romain Canon 2022-08-30 21:18:45 +02:00
parent 8c7568c94a
commit bf445b5364
4 changed files with 42 additions and 0 deletions

View File

@ -122,6 +122,11 @@ final class ArrayToken implements TraversingToken
throw new ShapedArrayCommaMissing($elements);
}
if ($stream->next() instanceof ClosingCurlyBracketToken) {
$stream->forward();
break;
}
$optional = false;
if ($stream->next() instanceof UnknownSymbolToken) {

View File

@ -25,6 +25,7 @@ final class TokenStream
$this->tokens = $tokens;
}
/** @phpstan-impure */
public function read(): Type
{
if ($this->done()) {
@ -54,6 +55,7 @@ final class TokenStream
return $type;
}
/** @phpstan-impure */
public function next(): Token
{
$peek = $this->peek + 1;
@ -65,6 +67,7 @@ final class TokenStream
return $this->tokens[$peek];
}
/** @phpstan-impure */
public function forward(): Token
{
$this->peek++;

View File

@ -553,6 +553,11 @@ final class NativeLexerTest extends TestCase
'transformed' => 'array{foo: string, bar?: int}',
'type' => ShapedArrayType::class,
],
'Shaped array with trailing comma' => [
'raw' => 'array{foo: string, bar: int,}',
'transformed' => 'array{foo: string, bar: int}',
'type' => ShapedArrayType::class,
],
'Shaped array with reserved keyword as key' => [
'raw' => 'array{string: string}',
'transformed' => 'array{string: string}',
@ -693,6 +698,16 @@ final class NativeLexerTest extends TestCase
'transformed' => 'class-string|int',
'type' => UnionType::class,
],
'Union type with shaped array' => [
'raw' => 'array{foo: string, bar: int}|string',
'transformed' => 'array{foo: string, bar: int}|string',
'type' => UnionType::class,
],
'Union type with shaped array with trailing comma' => [
'raw' => 'array{foo: string, bar: int,}|string',
'transformed' => 'array{foo: string, bar: int}|string',
'type' => UnionType::class,
],
'Union type followed by description' => [
'raw' => 'int|float lorem ipsum',
'transformed' => 'int|float',

View File

@ -33,6 +33,10 @@ final class ShapedArrayValuesMappingTest extends IntegrationTest
'foo' => 'fiz',
'bar' => 42,
],
'shapedArrayOnSeveralLinesWithTrailingComma' => [
'foo' => 'fiz',
'bar' => 42,
],
'advancedShapedArray' => [
'mandatoryString' => 'bar',
1337,
@ -55,6 +59,7 @@ final class ShapedArrayValuesMappingTest extends IntegrationTest
self::assertInstanceOf(SimpleObject::class, $result->shapedArrayWithObject['foo']); // @phpstan-ignore-line
self::assertSame($source['shapedArrayWithOptionalValue'], $result->shapedArrayWithOptionalValue);
self::assertSame($source['shapedArrayOnSeveralLines'], $result->shapedArrayOnSeveralLines);
self::assertSame($source['shapedArrayOnSeveralLinesWithTrailingComma'], $result->shapedArrayOnSeveralLinesWithTrailingComma);
self::assertSame('bar', $result->advancedShapedArray['mandatoryString']);
self::assertSame(1337, $result->advancedShapedArray[0]);
self::assertSame(42.404, $result->advancedShapedArray[1]);
@ -102,6 +107,14 @@ class ShapedArrayValues
*/
public array $shapedArrayOnSeveralLines;
/**
* @var array{
* foo: string,
* bar: int,
* }
*/
public array $shapedArrayOnSeveralLinesWithTrailingComma;
/** @var array{0: int, float, optionalString?: string, mandatoryString: string} */
public array $advancedShapedArray;
@ -120,6 +133,10 @@ class ShapedArrayValuesWithConstructor extends ShapedArrayValues
* foo: string,
* bar: int
* } $shapedArrayOnSeveralLines
* @param array{
* foo: string,
* bar: int,
* } $shapedArrayOnSeveralLinesWithTrailingComma
* @param array{0: int, float, optionalString?: string, mandatoryString: string} $advancedShapedArray
* @param array{stdclass: string} $shapedArrayWithClassNameAsKey
*/
@ -129,6 +146,7 @@ class ShapedArrayValuesWithConstructor extends ShapedArrayValues
array $shapedArrayWithObject,
array $shapedArrayWithOptionalValue,
array $shapedArrayOnSeveralLines,
array $shapedArrayOnSeveralLinesWithTrailingComma,
array $advancedShapedArray,
array $shapedArrayWithClassNameAsKey
) {
@ -137,6 +155,7 @@ class ShapedArrayValuesWithConstructor extends ShapedArrayValues
$this->shapedArrayWithObject = $shapedArrayWithObject;
$this->shapedArrayWithOptionalValue = $shapedArrayWithOptionalValue;
$this->shapedArrayOnSeveralLines = $shapedArrayOnSeveralLines;
$this->shapedArrayOnSeveralLinesWithTrailingComma = $shapedArrayOnSeveralLinesWithTrailingComma;
$this->advancedShapedArray = $advancedShapedArray;
$this->shapedArrayWithClassNameAsKey = $shapedArrayWithClassNameAsKey;
}