Compare commits

..
7 Commits
Author SHA1 Message Date
Stan Daniëls 754bb4d075 Add support for invokable classes as macro function (#765)
Macros can be used with invokable classes, like so.

```
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;

class ResponseMacroServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Response::macro('foo', new Foo());
    }
}

class Foo
{
    public function __invoke()
    {
        return 'foobar';
    }
}
```

When running `ide-helper:generate` the following fatal error was thrown.

```  Symfony\Component\Debug\Exception\FatalThrowableError  : ReflectionFunction::__construct() expects parameter 1 to be string, object given```

This commit fixes this error.
2019-02-18 20:54:27 +01:00
edcoreweb bcb881b20d Nested relations detection. (#763) 2019-02-03 16:59:09 +01:00
Tim Philips d00600d769 Include DocBloc’s from classes to allow deeper code inspection (#745)
* Add support to include DocBloc’s from classes to allow further code inspection

* Adjust for PSR2

* Additional fix for PSR2
2019-01-28 21:38:57 +01:00
Ahmed Fathy 858dd40844 Install doctrine/dbal on development (#753) 2019-01-28 21:25:55 +01:00
Kyle 4cd11a4d33 Allow Laravel 5.8 (#754) 2019-01-28 21:24:50 +01:00
Barry vd. Heuvel 5439781e7c Update composer.json 2018-12-19 13:13:32 +01:00
+pikari 190bf07c05 fix: warning when call the instance method (#735) 2018-12-19 13:12:44 +01:00
8 changed files with 100 additions and 35 deletions
+6 -6
View File
@@ -11,15 +11,15 @@
],
"require": {
"php": ">=7",
"illuminate/support": "^5.5,<5.8",
"illuminate/console": "^5.5,<5.8",
"illuminate/filesystem": "^5.5,<5.8",
"illuminate/support": "^5.5,<5.9",
"illuminate/console": "^5.5,<5.9",
"illuminate/filesystem": "^5.5,<5.9",
"barryvdh/reflection-docblock": "^2.0.6",
"composer/composer": "^1.6"
},
"require-dev": {
"illuminate/config": "^5.1,<5.8",
"illuminate/view": "^5.1,<5.8",
"illuminate/config": "^5.1,<5.9",
"illuminate/view": "^5.1,<5.9",
"phpro/grumphp": "^0.14",
"phpunit/phpunit" : "4.*",
"scrutinizer/ocular": "~1.1",
@@ -46,7 +46,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.5-dev"
"dev-master": "2.6-dev"
},
"laravel": {
"providers": [
+12
View File
@@ -193,4 +193,16 @@ return array(
'integer' => 'int',
'boolean' => 'bool',
),
/*
|--------------------------------------------------------------------------
| Include DocBlocks from classes
|--------------------------------------------------------------------------
|
| Include DocBlocks from classes to allow additional code inspection for
| magic methods and properties.
|
*/
'include_class_docblocks' => false,
);
+2 -2
View File
@@ -97,11 +97,11 @@ The `Illuminate/Support/helpers.php` is already set up, but you can add/remove y
### Automatic phpDocs for models
> You need to require `doctrine/dbal: ~2.3` in your own composer.json to get database columns.
> You need to add `doctrine/dbal: ~2.3` to require-dev in your own composer.json to get database columns.
```bash
composer require doctrine/dbal
composer require --dev doctrine/dbal
```
If you don't want to write your properties yourself, you can use the command `php artisan ide-helper:models` to generate
+9 -3
View File
@@ -36,7 +36,10 @@ namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
<?= $method->shouldReturn() ? 'return ': '' ?><?= $method->getRoot() ?>::<?= $method->getRealName() ?>(<?= $method->getParams() ?>);
<?php if($method->isInstanceCall()):?>
/** @var <?=$method->getRoot()?> $instance */
<?php endif?>
<?= $method->shouldReturn() ? 'return ': '' ?><?= $method->getRootMethodCall() ?>;
}
<?php endforeach; ?>
}
@@ -57,8 +60,11 @@ namespace <?= $namespace == '__root' ? '' : trim($namespace, '\\') ?> {
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
<?= $method->shouldReturn() ? 'return ': '' ?><?= $method->getRoot() ?>::<?= $method->getRealName() ?>(<?= $method->getParams() ?>);
<?php if($method->isInstanceCall()):?>
/** @var <?=$method->getRoot()?> $instance */
<?php endif?>
<?= $method->shouldReturn() ? 'return ': '' ?><?= $method->getRootMethodCall() ?>;
}
<?php endforeach; ?>
<?php endif; ?>}
+28 -8
View File
@@ -10,11 +10,12 @@
namespace Barryvdh\LaravelIdeHelper;
use ReflectionClass;
use Barryvdh\Reflection\DocBlock;
use Barryvdh\Reflection\DocBlock\Context;
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
use Barryvdh\Reflection\DocBlock\Tag\MethodTag;
use ReflectionClass;
use Illuminate\Config\Repository as ConfigRepository;
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
class Alias
{
@@ -35,17 +36,22 @@ class Alias
protected $interfaces = array();
protected $phpdoc = null;
/** @var ConfigRepository */
protected $config;
/**
* @param string $alias
* @param string $facade
* @param array $magicMethods
* @param array $interfaces
* @param ConfigRepository $config
* @param string $alias
* @param string $facade
* @param array $magicMethods
* @param array $interfaces
*/
public function __construct($alias, $facade, $magicMethods = array(), $interfaces = array())
public function __construct($config, $alias, $facade, $magicMethods = array(), $interfaces = array())
{
$this->alias = $alias;
$this->magicMethods = $magicMethods;
$this->interfaces = $interfaces;
$this->config = $config;
// Make the class absolute
$facade = '\\' . ltrim($facade, '\\');
@@ -389,6 +395,10 @@ class Alias
return new \ReflectionMethod($macro_func[0], $macro_func[1]);
}
if (is_object($macro_func) && is_callable($macro_func)) {
return new \ReflectionMethod($macro_func, '__invoke');
}
return new \ReflectionFunction($macro_func);
}
@@ -403,10 +413,20 @@ class Alias
$serializer = new DocBlockSerializer(1, $prefix);
if ($this->phpdoc) {
if ($this->config->get('ide-helper.include_class_docblocks')) {
// if a class doesn't expose any DocBlock tags
// we can perform reflection on the class and
// add in the original class DocBlock
if (count($this->phpdoc->getTags()) === 0) {
$class = new ReflectionClass($this->root);
$this->phpdoc = new DocBlock($class->getDocComment());
}
}
$this->removeDuplicateMethodsFromPhpDoc();
return $serializer->getDocComment($this->phpdoc);
}
return '';
}
+14 -12
View File
@@ -452,6 +452,8 @@ class ModelsCommand extends Command
) {
//Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php
$reflection = new \ReflectionMethod($model, $method);
// php 7.x type or fallback to docblock
$type = (string) $reflection->getReturnType() ?: $this->getReturnTypeFromDocBlock($reflection);
$file = new \SplFileObject($reflection->getFileName());
$file->seek($reflection->getStartLine() - 1);
@@ -466,19 +468,19 @@ class ModelsCommand extends Command
$code = substr($code, $begin, strrpos($code, '}') - $begin + 1);
foreach (array(
'hasMany',
'hasManyThrough',
'belongsToMany',
'hasOne',
'belongsTo',
'morphOne',
'morphTo',
'morphMany',
'morphToMany',
'morphedByMany'
) as $relation) {
'hasMany' => '\Illuminate\Database\Eloquent\Relations\HasMany',
'hasManyThrough' => '\Illuminate\Database\Eloquent\Relations\HasManyThrough',
'belongsToMany' => '\Illuminate\Database\Eloquent\Relations\BelongsToMany',
'hasOne' => '\Illuminate\Database\Eloquent\Relations\HasOne',
'belongsTo' => '\Illuminate\Database\Eloquent\Relations\BelongsTo',
'morphOne' => '\Illuminate\Database\Eloquent\Relations\MorphOne',
'morphTo' => '\Illuminate\Database\Eloquent\Relations\MorphTo',
'morphMany' => '\Illuminate\Database\Eloquent\Relations\MorphMany',
'morphToMany' => '\Illuminate\Database\Eloquent\Relations\MorphToMany',
'morphedByMany' => '\Illuminate\Database\Eloquent\Relations\MorphToMany'
) as $relation => $impl) {
$search = '$this->' . $relation . '(';
if ($pos = stripos($code, $search)) {
if (stripos($code, $search) || stripos($impl, $type) !== false) {
//Resolve the relation's model to a Relation object.
$methodReflection = new \ReflectionMethod($model, $method);
if ($methodReflection->getNumberOfParameters()) {
+1 -1
View File
@@ -203,7 +203,7 @@ class Generator
}
$magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array();
$alias = new Alias($name, $facade, $magicMethods, $this->interfaces);
$alias = new Alias($this->config, $name, $facade, $magicMethods, $this->interfaces);
if ($alias->isValid()) {
//Add extra methods, from other classes (magic static calls)
if (array_key_exists($name, $this->extra)) {
+28 -3
View File
@@ -34,6 +34,7 @@ class Method
protected $interfaces = array();
protected $real_name;
protected $return = null;
protected $root;
/**
* @param \ReflectionMethod|\ReflectionFunctionAbstract $method
@@ -50,6 +51,9 @@ class Method
$this->real_name = $method->isClosure() ? $this->name : $method->name;
$this->initClassDefinedProperties($method, $class);
//Reference the 'real' function in the declaring class
$this->root = '\\' . ltrim($class->getName(), '\\');
//Create a DocBlock and serializer instance
$this->initPhpDoc($method);
@@ -66,9 +70,6 @@ class Method
//Make the method static
$this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc));
//Reference the 'real' function in the declaring class
$this->root = '\\' . ltrim($class->getName(), '\\');
}
/**
@@ -110,6 +111,26 @@ class Method
return $this->root;
}
/**
* @return bool
*/
public function isInstanceCall()
{
return ! ($this->method->isClosure() || $this->method->isStatic());
}
/**
* @return string
*/
public function getRootMethodCall()
{
if ($this->isInstanceCall()) {
return "\$instance->{$this->getRealName()}({$this->getParams()})";
} else {
return "{$this->getRoot()}::{$this->getRealName()}({$this->getParams()})";
}
}
/**
* Get the docblock for this method
*
@@ -243,6 +264,10 @@ class Method
// Set the changed content
$tag->setContent($returnValue . ' ' . $tag->getDescription());
$this->return = $returnValue;
if ($tag->getType() === '$this') {
$tag->setType($this->root);
}
} else {
$this->return = null;
}