Larastan: Mixin, scope detection in 0.6.11

Created on 23 Dec 2020  路  11Comments  路  Source: nunomaduro/larastan

  • Larastan Version: 0.6.11
  • Phpstan Version: 0.12.64
  • --level used: max (8)

Description

Since version 0.6.11, some scopes and mixins are no longer recognized.
As I had no issue with 0.6.10, I forked the repo and reverted 2581f3b and it's working again.

Laravel code where the issue was found

 // DB::connection() must be added to avoid errors on the following lines
DB::query()->from('users')->exists();
DB::getDriverName();

// $relation->getQuery() must be added
$relation->getModel();

// Scope issues in a Model class
public function scopeAvailable(EloquentBuilder $query): void
{
    // Scope not recognized
    $query->notCanceled()->where('foo', 'bar');
}

// Scope not recognized in a Nova Resource
public static function indexQuery(NovaRequest $request, EloquentBuilder $query): void
{
    return parent::indexQuery(
        $request,
        // Scope is not recognized
        $query->whereHasMissingConfig()
    );
}

Thank you

bug

Most helpful comment

With 0.6.11 the unknown methods no longer return DummyMethodReflection.

We've opened up a big Can of worms :)
This is not the first - nor the last issues - regarding this change.

Yeah, I know. But actually a good thing. It means Larastan wasn't understanding those codes at all previously. Now we can add support for it.

All 11 comments

Hi,

With 0.6.11 the unknown methods no longer return DummyMethodReflection. These cases weren't even working correctly on previous versions. Now we have the ability to see them.

// Scope issues in a Model class

public function scopeAvailable(EloquentBuilder $query): void
{
   // Scope not recognized
   $query->notCanceled()->where('foo', 'bar');
}

Larastan doesn't know which model to look for. For this reason, EloquentBuilder is a generic class. So you can tell it which model this builder operates on. /** @param EloquentBuilder<User> $query */ above the method definition would fix that.

// Scope not recognized in a Nova Resource

public static function indexQuery(NovaRequest $request, EloquentBuilder $query): void
{
    return parent::indexQuery(
        $request,
        // Scope is not recognized
        $query->whereHasMissingConfig()
    );
}

Same as above. /** @param EloquentBuilder<User> $query */ should fix it.

The other two issues needs more detailed look.

// $relation->getQuery() must be added
$relation->getModel();

For this case, can you tell me how do you get the $relation? What is its type?

With 0.6.11 the unknown methods no longer return DummyMethodReflection.

We've opened up a big Can of worms :)
This is not the first - nor the last - issue regarding this change.

With 0.6.11 the unknown methods no longer return DummyMethodReflection.

We've opened up a big Can of worms :)
This is not the first - nor the last issues - regarding this change.

Yeah, I know. But actually a good thing. It means Larastan wasn't understanding those codes at all previously. Now we can add support for it.

Hi,

Adding the generic on the eloquent builder did the job for the scope issues.

At the end of the day, I think it was a good idea to open the Can of worms :) Adding generic on the EloquentBuilder seems natural.

// $relation->getQuery() must be added
$relation->getModel();

For this case, can you tell me how do you get the $relation? What is its type?

Call to an undefined method Illuminate\Database\Eloquent\Relations\Relation::getModel().

/** @var \Illuminate\Database\Eloquent\Relations\Relation $relation */
$relation = $model->{$viaRelationship}();

The Relation class has a @mixin \Illuminate\Database\Eloquent\Builder. The builder contains the getModel method.

$driver = DB::getDriverName();
Call to an undefined static method Illuminate\Support\Facades\DB::getDriverName().

Maybe related to this #704?

Maybe related to this #704?

PHPStan has built-in @mixin support.
https://github.com/phpstan/phpstan-src/commit/b02ee1444440ed995c17171c456feec2c56e0cb2

I think if you type hint a specific implementation of Relation it should work. Relation class is abstract, so Larastan may skip the checks on it.

Yeah I saw that in the PR, but as the forwarding is not recognized I though that larastan's @mixin support was maybe better or more suitable to Laravel magic.

I think if you type hint a specific implementation of Relation it should work. Relation class is abstract, so Larastan may skip the checks on it.

Indeed, it's working with a concrete relation class.

So the question is "why did the bevahiour changed?".

Everything is fixed here I guess. Please open a new issue if you have new errors.

Yep everthing is fixed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mariomka picture mariomka  路  4Comments

grcasanova picture grcasanova  路  4Comments

Braunson picture Braunson  路  4Comments

danielcosta picture danielcosta  路  4Comments

szepeviktor picture szepeviktor  路  4Comments