mirror of
https://github.com/barryvdh/laravel-ide-helper.git
synced 2026-08-18 01:57:13 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64a6b90258 | ||
|
|
25cc68c75f | ||
|
|
36c4406b3a | ||
|
|
9ba2f5c557 |
@@ -18,15 +18,8 @@ jobs:
|
||||
COMPOSER_NO_INTERACTION: 1
|
||||
strategy:
|
||||
matrix:
|
||||
php: [8.0, 7.4, 7.3, 7.2]
|
||||
lumen: [8.*, 7.*, 6.*]
|
||||
exclude:
|
||||
- lumen: 6.*
|
||||
php: 8.0
|
||||
- lumen: 7.*
|
||||
php: 8.0
|
||||
- lumen: 8.*
|
||||
php: 7.2
|
||||
php: [8.0, 7.4, 7.3]
|
||||
lumen: [8.*]
|
||||
name: P${{ matrix.php }} - Lumen${{ matrix.lumen }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -82,11 +75,8 @@ jobs:
|
||||
COMPOSER_NO_INTERACTION: 1
|
||||
strategy:
|
||||
matrix:
|
||||
php: [7.4, 7.3, 7.2]
|
||||
laravel: [8.*, 7.*, 6.*]
|
||||
exclude:
|
||||
- laravel: 8.*
|
||||
php: 7.2
|
||||
php: [8.0, 7.4, 7.3]
|
||||
laravel: [8.*]
|
||||
name: P${{ matrix.php }} - Laravel${{ matrix.laravel }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
@@ -13,6 +13,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 7.4
|
||||
coverage: none
|
||||
extensions: pdo_sqlite
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-progress --no-suggest
|
||||
|
||||
@@ -19,12 +19,10 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php: [8.0, 7.4, 7.3, 7.2]
|
||||
laravel: [8.*, 7.*, 6.*]
|
||||
php: [8.0, 7.4, 7.3]
|
||||
laravel: [8.*]
|
||||
dependency-version: [prefer-lowest, prefer-stable]
|
||||
exclude:
|
||||
- laravel: 8.*
|
||||
php: 7.2
|
||||
- php: 8.0
|
||||
dependency-version: prefer-lowest
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
[Next release](https://github.com/barryvdh/laravel-ide-helper/compare/v2.8.1...master)
|
||||
--------------
|
||||
### Changed
|
||||
- Dropped support for Laravel 6 and Laravel 7, as well as support for PHP 7.2 [\# / mfn]()
|
||||
|
||||
### Added
|
||||
- Fix phpdoc generate for custom cast with parameter [\#986 / artelkr](https://github.com/barryvdh/laravel-ide-helper/pull/986)
|
||||
|
||||
+11
-11
@@ -20,25 +20,25 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"php": "^7.3 || ^8.0",
|
||||
"ext-json": "*",
|
||||
"barryvdh/reflection-docblock": "^2.0.6",
|
||||
"composer/composer": "^1.6 || ^2",
|
||||
"doctrine/dbal": "~2.3",
|
||||
"illuminate/console": "^6 || ^7 || ^8",
|
||||
"illuminate/filesystem": "^6 || ^7 || ^8",
|
||||
"illuminate/support": "^6 || ^7 || ^8",
|
||||
"doctrine/dbal": "^2.6 || ^3",
|
||||
"illuminate/console": "^8",
|
||||
"illuminate/filesystem": "^8",
|
||||
"illuminate/support": "^8",
|
||||
"phpdocumentor/type-resolver": "^1.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-pdo_sqlite": "*",
|
||||
"friendsofphp/php-cs-fixer": "^2",
|
||||
"illuminate/config": "^6 || ^7 || ^8",
|
||||
"illuminate/view": "^6 || ^7 || ^8",
|
||||
"mockery/mockery": "^1.3.3",
|
||||
"orchestra/testbench": "^4 || ^5 || ^6",
|
||||
"illuminate/config": "^8",
|
||||
"illuminate/view": "^8",
|
||||
"mockery/mockery": "^1.4",
|
||||
"orchestra/testbench": "^6",
|
||||
"phpunit/phpunit": "^8.5 || ^9",
|
||||
"spatie/phpunit-snapshot-assertions": "^1.4 || ^2.2 || ^3 || ^4",
|
||||
"spatie/phpunit-snapshot-assertions": "^3 || ^4",
|
||||
"vimeo/psalm": "^3.12"
|
||||
},
|
||||
"config": {
|
||||
@@ -46,7 +46,7 @@
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.8-dev"
|
||||
"dev-master": "2.9-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
|
||||
+3
-1
@@ -17,6 +17,7 @@ use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
|
||||
use Barryvdh\Reflection\DocBlock\Tag\MethodTag;
|
||||
use Closure;
|
||||
use Illuminate\Config\Repository as ConfigRepository;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
use ReflectionClass;
|
||||
|
||||
@@ -368,8 +369,9 @@ class Alias
|
||||
}
|
||||
|
||||
// Check if the class is macroable
|
||||
// (Eloquent\Builder is also macroable but doesn't use Macroable trait)
|
||||
$traits = collect($reflection->getTraitNames());
|
||||
if ($traits->contains('Illuminate\Support\Traits\Macroable')) {
|
||||
if ($traits->contains('Illuminate\Support\Traits\Macroable') || $class === EloquentBuilder::class) {
|
||||
$properties = $reflection->getStaticProperties();
|
||||
$macros = isset($properties['macros']) ? $properties['macros'] : [];
|
||||
foreach ($macros as $macro_name => $macro_func) {
|
||||
|
||||
+19
-12
@@ -4,6 +4,7 @@ namespace Barryvdh\LaravelIdeHelper;
|
||||
|
||||
use Barryvdh\Reflection\DocBlock;
|
||||
use Barryvdh\Reflection\DocBlock\Tag;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class Macro extends Method
|
||||
@@ -32,25 +33,31 @@ class Macro extends Method
|
||||
*/
|
||||
protected function initPhpDoc($method)
|
||||
{
|
||||
$this->phpdoc = new DocBlock('/** */');
|
||||
$this->phpdoc = new DocBlock($method);
|
||||
|
||||
$this->addLocationToPhpDoc();
|
||||
|
||||
// Add macro parameters
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
$type = $parameter->hasType() ? $parameter->getType()->getName() : 'mixed';
|
||||
$type .= $parameter->hasType() && $parameter->getType()->allowsNull() ? '|null' : '';
|
||||
// Add macro parameters if they are missed in original docblock
|
||||
if (!$this->phpdoc->hasTag('param')) {
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
$type = $parameter->hasType() ? $parameter->getType()->getName() : 'mixed';
|
||||
$type .= $parameter->hasType() && $parameter->getType()->allowsNull() ? '|null' : '';
|
||||
|
||||
$name = $parameter->isVariadic() ? '...' : '';
|
||||
$name .= '$' . $parameter->getName();
|
||||
$name = $parameter->isVariadic() ? '...' : '';
|
||||
$name .= '$' . $parameter->getName();
|
||||
|
||||
$this->phpdoc->appendTag(Tag::createInstance("@param {$type} {$name}"));
|
||||
$this->phpdoc->appendTag(Tag::createInstance("@param {$type} {$name}"));
|
||||
}
|
||||
}
|
||||
|
||||
// Add macro return type
|
||||
if ($method->hasReturnType()) {
|
||||
$type = $method->getReturnType()->getName();
|
||||
$type .= $method->getReturnType()->allowsNull() ? '|null' : '';
|
||||
// Add macro return type if it missed in original docblock
|
||||
if ($method->hasReturnType() && !$this->phpdoc->hasTag('return')) {
|
||||
$builder = EloquentBuilder::class;
|
||||
$return = $method->getReturnType();
|
||||
|
||||
$type = $return->getName();
|
||||
$type .= $this->root === "\\{$builder}" && $return->getName() === $builder ? '|static' : '';
|
||||
$type .= $return->allowsNull() ? '|null' : '';
|
||||
|
||||
$this->phpdoc->appendTag(Tag::createInstance("@return {$type}"));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Barryvdh\LaravelIdeHelper\Tests;
|
||||
|
||||
use Barryvdh\LaravelIdeHelper\Alias;
|
||||
use Barryvdh\LaravelIdeHelper\Macro;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversDefaultClass \Barryvdh\LaravelIdeHelper\Alias
|
||||
*/
|
||||
class AliasTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::detectMethods
|
||||
*/
|
||||
public function testDetectMethodsMacroableMacros(): void
|
||||
{
|
||||
// Mock
|
||||
$macro = __FUNCTION__;
|
||||
$alias = new AliasMock();
|
||||
|
||||
// Macros
|
||||
Builder::macro(
|
||||
$macro,
|
||||
function () {
|
||||
// empty
|
||||
}
|
||||
);
|
||||
|
||||
// Prepare
|
||||
$alias->setClasses([Builder::class]);
|
||||
$alias->detectMethods();
|
||||
|
||||
// Test
|
||||
$this->assertNotNull($this->getAliasMacro($alias, Builder::class, $macro));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::detectMethods
|
||||
*/
|
||||
public function testDetectMethodsEloquentBuilderMacros(): void
|
||||
{
|
||||
// Mock
|
||||
$macro = __FUNCTION__;
|
||||
$alias = new AliasMock();
|
||||
|
||||
// Macros
|
||||
EloquentBuilder::macro(
|
||||
$macro,
|
||||
function () {
|
||||
// empty
|
||||
}
|
||||
);
|
||||
|
||||
// Prepare
|
||||
$alias->setClasses([EloquentBuilder::class]);
|
||||
$alias->detectMethods();
|
||||
|
||||
// Test
|
||||
$this->assertNotNull($this->getAliasMacro($alias, EloquentBuilder::class, $macro));
|
||||
}
|
||||
|
||||
protected function getAliasMacro(Alias $alias, string $class, string $method): ?Macro
|
||||
{
|
||||
return Arr::first(
|
||||
$alias->getMethods(),
|
||||
function ($macro) use ($class, $method) {
|
||||
return $macro instanceof Macro
|
||||
&& $macro->getDeclaringClass() === "\\{$class}"
|
||||
&& $macro->getName() === $method;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @noinspection PhpMultipleClassesDeclarationsInOneFile
|
||||
*/
|
||||
class AliasMock extends Alias
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
// no need to call parent
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classes
|
||||
*/
|
||||
public function setClasses(array $classes)
|
||||
{
|
||||
$this->classes = $classes;
|
||||
}
|
||||
|
||||
public function detectMethods()
|
||||
{
|
||||
parent::detectMethods();
|
||||
}
|
||||
}
|
||||
@@ -6,19 +6,9 @@ namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\LaravelCustomCas
|
||||
|
||||
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
|
||||
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
|
||||
use Illuminate\Foundation\Application;
|
||||
|
||||
class Test extends AbstractModelsCommand
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (version_compare(Application::VERSION, '7.0', '<')) {
|
||||
$this->markTestSkipped('This test requires Laravel 7.0 or higher');
|
||||
}
|
||||
}
|
||||
|
||||
public function test(): void
|
||||
{
|
||||
$command = $this->app->make(ModelsCommand::class);
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Barryvdh\LaravelIdeHelper\Tests;
|
||||
|
||||
use Barryvdh\LaravelIdeHelper\Macro;
|
||||
use Barryvdh\Reflection\DocBlock;
|
||||
use Barryvdh\Reflection\DocBlock\Tag;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use ReflectionFunctionAbstract;
|
||||
|
||||
use function array_map;
|
||||
use function implode;
|
||||
|
||||
use const PHP_EOL;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversDefaultClass \Barryvdh\LaravelIdeHelper\Macro
|
||||
*/
|
||||
class MacroTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers ::initPhpDoc
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function testInitPhpDocEloquentBuilderHasStaticInReturnType(): void
|
||||
{
|
||||
$class = new ReflectionClass(EloquentBuilder::class);
|
||||
$phpdoc = (new MacroMock())->getPhpDoc(
|
||||
new ReflectionFunction(
|
||||
function (): EloquentBuilder {
|
||||
return $this;
|
||||
}
|
||||
),
|
||||
$class
|
||||
);
|
||||
|
||||
$this->assertNotNull($phpdoc);
|
||||
$this->assertEquals(
|
||||
'@return \Illuminate\Database\Eloquent\Builder|static',
|
||||
$this->tagsToString($phpdoc, 'return')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::initPhpDoc
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function testInitPhpDocClosureWithoutDocBlock(): void
|
||||
{
|
||||
$phpdoc = (new MacroMock())->getPhpDoc(
|
||||
new ReflectionFunction(
|
||||
function (int $a = null): int {
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertNotNull($phpdoc);
|
||||
$this->assertEmpty($phpdoc->getText());
|
||||
$this->assertEquals('@param int|null $a', $this->tagsToString($phpdoc, 'param'));
|
||||
$this->assertEquals('@return int', $this->tagsToString($phpdoc, 'return'));
|
||||
$this->assertTrue($phpdoc->hasTag('see'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::initPhpDoc
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function testInitPhpDocClosureWithArgsAndReturnType(): void
|
||||
{
|
||||
$phpdoc = (new MacroMock())->getPhpDoc(
|
||||
new ReflectionFunction(
|
||||
/**
|
||||
* Test docblock.
|
||||
*/
|
||||
function (int $a = null): int {
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertNotNull($phpdoc);
|
||||
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
|
||||
$this->assertEquals('@param int|null $a', $this->tagsToString($phpdoc, 'param'));
|
||||
$this->assertEquals('@return int', $this->tagsToString($phpdoc, 'return'));
|
||||
$this->assertTrue($phpdoc->hasTag('see'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::initPhpDoc
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function testInitPhpDocClosureWithArgs(): void
|
||||
{
|
||||
$phpdoc = (new MacroMock())->getPhpDoc(
|
||||
new ReflectionFunction(
|
||||
/**
|
||||
* Test docblock.
|
||||
*/
|
||||
function (int $a = null) {
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertNotNull($phpdoc);
|
||||
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
|
||||
$this->assertEquals('@param int|null $a', $this->tagsToString($phpdoc, 'param'));
|
||||
$this->assertFalse($phpdoc->hasTag('return'));
|
||||
$this->assertTrue($phpdoc->hasTag('see'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::initPhpDoc
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function testInitPhpDocClosureWithReturnType(): void
|
||||
{
|
||||
$phpdoc = (new MacroMock())->getPhpDoc(
|
||||
new ReflectionFunction(
|
||||
/**
|
||||
* Test docblock.
|
||||
*/
|
||||
function (): int {
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertNotNull($phpdoc);
|
||||
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
|
||||
$this->assertFalse($phpdoc->hasTag('param'));
|
||||
$this->assertEquals('@return int', $this->tagsToString($phpdoc, 'return'));
|
||||
$this->assertTrue($phpdoc->hasTag('see'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::initPhpDoc
|
||||
*/
|
||||
public function testInitPhpDocParamsAddedOnlyNotPresent(): void
|
||||
{
|
||||
$phpdoc = (new MacroMock())->getPhpDoc(
|
||||
new ReflectionFunction(
|
||||
/**
|
||||
* Test docblock.
|
||||
*
|
||||
* @param \stdClass|null $a aaaaa
|
||||
*/
|
||||
function ($a = null): int {
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertNotNull($phpdoc);
|
||||
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
|
||||
$this->assertEquals('@param \stdClass|null $a aaaaa', $this->tagsToString($phpdoc, 'param'));
|
||||
$this->assertEquals('@return int', $this->tagsToString($phpdoc, 'return'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::initPhpDoc
|
||||
*/
|
||||
public function testInitPhpDocReturnAddedOnlyNotPresent(): void
|
||||
{
|
||||
$phpdoc = (new MacroMock())->getPhpDoc(
|
||||
new ReflectionFunction(
|
||||
/**
|
||||
* Test docblock.
|
||||
*
|
||||
* @return \stdClass|null rrrrrrr
|
||||
*/
|
||||
function ($a = null): int {
|
||||
return 0;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertNotNull($phpdoc);
|
||||
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
|
||||
$this->assertEquals('@param mixed $a', $this->tagsToString($phpdoc, 'param'));
|
||||
$this->assertEquals('@return \stdClass|null rrrrrrr', $this->tagsToString($phpdoc, 'return'));
|
||||
}
|
||||
|
||||
protected function tagsToString(DocBlock $docBlock, string $name)
|
||||
{
|
||||
$tags = $docBlock->getTagsByName($name);
|
||||
$tags = array_map(
|
||||
function (Tag $tag) {
|
||||
return trim((string)$tag);
|
||||
},
|
||||
$tags
|
||||
);
|
||||
$tags = implode(PHP_EOL, $tags);
|
||||
|
||||
return $tags;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @noinspection PhpMultipleClassesDeclarationsInOneFile
|
||||
*/
|
||||
class MacroMock extends Macro
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
// no need to call parent
|
||||
}
|
||||
|
||||
public function getPhpDoc(ReflectionFunctionAbstract $method, ReflectionClass $class = null): DocBlock
|
||||
{
|
||||
return (new Macro($method, '', $class ?? $method->getClosureScopeClass()))->phpdoc;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ namespace Barryvdh\LaravelIdeHelper\Tests;
|
||||
|
||||
use Barryvdh\LaravelIdeHelper\Method;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Foundation\Application;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class MethodTest extends TestCase
|
||||
@@ -59,10 +58,6 @@ DOC;
|
||||
*/
|
||||
public function testEloquentBuilderOutput()
|
||||
{
|
||||
if ((int) Application::VERSION < 8) {
|
||||
$this->markTestSkipped('This test requires Laravel 8.0 or higher');
|
||||
}
|
||||
|
||||
$reflectionClass = new \ReflectionClass(Builder::class);
|
||||
$reflectionMethod = $reflectionClass->getMethod('with');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user