mirror of
https://github.com/danog/phpdoc-parser.git
synced 2024-11-30 04:29:20 +01:00
Fixed parsing description started with HTML tag
This commit is contained in:
parent
2b0e830f0b
commit
1948aa842a
@ -12,7 +12,6 @@ class PhpDocParser
|
||||
private const DISALLOWED_DESCRIPTION_START_TOKENS = [
|
||||
Lexer::TOKEN_UNION,
|
||||
Lexer::TOKEN_INTERSECTION,
|
||||
Lexer::TOKEN_OPEN_ANGLE_BRACKET,
|
||||
];
|
||||
|
||||
/** @var TypeParser */
|
||||
|
@ -65,6 +65,14 @@ class TypeParser
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_COLON)) {
|
||||
$tokens->dropSavePoint(); // because of ConstFetchNode
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) {
|
||||
$tokens->pushSavePoint();
|
||||
|
||||
$isHtml = $this->isHtml($tokens);
|
||||
$tokens->rollback();
|
||||
if ($isHtml) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
$type = $this->parseGeneric($tokens, $type);
|
||||
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
@ -161,6 +169,35 @@ class TypeParser
|
||||
return new Ast\Type\NullableTypeNode($type);
|
||||
}
|
||||
|
||||
public function isHtml(TokenIterator $tokens): bool
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET);
|
||||
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$htmlTagName = $tokens->currentTokenValue();
|
||||
|
||||
$tokens->next();
|
||||
|
||||
if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!$tokens->isCurrentTokenType(Lexer::TOKEN_END)) {
|
||||
if (
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)
|
||||
&& strpos($tokens->currentTokenValue(), '/' . $htmlTagName . '>') !== false
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$tokens->next();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function parseGeneric(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $baseType): Ast\Type\GenericTypeNode
|
||||
{
|
||||
|
@ -66,6 +66,7 @@ class PhpDocParserTest extends \PHPUnit\Framework\TestCase
|
||||
* @dataProvider provideTemplateTagsData
|
||||
* @dataProvider provideExtendsTagsData
|
||||
* @dataProvider provideRealWorldExampleData
|
||||
* @dataProvider provideDescriptionWithOrWithoutHtml
|
||||
* @param string $label
|
||||
* @param string $input
|
||||
* @param PhpDocNode $expectedPhpDocNode
|
||||
@ -3130,6 +3131,78 @@ chunk. Must be higher that in the previous request.'),
|
||||
];
|
||||
}
|
||||
|
||||
public function provideDescriptionWithOrWithoutHtml(): \Iterator
|
||||
{
|
||||
yield [
|
||||
'Description with HTML tags in @return tag (close tags together)',
|
||||
'/**' . PHP_EOL .
|
||||
' * @return Foo <strong>Important <i>description</i></strong>' . PHP_EOL .
|
||||
' */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@return',
|
||||
new ReturnTagValueNode(
|
||||
new IdentifierTypeNode('Foo'),
|
||||
'<strong>Important <i>description</i></strong>'
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'Description with HTML tags in @throws tag (closed tags with text between)',
|
||||
'/**' . PHP_EOL .
|
||||
' * @throws FooException <strong>Important <em>description</em> etc</strong>' . PHP_EOL .
|
||||
' */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@throws',
|
||||
new ThrowsTagValueNode(
|
||||
new IdentifierTypeNode('FooException'),
|
||||
'<strong>Important <em>description</em> etc</strong>'
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'Description with HTML tags in @mixin tag',
|
||||
'/**' . PHP_EOL .
|
||||
' * @mixin Mixin <strong>Important description</strong>' . PHP_EOL .
|
||||
' */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@mixin',
|
||||
new MixinTagValueNode(
|
||||
new IdentifierTypeNode('Mixin'),
|
||||
'<strong>Important description</strong>'
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
yield [
|
||||
'Description with unclosed HTML tags in @return tag - unclosed HTML tag is parsed as generics',
|
||||
'/**' . PHP_EOL .
|
||||
' * @return Foo <strong>Important description' . PHP_EOL .
|
||||
' */',
|
||||
new PhpDocNode([
|
||||
new PhpDocTagNode(
|
||||
'@return',
|
||||
new ReturnTagValueNode(
|
||||
new GenericTypeNode(
|
||||
new IdentifierTypeNode('Foo'),
|
||||
[
|
||||
new IdentifierTypeNode('strong'),
|
||||
]
|
||||
),
|
||||
'Important description'
|
||||
)
|
||||
),
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
public function dataParseTagValue(): array
|
||||
{
|
||||
return [
|
||||
|
Loading…
Reference in New Issue
Block a user