diff --git a/src/DocBlock/DescriptionFactory.php b/src/DocBlock/DescriptionFactory.php index 6915c16f..7067626d 100644 --- a/src/DocBlock/DescriptionFactory.php +++ b/src/DocBlock/DescriptionFactory.php @@ -115,6 +115,10 @@ private function lex(string $contents): array # Notice that this also matches "{}", as a way to later introduce it as an escape sequence. \{(?1)?\} | + # Match a balanced pair of braces that is not an inline tag, e.g. "{braces}" used as part + # of the description of a surrounding inline tag. + \{[^{}]*\} + | # Make sure we match hanging "{". \{ ) diff --git a/tests/unit/DocBlock/DescriptionFactoryTest.php b/tests/unit/DocBlock/DescriptionFactoryTest.php index 6b087ee9..b9ece642 100644 --- a/tests/unit/DocBlock/DescriptionFactoryTest.php +++ b/tests/unit/DocBlock/DescriptionFactoryTest.php @@ -125,6 +125,33 @@ public function testDescriptionCanParseAStringStartingWithInlineTag(): void $this->assertSame($contents, $description->render()); } + /** + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Link + * @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter + * @uses \phpDocumentor\Reflection\Types\Context + * + * @covers ::__construct + * @covers ::create + */ + public function testDescriptionCanParseStringWithInlineTagContainingBalancedBraces(): void + { + $contents = 'This description has a {@link http://phpdoc.org/ This contains {braces}} in it.'; + $context = new Context(''); + $tagFactory = m::mock(TagFactory::class); + $tagFactory->shouldReceive('create') + ->once() + ->with('@link http://phpdoc.org/ This contains {braces}', $context) + ->andReturn(new LinkTag('http://phpdoc.org/', new Description('This contains {braces}'))); + + $factory = new DescriptionFactory($tagFactory); + $description = $factory->create($contents, $context); + + $this->assertSame($contents, $description->render()); + $this->assertSame('This description has a %1$s in it.', $description->getBodyTemplate()); + } + /** * @uses \phpDocumentor\Reflection\DocBlock\Description * @uses \phpDocumentor\Reflection\DocBlock\Tags\Link