Skip to content
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

[11.x] chore: update to PHPStan Level 1 #51956

Merged
merged 3 commits into from
Aug 1, 2024
Merged

Conversation

calebdw
Copy link
Contributor

@calebdw calebdw commented Jun 29, 2024

Hello!

This PR cleans up some bugs and brings the framework to PHPStan Level 1.

For reference, here is all of the errors on 11.x:

 ------ ------------------------------------------------------------------------- 
  Line   Illuminate/Auth/Access/Gate.php                                          
 ------ ------------------------------------------------------------------------- 
  590    Variable $result on left side of ??= always exists and is not nullable.  
         🪪  nullCoalesce.variable                                                
 ------ ------------------------------------------------------------------------- 

 ------ --------------------------------------------------------------- 
  Line   Illuminate/Bus/PendingBatch.php                                
 ------ --------------------------------------------------------------- 
  361    Variable $batch in isset() always exists and is not nullable.  
         🪪  isset.variable                                             
 ------ --------------------------------------------------------------- 

 ------ -------------------------------------------------------------------------------------------- 
  Line   Illuminate/Cache/RetrievesMultipleKeys.php (in context of class Illuminate\Cache\ApcStore)  
 ------ -------------------------------------------------------------------------------------------- 
  24     Method Illuminate\Cache\ApcStore::get() invoked with 2 parameters, 1 required.              
         🪪  arguments.count                                                                         
 ------ -------------------------------------------------------------------------------------------- 

 ------ ---------------------------------------------------------------------------------------------- 
  Line   Illuminate/Cache/RetrievesMultipleKeys.php (in context of class Illuminate\Cache\ArrayStore)  
 ------ ---------------------------------------------------------------------------------------------- 
  24     Method Illuminate\Cache\ArrayStore::get() invoked with 2 parameters, 1 required.              
         🪪  arguments.count                                                                           
 ------ ---------------------------------------------------------------------------------------------- 

 ------ ------------------------------------------------------------------------------------------------- 
  Line   Illuminate/Cache/RetrievesMultipleKeys.php (in context of class Illuminate\Cache\DatabaseStore)  
 ------ ------------------------------------------------------------------------------------------------- 
  24     Method Illuminate\Cache\DatabaseStore::get() invoked with 2 parameters, 1 required.              
         🪪  arguments.count                                                                              
 ------ ------------------------------------------------------------------------------------------------- 

 ------ --------------------------------------------------------------------------------------------- 
  Line   Illuminate/Cache/RetrievesMultipleKeys.php (in context of class Illuminate\Cache\FileStore)  
 ------ --------------------------------------------------------------------------------------------- 
  24     Method Illuminate\Cache\FileStore::get() invoked with 2 parameters, 1 required.              
         🪪  arguments.count                                                                          
 ------ --------------------------------------------------------------------------------------------- 

 ------ --------------------------------------------------------------------------------------------- 
  Line   Illuminate/Cache/RetrievesMultipleKeys.php (in context of class Illuminate\Cache\NullStore)  
 ------ --------------------------------------------------------------------------------------------- 
  24     Method Illuminate\Cache\NullStore::get() invoked with 2 parameters, 1 required.              
         🪪  arguments.count                                                                          
 ------ --------------------------------------------------------------------------------------------- 

 ------ ----------------------------------------------------------------------- 
  Line   Illuminate/Collections/Collection.php                                  
 ------ ----------------------------------------------------------------------- 
  601    Variable $value on left side of ?? always exists and is not nullable.  
         🪪  nullCoalesce.variable                                              
 ------ ----------------------------------------------------------------------- 

 ------ --------------------------------------------------------- 
  Line   Illuminate/Console/resources/views/components/alert.php  
 ------ --------------------------------------------------------- 
  2      Variable $content might not be defined.                  
         🪪  variable.undefined                                   
 ------ --------------------------------------------------------- 

 ------ --------------------------------------------------------------- 
  Line   Illuminate/Console/resources/views/components/bullet-list.php  
 ------ --------------------------------------------------------------- 
  2      Variable $elements might not be defined.                       
         🪪  variable.undefined                                         
 ------ --------------------------------------------------------------- 

 ------ -------------------------------------------------------- 
  Line   Illuminate/Console/resources/views/components/line.php  
 ------ -------------------------------------------------------- 
  1      Variable $marginTop might not be defined.               
         🪪  variable.undefined                                  
  2      Variable $bgColor might not be defined.                 
         🪪  variable.undefined                                  
  2      Variable $fgColor might not be defined.                 
         🪪  variable.undefined                                  
  2      Variable $title might not be defined.                   
         🪪  variable.undefined                                  
  3      Variable $title might not be defined.                   
         🪪  variable.undefined                                  
  6      Variable $content might not be defined.                 
         🪪  variable.undefined                                  
 ------ -------------------------------------------------------- 

 ------ --------------------------------------------------------------------- 
  Line   Illuminate/Console/resources/views/components/two-column-detail.php  
 ------ --------------------------------------------------------------------- 
  3      Variable $first might not be defined.                                
         🪪  variable.undefined                                               
  6      Variable $second might not be defined.                               
         🪪  variable.undefined                                               
 ------ --------------------------------------------------------------------- 

 ------ ------------------------------------------------------ 
  Line   Illuminate/Database/Connectors/ConnectionFactory.php  
 ------ ------------------------------------------------------ 
  191    Variable $e might not be defined.                     
         🪪  variable.undefined                                
 ------ ------------------------------------------------------ 

 ------ --------------------------------------------------- 
  Line   Illuminate/Database/Connectors/MySqlConnector.php  
 ------ --------------------------------------------------- 
  83     Variable $database might not be defined.           
         🪪  variable.undefined                             
  83     Variable $host might not be defined.               
         🪪  variable.undefined                             
  84     Variable $database might not be defined.           
         🪪  variable.undefined                             
  84     Variable $host might not be defined.               
         🪪  variable.undefined                             
 ------ --------------------------------------------------- 

 ------ ------------------------------------------------------ 
  Line   Illuminate/Database/Connectors/PostgresConnector.php  
 ------ ------------------------------------------------------ 
  169    Variable $database might not be defined.              
         🪪  variable.undefined                                
 ------ ------------------------------------------------------ 

 ------ --------------------------------------------------------------------------- 
  Line   Illuminate/Database/Console/DatabaseInspectionCommand.php                  
 ------ --------------------------------------------------------------------------- 
  66     Variable $database on left side of ??= always exists and is not nullable.  
         🪪  nullCoalesce.variable                                                  
 ------ --------------------------------------------------------------------------- 

 ------ ----------------------------------------------------------------------------------------------------------- 
  Line   Illuminate/Database/Eloquent/Attributes/ObservedBy.php                                                     
 ------ ----------------------------------------------------------------------------------------------------------- 
  16     Constructor of class Illuminate\Database\Eloquent\Attributes\ObservedBy has an unused parameter $classes.  
         🪪  constructor.unusedParameter                                                                            
 ------ ----------------------------------------------------------------------------------------------------------- 

 ------ --------------------------------------------------------------------------------------------------------- 
  Line   Illuminate/Database/Eloquent/Attributes/ScopedBy.php                                                     
 ------ --------------------------------------------------------------------------------------------------------- 
  16     Constructor of class Illuminate\Database\Eloquent\Attributes\ScopedBy has an unused parameter $classes.  
         🪪  constructor.unusedParameter                                                                          
 ------ --------------------------------------------------------------------------------------------------------- 

 ------ ------------------------------------------------------------------------------------------------------------------ 
  Line   Illuminate/Database/Eloquent/Concerns/HasAttributes.php (in context of class Illuminate\Database\Eloquent\Model)  
 ------ ------------------------------------------------------------------------------------------------------------------ 
  398    Variable $relation might not be defined.                                                                          
         🪪  variable.undefined                                                                                            
  1218   Variable $value in isset() always exists and is not nullable.                                                     
         🪪  isset.variable                                                                                                
  1335   Variable $value on left side of ?? always exists and is not nullable.                                             
         🪪  nullCoalesce.variable                                                                                         
  1399   Call to an undefined static method Illuminate\Support\Facades\Hash::verifyConfiguration().                        
         🪪  staticMethod.notFound                                                                                         
 ------ ------------------------------------------------------------------------------------------------------------------ 

 ------ --------------------------------------------------------------------------------------------------------------------- 
  Line   Illuminate/Database/Eloquent/Concerns/HasRelationships.php (in context of class Illuminate\Database\Eloquent\Model)  
 ------ --------------------------------------------------------------------------------------------------------------------- 
  320    Variable $ownerKey on left side of ?? always exists and is not nullable.                                             
         🪪  nullCoalesce.variable                                                                                            
 ------ --------------------------------------------------------------------------------------------------------------------- 

 ------ ---------------------------------------------------------------------------------------------------------------------------------------- 
  Line   Illuminate/Database/Eloquent/Relations/Concerns/CanBeOneOfMany.php (in context of class Illuminate\Database\Eloquent\Relations\HasOne)  
 ------ ---------------------------------------------------------------------------------------------------------------------------------------- 
  217    Method Illuminate\Database\Eloquent\Relations\HasOne::addOneOfManySubQueryConstraints() invoked with 4 parameters, 1-3 required.        
         🪪  arguments.count                                                                                                                     
  240    Method Illuminate\Database\Eloquent\Relations\HasOne::addOneOfManyJoinSubQueryConstraints() invoked with 2 parameters, 1 required.      
         🪪  arguments.count                                                                                                                     
 ------ ---------------------------------------------------------------------------------------------------------------------------------------- 

 ------ ------------------------------------------------------------------------------------------------------------------------------------------ 
  Line   Illuminate/Database/Eloquent/Relations/Concerns/CanBeOneOfMany.php (in context of class Illuminate\Database\Eloquent\Relations\MorphOne)  
 ------ ------------------------------------------------------------------------------------------------------------------------------------------ 
  217    Method Illuminate\Database\Eloquent\Relations\MorphOne::addOneOfManySubQueryConstraints() invoked with 4 parameters, 1-3 required.        
         🪪  arguments.count                                                                                                                       
  240    Method Illuminate\Database\Eloquent\Relations\MorphOne::addOneOfManyJoinSubQueryConstraints() invoked with 2 parameters, 1 required.      
         🪪  arguments.count                                                                                                                       
 ------ ------------------------------------------------------------------------------------------------------------------------------------------ 

 ------ ---------------------------------------------------------------- 
  Line   Illuminate/Database/Query/Grammars/Grammar.php                  
 ------ ---------------------------------------------------------------- 
  997    Variable $offset in isset() always exists and is not nullable.  
         🪪  isset.variable                                              
  1020   Variable $offset in isset() always exists and is not nullable.  
         🪪  isset.variable                                              
 ------ ---------------------------------------------------------------- 

 ------ ---------------------------------------------------------------- 
  Line   Illuminate/Database/Query/Grammars/MySqlGrammar.php             
 ------ ---------------------------------------------------------------- 
  137    Variable $offset in isset() always exists and is not nullable.  
         🪪  isset.variable                                              
  167    Variable $offset in isset() always exists and is not nullable.  
         🪪  isset.variable                                              
 ------ ---------------------------------------------------------------- 

 ------ ---------------------------------------------------------------------------------------------- 
  Line   Illuminate/Database/Schema/Builder.php                                                        
 ------ ---------------------------------------------------------------------------------------------- 
  147    Method Illuminate\Database\Schema\Builder::getTables() invoked with 1 parameter, 0 required.  
         🪪  arguments.count                                                                           
 ------ ---------------------------------------------------------------------------------------------- 

 ------ ----------------------------------------------------------------------------------- 
  Line   Illuminate/Database/Schema/Grammars/Grammar.php                                    
 ------ ----------------------------------------------------------------------------------- 
  328    Method Illuminate\Database\Grammar::wrap() invoked with 2 parameters, 1 required.  
         🪪  arguments.count                                                                
 ------ ----------------------------------------------------------------------------------- 

 ------ -------------------------------------------------------------------------------------- 
  Line   Illuminate/Foundation/Console/DownCommand.php                                         
 ------ -------------------------------------------------------------------------------------- 
  90     Method Illuminate\Console\Command::option() invoked with 2 parameters, 0-1 required.  
         🪪  arguments.count                                                                   
 ------ -------------------------------------------------------------------------------------- 

 ------ --------------------------------------------------------------------- 
  Line   Illuminate/Http/UploadedFile.php                                     
 ------ --------------------------------------------------------------------- 
  66     Variable $name on left side of ?? always exists and is always null.  
         🪪  nullCoalesce.variable                                            
 ------ --------------------------------------------------------------------- 

 ------ ------------------------------------------------------------------------------------- 
  Line   Illuminate/Log/Context/ContextServiceProvider.php                                    
 ------ ------------------------------------------------------------------------------------- 
  30     Call to an undefined static method Illuminate\Support\Facades\Context::dehydrate().  
         🪪  staticMethod.notFound                                                            
  39     Call to an undefined static method Illuminate\Support\Facades\Context::hydrate().    
         🪪  staticMethod.notFound                                                            
 ------ ------------------------------------------------------------------------------------- 

 ------ --------------------------------------------------------------- 
  Line   Illuminate/Mail/Mailer.php                                     
 ------ --------------------------------------------------------------- 
  422    Variable $view in isset() always exists and is not nullable.   
         🪪  isset.variable                                             
  426    Variable $plain in isset() always exists and is not nullable.  
         🪪  isset.variable                                             
  430    Variable $raw in isset() always exists and is not nullable.    
         🪪  isset.variable                                             
 ------ --------------------------------------------------------------- 

 ------ ---------------------------------------------------------------------- 
  Line   Illuminate/Notifications/Messages/SimpleMessage.php                   
 ------ ---------------------------------------------------------------------- 
  242    Variable $line on left side of ?? always exists and is not nullable.  
         🪪  nullCoalesce.variable                                             
 ------ ---------------------------------------------------------------------- 

 ------ ---------------------------------------------------------- 
  Line   Illuminate/Notifications/resources/views/email.blade.php  
 ------ ---------------------------------------------------------- 
  22     Variable $level might not be defined.                     
         🪪  variable.undefined                                    
 ------ ---------------------------------------------------------- 

 ------ ------------------------------------------------------ 
  Line   Illuminate/Routing/Middleware/SubstituteBindings.php  
 ------ ------------------------------------------------------ 
  43     Variable $route might not be defined.                 
         🪪  variable.undefined                                
  44     Variable $route might not be defined.                 
         🪪  variable.undefined                                
 ------ ------------------------------------------------------ 

 ------ ------------------------------------------------------------------------- 
  Line   Illuminate/Routing/Route.php                                             
 ------ ------------------------------------------------------------------------- 
  804    Variable $prefix on left side of ??= always exists and is not nullable.  
         🪪  nullCoalesce.variable                                                
 ------ ------------------------------------------------------------------------- 

 ------ ---------------------------------------- 
  Line   Illuminate/Routing/RouteCollection.php  
 ------ ---------------------------------------- 
  68     Variable $method might not be defined.  
         🪪  variable.undefined                  
 ------ ---------------------------------------- 

 ------ ------------------------------------------------- 
  Line   Illuminate/Testing/TestResponse.php              
 ------ ------------------------------------------------- 
  872    Variable $errorMissing might not be defined.     
         🪪  variable.undefined                           
  874    Variable $expectedMessage might not be defined.  
         🪪  variable.undefined                           
 ------ ------------------------------------------------- 

 ------ --------------------------------------------------------------------- 
  Line   Illuminate/Translation/Translator.php                                
 ------ --------------------------------------------------------------------- 
  279    Variable $key on left side of ?? always exists and is not nullable.  
         🪪  nullCoalesce.variable                                            
  280    Variable $key on left side of ?? always exists and is not nullable.  
         🪪  nullCoalesce.variable                                            
 ------ --------------------------------------------------------------------- 

 ------ -------------------------------------------------------------------------------------------------------------------- 
  Line   Illuminate/View/Compilers/Concerns/CompilesLoops.php (in context of class Illuminate\View\Compilers\BladeCompiler)  
 ------ -------------------------------------------------------------------------------------------------------------------- 
  28     Variable $expression on left side of ?? always exists and is not nullable.                                          
         🪪  nullCoalesce.variable                                                                                           
  103    Variable $expression on left side of ?? always exists and is not nullable.                                          
         🪪  nullCoalesce.variable                                                                                           
 ------ -------------------------------------------------------------------------------------------------------------------- 

 [ERROR] Found 61 errors                                                                                                

