-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add better support for macros and mixins #1006
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey 👋 very cool approach!
I left some in-line feedback.
Also: All / some? of the whitespace changes in resources/views/helper.php
generate a vastly differently indented _ide_helper.php
file:
- run master, generate _ide_helper.php , make a copy
- run your PR, generate _ide_helper.php
- diff them
- 💥
People tend to commit this file and those two versions are essentially "uncomparable".
I don't want to say it's the most important thing in the world, but some of those changes just look unnecessary anyway, so you might want to massage this a bit.
Maybe also rebase against master, there were some formatting changes already, creating merge conflicts currently.
Seeing that I had some exceptions thrown my way, we definitely should come up with some tests for this.
src/Macro.php
Outdated
|
||
// Add macro parameters | ||
foreach ($method->getParameters() as $parameter) { | ||
$type = $parameter->hasType() ? $parameter->getType() : 'mixed'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
./artisan ide-helper:generate
ErrorException
Function ReflectionType::__toString() is deprecated
at vendor/barryvdh/laravel-ide-helper/src/Macro.php:45
41|
42| // Add macro parameters
43| foreach ($method->getParameters() as $parameter) {
44| $type = $parameter->hasType() ? $parameter->getType() : 'mixed';
> 45| $type .= $parameter->hasType() && $parameter->getType()->allowsNull() ? '|null' : '';
46|
47| $name = $parameter->isVariadic() ? '...' : '';
48| $name .= '$' . $parameter->getName();
49|
+21 vendor frames
22 artisan:37
Illuminate\Foundation\Console\Kernel::handle()
I guess this is dependent on the PHP version? It's "just" a deprecation but people might run with E_ALL and thus trip over this.
This fixes it:
$type = $parameter->hasType() ? $parameter->getType() : 'mixed'; | |
$type = $parameter->hasType() ? $parameter->getType()->getName() : 'mixed'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed this to your suggestion.
src/Macro.php
Outdated
|
||
// Add macro return type | ||
if ($method->hasReturnType()) { | ||
$type = $method->getReturnType(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I have the same issue:
$ ./artisan ide-helper:generate
ErrorException
Function ReflectionType::__toString() is deprecated
at vendor/barryvdh/laravel-ide-helper/src/Macro.php:56
52|
53| // Add macro return type
54| if ($method->hasReturnType()) {
55| $type = $method->getReturnType();
> 56| $type .= $method->getReturnType()->allowsNull() ? '|null' : '';
57|
58| $this->phpdoc->appendTag(Tag::createInstance("@return {$type}"));
59| }
60| }
+21 vendor frames
22 artisan:37
Illuminate\Foundation\Console\Kernel::handle()
$type = $method->getReturnType(); | |
$type = $method->getReturnType()->getName(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed this to your suggestion.
I have adopted all of your suggestions. But I also have changed many things because I noticed that classes could be duplicate in the helper file if they have macros (Facades, Arr, Str, ...). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach LGTM and I only have some minor feedback; additionally:
- can you please rebase on master and solve the merge conflict?
- re-add the nice README entry you had?
- add a changelog entry?
Yes, we now have a changelog 😄
Thanks and sorry for the long delay, rest assured unless I get hit by a bus, the next feedback will be quicker 🤞
src/Generator.php
Outdated
*/ | ||
protected function getMacroableClasses(Collection $aliases) | ||
{ | ||
return collect(get_declared_classes()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
collect
Please don't use global helpers, it's a bad practice doing this in libraries. None of the helpers from Illuminate\Support\helpers.php
is currently in use.
Using the collection of course is fine!
src/Generator.php
Outdated
$traits = class_uses($class); | ||
|
||
// Filter only classes with the macroable trait | ||
return isset($traits['Illuminate\Support\Traits\Macroable']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use Illuminate\Support\Traits\Macroable::class
and also import it, thanks!
$type = $parameter->hasType() ? $parameter->getType()->getName() : 'mixed'; | ||
$type .= $parameter->hasType() && $parameter->getType()->allowsNull() ? '|null' : ''; | ||
|
||
$name = $parameter->isVariadic() ? '...' : ''; | ||
$name .= '$' . $parameter->getName(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very clean but also duplicate code of what happens in \Barryvdh\LaravelIdeHelper\Method::getParameters
- the other method seems more feature-complete though I can't say if this is necessary
- but it's written in a way which makes it not easily re-usable AFAICS, i.e. you just can't call it.
Would you be interested comparing the the two approaches and see if yours is missing something? E.g. default values seems to be handled, etc.
Unifying this is topic for a different PR IMHO and shouldn't be done here.
src/Generator.php
Outdated
$reflection = new ReflectionClass($class); | ||
|
||
// Filter out internal classes and class aliases | ||
return !$reflection->isInternal() && $reflection->getName() == $class; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return !$reflection->isInternal() && $reflection->getName() == $class; | |
return !$reflection->isInternal() && $reflection->getName() === $class; |
src/Generator.php
Outdated
|
||
// Filter out aliases | ||
return !$aliases->first(function (Alias $alias) use ($class) { | ||
return $alias->getExtends() == $class; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return $alias->getExtends() == $class; | |
return $alias->getExtends() === $class; |
Btw, do we still need the code in // Check if the class is macroable
$traits = collect($reflection->getTraitNames());
if ($traits->contains('Illuminate\Support\Traits\Macroable')) {
$properties = $reflection->getStaticProperties();
$macros = isset($properties['macros']) ? $properties['macros'] : [];
foreach ($macros as $macro_name => $macro_func) {
if (!in_array($macro_name, $this->usedMethods)) {
// Add macros
$this->methods[] = new Macro(
$this->getMacroFunction($macro_func),
$this->alias,
$reflection,
$macro_name,
$this->interfaces
);
$this->usedMethods[] = $macro_name;
}
}
} |
I have done a rebase and applied all your suggestions. |
Yes, this code is still needed. My old approach had an own function to detect macros but my new approach uses this part of the code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, IMHO this looks great \o/
@barryvdh IMHO we're good to merge here!
Co-authored-by: Dominik Krämer <[email protected]>
I have added macro support for all macroable classes, not only the alias classes.
But this only works if the macros are declared in any loaded service provider and type hinting is used.
Also no description is possible, only parameter and return types.