Skip to content

Conversation

@jtojnar
Copy link
Contributor

@jtojnar jtojnar commented Oct 11, 2024

No description provided.

jtojnar added 17 commits March 4, 2025 02:31
Not sure if this is expected but at least it works the same as before.
`DOMAttr::$value` must be a `string`.

Let’s add helpers for manipulating the `readability` attribute
so that we do not have to keep casting it from and to `string`
in order to appease `strict_types`.
To preserve BC, we are not using type hints for now.
This is bad state so it should not be a breaking change.
Since we require PHP 7.4, contravariance in param types is supported,
so we do not need to worry about subclasses that widen the param type.
It will be only breaking in the unlikely case a subclass uses a type that
contradicts the PHPDoc type annotation and does not not extend `DOMNode`.

Also fix the type annotation since some invocations pass it a `DOMText`,
an arbitrary sibling/child `DOMNode` or even `null`.
Because PHPStan does not currently analyze XPath expressions, we need to use a @var cast:
https://phpstan.org/writing-php-code/phpdocs-basics#inline-%40var

These are list of elements since asterisk wildcard only selects elements:
https://www.w3.org/TR/1999/REC-xpath-19991116/#path-abbrev
We use `DOMDocument::registerNodeClass()` to make DOM methods return
`JSLikeHTMLElement` instead of `DOMElement`. Unfortunately, it is not
possible for PHPStan to detect that so we need to cast it ourselves:
phpstan/phpstan#10748
We may want to deprecate it in the future just to get rid of this mess.

Also add PHPStan stubs for DOM classes so that we do not need to cast everything.
It is fine to do that globally as we only ever use DOM with `JSLikeHTMLElement` registered.

This patch also allows us to get rid of the assertions in tests.
Nothing affecting correctness, just stuff making it easier for PHPStan to reason about the code.
We cannot use stubs since PHPStan already has them to override
The argument can only be `DOMElement`.

Discovered by bleeding edge PHPStan.
`isset` does two things: it checks if the entity resulting from the chain of accessors is defined, and if it is not `null`.
We know that the properties are always defined so we can just replace those `isset`s with `null` checks.
This will allow us to reason about the code more clearly.
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.

1 participant