phpDocumentor / ReflectionDocBlock

MIT License
9.35k stars 119 forks source link

[Bug] Empty array of tags when using DocBlockFactory::createInstance() #265

Closed evroon closed 2 years ago

evroon commented 3 years ago

If I parse a PHP class like this:


$refClass = new \ReflectionClass($this);
$properties = $refClass->getProperties(
    \ReflectionProperty::IS_PROTECTED | \ReflectionProperty::IS_PUBLIC
);
foreach ($properties as $property) {
    $docblock = new \phpDocumentor\Reflection\DocBlock($property);
    var_dump($docblock->getTags());
}

The getTags() always returns an empty array, even though there are (valid and/or invalid) tags. When using the DocBlockFactory as described in the first example, it does return tags.

Now the method above is probably supposed to be deprecated, as I'm porting this library from version 2 to 5, but that is not documented from what I see.

I also have one semi-related question: Why are custom classes needed to add simple custom tags? In version 2 using custom tags worked without problem from what I know.

jaapio commented 2 years ago

Hi,

You will need to use the https://github.com/phpDocumentor/ReflectionDocBlock/blob/master/src/DocBlockFactory.php#L79 to create a docblock. Not the docblock constructor.

The docblock class is a value object without any knowledge, the factories in this library are responsible to create new objects. That's a design choice, which allows you to create a new factory but reuse the objects and visa versa.

Regarding the question about custom tags, we wanted this library to be type strict, and allow the consumers of the library to be type strict, and not checking all tags by their names.

If you want to have some generic tag, you could create your own tag factory, and wrap the StandardTagFactory to use that by default. When it returns and InvalidTag you could execute your own logic.

class MyTagFactory implements TagFactoryInterface
{
     __construct(private StandardTagFactory $standard)
     create(string $tagLine, ?TypeContext $context = null) {
          $tag = $this->standard->create($tagLine, $context);
          if ($tag instanceof InvalidTag) {
              //Do your magic
              return new MyTag();
          }

          return $tag
     }
}