From f1992aea27f0d157c454d5819fc7f63b57ada652 Mon Sep 17 00:00:00 2001 From: stefanScrumble Date: Fri, 8 Mar 2024 11:04:35 +0100 Subject: [PATCH] Fix collection attribute typing --- src/Console/ModelsCommand.php | 58 ++++++++++++----- .../Models/WithCollection.php | 30 +++++++++ .../GenerateMixinCollection/Test.php | 22 +++++++ .../__snapshots__/Test__test__1.php | 62 +++++++++++++++++++ 4 files changed, 157 insertions(+), 15 deletions(-) create mode 100644 tests/Console/ModelsCommand/GenerateMixinCollection/Models/WithCollection.php create mode 100644 tests/Console/ModelsCommand/GenerateMixinCollection/Test.php create mode 100644 tests/Console/ModelsCommand/GenerateMixinCollection/__snapshots__/Test__test__1.php diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index d2d484f..6c78a63 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -194,7 +194,7 @@ class ModelsCommand extends Command protected function getArguments() { return [ - ['model', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Which models to include', []], + ['model', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Which models to include', []], ]; } @@ -206,20 +206,21 @@ class ModelsCommand extends Command protected function getOptions() { return [ - ['filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file'], - ['dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, - 'The model dir, supports glob patterns', [], ], - ['write', 'W', InputOption::VALUE_NONE, 'Write to Model file'], - ['write-mixin', 'M', InputOption::VALUE_NONE, - "Write models to {$this->filename} and adds @mixin to each model, avoiding IDE duplicate declaration warnings", - ], - ['nowrite', 'N', InputOption::VALUE_NONE, 'Don\'t write to Model file'], - ['reset', 'R', InputOption::VALUE_NONE, 'Refresh the properties/methods list, but keep the text'], - ['phpstorm-noinspections', 'p', InputOption::VALUE_NONE, - 'Add PhpFullyQualifiedNameUsageInspection and PhpUnnecessaryFullyQualifiedNameInspection PHPStorm ' . - 'noinspection tags', - ], - ['ignore', 'I', InputOption::VALUE_OPTIONAL, 'Which models to ignore', ''], + ['filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file'], + ['dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, + 'The model dir, supports glob patterns', [],], + ['write', 'W', InputOption::VALUE_NONE, 'Write to Model file'], + ['write-mixin', 'M', InputOption::VALUE_NONE, + "Write models to {$this->filename} and adds @mixin to each model, avoiding IDE duplicate declaration warnings", + ], + ['nowrite', 'N', InputOption::VALUE_NONE, 'Don\'t write to Model file'], + ['reset', 'R', InputOption::VALUE_NONE, 'Remove the original phpdocs instead of appending'], + ['smart-reset', 'r', InputOption::VALUE_NONE, 'Refresh the properties/methods list, but keep the text'], + ['phpstorm-noinspections', 'p', InputOption::VALUE_NONE, + 'Add PhpFullyQualifiedNameUsageInspection and PhpUnnecessaryFullyQualifiedNameInspection PHPStorm ' . + 'noinspection tags', + ], + ['ignore', 'I', InputOption::VALUE_OPTIONAL, 'Which models to ignore', ''], ]; } @@ -1236,12 +1237,39 @@ class ModelsCommand extends Command $phpdoc = new DocBlock($reflection, $context); if ($phpdoc->hasTag('return')) { + $returnTag = $phpdoc->getTagsByName('return')[0]; + + if ($typeAlias = $this->extractTypeAlias($returnTag->getContent(), $context->getNamespaceAliases())) { + return $typeAlias; + } + $type = $phpdoc->getTagsByName('return')[0]->getType(); } return $type; } + /** + * @param string $typeAlias + * @param array $namespaceAliases + * @return string|null + */ + private function extractTypeAlias(string $typeAlias, array $namespaceAliases): string|null { + $matches = []; + preg_match('/(\w+)(<.*>)/', $typeAlias, $matches); + $matchCount = count($matches); + + if ($matchCount === 0 || $matchCount === 1) { + return null; + } + + if (empty($namespaceAliases[$matches[1]])) { + return null; + } + + return $namespaceAliases[$matches[1]].($matches[2] ?? ''); + } + protected function getReturnTypeFromReflection(\ReflectionMethod $reflection): ?string { $returnType = $reflection->getReturnType(); diff --git a/tests/Console/ModelsCommand/GenerateMixinCollection/Models/WithCollection.php b/tests/Console/ModelsCommand/GenerateMixinCollection/Models/WithCollection.php new file mode 100644 index 0000000..997ae3b --- /dev/null +++ b/tests/Console/ModelsCommand/GenerateMixinCollection/Models/WithCollection.php @@ -0,0 +1,30 @@ + + */ + public function getCollectionAttribute(): Collection + { + return new Collection(); + } + + /** + * @return Collection + */ + public function getCollectionWithoutTemplateAttribute(): Collection + { + return new Collection(); + } + + public function getCollectionWithoutDocBlockAttribute(): Collection + { + return new Collection(); + } +} diff --git a/tests/Console/ModelsCommand/GenerateMixinCollection/Test.php b/tests/Console/ModelsCommand/GenerateMixinCollection/Test.php new file mode 100644 index 0000000..2231752 --- /dev/null +++ b/tests/Console/ModelsCommand/GenerateMixinCollection/Test.php @@ -0,0 +1,22 @@ +app->make(ModelsCommand::class); + + $tester = $this->runCommand($command, [ + '--write-mixin' => true, + ]); + + $this->assertSame(0, $tester->getStatusCode()); + $this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay()); + $this->assertMatchesMockedSnapshot(); + } +} diff --git a/tests/Console/ModelsCommand/GenerateMixinCollection/__snapshots__/Test__test__1.php b/tests/Console/ModelsCommand/GenerateMixinCollection/__snapshots__/Test__test__1.php new file mode 100644 index 0000000..e3abb05 --- /dev/null +++ b/tests/Console/ModelsCommand/GenerateMixinCollection/__snapshots__/Test__test__1.php @@ -0,0 +1,62 @@ + + */ + public function getCollectionAttribute(): Collection + { + return new Collection(); + } + + /** + * @return Collection + */ + public function getCollectionWithoutTemplateAttribute(): Collection + { + return new Collection(); + } + + public function getCollectionWithoutDocBlockAttribute(): Collection + { + return new Collection(); + } +} + + */ + + +namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateMixinCollection\Models{ +/** + * Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateMixinCollection\Models\WithCollection + * + * @property-read \Illuminate\Support\Collection $collection + * @property-read \Illuminate\Support\Collection $collection_without_doc_block + * @property-read \Illuminate\Support\Collection $collection_without_template + * @method static \Illuminate\Database\Eloquent\Builder|WithCollection newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|WithCollection newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|WithCollection query() + * @mixin \Eloquent + */ + #[\AllowDynamicProperties] + class IdeHelperWithCollection {} +} +