rector-src icon indicating copy to clipboard operation
rector-src copied to clipboard

fix: skip non-native methods

Open calebdw opened this issue 1 month ago • 11 comments

Hello!

This prevents ALL non-native methods (not just those from annotations) from being converted to first class callables:

This change resulted in the following phpstan error:

image image

calebdw avatar Dec 09 '25 19:12 calebdw

Thanks :+1:

Can you also add test fixture that verifies this change? Just so we don't accidentally change it in the future.

TomasVotruba avatar Dec 09 '25 20:12 TomasVotruba

It's already testing by the existing annotation fixture---I didn't want to write a whole PHPStan extension just to test something other than a AnnotationMethodReflection (e.g., Laravel's macro system)

calebdw avatar Dec 09 '25 21:12 calebdw

No need for extension. What is "non-native method" apart the @method?

TomasVotruba avatar Dec 09 '25 22:12 TomasVotruba

This is a Macro:

MenuItem::macro('reportable', static function (string $class): MenuItem {
    if (! class_exists($class) || ! is_a($class, Reportable::class, true)) {
        throw new RuntimeException("Invalid reportable class [{$class}].");
    }

    $instance = resolve($class);

    return MenuItem::make($instance->name())
        ->canSeeWith($instance::permissions())
        ->path($instance->route());
});

See: https://github.com/larastan/larastan/blob/3.x/src/Methods/MacroMethodsClassReflectionExtension.php

calebdw avatar Dec 10 '25 00:12 calebdw

So in short, the reportable() does not exist?

TomasVotruba avatar Dec 10 '25 09:12 TomasVotruba

Yes, it's not an actual method, it's a closure that is called through __call: https://github.com/laravel/framework/blob/12.x/src/Illuminate/Macroable/Traits/Macroable.php

Note, this does not actually result in a php error, so I'm not sure why phpstan added a check for it. I'm thinking about just globally ignoring callable.nonNativeMethod, but I figured that rector should not make changes that result in phpstan errors

calebdw avatar Dec 10 '25 14:12 calebdw

I see. How would you implement it if no Rector nor PHPStan would exists?

TomasVotruba avatar Dec 10 '25 15:12 TomasVotruba

I'm not sure what you're asking? Implement what?

calebdw avatar Dec 10 '25 15:12 calebdw

The change this rule is doing. How would you upgrade code yourself manually, without any tooling.

TomasVotruba avatar Dec 10 '25 17:12 TomasVotruba

I would be fine with this upgrade in favor of the first class callable, however, other people might not like it since it throws phpstan errors.

This PR just ensures that an actual method exists on the declaring class and that the method in not a macro or annotation

calebdw avatar Dec 10 '25 20:12 calebdw

Allright, lets go this way then.

We still need a test fixture to backup this change.

TomasVotruba avatar Dec 10 '25 21:12 TomasVotruba

Just checking, as there is no feedback in past 2 weeks. Any plan to finish this? I want to avoid staling failing PRs here.

TomasVotruba avatar Dec 25 '25 22:12 TomasVotruba

Yes, I plan to, but it's Christmas and I'm sick---I haven't had time yet to write a custom phpstan extension just to test this.

If you'd like to merge now then feel free, there's an existing passing test that covers this.

calebdw avatar Dec 25 '25 22:12 calebdw

To be transparent, I've just globally ignored these phpstan errors in my config as I don't care to enforce them and it doesn't cause any sort of runtime error

Not sure these phpstan rules were added in the first place...

calebdw avatar Dec 25 '25 22:12 calebdw

I see, let's give this a go then :+1:

TomasVotruba avatar Dec 25 '25 22:12 TomasVotruba

Sounds good, thank you sir and have a Merry Christmas!!

calebdw avatar Dec 25 '25 22:12 calebdw

Thank you :+1: Merry Christmas to you and your family :christmas_tree:

TomasVotruba avatar Dec 25 '25 22:12 TomasVotruba