-
Notifications
You must be signed in to change notification settings - Fork 672
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
Encourage using DOMDocument factory methods to prevent objects broken state #10620
base: 5.x
Are you sure you want to change the base?
Encourage using DOMDocument factory methods to prevent objects broken state #10620
Conversation
Looks like the failed check is unrelated to the PR |
I'm not so sure about this. How people use it is usually Source: https://github.com/search?q=%22new+DOMText%22+language%3APHP&type=code |
Perhaps we could do something like this instead: https://psalm.dev/r/26c873ea00 |
I found these snippets: https://psalm.dev/r/26c873ea00<?php
/**
* @template _Owner as never|Doc|null
*/
class Node {
/** @var _Owner */
public Doc|null $owner;
/** @psalm-assert self<never> $this */
public function __construct() {}
}
/** @template-extends Node<null> */
class Doc extends Node {
/** @psalm-assert Node<Doc> $child */
public function add(Node $child): void {}
}
$d = new Doc;
$d->owner;
/** @psalm-trace $d->owner */;
$n = new Node;
$n->__construct(); // we need to apply constructor assertions automatically
$n->owner;
/** @psalm-trace $n->owner */;
$d->add($n);
$n->owner;
/** @psalm-trace $n->owner */;
|
Or this: https://psalm.dev/r/4bc562b64e |
I found these snippets: https://psalm.dev/r/4bc562b64e<?php
/**
* @template _Owner as never|Doc|null
*/
class Node {
/** @var _Owner */
public Doc|null $owner;
/** @psalm-self-out self<never> */
public function __construct() {}
}
/** @template-extends Node<null> */
class Doc extends Node {
/** @psalm-assert Node<Doc> $child */
public function add(Node $child): void {}
}
$d = new Doc;
$d->owner; // null
/** @psalm-trace $d->owner */;
$n = new Node;
/** @psalm-suppress DirectConstructorCall */
$n->__construct(); // we need to apply constructor assertions automatically
$n->owner; // never
/** @psalm-trace $n->owner */;
$d->add($n);
$n->owner; // Doc
/** @psalm-trace $n->owner */;
|
Yes, I agree this proposal is questionable. Our company's codebase also have |
I found these snippets: https://psalm.dev/r/f596da8a0d<?php
/**
* @template _Owner as never|Doc|null
*/
class Node {
/** @var _Owner */
public Doc|null $owner;
/** @psalm-self-out self<never> */
public function __construct() {}
}
/** @template-extends Node<null> */
class Doc extends Node {
/** @psalm-assert Node<Doc> ...$child */
public function append(Node ...$child): void {}
}
$d = new Doc;
$d->owner; // null
/** @psalm-trace $d->owner */;
$n = new Node;
/** @psalm-suppress DirectConstructorCall */
$n->__construct(); // we need to apply constructor assertions automatically
$n->owner; // never
/** @psalm-trace $n->owner */;
$d->append($n);
$n->owner; // it's still never, not Doc :(
/** @psalm-trace $n->owner */;
|
Manually created DOMNode objects have broken internal state because they don't have
ownerDocument
until added to one.It leads to DOMException/warning
Invalid State Error
when callingownerDocument
field.This PR encourages using factory methods that immediately bind freshly created object to
ownerDocument
and thus its internal state is valid.