From 1724f16b18cdc8c9f33ba9bb93f7c9cea7e05700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Bartus?= Date: Wed, 6 Jan 2021 18:21:18 +0100 Subject: [PATCH] fix: resolve type aliases in docblocks --- phpstan-baseline.neon | 16 +- src/Parser/DocBlockParser.php | 9 +- src/Parser/NodeVisitor.php | 4 +- tests/Parser/DocBlockParserTest.php | 424 ++++++++++++++++++++++------ tests/Parser/NodeVisitorTest.php | 37 ++- 5 files changed, 393 insertions(+), 97 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index c1668a0c..cd27cea0 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -3151,17 +3151,22 @@ parameters: path: tests/Parser/DocBlockParserTest.php - - message: "#^Method Doctum\\\\Tests\\\\Parser\\\\DocBlockParserTest\\:\\:testParse7dot1plus\\(\\) has parameter \\$expected with no value type specified in iterable type array\\.$#" + message: "#^Parameter \\#2 \\$context of method Doctum\\\\Parser\\\\DocBlockParser\\:\\:parse\\(\\) expects Doctum\\\\Parser\\\\ParserContext, PHPUnit\\\\Framework\\\\MockObject\\\\MockObject given\\.$#" + count: 3 + path: tests/Parser/DocBlockParserTest.php + + - + message: "#^Method Doctum\\\\Tests\\\\Parser\\\\DocBlockParserTest\\:\\:testParseWithNamespace\\(\\) has parameter \\$expected with no value type specified in iterable type array\\.$#" count: 1 path: tests/Parser/DocBlockParserTest.php - - message: "#^Method Doctum\\\\Tests\\\\Parser\\\\DocBlockParserTest\\:\\:getParseTests\\(\\) return type has no value type specified in iterable type array\\.$#" + message: "#^Method Doctum\\\\Tests\\\\Parser\\\\DocBlockParserTest\\:\\:testParseWithAliases\\(\\) has parameter \\$expected with no value type specified in iterable type array\\.$#" count: 1 path: tests/Parser/DocBlockParserTest.php - - message: "#^Method Doctum\\\\Tests\\\\Parser\\\\DocBlockParserTest\\:\\:getParseTestsphp7dot1plus\\(\\) return type has no value type specified in iterable type array\\.$#" + message: "#^Method Doctum\\\\Tests\\\\Parser\\\\DocBlockParserTest\\:\\:getParseTests\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 path: tests/Parser/DocBlockParserTest.php @@ -3170,6 +3175,11 @@ parameters: count: 1 path: tests/Parser/DocBlockParserTest.php + - + message: "#^Method Doctum\\\\Tests\\\\Parser\\\\DocBlockParserTest\\:\\:getContextMock\\(\\) has parameter \\$aliases with no value type specified in iterable type array\\.$#" + count: 1 + path: tests/Parser/DocBlockParserTest.php + - message: "#^Method Doctum\\\\Tests\\\\Parser\\\\NodeVisitorTest\\:\\:testMethodTypehints\\(\\) has parameter \\$expectedHints with no value type specified in iterable type array\\.$#" count: 1 diff --git a/src/Parser/DocBlockParser.php b/src/Parser/DocBlockParser.php index 2f02cc1a..7561fdc8 100644 --- a/src/Parser/DocBlockParser.php +++ b/src/Parser/DocBlockParser.php @@ -23,10 +23,11 @@ use phpDocumentor\Reflection\DocBlock\Tags\Var_; use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag; use phpDocumentor\Reflection\DocBlockFactory; +use phpDocumentor\Reflection\Types\Context; class DocBlockParser { - public function parse(?string $comment): DocBlockNode + public function parse(?string $comment, ParserContext $context): DocBlockNode { $docBlock = null; $errorMessage = ''; @@ -38,7 +39,11 @@ public function parse(?string $comment): DocBlockNode try { $factory = DocBlockFactory::createInstance(); - $docBlock = $factory->create($comment); + $docBlockContext = new Context( + $context->getNamespace() ?? '', + $context->getAliases() ?: [] + ); + $docBlock = $factory->create($comment, $docBlockContext); } catch (\Exception $e) { $errorMessage = $e->getMessage(); } diff --git a/src/Parser/NodeVisitor.php b/src/Parser/NodeVisitor.php index e501326d..433973f1 100644 --- a/src/Parser/NodeVisitor.php +++ b/src/Parser/NodeVisitor.php @@ -85,7 +85,9 @@ public function leaveNode(AbstractNode $node) protected function addAliases(UseNode $node) { foreach ($node->uses as $use) { - $this->context->addAlias($use->alias !== null ? $use->alias->__toString() : null, $use->name->__toString()); + $alias = $use->getAlias()->toString(); + $fullName = $use->name->__toString(); + $this->context->addAlias($alias, $fullName); } } diff --git a/tests/Parser/DocBlockParserTest.php b/tests/Parser/DocBlockParserTest.php index 8a0eded6..ce08b9e7 100644 --- a/tests/Parser/DocBlockParserTest.php +++ b/tests/Parser/DocBlockParserTest.php @@ -12,19 +12,54 @@ namespace Doctum\Tests\Parser; use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\MockObject\MockObject; +use Doctum\Parser\ParserContext; use Doctum\Parser\DocBlockParser; use Doctum\Parser\Node\DocBlockNode; class DocBlockParserTest extends TestCase { + private const NAMESPACE = '\\Foobar\\'; + private const ALIASES = [ + 'SingleClass' => '\\Foo\\Bar\\Baz', + 'SingleClass2' => '\\Foo\\Bar\\SingleClass2', + 'SomeClass' => '\\Foo\\SomeClass', + ]; + /** * @dataProvider getParseTests */ public function testParse(string $comment, array $expected): void { $parser = new DocBlockParser(); + $expected = isset($expected['pure']) ? $expected['pure'] : $expected[0]; + $this->assertEquals($this->createDocblock($expected), $parser->parse($comment, $this->getContextMock())); + } - $this->assertEquals($this->createDocblock($expected), $parser->parse($comment)); + /** + * @dataProvider getParseTests + */ + public function testParseWithNamespace(string $comment, array $expected): void + { + $parser = new DocBlockParser(); + $expected = isset($expected['namespace']) ? $expected['namespace'] : $expected[0]; + $this->assertEquals($this->createDocblock($expected), $parser->parse($comment, $this->getContextMock(self::NAMESPACE))); + } + + /** + * @dataProvider getParseTests + */ + public function testParseWithAliases(string $comment, array $expected): void + { + $parser = new DocBlockParser(); + $expected = isset($expected['namespaceAndAlias']) ? $expected['namespaceAndAlias'] : $expected[0]; + $this->assertEquals( + $this->createDocblock($expected), + $parser->parse( + $comment, + $this->getContextMock(self::NAMESPACE, self::ALIASES) + ) + ); } public function getParseTests(): array @@ -35,7 +70,7 @@ public function getParseTests(): array /** */ ', - [], + [[]], ], [ ' @@ -43,11 +78,11 @@ public function getParseTests(): array * The short desc. */ ', - ['shortdesc' => 'The short desc.'], + [['shortdesc' => 'The short desc.']], ], [ '/** The short desc. */', - ['shortdesc' => 'The short desc.'], + [['shortdesc' => 'The short desc.']], ], [ ' @@ -56,7 +91,7 @@ public function getParseTests(): array * lines. */ ', - ['shortdesc' => "The short desc on two\nlines."], + [['shortdesc' => "The short desc on two\nlines."]], ], [ ' @@ -66,7 +101,7 @@ public function getParseTests(): array * And a long desc. */ ', - ['shortdesc' => 'The short desc.', 'longdesc' => 'And a long desc.'], + [['shortdesc' => 'The short desc.', 'longdesc' => 'And a long desc.']], ], [ ' @@ -80,7 +115,7 @@ public function getParseTests(): array * With another paragraph. */ ', - ['shortdesc' => "The short desc on two\nlines.", 'longdesc' => "And a long desc on\nseveral lines too.\n\nWith another paragraph."], + [['shortdesc' => "The short desc on two\nlines.", 'longdesc' => "And a long desc on\nseveral lines too.\n\nWith another paragraph."]], ], [ ' @@ -88,7 +123,7 @@ public function getParseTests(): array * The short desc with a @tag embedded. And the short desc continues after dot on same line. */ ', - ['shortdesc' => 'The short desc with a @tag embedded. And the short desc continues after dot on same line.'], + [['shortdesc' => 'The short desc with a @tag embedded. And the short desc continues after dot on same line.']], ], [ ' @@ -96,7 +131,7 @@ public function getParseTests(): array * @see http://symfony.com/ This is a link description. */ ', - ['tags' => ['see' => [['http://symfony.com/ This is a link description.', 'http://symfony.com/', 'This is a link description.']]]], + [['tags' => ['see' => [['http://symfony.com/ This is a link description.', 'http://symfony.com/', 'This is a link description.']]]]], ], [ ' @@ -104,7 +139,7 @@ public function getParseTests(): array * @author fabien@example.com */ ', - ['tags' => ['author' => 'fabien@example.com']], + [['tags' => ['author' => 'fabien@example.com']]], ], [ ' @@ -113,7 +148,7 @@ public function getParseTests(): array * @author Thomas */ ', - ['tags' => ['author' => ['Fabien ', 'Thomas ']]], + [['tags' => ['author' => ['Fabien ', 'Thomas ']]]], ], [ ' @@ -122,11 +157,33 @@ public function getParseTests(): array */ ', [ - 'tags' => [ - 'var' => [ // Array from found tags. - [ // First found tag. - [['\SingleClass', false], ['\MultipleClass', true]], // Array from data types. - 'Property Description', + 'pure' => [ + 'tags' => [ + 'var' => [ // Array from found tags. + [ // First found tag. + [['\SingleClass', false], ['\MultipleClass', true]], // Array from data types. + 'Property Description', + ], + ], + ], + ], + 'namespace' => [ + 'tags' => [ + 'var' => [ // Array from found tags. + [ // First found tag. + [[self::NAMESPACE . 'SingleClass', false], ['\MultipleClass', true]], // Array from data types. + 'Property Description', + ], + ], + ], + ], + 'namespaceAndAlias' => [ + 'tags' => [ + 'var' => [ // Array from found tags. + [ // First found tag. + [[self::ALIASES['SingleClass'], false], ['\MultipleClass', true]], // Array from data types. + 'Property Description', + ], ], ], ], @@ -139,14 +196,42 @@ public function getParseTests(): array */ ', [ - 'shortDesc' => '', - 'longDesc' => '', - 'tags' => [ - 'param' => [ // Array from found tags. - [ // First found tag. - [['\SingleClass', false], ['\MultipleClass', true]], // Array from data types. - 'paramName', - 'Param Description', + 'pure' => [ + 'shortDesc' => '', + 'longDesc' => '', + 'tags' => [ + 'param' => [ // Array from found tags. + [ // First found tag. + [['\SingleClass', false], ['\MultipleClass', true]], // Array from data types. + 'paramName', + 'Param Description', + ], + ], + ], + ], + 'namespace' => [ + 'shortDesc' => '', + 'longDesc' => '', + 'tags' => [ + 'param' => [ // Array from found tags. + [ // First found tag. + [[self::NAMESPACE . 'SingleClass', false], ['\MultipleClass', true]], // Array from data types. + 'paramName', + 'Param Description', + ], + ], + ], + ], + 'namespaceAndAlias' => [ + 'shortDesc' => '', + 'longDesc' => '', + 'tags' => [ + 'param' => [ // Array from found tags. + [ // First found tag. + [[self::ALIASES['SingleClass'], false], ['\MultipleClass', true]], // Array from data types. + 'paramName', + 'Param Description', + ], ], ], ], @@ -160,17 +245,51 @@ public function getParseTests(): array */ ', [ - 'shortDesc' => '', - 'longDesc' => '', - 'tags' => [ - 'throws' => [ // Array from found tags. - [ // First found tag. - '\SingleClass1', - 'Exception Description One', + 'pure' => [ + 'shortDesc' => '', + 'longDesc' => '', + 'tags' => [ + 'throws' => [ // Array from found tags. + [ // First found tag. + '\SingleClass1', + 'Exception Description One', + ], + [ // Second found tag. + '\SingleClass2', + 'Exception Description Two', + ], + ], + ], + ], + 'namespace' => [ + 'shortDesc' => '', + 'longDesc' => '', + 'tags' => [ + 'throws' => [ // Array from found tags. + [ // First found tag. + self::NAMESPACE . 'SingleClass1', + 'Exception Description One', + ], + [ // Second found tag. + self::NAMESPACE . 'SingleClass2', + 'Exception Description Two', + ], ], - [ // Second found tag. - '\SingleClass2', - 'Exception Description Two', + ], + ], + 'namespaceAndAlias' => [ + 'shortDesc' => '', + 'longDesc' => '', + 'tags' => [ + 'throws' => [ // Array from found tags. + [ // First found tag. + self::NAMESPACE . 'SingleClass1', + 'Exception Description One', + ], + [ // Second found tag. + self::ALIASES['SingleClass2'], + 'Exception Description Two', + ], ], ], ], @@ -183,11 +302,33 @@ public function getParseTests(): array */ ', [ - 'tags' => [ - 'return' => [ // Array from found tags. - [ // First found tag. - [['\SingleClass', false], ['\MultipleClass', true]], // Array from data types. - 'Return Description', + 'pure' => [ + 'tags' => [ + 'return' => [ // Array from found tags. + [ // First found tag. + [['\SingleClass', false], ['\MultipleClass', true]], // Array from data types. + 'Return Description', + ], + ], + ], + ], + 'namespace' => [ + 'tags' => [ + 'return' => [ // Array from found tags. + [ // First found tag. + [[self::NAMESPACE . 'SingleClass', false], ['\MultipleClass', true]], // Array from data types. + 'Return Description', + ], + ], + ], + ], + 'namespaceAndAlias' => [ + 'tags' => [ + 'return' => [ // Array from found tags. + [ // First found tag. + [[self::ALIASES['SingleClass'], false], ['\MultipleClass', true]], // Array from data types. + 'Return Description', + ], ], ], ], @@ -215,58 +356,174 @@ public function getParseTests(): array */ ', [ - 'shortDesc' => '', - 'longDesc' => '', - 'tags' => [ - 'author' => ['Author Name'], - 'covers' => ['\SomeClass::SomeMethod'], - 'deprecated' => ['1.0 for ever'], - 'todo' => ['Something needs to be done'], - 'example' => ['Description'], - 'link' => ['http://www.google.com'], - 'method' => ['void setInteger(int $integer)'], - 'property-read' => [ // array of all properties - [ // array of one property - [ // array of all typehints of one property - [ // array of one typehint - 'string', // the typehint - null, // whether or not the typehint is an array + 'pure' => [ + 'shortDesc' => '', + 'longDesc' => '', + 'tags' => [ + 'author' => ['Author Name'], + 'covers' => ['\SomeClass::SomeMethod'], + 'deprecated' => ['1.0 for ever'], + 'todo' => ['Something needs to be done'], + 'example' => ['Description'], + 'link' => ['http://www.google.com'], + 'method' => ['void setInteger(int $integer)'], + 'property-read' => [ // array of all properties + [ // array of one property + [ // array of all typehints of one property + [ // array of one typehint + 'string', // the typehint + null, // whether or not the typehint is an array + ], ], + 'myProperty', // property name + '', // property description ], - 'myProperty', // property name - '', // property description ], + 'property' => [ // see above + [ + [ + [ + 'string', + null, + ], + ], + 'myProperty', + '', + ], + ], + 'property-write' => [ // see above + [ + [ + [ + 'string', + null, + ], + ], + 'myProperty', + '', + ], + ], + 'see' => [['\SomeClass::SomeMethod This is a description.', '\SomeClass::SomeMethod', 'This is a description.']], + 'since' => ['1.0.1 First time this was introduced.'], + 'source' => ['2 1 Check that ensures lazy counting.'], + 'uses' => ['\MyClass::$items to retrieve the count from.'], + 'version' => ['1.0.1'], + 'unknown' => ['any text'], ], - 'property' => [ // see above - [ + ], + 'namespace' => [ + 'shortDesc' => '', + 'longDesc' => '', + 'tags' => [ + 'author' => ['Author Name'], + 'covers' => [self::NAMESPACE . 'SomeClass::SomeMethod'], + 'deprecated' => ['1.0 for ever'], + 'todo' => ['Something needs to be done'], + 'example' => ['Description'], + 'link' => ['http://www.google.com'], + 'method' => ['void setInteger(int $integer)'], + 'property-read' => [ // array of all properties + [ // array of one property + [ // array of all typehints of one property + [ // array of one typehint + 'string', // the typehint + null, // whether or not the typehint is an array + ], + ], + 'myProperty', // property name + '', // property description + ], + ], + 'property' => [ // see above [ [ - 'string', - null, + [ + 'string', + null, + ], + ], + 'myProperty', + '', + ], + ], + 'property-write' => [ // see above + [ + [ + [ + 'string', + null, + ], ], + 'myProperty', + '', ], - 'myProperty', - '', ], + 'see' => [[self::NAMESPACE . 'SomeClass::SomeMethod This is a description.', self::NAMESPACE . 'SomeClass::SomeMethod', 'This is a description.']], + 'since' => ['1.0.1 First time this was introduced.'], + 'source' => ['2 1 Check that ensures lazy counting.'], + 'uses' => [self::NAMESPACE . 'MyClass::$items to retrieve the count from.'], + 'version' => ['1.0.1'], + 'unknown' => ['any text'], ], - 'property-write' => [ // see above - [ + ], + 'namespaceAndAlias' => [ + 'shortDesc' => '', + 'longDesc' => '', + 'tags' => [ + 'author' => ['Author Name'], + 'covers' => [self::ALIASES['SomeClass'] . '::SomeMethod'], + 'deprecated' => ['1.0 for ever'], + 'todo' => ['Something needs to be done'], + 'example' => ['Description'], + 'link' => ['http://www.google.com'], + 'method' => ['void setInteger(int $integer)'], + 'property-read' => [ // array of all properties + [ // array of one property + [ // array of all typehints of one property + [ // array of one typehint + 'string', // the typehint + null, // whether or not the typehint is an array + ], + ], + 'myProperty', // property name + '', // property description + ], + ], + 'property' => [ // see above [ [ - 'string', - null, + [ + 'string', + null, + ], ], + 'myProperty', + '', ], - 'myProperty', - '', ], + 'property-write' => [ // see above + [ + [ + [ + 'string', + null, + ], + ], + 'myProperty', + '', + ], + ], + 'see' => [[ + self::ALIASES['SomeClass'] . '::SomeMethod This is a description.', + self::ALIASES['SomeClass'] . '::SomeMethod', + 'This is a description.' + ]], + 'since' => ['1.0.1 First time this was introduced.'], + 'source' => ['2 1 Check that ensures lazy counting.'], + 'uses' => [self::NAMESPACE . 'MyClass::$items to retrieve the count from.'], + 'version' => ['1.0.1'], + 'unknown' => ['any text'], ], - 'see' => [['\SomeClass::SomeMethod This is a description.', '\SomeClass::SomeMethod', 'This is a description.']], - 'since' => ['1.0.1 First time this was introduced.'], - 'source' => ['2 1 Check that ensures lazy counting.'], - 'uses' => ['\MyClass::$items to retrieve the count from.'], - 'version' => ['1.0.1'], - 'unknown' => ['any text'], ], ], ], @@ -279,7 +536,7 @@ public function getParseTests(): array * * @return array */', - [ + [[ 'shortDesc' => 'Saves the display field for a table.', 'longDesc' => '', 'tags' => [ @@ -307,7 +564,7 @@ public function getParseTests(): array ], ] ], - ] + ]] ], [ '/** @@ -319,7 +576,7 @@ public function getParseTests(): array * * @return array, $message */', - [ + [[ 'shortDesc' => "Prepares queries for adding users and\nalso create database and return query and message", 'longDesc' => '', 'tags' => [ @@ -349,7 +606,7 @@ public function getParseTests(): array 'array, $message', ] ], - ], + ]], ], ]; } @@ -380,4 +637,13 @@ private function createDocblock(array $elements): DocBlockNode return $docblock; } + + private function getContextMock(string $namespace = '', array $aliases = []): MockObject + { + $contextMock = $this->getMockBuilder(ParserContext::class)->disableOriginalConstructor()->getMock(); + $contextMock->expects($this->once())->method('getNamespace')->will($this->returnValue($namespace)); + $contextMock->expects($this->once())->method('getAliases')->will($this->returnValue($aliases)); + + return $contextMock; + } } diff --git a/tests/Parser/NodeVisitorTest.php b/tests/Parser/NodeVisitorTest.php index 1001cffc..9309366c 100644 --- a/tests/Parser/NodeVisitorTest.php +++ b/tests/Parser/NodeVisitorTest.php @@ -334,6 +334,7 @@ private function getMethodTypehintsDocblockMixedClassParameters(): array */ public function testUpdateMethodParametersFromTags(): void { + $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); $docBlockParser = new DocBlockParser(); $docBlockNode = $docBlockParser->parse( '/**' . "\n" @@ -342,9 +343,10 @@ public function testUpdateMethodParametersFromTags(): void . '* @param $param9' . "\n" . '* @param foo' . "\n" . '* @param type1 $param4 Description 4' . "\n" - . '**/' . "\n" + . '**/' . "\n", + $parserContext ); - $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); + $visitor = new NodeVisitor($parserContext); $function = new FunctionReflection('fun1', 0); @@ -373,13 +375,15 @@ public function testUpdateMethodParametersFromTags(): void */ public function testUpdateMethodParametersFromTagsVariadic(): void { + $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); $docBlockParser = new DocBlockParser(); $docBlockNode = $docBlockParser->parse( '/**' . "\n" . '* @param FooBar|baz|string ...$args' . "\n" - . '**/' . "\n" + . '**/' . "\n", + $parserContext ); - $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); + $visitor = new NodeVisitor($parserContext); $function = new FunctionReflection('fun1', 0); @@ -400,6 +404,8 @@ public function testUpdateMethodParametersFromTagsVariadic(): void */ public function testUpdateMethodParametersFromInvalidTags(): void { + + $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); $docBlockParser = new DocBlockParser(); $docBlockNode = $docBlockParser->parse( '/**' . "\n" @@ -409,9 +415,10 @@ public function testUpdateMethodParametersFromInvalidTags(): void . '* @param foo' . "\n" . '* @param type1 $param4 Description 4' . "\n" . '* @param array[\Illuminate\Notifications\Channels\Notification] $notification' . "\n" - . '**/' . "\n" + . '**/' . "\n", + $parserContext ); - $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); + $visitor = new NodeVisitor($parserContext); $function = new FunctionReflection('fun1', 0); @@ -441,13 +448,15 @@ public function testUpdateMethodParametersFromInvalidTags(): void */ public function testUpdateMethodParametersFromInvalidTagsReport(): void { + $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); $docBlockParser = new DocBlockParser(); $docBlockNode = $docBlockParser->parse( '/**' . "\n" . '* @param array[\Illuminate\Notifications\Channels\Notification] $notification' . "\n" - . '**/' . "\n" + . '**/' . "\n", + $parserContext ); - $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); + $visitor = new NodeVisitor($parserContext); $function = new FunctionReflection('fun1', 0); @@ -472,13 +481,15 @@ public function testUpdateMethodParametersFromInvalidTagsReport(): void */ public function testAddTagFromCommentToMethodInvalidHint(): void { + $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); $docBlockParser = new DocBlockParser(); $docBlockNode = $docBlockParser->parse( '/**' . "\n" . '* @var \Illuminate\Support\Carbon;' . "\n" - . '**/' . "\n" + . '**/' . "\n", + $parserContext ); - $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); + $visitor = new NodeVisitor($parserContext); $property = new PropertyReflection('prop1', 0); @@ -502,13 +513,15 @@ public function testAddTagFromCommentToMethodInvalidHint(): void */ public function testAddTagFromCommentToMethodHintVariadic(): void { + $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); $docBlockParser = new DocBlockParser(); $docBlockNode = $docBlockParser->parse( '/**' . "\n" . '* @var FooBar|baz|string ...$args' . "\n" - . '**/' . "\n" + . '**/' . "\n", + $parserContext ); - $parserContext = new ParserContext(new TrueFilter(), new DocBlockParser(), new Standard()); + $visitor = new NodeVisitor($parserContext); $property = new PropertyReflection('args', 0);