From 8ba53770740fbf5b7f969c7fad7fdc582df4513d Mon Sep 17 00:00:00 2001 From: Kerigard <2fenix7@gmail.com> Date: Sat, 17 Sep 2022 20:55:57 +0300 Subject: [PATCH 1/7] feat: add separation of tags into groups --- config/ide-helper.php | 11 ++ src/Alias.php | 2 +- src/Console/ModelsCommand.php | 9 +- src/Eloquent.php | 3 +- src/Method.php | 2 +- .../SeparateTags/Models/Post.php | 24 +++ .../ModelsCommand/SeparateTags/Test.php | 31 +++ .../__snapshots__/Test__test__1.php | 183 ++++++++++++++++++ tests/MethodTest.php | 52 ++++- 9 files changed, 310 insertions(+), 7 deletions(-) create mode 100644 tests/Console/ModelsCommand/SeparateTags/Models/Post.php create mode 100644 tests/Console/ModelsCommand/SeparateTags/Test.php create mode 100644 tests/Console/ModelsCommand/SeparateTags/__snapshots__/Test__test__1.php diff --git a/config/ide-helper.php b/config/ide-helper.php index f9110aae7..652acec4a 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -109,6 +109,17 @@ 'write_eloquent_model_mixins' => false, + /* + |-------------------------------------------------------------------------- + | Separate Tag Groups + |-------------------------------------------------------------------------- + | + | Set to true to separate tags into groups with an empty string. + | + */ + + 'separate_tags' => false, + /* |-------------------------------------------------------------------------- | Helper files to include diff --git a/src/Alias.php b/src/Alias.php index 1907ecd0c..a49f3dc1f 100644 --- a/src/Alias.php +++ b/src/Alias.php @@ -421,7 +421,7 @@ protected function getMacroFunction($macro_func) */ public function getDocComment($prefix = "\t\t") { - $serializer = new DocBlockSerializer(1, $prefix); + $serializer = new DocBlockSerializer(1, $prefix, true, null, $this->config->get('ide-helper.separate_tags')); if (!$this->phpdoc) { return ''; diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index d40b64514..5abfd778e 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -105,6 +105,8 @@ class ModelsCommand extends Command protected $keep_text; protected $phpstorm_noinspections; protected $write_model_external_builder_methods; + protected $separate_tags = false; + /** * @var bool[string] */ @@ -157,6 +159,7 @@ public function handle() $this->write_model_external_builder_methods = $this->laravel['config']->get('ide-helper.write_model_external_builder_methods', true); $this->write_model_relation_count_properties = $this->laravel['config']->get('ide-helper.write_model_relation_count_properties', true); + $this->separate_tags = $this->laravel['config']->get('ide-helper.separate_tags', false); $this->write = $this->write_mixin ? true : $this->write; //If filename is default and Write is not specified, ask what to do @@ -931,14 +934,14 @@ protected function createPhpDocs($class) // remove the already existing tag to prevent duplicates foreach ($phpdoc->getTagsByName('mixin') as $tag) { - if($tag->getContent() === $eloquentClassNameInModel) { + if ($tag->getContent() === $eloquentClassNameInModel) { $phpdoc->deleteTag($tag); } } $phpdoc->appendTag(Tag::createInstance('@mixin ' . $eloquentClassNameInModel, $phpdoc)); } - + if ($this->phpstorm_noinspections) { /** * Facades, Eloquent API @@ -954,7 +957,7 @@ protected function createPhpDocs($class) ); } - $serializer = new DocBlockSerializer(); + $serializer = new DocBlockSerializer(0, ' ', true, null, $this->separate_tags); $docComment = $serializer->getDocComment($phpdoc); if ($this->write_mixin) { diff --git a/src/Eloquent.php b/src/Eloquent.php index 23f39dd98..51cf0a64c 100644 --- a/src/Eloquent.php +++ b/src/Eloquent.php @@ -70,7 +70,8 @@ public static function writeEloquentModelHelper(Command $command, Filesystem $fi return; } - $serializer = new DocBlockSerializer(); + $separateTags = $command->getLaravel()['config']->get('ide-helper.separate_tags'); + $serializer = new DocBlockSerializer(0, ' ', true, null, $separateTags); $serializer->getDocComment($phpdoc); $docComment = $serializer->getDocComment($phpdoc); diff --git a/src/Method.php b/src/Method.php index f7f7ffaaf..0a57129a2 100644 --- a/src/Method.php +++ b/src/Method.php @@ -145,7 +145,7 @@ public function getRootMethodCall() */ public function getDocComment($prefix = "\t\t") { - $serializer = new DocBlockSerializer(1, $prefix); + $serializer = new DocBlockSerializer(1, $prefix, true, null, config('ide-helper.separate_tags')); return $serializer->getDocComment($this->phpdoc); } diff --git a/tests/Console/ModelsCommand/SeparateTags/Models/Post.php b/tests/Console/ModelsCommand/SeparateTags/Models/Post.php new file mode 100644 index 000000000..bb7cba956 --- /dev/null +++ b/tests/Console/ModelsCommand/SeparateTags/Models/Post.php @@ -0,0 +1,24 @@ +hasMany(Post::class); + } +} diff --git a/tests/Console/ModelsCommand/SeparateTags/Test.php b/tests/Console/ModelsCommand/SeparateTags/Test.php new file mode 100644 index 000000000..7215b600b --- /dev/null +++ b/tests/Console/ModelsCommand/SeparateTags/Test.php @@ -0,0 +1,31 @@ +set('ide-helper.separate_tags', true); + } + + public function test(): void + { + $command = $this->app->make(ModelsCommand::class); + + $tester = $this->runCommand($command, [ + '--write' => true, + ]); + + $this->assertSame(0, $tester->getStatusCode()); + $this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay()); + $this->assertMatchesMockedSnapshot(); + } +} diff --git a/tests/Console/ModelsCommand/SeparateTags/__snapshots__/Test__test__1.php b/tests/Console/ModelsCommand/SeparateTags/__snapshots__/Test__test__1.php new file mode 100644 index 000000000..773d9be12 --- /dev/null +++ b/tests/Console/ModelsCommand/SeparateTags/__snapshots__/Test__test__1.php @@ -0,0 +1,183 @@ +hasMany(Post::class); + } +} diff --git a/tests/MethodTest.php b/tests/MethodTest.php index 98010b0f3..b99fc32c2 100644 --- a/tests/MethodTest.php +++ b/tests/MethodTest.php @@ -6,10 +6,18 @@ use Barryvdh\LaravelIdeHelper\Method; use Illuminate\Database\Eloquent\Builder; -use PHPUnit\Framework\TestCase; class MethodTest extends TestCase { + protected function getEnvironmentSetUp($app) + { + parent::getEnvironmentSetUp($app); + + if ($this->getName() == 'testSeparateTags') { + $app['config']->set('ide-helper.separate_tags', true); + } + } + /** * Test that we can actually instantiate the class */ @@ -128,6 +136,48 @@ public function testClassAliases() $this->assertSame([], $method->getParamsWithDefault(false)); $this->assertTrue($method->shouldReturn()); } + + /** + * Test class output when separating tag groups + */ + public function testSeparateTags() + { + $reflectionClass = new \ReflectionClass(Builder::class); + $reflectionMethod = $reflectionClass->getMethod('paginate'); + + $method = new Method($reflectionMethod, 'Builder', $reflectionClass); + + $output = <<<'DOC' +/** + * Paginate the given query. + * + * @param int|null $perPage + * @param array $columns + * @param string $pageName + * @param int|null $page + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + * + * @throws \InvalidArgumentException + * + * @static + */ +DOC; + + $this->assertSame($output, $method->getDocComment('')); + $this->assertSame('paginate', $method->getName()); + $this->assertSame('\\' . Builder::class, $method->getDeclaringClass()); + $this->assertSame('$perPage, $columns, $pageName, $page', $method->getParams(true)); + $this->assertSame(['$perPage', '$columns', '$pageName', '$page'], $method->getParams(false)); + $this->assertSame( + '$perPage = null, $columns = [], $pageName = \'page\', $page = null', + $method->getParamsWithDefault(true) + ); + $this->assertSame( + ['$perPage = null', '$columns = []', '$pageName = \'page\'', '$page = null'], + $method->getParamsWithDefault(false) + ); + $this->assertTrue($method->shouldReturn()); + } } class ExampleClass From d3e46725ac5d0abacb093aa2c398400dab19d638 Mon Sep 17 00:00:00 2001 From: Kerigard <2fenix7@gmail.com> Date: Sat, 17 Sep 2022 21:12:38 +0300 Subject: [PATCH 2/7] docs: update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2f1ad9fd..201d12520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ All notable changes to this project will be documented in this file. - Fix issue where \Eloquent is not included when using write_mixin [#1352 / Jefemy](https://github.com/barryvdh/laravel-ide-helper/pull/1352) - Fix model factory method arguments for Laravel >= 9 [#1361 / wimski](https://github.com/barryvdh/laravel-ide-helper/pull/1361) +### Added +- Added separation of tags into groups [#1377 / Kerigard](https://github.com/barryvdh/laravel-ide-helper/pull/1377) + 2022-03-06, 2.12.3 ------------------ From bb35b5f60222fde3824bc531cfd8836b4cf7b905 Mon Sep 17 00:00:00 2001 From: Kerigard <2fenix7@gmail.com> Date: Sat, 5 Nov 2022 19:44:12 +0300 Subject: [PATCH 3/7] chore: increase the minimum version of reflection-docblock --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 215a9ca3a..b0790a624 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "require": { "php": "^7.3 || ^8.0", "ext-json": "*", - "barryvdh/reflection-docblock": "^2.0.6", + "barryvdh/reflection-docblock": "^2.1.0", "composer/class-map-generator": "^1.0", "doctrine/dbal": "^2.6 || ^3", "illuminate/console": "^8 || ^9", From 35385f449407d045657d0fbc68edf26df8e6af5b Mon Sep 17 00:00:00 2001 From: Kerigard <2fenix7@gmail.com> Date: Sun, 26 Feb 2023 14:00:39 +0300 Subject: [PATCH 4/7] fix: change the name of the configuration parameter --- config/ide-helper.php | 4 ++-- src/Alias.php | 3 ++- src/Console/ModelsCommand.php | 6 +++--- src/Eloquent.php | 2 +- src/Method.php | 2 +- tests/Console/ModelsCommand/SeparateTags/Test.php | 2 +- tests/MethodTest.php | 2 +- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/config/ide-helper.php b/config/ide-helper.php index 76708093c..e12f546c6 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -111,14 +111,14 @@ /* |-------------------------------------------------------------------------- - | Separate Tag Groups + | PHPDOC: Separate Tag Groups |-------------------------------------------------------------------------- | | Set to true to separate tags into groups with an empty string. | */ - 'separate_tags' => false, + 'phpdoc_separate_tags' => false, /* |-------------------------------------------------------------------------- diff --git a/src/Alias.php b/src/Alias.php index a49f3dc1f..3c205bdb8 100644 --- a/src/Alias.php +++ b/src/Alias.php @@ -421,7 +421,8 @@ protected function getMacroFunction($macro_func) */ public function getDocComment($prefix = "\t\t") { - $serializer = new DocBlockSerializer(1, $prefix, true, null, $this->config->get('ide-helper.separate_tags')); + $separateTags = $this->config->get('ide-helper.phpdoc_separate_tags', false); + $serializer = new DocBlockSerializer(1, $prefix, true, null, $separateTags); if (!$this->phpdoc) { return ''; diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index 440309b68..6477dc3b2 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -106,7 +106,7 @@ class ModelsCommand extends Command protected $keep_text; protected $phpstorm_noinspections; protected $write_model_external_builder_methods; - protected $separate_tags = false; + protected $phpdoc_separate_tags = false; /** * @var bool[string] @@ -160,7 +160,7 @@ public function handle() $this->write_model_external_builder_methods = $this->laravel['config']->get('ide-helper.write_model_external_builder_methods', true); $this->write_model_relation_count_properties = $this->laravel['config']->get('ide-helper.write_model_relation_count_properties', true); - $this->separate_tags = $this->laravel['config']->get('ide-helper.separate_tags', false); + $this->phpdoc_separate_tags = $this->laravel['config']->get('ide-helper.phpdoc_separate_tags', false); $this->write = $this->write_mixin ? true : $this->write; //If filename is default and Write is not specified, ask what to do @@ -1011,7 +1011,7 @@ protected function createPhpDocs($class) ); } - $serializer = new DocBlockSerializer(0, ' ', true, null, $this->separate_tags); + $serializer = new DocBlockSerializer(0, ' ', true, null, $this->phpdoc_separate_tags); $docComment = $serializer->getDocComment($phpdoc); if ($this->write_mixin) { diff --git a/src/Eloquent.php b/src/Eloquent.php index 51cf0a64c..75bac4850 100644 --- a/src/Eloquent.php +++ b/src/Eloquent.php @@ -70,7 +70,7 @@ public static function writeEloquentModelHelper(Command $command, Filesystem $fi return; } - $separateTags = $command->getLaravel()['config']->get('ide-helper.separate_tags'); + $separateTags = $command->getLaravel()['config']->get('ide-helper.phpdoc_separate_tags', false); $serializer = new DocBlockSerializer(0, ' ', true, null, $separateTags); $serializer->getDocComment($phpdoc); $docComment = $serializer->getDocComment($phpdoc); diff --git a/src/Method.php b/src/Method.php index 0a57129a2..13793d90d 100644 --- a/src/Method.php +++ b/src/Method.php @@ -145,7 +145,7 @@ public function getRootMethodCall() */ public function getDocComment($prefix = "\t\t") { - $serializer = new DocBlockSerializer(1, $prefix, true, null, config('ide-helper.separate_tags')); + $serializer = new DocBlockSerializer(1, $prefix, true, null, config('ide-helper.phpdoc_separate_tags', false)); return $serializer->getDocComment($this->phpdoc); } diff --git a/tests/Console/ModelsCommand/SeparateTags/Test.php b/tests/Console/ModelsCommand/SeparateTags/Test.php index 7215b600b..68354af41 100644 --- a/tests/Console/ModelsCommand/SeparateTags/Test.php +++ b/tests/Console/ModelsCommand/SeparateTags/Test.php @@ -13,7 +13,7 @@ protected function getEnvironmentSetUp($app) { parent::getEnvironmentSetUp($app); - $app['config']->set('ide-helper.separate_tags', true); + $app['config']->set('ide-helper.phpdoc_separate_tags', true); } public function test(): void diff --git a/tests/MethodTest.php b/tests/MethodTest.php index b99fc32c2..fd9bfa64a 100644 --- a/tests/MethodTest.php +++ b/tests/MethodTest.php @@ -14,7 +14,7 @@ protected function getEnvironmentSetUp($app) parent::getEnvironmentSetUp($app); if ($this->getName() == 'testSeparateTags') { - $app['config']->set('ide-helper.separate_tags', true); + $app['config']->set('ide-helper.phpdoc_separate_tags', true); } } From b69814cb1632b30d1eee584f3fb93186838c378b Mon Sep 17 00:00:00 2001 From: Kerigard <2fenix7@gmail.com> Date: Sun, 26 Feb 2023 14:02:35 +0300 Subject: [PATCH 5/7] docs: add tag separation in readme --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 92f04fa50..0e9dcebb8 100644 --- a/README.md +++ b/README.md @@ -263,6 +263,33 @@ add support for creating a new dedicated class instead of using local scopes in If for some reason it's undesired to have them generated (one for each column), you can disable this via config `write_model_external_builder_methods` and setting it to `false`. +#### Separating docblock tags into groups + +By default, all docblock tags are written sequentially on each line. Problems can arise when using Laravel Pint or other linters because they use different formatting. + +Change the `phpdoc_separate_tags` setting in the config to `true` to fix this behavior. + +```php +// => before + +/** + * @property integer $id + * @property-write mixed $first_name Set the user's first name. + * @method static \Illuminate\Database\Eloquent\Builder|Post newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Post query() + */ + +// => after + +/** + * @property integer $id + * @property-write mixed $first_name Set the user's first name. + * + * @method static \Illuminate\Database\Eloquent\Builder|Post newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Post query() + */ +``` + #### Unsupported or custom database types Common column types (e.g. varchar, integer) are correctly mapped to PHP types (`string`, `int`). From 4fc01b238f201b72c2c154bd34661d21b23390a3 Mon Sep 17 00:00:00 2001 From: Kerigard <2fenix7@gmail.com> Date: Sun, 26 Feb 2023 14:25:45 +0300 Subject: [PATCH 6/7] test: update separate tags --- .../__snapshots__/Test__test__1.php | 2 +- tests/MethodTest.php | 36 ++++++++----------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/tests/Console/ModelsCommand/SeparateTags/__snapshots__/Test__test__1.php b/tests/Console/ModelsCommand/SeparateTags/__snapshots__/Test__test__1.php index 773d9be12..577afb261 100644 --- a/tests/Console/ModelsCommand/SeparateTags/__snapshots__/Test__test__1.php +++ b/tests/Console/ModelsCommand/SeparateTags/__snapshots__/Test__test__1.php @@ -83,7 +83,7 @@ * @property string $macaddress_not_nullable * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at - * @property-read \Illuminate\Database\Eloquent\Collection|Post[] $posts + * @property-read \Illuminate\Database\Eloquent\Collection $posts * @property-read int|null $posts_count * @property-write mixed $first_name Set the user's first name. * diff --git a/tests/MethodTest.php b/tests/MethodTest.php index fd9bfa64a..67a078f03 100644 --- a/tests/MethodTest.php +++ b/tests/MethodTest.php @@ -6,6 +6,7 @@ use Barryvdh\LaravelIdeHelper\Method; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Model; class MethodTest extends TestCase { @@ -142,40 +143,31 @@ public function testClassAliases() */ public function testSeparateTags() { - $reflectionClass = new \ReflectionClass(Builder::class); - $reflectionMethod = $reflectionClass->getMethod('paginate'); + $reflectionClass = new \ReflectionClass(Model::class); + $reflectionMethod = $reflectionClass->getMethod('toJson'); - $method = new Method($reflectionMethod, 'Builder', $reflectionClass); + $method = new Method($reflectionMethod, 'Model', $reflectionClass); $output = <<<'DOC' /** - * Paginate the given query. + * Convert the model instance to JSON. * - * @param int|null $perPage - * @param array $columns - * @param string $pageName - * @param int|null $page - * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + * @param int $options + * @return string * - * @throws \InvalidArgumentException + * @throws \Illuminate\Database\Eloquent\JsonEncodingException * * @static */ DOC; $this->assertSame($output, $method->getDocComment('')); - $this->assertSame('paginate', $method->getName()); - $this->assertSame('\\' . Builder::class, $method->getDeclaringClass()); - $this->assertSame('$perPage, $columns, $pageName, $page', $method->getParams(true)); - $this->assertSame(['$perPage', '$columns', '$pageName', '$page'], $method->getParams(false)); - $this->assertSame( - '$perPage = null, $columns = [], $pageName = \'page\', $page = null', - $method->getParamsWithDefault(true) - ); - $this->assertSame( - ['$perPage = null', '$columns = []', '$pageName = \'page\'', '$page = null'], - $method->getParamsWithDefault(false) - ); + $this->assertSame('toJson', $method->getName()); + $this->assertSame('\\' . Model::class, $method->getDeclaringClass()); + $this->assertSame('$options', $method->getParams(true)); + $this->assertSame(['$options'], $method->getParams(false)); + $this->assertSame('$options = 0', $method->getParamsWithDefault(true)); + $this->assertSame(['$options = 0'], $method->getParamsWithDefault(false)); $this->assertTrue($method->shouldReturn()); } } From 7e2d6c1badab0b63442b5513fe397f53d98c18bd Mon Sep 17 00:00:00 2001 From: Vladislav Sidelnikov <46793484+Kerigard@users.noreply.github.com> Date: Mon, 27 Feb 2023 08:54:35 +0300 Subject: [PATCH 7/7] Update CHANGELOG.md Co-authored-by: Markus Podar --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d80921e19..c5af6856f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ All notable changes to this project will be documented in this file. ### Added - Add support for `immutable_date:*` and `immutable_datetime:*` casts. [#1380 / thekonz](https://github.com/barryvdh/laravel-ide-helper/pull/1380) -- Added separation of tags into groups [#1377 / Kerigard](https://github.com/barryvdh/laravel-ide-helper/pull/1377) +- Added separation of phpdoc tags into groups [#1377 / Kerigard](https://github.com/barryvdh/laravel-ide-helper/pull/1377) 2023-02-04, 2.13.0 ------------------