Skip to content

Commit 1d684e9

Browse files
committed
Allow balanced braces inside inline tag descriptions
The inline-tag tokenizer used in DescriptionFactory recognised nested inline tags and hanging '{', but not a bare balanced pair such as '{braces}' used as part of an inline tag body. Matching such a pair now preserves the surrounding inline tag instead of truncating it at the first closing brace. Refs #255
1 parent 7bae675 commit 1d684e9

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

src/DocBlock/DescriptionFactory.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ private function lex(string $contents): array
115115
# Notice that this also matches "{}", as a way to later introduce it as an escape sequence.
116116
\{(?1)?\}
117117
|
118+
# Match a balanced pair of braces that is not an inline tag, e.g. "{braces}" used as part
119+
# of the description of a surrounding inline tag.
120+
\{[^{}]*\}
121+
|
118122
# Make sure we match hanging "{".
119123
\{
120124
)

tests/unit/DocBlock/DescriptionFactoryTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,33 @@ public function testDescriptionCanParseAStringWithInlineTag(): void
109109
* @covers ::__construct
110110
* @covers ::create
111111
*/
112+
/**
113+
* @uses \phpDocumentor\Reflection\DocBlock\Description
114+
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Link
115+
* @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag
116+
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter
117+
* @uses \phpDocumentor\Reflection\Types\Context
118+
*
119+
* @covers ::__construct
120+
* @covers ::create
121+
*/
122+
public function testDescriptionCanParseStringWithInlineTagContainingBalancedBraces(): void
123+
{
124+
$contents = 'This description has a {@link http://phpdoc.org/ This contains {braces}} in it.';
125+
$context = new Context('');
126+
$tagFactory = m::mock(TagFactory::class);
127+
$tagFactory->shouldReceive('create')
128+
->once()
129+
->with('@link http://phpdoc.org/ This contains {braces}', $context)
130+
->andReturn(new LinkTag('http://phpdoc.org/', new Description('This contains {braces}')));
131+
132+
$factory = new DescriptionFactory($tagFactory);
133+
$description = $factory->create($contents, $context);
134+
135+
$this->assertSame($contents, $description->render());
136+
$this->assertSame('This description has a %1$s in it.', $description->getBodyTemplate());
137+
}
138+
112139
public function testDescriptionCanParseAStringStartingWithInlineTag(): void
113140
{
114141
$contents = '{@link http://phpdoc.org/ This} is text for a description that starts with an inline tag.';

0 commit comments

Comments
 (0)