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
+28 -1
View File
@@ -210,7 +210,7 @@ class ModelsCommand extends Command
return [ return [
['filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file'], ['filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file'],
['dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, ['dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
'The model dir, supports glob patterns', [], ], 'The model dir, supports glob patterns', [],],
['write', 'W', InputOption::VALUE_NONE, 'Write to Model file'], ['write', 'W', InputOption::VALUE_NONE, 'Write to Model file'],
['write-mixin', 'M', InputOption::VALUE_NONE, ['write-mixin', 'M', InputOption::VALUE_NONE,
"Write models to {$this->filename} and adds @mixin to each model, avoiding IDE duplicate declaration warnings", "Write models to {$this->filename} and adds @mixin to each model, avoiding IDE duplicate declaration warnings",
@@ -1260,12 +1260,39 @@ class ModelsCommand extends Command
$phpdoc = new DocBlock($reflection, $context); $phpdoc = new DocBlock($reflection, $context);
if ($phpdoc->hasTag('return')) { 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(); $type = $phpdoc->getTagsByName('return')[0]->getType();
} }
return $type; 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 protected function getReturnTypeFromReflection(\ReflectionMethod $reflection): ?string
{ {
$returnType = $reflection->getReturnType(); $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 {}
}