mirror of
https://github.com/barryvdh/ReflectionDocBlock.git
synced 2026-08-18 01:57:13 +00:00
Support braces in types for @return
In this change, I have introduced a miniature automaton-light to parse the type from the @return body. This will prevent issues with people using generics and other unsupported forms of types. This change does _not_ allow for the use of Generics or similar; the TypeResolver will still fail to resolve this type. This will remove a breaking issue in consuming applications where a runtime exception used to be thrown. Please note that this change is only for @return; other tags still need to be done. This will resolve issue #186
This commit is contained in:
@@ -50,11 +50,10 @@ final class Return_ extends BaseTag implements Factory\StaticMethod
|
||||
Assert::notNull($typeResolver);
|
||||
Assert::notNull($descriptionFactory);
|
||||
|
||||
$parts = preg_split('/\s+/Su', $body, 2);
|
||||
Assert::isArray($parts);
|
||||
list($type, $description) = self::splitBodyIntoTypeAndTheRest($body);
|
||||
|
||||
$type = $typeResolver->resolve($parts[0] ?? '', $context);
|
||||
$description = $descriptionFactory->create($parts[1] ?? '', $context);
|
||||
$type = $typeResolver->resolve($type, $context);
|
||||
$description = $descriptionFactory->create($description, $context);
|
||||
|
||||
return new static($type, $description);
|
||||
}
|
||||
@@ -71,4 +70,29 @@ final class Return_ extends BaseTag implements Factory\StaticMethod
|
||||
{
|
||||
return $this->type . ' ' . (string) $this->description;
|
||||
}
|
||||
|
||||
private static function splitBodyIntoTypeAndTheRest(string $body) : array
|
||||
{
|
||||
$type = '';
|
||||
$nestingLevel = 0;
|
||||
for ($i = 0; $i < strlen($body); $i++) {
|
||||
$character = $body[$i];
|
||||
|
||||
if (trim($character) === '' && $nestingLevel === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
$type .= $character;
|
||||
if (in_array($character, ['<', '(', '[', '{'])) {
|
||||
$nestingLevel++;
|
||||
}
|
||||
if (in_array($character, ['>', ')', ']', '}'])) {
|
||||
$nestingLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
$description = trim(substr($body, strlen($type)));
|
||||
|
||||
return [$type, $description];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +148,41 @@ class ReturnTest extends TestCase
|
||||
$this->assertSame($description, $fixture->getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* This test checks whether a braces in a Type are allowed.
|
||||
*
|
||||
* The advent of generics poses a few issues, one of them is that spaces can now be part of a type. In the past we
|
||||
* could purely rely on spaces to split the individual parts of the body of a tag; but when there is a type in play
|
||||
* we now need to check for braces.
|
||||
*
|
||||
* This test tests whether an error occurs demonstrating that the braces were taken into account; this test is still
|
||||
* expected to produce an exception because the TypeResolver does not support generics.
|
||||
*
|
||||
* @covers ::create
|
||||
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Return_::<public>
|
||||
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
|
||||
* @uses \phpDocumentor\Reflection\TypeResolver
|
||||
* @uses \phpDocumentor\Reflection\DocBlock\Description
|
||||
* @uses \phpDocumentor\Reflection\Types\String_
|
||||
* @uses \phpDocumentor\Reflection\Types\Context
|
||||
*/
|
||||
public function testFactoryMethodWithGenericWithSpace()
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('"\array😁<string,😁 😁string>" is not a valid Fqsen.');
|
||||
|
||||
$descriptionFactory = m::mock(DescriptionFactory::class);
|
||||
$resolver = new TypeResolver();
|
||||
$context = new Context('');
|
||||
|
||||
$description = new Description('My Description');
|
||||
$descriptionFactory->shouldReceive('create')
|
||||
->with('My Description', $context)
|
||||
->andReturn($description);
|
||||
|
||||
Return_::create('array😁<string,😁 string> My Description', $resolver, $descriptionFactory, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::create
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user