Compare commits

...
Author SHA1 Message Date
Barry vd. Heuvel 6d19a48da4 Fix test 2024-12-29 19:42:42 +01:00
laravel-ide-helper aed6c0c5b8 composer fix-style 2024-12-29 18:32:32 +00:00
Barry vd. Heuvel 5bbe750505 Merge branch 'feat-meta-hints' of github.com:barryvdh/laravel-ide-helper into feat-meta-hints 2024-12-29 19:31:53 +01:00
Barry vd. Heuvel d5323b80d8 map to string 2024-12-29 19:31:39 +01:00
laravel-ide-helper aa9b48185f composer fix-style 2024-12-29 18:27:55 +00:00
Barry vd. Heuvel b4a605a491 Merge branch 'feat-meta-hints' of github.com:barryvdh/laravel-ide-helper into feat-meta-hints 2024-12-29 19:27:12 +01:00
Barry vd. Heuvel 701cf67ba0 Add translations 2024-12-29 19:26:20 +01:00
laravel-ide-helper 68688b98fa composer fix-style 2024-12-29 18:19:34 +00:00
Barry vd. Heuvel 1353c67516 Fix view instance 2024-12-29 19:19:01 +01:00
Barry vd. Heuvel 6b934aa43a Use php-templates from vs-code 2024-12-29 19:16:23 +01:00
laravel-ide-helper 9f2a32f4d1 composer fix-style 2024-12-29 13:19:34 +00:00
Barry vd. Heuvel 61fd354706 Add phpstorm meta hints 2024-12-29 14:19:05 +01:00
Barry vd. Heuvel 2a41415f01 Add TLDR section, update options (#1639) 2024-12-29 13:10:58 +01:00
Barry vd. Heuvelandlaravel-ide-helper a7fc73e8e4 Format IDE helper (#1638)
* Format IDE helper

* composer fix-style

* Format IDE helper

* composer fix-style

---------

Co-authored-by: laravel-ide-helper <[email protected]>
2024-12-29 12:56:55 +01:00
Barry vd. Heuvelandpb30 f343efa140 Pb30 version var rename (#1637)
* Update view "version" variable name to avoid potential conflicts

* Remove version

---------

Co-authored-by: pb30 <[email protected]>
2024-12-29 12:11:06 +01:00
14 changed files with 603 additions and 114 deletions
+1
View File
@@ -54,6 +54,7 @@
- Fix type of hashed model property to `string`
### Changed
- Update view "version" variable name to avoid potential conflicts
- Add support for EloquentBuilder generics introduced in Laravel 11.15.
- Drop support for Laravel versions earlier than 11.15.
+20 -35
View File
@@ -33,42 +33,27 @@ Require this package with composer using the following command:
composer require --dev barryvdh/laravel-ide-helper
```
> [!NOTE]
> If you encounter version conflicts with doctrine/dbal, please try:
> `composer require --dev barryvdh/laravel-ide-helper --with-all-dependencies`
This package makes use of [Laravels package auto-discovery mechanism](https://medium.com/@taylorotwell/package-auto-discovery-in-laravel-5-5-ea9e3ab20518), which means if you don't install dev dependencies in production, it also won't be loaded.
If for some reason you want manually control this:
- add the package to the `extra.laravel.dont-discover` key in `composer.json`, e.g.
```json
"extra": {
"laravel": {
"dont-discover": [
"barryvdh/laravel-ide-helper"
]
}
}
```
- Add the following class to the `providers` array in `config/app.php` (`bootstrap/providers.php` for Laravel 11+):
```php
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
```
If you want to manually load it only in non-production environments, instead you can add this to your `AppServiceProvider` with the `register()` method:
```php
public function register()
{
if ($this->app->isLocal()) {
$this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
}
// ...
}
```
> Note: Avoid caching the configuration in your development environment, it may cause issues after installing this package; respectively clear the cache beforehand via `php artisan cache:clear` if you encounter problems when running the commands
## Usage
### TL;DR
Run this to generate autocompletion for Facades. This creates _ide_helper.php
```
php artisan ide-helper:generate
```
Run this to add phpdocs for your models. Add -RW to Reset existing phpdocs and Write to the models directly.
```
php artisan ide-helper:models -RW
```
If you don't want the full _ide_helper.php file, you can run add `--write-eloquent-helper` to the model command to generate small version, which is required for the `@mixin \Eloquent` to be able to add the QueryBuilder methods.
If you don't want to add all the phpdocs to your Models directly, you can use `--nowrite` to create a seperate file. The `--write-mixin` option can be used to only add a `@mixin` to your models, but add the generated phpdocs in a seperate file. This avoids having the results marked as duplicate.
_Check out [this Laracasts video](https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15) for a quick introduction/explanation!_
- `php artisan ide-helper:generate` - [PHPDoc generation for Laravel Facades ](#automatic-phpdoc-generation-for-laravel-facades)
@@ -86,8 +71,6 @@ You can now re-generate the docs yourself (for future updates)
php artisan ide-helper:generate
```
> Note: `bootstrap/compiled.php` has to be cleared first, so run `php artisan clear-compiled` before generating.
This will generate the file `_ide_helper.php` which is expected to be additionally parsed by your IDE for autocomplete. You can use the config `filename` to change its name.
You can configure your `composer.json` to do this each time you update your dependencies:
@@ -149,6 +132,8 @@ The class name will be different from the model, avoiding the IDE duplicate anno
> Please make sure to back up your models, before writing the info.
> You need the _ide_helper.php file to add the QueryBuilder methods. You can add --write-eloquent-helper/-E to generate a minimal version. If this file does not exist, you will be prompted for it.
Writing to the models should keep the existing comments and only append new properties/methods. It will not update changed properties/methods.
With the `--reset (-R)` option, the whole existing PHPDoc is replaced, including any comments that have been made.
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Taylor Otwell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+5
View File
@@ -0,0 +1,5 @@
The templates here are based on the official VS Code extension by Laravel https://github.com/laravel/vs-code-extension
Modifications:
- return instead of echo
- do not serialize to JSON
+131
View File
@@ -0,0 +1,131 @@
<?php
$local = collect(glob(config_path('/*.php')))
->merge(glob(config_path('**/*.php')))
->map(fn ($path) => [
(string) Illuminate\Support\Str::of($path)
->replace([config_path('/'), '.php'], '')
->replace('/', '.'),
$path,
]);
$vendor = collect(glob(base_path('vendor/**/**/config/*.php')))->map(fn (
$path
) => [
(string) Illuminate\Support\Str::of($path)
->afterLast('/config/')
->replace('.php', '')
->replace('/', '.'),
$path,
]);
$configPaths = $local
->merge($vendor)
->groupBy(0)
->map(fn ($items) => $items->pluck(1));
$cachedContents = [];
$cachedParsed = [];
function vsCodeGetConfigValue($value, $key, $configPaths)
{
$parts = explode('.', $key);
$toFind = $key;
$found = null;
while (count($parts) > 0) {
array_pop($parts);
$toFind = implode('.', $parts);
if ($configPaths->has($toFind)) {
$found = $toFind;
break;
}
}
if ($found === null) {
return null;
}
$file = null;
$line = null;
if ($found === $key) {
$file = $configPaths->get($found)[0];
} else {
foreach ($configPaths->get($found) as $path) {
$cachedContents[$path] ??= file_get_contents($path);
$cachedParsed[$path] ??= token_get_all($cachedContents[$path]);
$keysToFind = Illuminate\Support\Str::of($key)
->replaceFirst($found, '')
->ltrim('.')
->explode('.');
if (is_numeric($keysToFind->last())) {
$index = $keysToFind->pop();
if ($index !== '0') {
return null;
}
$key = collect(explode('.', $key));
$key->pop();
$key = $key->implode('.');
$value = 'array(...)';
}
$nextKey = $keysToFind->shift();
$expectedDepth = 1;
$depth = 0;
foreach ($cachedParsed[$path] as $token) {
if ($token === '[') {
$depth++;
}
if ($token === ']') {
$depth--;
}
if (!is_array($token)) {
continue;
}
$str = trim($token[1], '"\'');
if (
$str === $nextKey &&
$depth === $expectedDepth &&
$token[0] === T_CONSTANT_ENCAPSED_STRING
) {
$nextKey = $keysToFind->shift();
$expectedDepth++;
if ($nextKey === null) {
$file = $path;
$line = $token[2];
break;
}
}
}
if ($file) {
break;
}
}
}
return [
'name' => $key,
'value' => $value,
'file' => $file === null ? null : str_replace(base_path('/'), '', $file),
'line' => $line,
];
}
return collect(Illuminate\Support\Arr::dot(config()->all()))
->map(fn ($value, $key) => vsCodeGetConfigValue($value, $key, $configPaths))
->filter()
->values();
+46
View File
@@ -0,0 +1,46 @@
<?php
function vsCodeGetRouterReflection(Illuminate\Routing\Route $route)
{
if ($route->getActionName() === 'Closure') {
return new ReflectionFunction($route->getAction()['uses']);
}
if (!str_contains($route->getActionName(), '@')) {
return new ReflectionClass($route->getActionName());
}
try {
return new ReflectionMethod($route->getControllerClass(), $route->getActionMethod());
} catch (Throwable $e) {
$namespace = app(Illuminate\Routing\UrlGenerator::class)->getRootControllerNamespace()
?? (app()->getNamespace() . 'Http\Controllers');
return new ReflectionMethod(
$namespace . '\\' . ltrim($route->getControllerClass(), '\\'),
$route->getActionMethod(),
);
}
}
return collect(app('router')->getRoutes()->getRoutes())
->map(function (Illuminate\Routing\Route $route) {
try {
$reflection = vsCodeGetRouterReflection($route);
} catch (Throwable $e) {
$reflection = null;
}
return [
'method' => collect($route->methods())->filter(function ($method) {
return $method !== 'HEAD';
})->implode('|'),
'uri' => $route->uri(),
'name' => $route->getName(),
'action' => $route->getActionName(),
'parameters' => $route->parameterNames(),
'filename' => $reflection ? $reflection->getFileName() : null,
'line' => $reflection ? $reflection->getStartLine() : null,
];
})
;
+143
View File
@@ -0,0 +1,143 @@
<?php
function vsCodeGetTranslationsFromFile($file, $path, $namespace)
{
$key = pathinfo($file, PATHINFO_FILENAME);
if ($namespace) {
$key = "{$namespace}::{$key}";
}
$lang = collect(explode(DIRECTORY_SEPARATOR, str_replace($path, '', $file)))
->filter()
->first();
$fileLines = Illuminate\Support\Facades\File::lines($file);
$lines = [];
$inComment = false;
foreach ($fileLines as $index => $line) {
$trimmed = trim($line);
if (substr($trimmed, 0, 2) === '/*') {
$inComment = true;
continue;
}
if ($inComment) {
if (substr($trimmed, -2) !== '*/') {
continue;
}
$inComment = false;
}
if (substr($trimmed, 0, 2) === '//') {
continue;
}
$lines[] = [$index + 1, $trimmed];
}
return [
'k' => $key,
'la' => $lang,
'vs' => collect(Illuminate\Support\Arr::dot((Illuminate\Support\Arr::wrap(__($key, [], $lang)))))
->map(
fn ($value, $key) => vsCodeTranslationValue(
$key,
$value,
str_replace(base_path(DIRECTORY_SEPARATOR), '', $file),
$lines
)
)
->filter(),
];
}
function vsCodeTranslationValue($key, $value, $file, $lines): ?array
{
if (is_array($value)) {
return null;
}
$lineNumber = 1;
$keys = explode('.', $key);
$index = 0;
$currentKey = array_shift($keys);
foreach ($lines as $index => $line) {
if (
strpos($line[1], '"' . $currentKey . '"', 0) !== false ||
strpos($line[1], "'" . $currentKey . "'", 0) !== false
) {
$lineNumber = $line[0];
$currentKey = array_shift($keys);
}
if ($currentKey === null) {
break;
}
}
return [
'v' => $value,
'p' => $file,
'li' => $lineNumber,
'pa' => preg_match_all("/\:([A-Za-z0-9_]+)/", $value, $matches)
? $matches[1]
: [],
];
}
function vscodeCollectTranslations(string $path, ?string $namespace = null)
{
$realPath = realpath($path);
if (!is_dir($realPath)) {
return collect();
}
return collect(Illuminate\Support\Facades\File::allFiles($realPath))->map(
fn ($file) => vsCodeGetTranslationsFromFile($file, $path, $namespace)
);
}
$loader = app('translator')->getLoader();
$namespaces = $loader->namespaces();
$reflection = new ReflectionClass($loader);
$property = $reflection->hasProperty('paths')
? $reflection->getProperty('paths')
: $reflection->getProperty('path');
$property->setAccessible(true);
$paths = Illuminate\Support\Arr::wrap($property->getValue($loader));
$default = collect($paths)->flatMap(
fn ($path) => vscodeCollectTranslations($path)
);
$namespaced = collect($namespaces)->flatMap(
fn ($path, $namespace) => vscodeCollectTranslations($path, $namespace)
);
$final = [];
foreach ($default->merge($namespaced) as $value) {
foreach ($value['vs'] as $key => $v) {
$dotKey = "{$value['k']}.{$key}";
if (!isset($final[$dotKey])) {
$final[$dotKey] = [];
}
$final[$dotKey][$value['la']] = $v;
if ($value['la'] === Illuminate\Support\Facades\App::currentLocale()) {
$final[$dotKey]['default'] = $v;
}
}
}
return collect($final);
+61
View File
@@ -0,0 +1,61 @@
<?php
function vsCodeFindBladeFiles($path)
{
$paths = [];
if (!is_dir($path)) {
return $paths;
}
foreach (
Symfony\Component\Finder\Finder::create()
->files()
->name('*.blade.php')
->in($path) as $file
) {
$paths[] = [
'path' => str_replace(base_path(DIRECTORY_SEPARATOR), '', $file->getRealPath()),
'isVendor' => str_contains($file->getRealPath(), base_path('vendor')),
'key' => Illuminate\Support\Str::of($file->getRealPath())
->replace(realpath($path), '')
->replace('.blade.php', '')
->ltrim(DIRECTORY_SEPARATOR)
->replace(DIRECTORY_SEPARATOR, '.'),
];
}
return $paths;
}
$paths = collect(
app('view')
->getFinder()
->getPaths()
)->flatMap(function ($path) {
return vsCodeFindBladeFiles($path);
});
$hints = collect(
app('view')
->getFinder()
->getHints()
)->flatMap(function ($paths, $key) {
return collect($paths)->flatMap(function ($path) use ($key) {
return collect(vsCodeFindBladeFiles($path))->map(function ($value) use (
$key
) {
return array_merge($value, ['key' => "{$key}::{$value['key']}"]);
});
});
});
[$local, $vendor] = $paths
->merge($hints)
->values()
->partition(function ($v) {
return !$v['isVendor'];
});
return $local
->sortBy('key', SORT_NATURAL)
->merge($vendor->sortBy('key', SORT_NATURAL));
+35 -31
View File
@@ -14,31 +14,34 @@
/**
* A helper file for Laravel, to provide autocomplete information to your IDE
* Generated for Laravel <?= $version ?>.
* Generated for Laravel <?= app()->version() ?>.
*
* This file should not be included in your code, only analyzed by your IDE!
*
* @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper
*/
<?php
$s1 = ' ';
$s2 = $s1 . $s1;
$s3 = $s1 . $s2;
?>
<?php foreach ($namespaces_by_extends_ns as $namespace => $aliases) : ?>
namespace <?= $namespace === '__root' ? '' : trim($namespace, '\\') ?> {
<?php foreach ($aliases as $alias) : ?>
<?= trim($alias->getDocComment(' ')) ?>
<?= $alias->getClassType() ?> <?= $alias->getExtendsClass() ?> {
<?php echo trim($alias->getDocComment($s1)) . "\n{$s1}" . $alias->getClassType() ?> <?= $alias->getExtendsClass() ?> {
<?php foreach ($alias->getMethods() as $method) : ?>
<?= trim($method->getDocComment(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
<?= trim($method->getDocComment($s2)) . "\n{$s2}" ?>public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
{<?php if ($method->getDeclaringClass() !== $method->getRoot()) : ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
<?= "\n" . $s3?>//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
<?php if ($method->isInstanceCall()) : ?>
/** @var <?=$method->getRoot()?> $instance */
<?php endif?>
<?= $method->shouldReturn() ? 'return ' : '' ?><?= $method->getRootMethodCall() ?>;
<?php if ($method->isInstanceCall()) : ?>
<?= $s3 ?>/** @var <?=$method->getRoot()?> $instance */
<?php endif?>
<?= $s3 . ($method->shouldReturn() ? 'return ' : '') ?><?= $method->getRootMethodCall() ?>;
}
<?php endforeach; ?>
}
<?php endforeach; ?>
@@ -48,26 +51,27 @@ namespace <?= $namespace === '__root' ? '' : trim($namespace, '\\') ?> {
<?php foreach ($namespaces_by_alias_ns as $namespace => $aliases) : ?>
namespace <?= $namespace === '__root' ? '' : trim($namespace, '\\') ?> {
<?php foreach ($aliases as $alias) : ?>
<?php if ($alias->getExtendsNamespace() === '\Illuminate\Database\Eloquent') : ?>
<?= $alias->getPhpDocTemplates(' ') ?>
<?php endif?>
<?= $alias->getClassType() ?> <?= $alias->getShortName() ?> extends <?= $alias->getExtends() ?> {<?php if ($alias->getExtendsNamespace() === '\Illuminate\Database\Eloquent') : ?>
<?php foreach ($alias->getMethods() as $method) : ?>
<?= trim($method->getDocComment(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
{<?php if ($method->getDeclaringClass() !== $method->getRoot()) : ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
<?php foreach ($aliases as $alias) : ?>
<?php if ($alias->getExtendsNamespace() === '\Illuminate\Database\Eloquent') : ?>
<?= "\n" . $alias->getPhpDocTemplates($s1) . "\n" ?>
<?php endif?>
<?= $s1 . $alias->getClassType() ?> <?= $alias->getShortName() ?> extends <?= $alias->getExtends() ?> {<?php if ($alias->getExtendsNamespace() === '\Illuminate\Database\Eloquent') : ?>
<?php foreach ($alias->getMethods() as $method) : ?>
<?= $s2 . trim($method->getDocComment($s2)) . "\n" ?>
<?= $s2 ?>public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>)
<?= $s2?>{<?php if ($method->getDeclaringClass() !== $method->getRoot()) : ?>
<?= $s2 ?>//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
<?php if ($method->isInstanceCall()) : ?>
/** @var <?=$method->getRoot()?> $instance */
<?php endif?>
<?= $method->shouldReturn() ? 'return ' : '' ?><?= $method->getRootMethodCall() ?>;
}
<?php endforeach; ?>
<?php endif; ?>}
<?php endforeach; ?>
<?php if ($method->isInstanceCall()) : ?>
<?= $s3 ?>/** @var <?=$method->getRoot()?> $instance */
<?php endif?>
<?= $s3 . ($method->shouldReturn() ? 'return ' : '') ?><?= $method->getRootMethodCall() ?>;
<?= $s2 ?>}
<?php endforeach; ?>
<?php endif; ?>}
<?php endforeach; ?>
}
<?php endforeach; ?>
+24
View File
@@ -21,6 +21,14 @@ namespace PHPSTORM_META {
]));
<?php endforeach; ?>
<?php foreach ($configMethods as $method) : ?>
override(<?= $method ?>, map([
<?php foreach ($configValues as $name => $value) : ?>
'<?= $name ?>' => '<?= $value ?>',
<?php endforeach; ?>
]));
<?php endforeach; ?>
<?php if (count($factories)) : ?>
override(\factory(0), map([
'' => '@FactoryBuilder',
@@ -65,4 +73,20 @@ namespace PHPSTORM_META {
override(\tap(0), type(0));
override(\optional(0), type(0));
<?php if (isset($expectedArgumentSets)): ?>
<?php foreach ($expectedArgumentSets as $name => $argumentsList) : ?>
registerArgumentsSet('<?= $name ?>', <?php foreach ($argumentsList as $i => $arg) : ?><?php if($i % 5 == 0) {
echo "\n";
} ?><?= var_export($arg, true); ?>,<?php endforeach; ?>);
<?php endforeach; ?>
<?php endif ?>
<?php if (isset($expectedArguments)) : ?>
<?php foreach ($expectedArguments as $function => $arguments) : ?>
<?php foreach ($arguments as $index => $argumentSet) : ?>
expectedArguments(<?= $function ?>, <?= $index ?>, argumentsSet('<?= $argumentSet ?>'));
<?php endforeach; ?>
<?php endforeach; ?>
<?php endif; ?>
}
+112 -16
View File
@@ -16,6 +16,7 @@ use Illuminate\Console\Command;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\View\Factory;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Collection;
use RuntimeException;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@@ -51,19 +52,29 @@ class MetaCommand extends Command
protected $config;
protected $methods = [
'new \Illuminate\Contracts\Container\Container',
'\Illuminate\Container\Container::makeWith(0)',
'\Illuminate\Contracts\Container\Container::get(0)',
'\Illuminate\Contracts\Container\Container::make(0)',
'\Illuminate\Contracts\Container\Container::makeWith(0)',
'\App::get(0)',
'\App::make(0)',
'\App::makeWith(0)',
'\app(0)',
'\resolve(0)',
'\Psr\Container\ContainerInterface::get(0)',
'new \Illuminate\Contracts\Container\Container',
'\Illuminate\Container\Container::makeWith(0)',
'\Illuminate\Contracts\Container\Container::get(0)',
'\Illuminate\Contracts\Container\Container::make(0)',
'\Illuminate\Contracts\Container\Container::makeWith(0)',
'\App::get(0)',
'\App::make(0)',
'\App::makeWith(0)',
'\app(0)',
'\resolve(0)',
'\Psr\Container\ContainerInterface::get(0)',
];
protected $configMethods = [
'\config()',
'\Illuminate\Config\Repository::get()',
'\Illuminate\Config\Repository::set()',
'\Illuminate\Support\Facades\Config::get()',
'\Illuminate\Support\Facades\Config::set()',
];
protected $templateCache = [];
/**
*
* @param Filesystem $files
@@ -108,7 +119,7 @@ class MetaCommand extends Command
}
$reflectionClass = new \ReflectionClass($concrete);
if (is_object($concrete) && !$reflectionClass->isAnonymous()) {
if (is_object($concrete) && !$reflectionClass->isAnonymous() && $abstract !== get_class($concrete)) {
$bindings[$abstract] = get_class($concrete);
}
} catch (\Throwable $e) {
@@ -120,10 +131,18 @@ class MetaCommand extends Command
$this->unregisterClassAutoloadExceptions($ourAutoloader);
$content = $this->view->make('meta', [
'bindings' => $bindings,
'methods' => $this->methods,
'factories' => $factories,
$configValues = $this->loadTemplate('configs')->pluck('value', 'name')->map(function ($value, $key) {
return gettype($value);
});
$content = $this->view->make('ide-helper::meta', [
'bindings' => $bindings,
'methods' => $this->methods,
'factories' => $factories,
'configMethods' => $this->configMethods,
'configValues' => $configValues,
'expectedArgumentSets' => $this->getExpectedArgumentSets(),
'expectedArguments' => $this->getExpectedArguments(),
])->render();
$filename = $this->option('filename');
@@ -167,6 +186,83 @@ class MetaCommand extends Command
return $autoloader;
}
protected function getExpectedArgumentSets()
{
return [
'configs' => $this->loadTemplate('configs')->pluck('name')->filter()->toArray(),
'routes' => $this->loadTemplate('routes')->pluck('name')->filter()->toArray(),
'views' => $this->loadTemplate('views')->pluck('key')->filter()->map(function ($value) {
return (string) $value;
})->toArray(),
'translations' => $this->loadTemplate('translations')->filter()->keys()->toArray(),
];
}
protected function getExpectedArguments()
{
return [
'\config()' => [
0 => 'configs',
],
'\Illuminate\Config\Repository::get()' => [
0 => 'configs',
],
'\Illuminate\Config\Repository::set()' => [
0 => 'configs',
],
'\Illuminate\Support\Facades\Config::get()' => [
0 => 'configs',
],
'\Illuminate\Support\Facades\Config::set()' => [
0 => 'configs',
],
'\route()' => [
0 => 'routes',
],
'\Illuminate\Support\Facades\Route::get()' => [
0 => 'routes',
],
'\Illuminate\Routing\Router::get()' => [
0 => 'routes',
],
'\view()' => [
0 => 'views',
],
'\Illuminate\Support\Facades\View::make()' => [
0 => 'views',
],
'\Illuminate\View\Factory::make()' => [
0 => 'views',
],
'\__()' => [
0 => 'translations',
],
'\trans()' => [
0 => 'translations',
],
'\Illuminate\Contracts\Translation\Translator::get()' => [
0 => 'translations',
],
];
}
/**
* @return Collection
*/
protected function loadTemplate($name)
{
if (!isset($this->templateCache[$name])) {
$file = __DIR__ . '/../../php-templates/' . basename($name) . '.php';
$value = $this->files->requireOnce($file) ?: [];
if (!$value instanceof Collection) {
$value = collect($value);
}
$this->templateCache[$name] = $value;
}
return $this->templateCache[$name];
}
/**
* Get the console command options.
*
+2 -4
View File
@@ -79,12 +79,11 @@ class Generator
public function generate()
{
$app = app();
return $this->view->make('helper')
return $this->view->make('ide-helper::helper')
->with('namespaces_by_extends_ns', $this->getAliasesByExtendsNamespace())
->with('namespaces_by_alias_ns', $this->getAliasesByAliasNamespace())
->with('real_time_facades', $this->getRealTimeFacades())
->with('helpers', $this->helpers)
->with('version', $app->version())
->with('include_fluent', $this->config->get('ide-helper.include_fluent', true))
->with('factories', $this->config->get('ide-helper.include_factory_builders') ? Factories::all() : [])
->render();
@@ -106,12 +105,11 @@ class Generator
}
$app = app();
return $this->view->make('helper')
return $this->view->make('ide-helper::helper')
->with('namespaces_by_extends_ns', [])
->with('namespaces_by_alias_ns', ['__root' => [$alias]])
->with('real_time_facades', [])
->with('helpers', '')
->with('version', $app->version())
->with('include_fluent', false)
->with('factories', [])
->render();
-26
View File
@@ -20,10 +20,6 @@ use Illuminate\Console\Events\CommandFinished;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Database\Events\MigrationsEnded;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\Engines\EngineResolver;
use Illuminate\View\Engines\PhpEngine;
use Illuminate\View\Factory;
use Illuminate\View\FileViewFinder;
class IdeHelperServiceProvider extends ServiceProvider implements DeferrableProvider
{
@@ -65,12 +61,6 @@ class IdeHelperServiceProvider extends ServiceProvider implements DeferrableProv
$configPath = __DIR__ . '/../config/ide-helper.php';
$this->mergeConfigFrom($configPath, 'ide-helper');
$this->app->when([GeneratorCommand::class, MetaCommand::class, ModelsCommand::class])
->needs(\Illuminate\Contracts\View\Factory::class)
->give(function () {
return $this->createLocalViewFactory();
});
$this->commands(
[
GeneratorCommand::class,
@@ -95,20 +85,4 @@ class IdeHelperServiceProvider extends ServiceProvider implements DeferrableProv
EloquentCommand::class,
];
}
/**
* @return Factory
*/
private function createLocalViewFactory()
{
$resolver = new EngineResolver();
$resolver->register('php', function () {
return new PhpEngine($this->app['files']);
});
$finder = new FileViewFinder($this->app['files'], [__DIR__ . '/../resources/views']);
$factory = new Factory($resolver, $finder, $this->app['events']);
$factory->addExtension('php', 'php');
return $factory;
}
}
@@ -27,7 +27,7 @@ class MetaCommandTest extends TestCase
$mockFileSystem
->shouldReceive('getRequire')
->andReturnUsing(function ($__path, $__data) {
->andReturnUsing(function ($__path, $__data = []) {
return (static function () use ($__path, $__data) {
extract($__data, EXTR_SKIP);
@@ -60,7 +60,7 @@ class MetaCommandTest extends TestCase
$mockFileSystem
->shouldReceive('getRequire')
->andReturnUsing(function ($__path, $__data) {
->andReturnUsing(function ($__path, $__data = []) {
return (static function () use ($__path, $__data) {
extract($__data, EXTR_SKIP);