Thanks!

$this->addOneOfManySubQueryConstraints($subQuery, $groupBy, $columns, $aggregate);
$this->addOneOfManySubQueryConstraints($subQuery, column: null, aggregate: $aggregate);
Copy link
Contributor Author

@calebdw calebdw Jun 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a tricky one:

The method only accepts 3 arguments while 4 were being passed in:

/**
* Add constraints for inner join subselect for one of many relationships.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string|null $column
* @param string|null $aggregate
* @return void
*/
abstract public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null);

However, the only two implementations don't even use the last two arguments:

public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)
{
$query->addSelect($this->foreignKey);
}

public function addOneOfManySubQueryConstraints(Builder $query, $column = null, $aggregate = null)
{
$query->addSelect($this->foreignKey, $this->morphType);
}

Additionally, the $groupBy and $columns variables that were being passed could be arrays whereas the $column parameter can only be string|null---given all this I just decided to pass null here for the column parameter.

However, I'm open to other ideas if there's something more meaningful we can pass.

@calebdw calebdw force-pushed the phpstan_1 branch 3 times, most recently from 3e55014 to 2ee3bbf Compare July 24, 2024 14:59
@driesvints
Copy link
Member

@calebdw don't forget to mark the PR ready for review if you need a new one.

@calebdw
Copy link
Contributor Author

calebdw commented Jul 26, 2024

Will do @driesvints!

@calebdw calebdw marked this pull request as ready for review July 26, 2024 14:33
@taylorotwell taylorotwell merged commit 582955c into laravel:11.x Aug 1, 2024
29 checks passed
@calebdw
Copy link
Contributor Author

calebdw commented Aug 1, 2024

Thanks!

@calebdw calebdw deleted the phpstan_1 branch August 1, 2024 18:56
@taylorotwell
Copy link
Member

This has broken the actions and are facades appear to be all messed up.

@calebdw
Copy link
Contributor Author

calebdw commented Aug 1, 2024

I'll take a look

@calebdw
Copy link
Contributor Author

calebdw commented Aug 1, 2024

@taylorotwell, all of the tests passed when this was merged so what was the issue?

image

@calebdw
Copy link
Contributor Author

calebdw commented Aug 1, 2024

It looks like there might be a bug in the laravel/facade-documenter parsing?

For static forwarding, facades should use @mixin instead of @see---then the rest of the method declarations are likely not necessary as forwarding should work as intended.

If all the facades properly use the @mixin tag then I don't see a need for the laravel/facade-documenter action to run anymore

@timacdonald
Copy link
Member

@calebdw, I've fixed the documenter so that it won't bork the docblocks when it cannot document things properly.

I don't feel we should use @mixin on Facades. We should continue to use the @see.

Most tooling I have seen interprets @mixin as "make the static methods available as static methods and make the instance methods available as instance methods". Essentially making the class a proxy layer.

I know that PHPStan have a different interpretation of this that works with Facades, which is "when __callStatic is defined, make non-static methods available statically".

However, because of this difference in interpretation, language servers all work differently. If we were to use @mixin, anyone using intelephense, for example, would have broken completions. That is VSCode, Sublime, (neo)Vim, and many other editors.

I don't think we should appease PHPStan while making the development experience worse for a lot of humans.

Screenshot 2024-08-05 at 10 49 16 Screenshot 2024-08-05 at 10 49 29

On a personal note, I believe that PHPStan should have introduced a static-mixin tag for this behaviour. PHPStan is intended to tell you if you code is "correct". It is possible to create broken code by using @mixin and defining __callStatic and PHPStan will tell me everything is okay.

Here is a quick example of PHPStan showing everything is okay but it is not due to the weird @mixin interpretation: https://phpstan.org/r/cad543f6-69d1-4781-9988-29688893d7ca

@calebdw
Copy link
Contributor Author

calebdw commented Aug 5, 2024

On a personal note, I believe that PHPStan should have introduced a static-mixin tag for this behaviour.

There's an open PR for this: phpstan/phpstan#11259

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants