-
Notifications
You must be signed in to change notification settings - Fork 663
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
False positive PropertyNotSetInConstructor #5630
Comments
I found these snippets: https://psalm.dev/r/106a0483f7<?php
trait CreatedAt {
protected DateTimeImmutable $createdAt;
private function onCreated(): void {
$this->createdAt = new DateTimeImmutable();
}
}
class Foo {
use CreatedAt;
public function __construct() {
$this->onCreated();
}
}
class Bar extends Foo {}
|
I also have an example at: https://psalm.dev/r/9a28243243 |
I found these snippets: https://psalm.dev/r/9a28243243<?php declare(strict_types=1);
namespace Jorpo\Concerto\Event
{
abstract class Event
{
protected string $uniqueId;
protected string $when;
protected function generateUniqueId(): void
{
$this->uniqueId = 'test';
}
protected function now(): void
{
if (empty($this->when)) {
$this->when = 'test';
}
}
}
}
namespace Jorpo\Concerto\FieldTypes\EnableFieldType\Model
{
use Jorpo\Concerto\Event\Event;
class SomeEvent extends Event
{
protected string $someValue;
public function __construct(string $someValue)
{
$this->someValue = $someValue;
$this->now();
$this->generateUniqueId();
}
public function fieldTypeId(): string
{
return $this->someValue;
}
}
}
|
@designermonkey that's not supposed to work. You need to declare your initializer methods |
I found these snippets: https://psalm.dev/r/20ede335c0<?php
abstract class Event {
protected string $uniqueId;
final protected function generateUniqueId(): void {
$this->uniqueId = 'test';
}
}
final class SomeEvent extends Event {
public function __construct(string $someValue) {
$this->generateUniqueId();
}
}
|
Interesting. Could you point me to some further reading about why thta need to be final? Either way, the error returned isn't exactly very clear though. Is it supposed to be returning a different one in my use case? |
Well, that's fairly simple. Given class class C {
private int $prop;
protected function initProp(): void { $this->prop = 1; }
public function __construct() { $this->initProp(); }
public function getProp(): int { return $this->prop; }
} it can be shown that class D extends C {
protected function initProp(): void {}
}
(new D)->getProp(); // will fail Psalm cannot assume this won't happen, unless the method is private or final or the class itself is final. |
There is no room for "can". When a descendant overrides There is no problem with class |
I wish that was true. But Psalm does not necessarily has access to all descendants - e.g. when a library ships a non-final class meant to be extended by the consumers of that library. |
The crux of this bug is the incorrect belief that access to descendants is required to validate ancestors. It is not. Psalm should not be expected to prophesize problems with a class that is perfectly correct and innocent as it is, but its descendants might potentially do something wrong, like failing to call the parent constructor, or otherwise actively frustrating the base class's intention to initialize the property. When descendants actually commit those sins, Psalm should report problems about those descendants while analyzing their code, at which point Psalm will have access to the entire inheritance chain leading to the actual occurrence of the problem. |
Lint tools' insistence on weaving morbid prophecies about an Evil Child that will be born some day are one of the big causes of the proliferation of libraries that are cripplingly locked down using |
Me: Is this a constructor? |
Quite a big discussion here, but looks like even |
I found these snippets: https://psalm.dev/r/c8408355be<?php
trait Tr
{
protected int $a;
final protected function set(): void
{
$this->a = 5;
}
}
class B
{
use Tr;
protected function __construct()
{
$this->set();
}
}
final class Cl extends B
{
}
|
Hmm, probably my example is actually a next bug: #5062 |
Seriously, this needs more urgent attention. It is absolutely unacceptable for a lint tool to force programmers to entirely throw away a huge chunk of what constitutes OO programming. This bug forces programmers to lock their libraries down with |
Hey @rulatir, feel free to take a look at it. I'd be fine with not raising this error when we can show that a parent correctly initialize the property, even if a child could theoretically override the method |
I do feel free to "take a look at it". I don't feel able to "take a look at it", not without investing weeks to learn the basics of the project, all the while someone who already knows the codebase could probably fix this bug in 10 minutes. And this is normal. People who come to a bugtracker should be assumed to be in the position I am in: harmed by a bug, but not knowing the rocket science required to fix it. I no longer use psalm in my projects, but this bug doesn't just harm psalm users. It harms users of all libraries developed with psalm as a linter, which end up being completely locked down with |
@rulatir You seem engaged in your own little crusade against However, you managed to both massively overestimate the time it would take you to learn how to fix this issue and also massively underestimate the time it would take me (or anyone else in the project) to fix it. And you did this to justify your demand for other to fix a problem that doesn't even exists in a tool you don't use. That's quite a performance there, pal. This bug tracker currently has 900 open issues and many are more critical than this. So as I said, if you're concerned enough to do anything more than complain, feel free to take a look at it. |
My crusade is against false positives in general. They are massively harmful. |
Property
$createdAt
was initialized itFoo
constructor. But psalm knows nothing about it inBar
.https://psalm.dev/r/106a0483f7
The text was updated successfully, but these errors were encountered: