Make package more friendly to extending and overriding #70
Replies: 4 comments 5 replies
-
Hi @gbespyatykh Can you provide an example of what you would like to be able to add and how it should be rendered in the docblock ? |
Beta Was this translation helpful? Give feedback.
-
@bastien-phi, hi! Any text or docblock tags: /**
* Comment that will not be overwritten after docblock generation
*
* @author John Doe
* @package Foo Bar
* @deprecated since 1.0.0
* @api
* @see https://github.com/Soyhuce/next-ide-helper/discussions/70 for more info (eg)
* ....
*
* @generated content next...
*/
class SomeModel {} Now, I use temporary hardcoded solution to keep comments. Ugly and quick implemented /**
* Full copy of this packages' command, that contains overrides for almost all private methods
*/
class NextIdeHelperModelsCommand extends ModelsCommand
{
protected $name = 'next-ide-helper:models';
// ...
private function renderers(Model $model): array
{
return [
$this->extendModelDocBlock($model),
$this->extendQueryBuilderDocBlock($model),
];
}
private function extendModelDocBlock(Model $model): Renderer
{
return new class ($model) extends ModelDocBlock
{
use IdeHelperTempMixin;
};
}
private function extendQueryBuilderDocBlock(Model $model): Renderer
{
return new class ($model) extends QueryBuilderDocBlock
{
use IdeHelperTempMixin;
};
}
}
/**
* Keep any comments before @generated tag. Add it before generated comments
*/
trait IdeHelperTempMixin
{
protected function replacePreviousBlock(string $docBlock, string $fqcn, string $file): void
{
$start = '/**';
$directive = PHP_EOL . ' * @generated';
$content = File::get($file);
$previousDocBlock = $this->previousDocBlock($fqcn);
if (Str::contains($previousDocBlock, $directive)) {
$custom = Str::between($previousDocBlock, $start, $directive);
$docBlock = Str::replaceFirst($start, $start . $custom . $directive, $docBlock);
} else {
$docBlock = Str::replaceFirst($start, $start . $directive, $docBlock);
}
$class = Str::afterLast($fqcn, '\\');
$updatedContent = str_replace(
"{$previousDocBlock}class {$class}",
"{$docBlock}class {$class}",
$content
);
File::put($file, $updatedContent);
}
private function previousDocBlock(string $fqcn): string
{
$docBlock = (new ReflectionClass($fqcn))->getDocComment();
if ($docBlock === false) {
return '';
}
return $docBlock . PHP_EOL;
}
}
|
Beta Was this translation helpful? Give feedback.
-
I believe that you package is more clean and promising solution than barryvdh/laravel-ide-helper, but it needs more flexibility now |
Beta Was this translation helpful? Give feedback.
-
Another example. I use dedicated traits for relations. It deduplicates the code and provides correct type inference for completion of builder-related methods (using hacky suppression tag). And there is no need to generate class FoundationDetail extends AbstractModel
{
use BelongsToFoundation;
// ...
} <?php
namespace App\Relations;
use App\Models\Foundation\Foundation;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property-read \App\Models\Foundation\Foundation $foundation
* @mixin \App\Lib\Database\AbstractModel
*/
trait BelongsToFoundation
{
/**
* @noinspection PhpDocSignatureInspection
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo|\App\Builders\Foundation\FoundationBuilder
*/
public function foundation(): BelongsTo
{
return $this->belongsTo(Foundation::class, 'foundation_id', 'id');
}
} |
Beta Was this translation helpful? Give feedback.
-
There is no way to add custom phpdoc directives or plain text to generated docblocks. Any existed class-level comments are erased and replaced by generated dockblock after running the command.
I propose to implement the following features:
Ability to override lists of applied renderers and amenders in models command. It can be done: via package config; changing visibility of corresponding methods; customizeable container bindings
Entity methods that allow to add custom comments before or after the generated dockblocks which can be used in resolvers
Beta Was this translation helpful? Give feedback.
All reactions