Skip to content

[TASK] Add PHPStan extension to allow assertions#1624

Merged
oliverklee merged 6 commits into
mainfrom
task/allow-assert-instanceof
May 24, 2026
Merged

[TASK] Add PHPStan extension to allow assertions#1624
oliverklee merged 6 commits into
mainfrom
task/allow-assert-instanceof

Conversation

@JakeQZ
Copy link
Copy Markdown
Collaborator

@JakeQZ JakeQZ commented May 15, 2026

Suppress warnings for assert()s that, according to the DocBlock, can never fail, but in reality could, due to programmer error, since the DocBlock types are not enforced by PHP.

This allows us to retain treatPhpDocTypesAsCertain:true for stricter static analysis, whilst also using assertions for runtime checks in a development environment, without cluttering up the code with @phpstan-ignore comments.

This change reverts and replaces #1622.

Suppress warnings for `assert()`s that, according to the DocBlock,
can never fail, but in reality could, due to programmer error,
since the DocBlock types are not enforced by PHP.

This allows us to retain `treatPhpDocTypesAsCertain:true` for stricter static
analysis, whilst also using assertions for runtime checks in a development
environment, without cluttering up the code with `@phpstan-ignore` comments.

This change reverts and replaces #1622.
@JakeQZ JakeQZ self-assigned this May 15, 2026
@JakeQZ JakeQZ added enhancement cleanup developer-specific Issues that only affect maintainers, contributors, and people submitting PRs labels May 15, 2026
@coveralls
Copy link
Copy Markdown

coveralls commented May 15, 2026

Coverage Status

coverage: 98.282% (+0.03%) from 98.252% — task/allow-assert-instanceof into main

@JakeQZ
Copy link
Copy Markdown
Collaborator Author

JakeQZ commented May 15, 2026

Got some helpful pointers from some kind folk in response to phpstan/phpstan#14616.

Not sure about the location and namespace of the extension class (file).

Also, I read some suggestions that PHPStan extensions should have a corresponding TestCase. So that may be needed as part of this PR, once we've agreed on locations and namespaces.

Looking for initial comments and feedback on this, rather than merging right now...

@JakeQZ
Copy link
Copy Markdown
Collaborator Author

JakeQZ commented May 15, 2026

Catering for

if ($impossibleConditionAccordingToDocBlock) {
    throw \Exception();
}

looks quite challenging...

@oliverklee oliverklee added the testing Changes that primarily add or improve unit tests. label May 16, 2026
@oliverklee
Copy link
Copy Markdown
Collaborator

Concerning the location: I'd say we put this in src/PHPStan/ and block this directory from export using .gitattributes. Then we can do over coverage magic (and later: infection and fuzzing magic) on this class as well.

The class then also needs to be @internal.

@oliverklee
Copy link
Copy Markdown
Collaborator

Also, we might consider moving this to a separate repo & package at some point in time so we can reuse it in PHP-CSS-Parser.

@oliverklee
Copy link
Copy Markdown
Collaborator

As far as the code is concerned, this already looks quite good to me!

@JakeQZ
Copy link
Copy Markdown
Collaborator Author

JakeQZ commented May 19, 2026

Concerning the location: I'd say we put this in src/PHPStan/ and block this directory from export using .gitattributes.

Done.

The class then also needs to be @internal.

Done.

Also, we might consider moving this to a separate repo & package at some point in time so we can reuse it in PHP-CSS-Parser.

I took this challenge on as a break from my paid work. Then sort-of wished I hadn't. But I think it was a decent learning curve, with a result that is potentially reusable, at least as an example.

Also, I read some suggestions that PHPStan extensions should have a corresponding TestCase. So that may be needed as part of this PR

I dug into this and have added tests.

@JakeQZ JakeQZ marked this pull request as draft May 19, 2026 03:06
@JakeQZ JakeQZ marked this pull request as ready for review May 19, 2026 03:06
@JakeQZ
Copy link
Copy Markdown
Collaborator Author

JakeQZ commented May 19, 2026

@oliverklee request-review

*/
public static function fromHtml(string $unprocessedHtml): self
{
// @phpstan-ignore-next-line argument.type We're checking for a contract violation here.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This line ignores everything, not just the specified identifier

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for spotting that. It seems we have been using @phpstan-ignore-next-line in several places where we should have @phpstan-ignore, which also only ignores warnings from the next line, but allows (requires) a warning type parameter to narrow down which warnings should be suppressed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

#1628 for the other cases.

@oliverklee oliverklee merged commit 914eef7 into main May 24, 2026
33 checks passed
@oliverklee oliverklee deleted the task/allow-assert-instanceof branch May 24, 2026 07:59
@oliverklee
Copy link
Copy Markdown
Collaborator

I'd like to have this for our sister project as well. Should I port it, or would you be willing (or like) to do it, @JakeQZ ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cleanup developer-specific Issues that only affect maintainers, contributors, and people submitting PRs enhancement testing Changes that primarily add or improve unit tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants