chore: Setup PHPStan Level 5 - #3553
Conversation
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
There was a problem hiding this comment.
Okay this was a big one.
Most of this looks great, a few things came up that we need to take a decision on:
- I prefer not switching from the DatabaseInterface to the Database abstract. The interface is guaranteed to be bound into ioc, that's the whole idea of the interface. Using the implementation everywhere seems off to me. If it really helps we can typehint the property with that class as well
DatabaseInterface|Connection, but dropping the interface - especially in construct arguments typehints - is going to bite us in the long run. - I noticed some places where full class names were used and not imported, let's try to import all the things.
- Some changes to go from filesystem Cloud interface to Filesystem aren't correct. Only the Cloud interface has the
urlmethod we need. We cannot drop that or we'll break things. - I saw that we are doing
existsandgetordeletesometimes. If possible it would be a huge deal in cutting latency if we can use onlygetanddeleteand capture any thrown errors to reduce api calls to cloud based storage. - In some changes we moved from
selftostatic. Now I can be wrong, but I thought that doing that enforces the returned class to be this implementation and not any class extending this implementation. This would be a huge deal in extensibility and being able to apply raw/higher level overrides.
|
(@luceos gonna reply here globally here about some of the issues raised here) Database connection interface // The interface
interface ConnectionInterface { ... }
// Illuminate implementation
abstract class Connection extends ConnectionInterface
{
public function getSchemaBuilder(); // doesn't exist in the interface
}
// Solution 1: actually inject the implementation because that's what we actually expect.
class Example
{
public function __construct(Connection $db) { ... }
public function example()
{
$this->db->getSchemaBuilder()->...
}
}
// Solution 2: hack around it everywhere we expect implementation-specific instances.
class Example
{
public function __construct(ConnetionInterface $db) { ... }
public function example()
{
/** @var Connection */
$db = $this->db;
$db->getSchemaBuilder()->...
}
}Filesystem vs Cloud (#3553 (comment), #3553 (comment)) self vs static
|
|
@SychO9 in regards to generics PHPStan has a way to work around that issue https://phpstan.org/blog/generics-in-php-using-phpdocs NVM, I just saw your mention of the docblock 🤦 |
|
Thanks for the clarification. I hope this doesn't bite is in the behind in the long run 💪 |
|
I do think it might be better to use stubs to tell phpstan that the interface does have the methods even though that's not the case. Same for the filesystem, perhaps using a stub to change the return type to Not sure yet, need to consider this more. |
rather than hack every bit of the codebase with a phpdoc @var Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
…ce` ignore for now. Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
# Conflicts: # framework/core/src/Admin/Content/AdminPayload.php
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
|
New changes:
|
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
# Conflicts: # framework/core/src/Discussion/Discussion.php
Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>
You mean you reverted I'm okay with this if that's the case 👍 Thanks for considering my argumentation. |
|
yup |
askvortsov1
left a comment
There was a problem hiding this comment.
re: the exists + get into one issue: if we want to do this, we should consider making either a wrapper interface/class or an explicit util method. Probably the latter.
askvortsov1
left a comment
There was a problem hiding this comment.
Another general comment. From a maintainer's / reviewer's perspective, it can be hard to tell why certain things are overriden. I think it would be helpful in the future if there were comments on each stub file explaining what the goal of overriding / stubbing the class in question is.
Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>

Closes #3559
Changes proposed in this pull request:
Reviewers should focus on:
\Illuminate\Database\ConnectionInterfaceby\Illuminate\Database\Connection. Ideally we would stick to injecting the interface as that is more correct to separate the implementation from the contract. But in most of our codebase, we use methods that only exist within the implementation and not the interface. We could just leave it and fool phpstan with docblocks, but I thought it would be better to be explicit about what we expect injected. Thoughts are very welcome about this especially.Necessity
Confirmed
composer test).