Improved type hinting to pass some PHPStan / PHPCS rules better#58
Improved type hinting to pass some PHPStan / PHPCS rules better#58reinfi merged 14 commits intoreinfi:mainfrom
Conversation
Fixes PHPStan error: > Call to function`in_array()` with arguments `'applicationId'`, `['applicationId']` and `true` will always evaluate to `true`. See: https://phpstan.org/error-identifiers/function.alreadyNarrowedType
For increased compatibility with some PHPCS rules
Null values should simply be skipped
| )->addBody($this->intend('ARRAY_FILTER_USE_BOTH')) | ||
| ->addBody(');'); | ||
| if (count($notRequiredParameterNames) === 1) { | ||
| $method->addBody($this->intend('static fn (mixed $value): bool => $value === null')); |
There was a problem hiding this comment.
That is not correct as it requires to check the key because if you have a nullable but required value it now would be removed
There was a problem hiding this comment.
You are totally right, I embarrassingly failed to apply the outer negation when I removed the needless in_array() 🙈 Fixed it now!
There was a problem hiding this comment.
still not correct, you explicitly need to check for the key
There was a problem hiding this comment.
My intent was to fix this:
Call to function
in_array()with arguments'applicationId',['applicationId']andtruewill always evaluate totrue.
Checking whether 'applicationId' is in the array ['applicationId'] is not meaningful, but maybe I did the "fix" wrong?
There was a problem hiding this comment.
Test:
type: object
required:
- requiredNotNull
- requiredNullable
properties:
requiredNotNull:
type: string
requiredNullable:
type: string
notRequired:
type: stringcurrently produces
public function __construct(
public string $requiredNotNull,
public string $requiredNullable,
public ?string $notRequired = null,
) {
}
public function jsonSerialize(): array
{
return array_filter(
[
'requiredNotNull' => $this->requiredNotNull,
'requiredNullable' => $this->requiredNullable,
'notRequired' => $this->notRequired,
],
static fn (mixed $value, string $key): bool => !(in_array($key, ['notRequired'], true) && $value === null),
ARRAY_FILTER_USE_BOTH
);
}should be to pass PHPStan inspection:
public function __construct(
public string $requiredNotNull,
public string $requiredNullable,
public ?string $notRequired = null,
) {
}
public function jsonSerialize(): array
{
return array_filter(
[
'requiredNotNull' => $this->requiredNotNull,
'requiredNullable' => $this->requiredNullable,
'notRequired' => $this->notRequired,
],
static fn (mixed $value, string $key): bool => !($key === 'notRequired' && $value === null),
ARRAY_FILTER_USE_BOTH
);
}hope that helps
There was a problem hiding this comment.
@reinfi I finally took time to delve into this, I understand you now and I fixed the logic + added tests for all of the different cases 👍
|
|
||
| $class->addComment(sprintf('@implements %s<int, %s>', ArrayAccess::class, $type)); | ||
| $class->addComment(sprintf('@implements %s<%s>', IteratorAggregate::class, $type)); | ||
| $class->addComment(sprintf('@implements \%s<int, %s>', ArrayAccess::class, $type)); |
There was a problem hiding this comment.
not really a fan of this because the classes are already imported.
There was a problem hiding this comment.
Yeah, I agree in principle. In my project though there's a Drupal.Classes.UseGlobalClass.RedundantUseStatement ("Non-namespaced classes/interfaces/traits should not be referenced with use statements") phpcs rule that php code beautifier auto-fixes but without auto-fixing the comments, so I thought that maybe it could be okay to do the direct reference in the comments to avoid this 🙈
It should really be something to be filed for Drupal.Classes.UseGlobalClass.RedundantUseStatement, I will do that as well
I generally believe that auto-generated code should not be made to pass the coding style of the project that uses it – but this code was so close that I decided to give it a quick look to see if my PHPStan and PHPCS configs required required some adaptions to pass or if all could be auto-fixed.
This PR is a summary of all the PHPStan / PHPCS fixed I found and which would be feasible to do directly in this project, and which should not have any negative side consequences.
I have kept the commits atomic and descriptive.
Copilot summary
This pull request includes a variety of changes to improve code clarity, ensure proper type annotations, and enhance the handling of nullable and non-required parameters in JSON serialization. The changes span across multiple files, focusing on both the main codebase and test files.
Improvements to type annotations and interface clarity:
@implementsannotations insrc/Generator/ArrayObjectResolver.phpto include fully qualified class names forArrayAccessandIteratorAggregate.Enhancements to JSON serialization:
@return array<string, mixed>annotations tojsonSerializemethods insrc/Serialization/SerializableResolver.phpand various test files for better type clarity. [1] [2] [3] [4] [5] and others)jsonSerializemethods by refactoring lambda functions and simplifying conditions insrc/Serialization/SerializableResolver.phpand test files. [1] [2] [3] [4] [5]Handling of enum values:
nullvalues in thetransformEnummethod insrc/Generator/ClassTransformer.phpto ensure only valid enum values are processed.Additional minor improvements:
@returntype annotations forjsonSerializemethods insrc/Serialization/ArrayObjectSerialization.phpto improve code documentation.These changes collectively enhance code readability, maintainability, and correctness, particularly in scenarios involving JSON serialization and type annotations.