-
-
Notifications
You must be signed in to change notification settings - Fork 59
Description
Glossary
Strategies/Strategy=phpDocumentor\Reflection\Php\ProjectFactoryStrategyElement(s)=phpDocumentor\Reflection\ElementProjectFactory=phpDocumentor\Reflection\Php\ProjectFactoryFile=phpDocumentor\Reflection\Php\FileContextStack=phpDocumentor\Reflection\Php\Factory\ContextStack
Is your feature request related to a problem? Please describe.
I'd like to implement some custom Strategies and Element to parse out of a framework function-calls (similar to what phpDocumentor\Reflection\Php\Factory\Define does).
The ProjectFactory allows to add in its constructor Strategies. The Strategies are build based on the ProjectFactoryStrategy-interface. So it is possible to implement own ones.
class CustomStrategy extends Factory\AbstractFactory implements ProjectFactoryStrategy
{
public function matches(ContextStack $context, object $object): bool
{
return true;
}
protected function doCreate(ContextStack $context, object $object, StrategyContainer $strategies): void
{
// do something
}
}and register them:
$strategies = new ProjectFactoryStrategies([new CustomStrategy()]);
$projectFactory = new ProjectFactory($strategies);Inside of each Strategy it is possible to access the current File via $file = $context->peek(); in doCreate() via ContextStack. This File implementation is not extendable in many ways:
- The
File-class is final. - The class only restricts to
Elementimplementation viaadd*-method (addTrait(),addInterface(),addClass(), ...). - Those
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 to Project or File. You can access the Project via ContextStack::getProject() but not decorate/extend it and set back to the stack. Same goes for File.
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:
/**
* @param Element $element
*/
public function addCustomElement(Element $element): void
{
$this->customElements[(string)$element->->getFqsen()] = $element;
}
/**
* @return Element[]
*/
public function getCustomElements(): array
{
return $this->customElements;
}
This would allow to implement some custom Elements and set those in Strategies to the File to access them lateron via the Project::getFiles() again:
foreach($project->getFiles() as $file) {
foreach($file->getCustomElements()() as $customElements) {
// let's go.
}
}v2)
Remove from 3. the final from all classes which implement Element to allow to extend them. This way you could have:
class MyCustomFunction extends phpDocumentor\Reflection\Php\Function_
{
public function setSomething(): void
{
// ..
}
}And set this via File::addFunction() in a Strategy to access it lateron via:
foreach($project->getFiles() as $file) {
foreach($file->getFunctions() as $func) {
if($func instanceof MyCustomFunction::class){
// do something
}
}
}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 own Strategy, so it could be removed/not added to avoid overhead and File could have new methods:
/**
* @param FunctionCall$element
*/
public function addFunctionCall(FunctionCall $funcCall): void
{
$this->funcCalls[(string)$funcCall->->getFqsen()] = $funcCall;
}
/**
* @return funcCall[]
*/
public function getFunctionCalls(): array
{
return $this->funcCalls;
}Access could be easy as all others are:
foreach($project->getFiles() as $file) {
foreach($file->getFunctionCalls()() as $funcCalls) {
// let's go.
}
}