Skip to content

Add type specifier for Drupal\Component\Assertion\Inspector #834

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

Merged
merged 4 commits into from
Mar 27, 2025

Conversation

mglaman
Copy link
Owner

@mglaman mglaman commented Mar 27, 2025

Backport of #826

Niklan and others added 2 commits March 27, 2025 10:58
* WIP

* WIP

* WIP

* WIP

* Fix CI errors

* Try TypeCombinator instead of UnionType

---------

Co-authored-by: Matt Glaman <nmd.matt@gmail.com>
(cherry picked from commit f7bc280)
@mglaman
Copy link
Owner Author

mglaman commented Mar 27, 2025

@Niklan I'm backporting this to 1.x, but there are two failures. I think it might just be a difference in PHPStan 1.0 and 2.0 but wanted your feedback before adjusting the tests

// Inspector::assertAllArrays()
$input = mixed_function();
\assert(Inspector::assertAllArrays($input));
assertType('iterable<array<mixed, mixed>>', $input);

Failed asserting that two strings are identical.
Expected :'iterable<array<mixed, mixed>>'
Actual   :'iterable<array>'
// Inspector::assertAllHaveKey()
$input = mixed_function();
assert(Inspector::assertAllHaveKey($input, 'foo', 'baz'));
assertType("array<mixed, array<hasOffset('baz')&hasOffset('foo'), mixed>>", $input);

Expected :'array<mixed, array<hasOffset('baz')&hasOffset('foo'), mixed>>'
Actual   :'array<array<hasOffset('baz')&hasOffset('foo'), mixed>>'

@Niklan
Copy link
Contributor

Niklan commented Mar 27, 2025

@mglaman I did some testing locally. The API from PHPStan is the same, and it dumps the type internally properly:

^ PHPStan\Type\ArrayType^ {#19170
  -itemType: PHPStan\Type\MixedType^ {#19338
    -isExplicitMixed: true
    -subtractedType: null
  }
  -keyType: PHPStan\Type\MixedType^ {#19229
    -isExplicitMixed: true
    -subtractedType: null
  }
}

PHPStan v1 appears to treat mixed types as insufficiently specific in certain scenarios. Specifically, when mixed is the sole subtype (e.g., in array<mixed, mixed>) or when it's not part of an enumeration as in assertAllHaveKey(), PHPStan v1 simply omits it from the resolved type.

I think it it safe to change those assertions for v1 to:

// Inspector::assertAllArrays()
$input = mixed_function();
\assert(Inspector::assertAllArrays($input));
assertType('iterable<array>', $input);

and

// Inspector::assertAllHaveKey()
$input = mixed_function();
assert(Inspector::assertAllHaveKey($input, 'foo', 'baz'));
assertType("array<array<hasOffset('baz')&hasOffset('foo'), mixed>>", $input);

The tests are passing this way, but I think it will create some noise when projects update to Drupal 11.2+ and PHPStan v2 becomes available, because it will detect mixed. But I don't think we can do anything here, because it looks like a limitation for PHPStan v1, such as its inability to handle arguments with a reference, which leads to weird reports, but it is fine in v2.

@mglaman
Copy link
Owner Author

mglaman commented Mar 27, 2025

Thank you @Niklan for confirming!

@mglaman mglaman merged commit ffeb015 into 1.x Mar 27, 2025
15 of 17 checks passed
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.

2 participants