Fix collection attribute typing

This commit is contained in:
stefanScrumble
2024-01-04 11:19:16 +01:00
parent 1cce49c621
commit 9a4c79f822
4 changed files with 157 additions and 16 deletions
+43 -16
View File
@@ -196,7 +196,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', []],
];
}
@@ -208,21 +208,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, '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', ''],
['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', ''],
];
}
@@ -1260,12 +1260,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();
@@ -0,0 +1,30 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateMixinCollection\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
class WithCollection extends Model
{
/**
* @return Collection<int, string>
*/
public function getCollectionAttribute(): Collection
{
return new Collection();
}
/**
* @return Collection
*/
public function getCollectionWithoutTemplateAttribute(): Collection
{
return new Collection();
}
public function getCollectionWithoutDocBlockAttribute(): Collection
{
return new Collection();
}
}
@@ -0,0 +1,22 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateMixinCollection;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
class Test extends AbstractModelsCommand
{
public function test(): void
{
$command = $this->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();
}
}
@@ -0,0 +1,62 @@
<?php
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateMixinCollection\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
/**
* @mixin IdeHelperWithCollection
*/
class WithCollection extends Model
{
/**
* @return Collection<int, string>
*/
public function getCollectionAttribute(): Collection
{
return new Collection();
}
/**
* @return Collection
*/
public function getCollectionWithoutTemplateAttribute(): Collection
{
return new Collection();
}
public function getCollectionWithoutDocBlockAttribute(): Collection
{
return new Collection();
}
}
<?php
// @formatter:off
// phpcs:ignoreFile
/**
* A helper file for your Eloquent Models
* Copy the phpDocs from this file to the correct Model,
* And remove them from this file, to prevent double declarations.
*
* @author Barry vd. Heuvel <[email protected]>
*/
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateMixinCollection\Models{
/**
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\GenerateMixinCollection\Models\WithCollection
*
* @property-read \Illuminate\Support\Collection<int, string> $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 {}
}