Closed Chrico closed 2 years ago
Hi,
Thanks for your request, I would like to discuss some options we have. The reason our model is final and not extendable is because we want to limit this library to just reflect the things we need in phpDocumentor. However, I see the options you could have when our model would be more open for extension.
Earlier we were thinking about some meta information which should contain some free format meta-data tree on each element. In your request, this could be a list of function calls done in a certain file. But in #90 the request was to add some other information to functions.
I see several options to add the meta information.
In this example, meta can be literally anything. As long as the new Meta
interface is used.
final class File
{
public function addMeta(Meta $meta)
{
}
}
The addMeta
will be introduced on all elements. This approach has one important done side. Since the Meta
interface is a free format for the users of this library they will have to check everything once consuming. It would also break the option to cache the result. That why we are so strict about what can be added. We optimized this library for speed, and allow caching of the results. Any circular relations would break this.
The ContextStack
is an object passed into each of the Strategies
. Allowing users to inject their own information into the factories ContextStack
would be a solution, which will never break this library, and allowing people to collect all information collect during the processing of the node tree.
Since you can always identify each element by it's unique name, files to have the filename and path, elements have the FQSEN
.
This would allow you to create your own meta-data model, which is fully typed. Inject it into your own strategies. Wrap our strategies in your ect. It would never interfere with our changes, making your work detached from whatever we change in this library.
In this situation, we would need to introduce a ContextFactory
which can be added to the ProjectFactory
. The context will use this factory to reproduce itself, taking the carry with it.
I think the latter would be my preferred way to go. Of course, this would come with some proper documentation to help users to create their own metadata. Because it is most flexible and will never interfere with the purpose of this library. There will breaking changes in the strategies once php develops. It is not clear enough right now, but they are not part of our public interface. And should not be consumed by other projects. Since we have to be as close as possible to what php as language does.
I would like to know what you think of this. Thanks for your help!
I created a Metadata class to make is possible to extend the parser output. A first draft of the docs about this can be found here:
https://github.com/phpDocumentor/Reflection/blob/5.x/docs/meta-data.rst#metadata
I'm now testing it myself with a realworld project.
Glossary
Strategies
/Strategy
=phpDocumentor\Reflection\Php\ProjectFactoryStrategy
Element(s)
=phpDocumentor\Reflection\Element
ProjectFactory
=phpDocumentor\Reflection\Php\ProjectFactory
File
=phpDocumentor\Reflection\Php\File
ContextStack
=phpDocumentor\Reflection\Php\Factory\ContextStack
Is your feature request related to a problem? Please describe.
I'd like to implement some custom
Strategies
andElement
to parse out of a framework function-calls (similar to whatphpDocumentor\Reflection\Php\Factory\Define
does).The
ProjectFactory
allows to add in its constructorStrategies
. TheStrategies
are build based on theProjectFactoryStrategy
-interface. So it is possible to implement own ones.and register them:
Inside of each
Strategy
it is possible to access the currentFile
via$file = $context->peek();
indoCreate()
viaContextStack
. ThisFile
implementation is not extendable in many ways:File
-class is final.Element
implementation viaadd*
-method (addTrait()
,addInterface()
,addClass()
, ...).Element
-implementations likephpDocumentor\Reflection\Php\Constant
,phpDocumentor\Reflection\Php\Function_
are all final as well, so not extendable.On
ContextStack
we also have no possibility to do anything toProject
orFile
. You can access theProject
viaContextStack::getProject()
but not decorate/extend it and set back to the stack. Same goes forFile
.Describe the solution you'd like
There are 2 options (plus 1 bonus) which come into my mind:
v1)
In 2. it could be possible to extend the
phpDocumentor\Reflection\Php\File
-class by 2 new methods:This would allow to implement some custom
Elements
and set those inStrategies
to theFile
to access them lateron via theProject::getFiles()
again:v2)
Remove from 3. the
final
from all classes which implementElement
to allow to extend them. This way you could have:And set this via
File::addFunction()
in aStrategy
to access it lateron via:v3)
And last but not least to cover my specific use case: Add similar to
phpDocumentor\Reflection\Php\Factory\Define
following new classes:phpDocumentor\Reflection\Php\Factory\FunctionCall
(aStrategy
)phpDocumentor\Reflection\Php\FunctionCall
(anElement
)to collect all inline function calls in
Files
. This could be parsed by an ownStrategy
, so it could be removed/not added to avoid overhead andFile
could have new methods:Access could be easy as all others are: