From e2ce62cfcf455d055f226ae9ae0806bbe3170fb5 Mon Sep 17 00:00:00 2001 From: Vincent QUATREVIEUX Date: Mon, 4 Mar 2024 10:45:07 +0100 Subject: [PATCH] chore: Update to psalm 5 --- composer.json | 2 +- psalm.xml | 2 ++ src/Aggregate/ArrayChildBuilder.php | 2 +- src/Aggregate/ChildAggregateInterface.php | 1 + .../Collection/ChildrenCollectionInterface.php | 6 +++++- src/Aggregate/Collection/DependencyIterator.php | 2 ++ src/Aggregate/Collection/DependencyTree.php | 3 +++ src/Aggregate/Collection/Level.php | 1 + src/Aggregate/FormBuilder.php | 2 ++ src/Aggregate/FormBuilderInterface.php | 2 +- src/Aggregate/RootForm.php | 1 + src/Aggregate/View/ArrayElementView.php | 3 +++ src/Aggregate/View/FormView.php | 3 +++ src/Choice/LazzyChoice.php | 1 + src/Custom/CustomFormBuilder.php | 1 + src/Filter/FilterVar.php | 11 ++++++++++- src/Leaf/BooleanStringElement.php | 1 + src/Leaf/Date/DateTimeElement.php | 3 +++ src/Leaf/Date/DateTimeElementBuilder.php | 2 +- src/Leaf/Helper/EmailElementBuilder.php | 2 +- src/Leaf/Helper/UrlElementBuilder.php | 2 +- src/Leaf/NumberElementBuilder.php | 2 +- src/Leaf/Transformer/LocalizedNumberTransformer.php | 2 +- src/Leaf/View/SelectHtmlRenderer.php | 2 ++ src/Leaf/View/SimpleFieldHtmlRenderer.php | 2 ++ src/Phone/PhoneChildBuilder.php | 2 +- src/Phone/PhoneElementBuilder.php | 2 +- src/RootElementInterface.php | 2 ++ src/View/FieldSetViewInterface.php | 5 +++++ src/View/RenderableTrait.php | 4 +++- tests/StaticAnalysis/ArrayElementConfigure.php | 11 ++++++++++- tests/StaticAnalysis/SubClassChildBuilderForm.php | 3 +++ 32 files changed, 76 insertions(+), 14 deletions(-) diff --git a/composer.json b/composer.json index 4b58d96..8788636 100755 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ "symfony/security-csrf": "~4.3|~5.0|~6.0", "giggsey/libphonenumber-for-php": "~8.0", "phpunit/phpunit": "~7.0|~8.0|~9.0", - "vimeo/psalm": "~4.20", + "vimeo/psalm": "~5.22", "symfony/http-foundation": "~4.3|~5.0|~6.0", "symfony/form": "~4.3|~5.0|~6.0" }, diff --git a/psalm.xml b/psalm.xml index 1e1d23e..21a9869 100644 --- a/psalm.xml +++ b/psalm.xml @@ -2,6 +2,8 @@ filterEmptyValues) { return []; diff --git a/src/Aggregate/ChildAggregateInterface.php b/src/Aggregate/ChildAggregateInterface.php index 87b143a..12a4c8a 100644 --- a/src/Aggregate/ChildAggregateInterface.php +++ b/src/Aggregate/ChildAggregateInterface.php @@ -16,6 +16,7 @@ * @template T * @extends ElementInterface * @extends ArrayAccess + * @extends IteratorAggregate */ interface ChildAggregateInterface extends ElementInterface, ArrayAccess, IteratorAggregate { diff --git a/src/Aggregate/Collection/ChildrenCollectionInterface.php b/src/Aggregate/Collection/ChildrenCollectionInterface.php index 7f355c5..7757f31 100644 --- a/src/Aggregate/Collection/ChildrenCollectionInterface.php +++ b/src/Aggregate/Collection/ChildrenCollectionInterface.php @@ -7,12 +7,16 @@ use Bdf\Form\Child\ChildInterface; use Countable; use Iterator; +use IteratorAggregate; /** * Collection of form child elements * Handle dependency tree + * + * @extends IteratorAggregate + * @extends ArrayAccess */ -interface ChildrenCollectionInterface extends \IteratorAggregate, ArrayAccess, Countable +interface ChildrenCollectionInterface extends IteratorAggregate, ArrayAccess, Countable { /** * Add a child to the dependency tree diff --git a/src/Aggregate/Collection/DependencyIterator.php b/src/Aggregate/Collection/DependencyIterator.php index ea3d7f1..7a0733e 100644 --- a/src/Aggregate/Collection/DependencyIterator.php +++ b/src/Aggregate/Collection/DependencyIterator.php @@ -9,6 +9,8 @@ * Iterate over @see DependencyTree * * Iterate first on the last level, and go to lower levels, to root + * + * @implements Iterator */ final class DependencyIterator implements Iterator { diff --git a/src/Aggregate/Collection/DependencyTree.php b/src/Aggregate/Collection/DependencyTree.php index 9db1dea..c07630c 100644 --- a/src/Aggregate/Collection/DependencyTree.php +++ b/src/Aggregate/Collection/DependencyTree.php @@ -24,6 +24,9 @@ * add(E4(E2, E3)) -> lvl0(E1, E4), lvl1(E3), lvl2(E2) [E4 added to lvl0, E3 shift to lvl1, E2 shift to lvl2] * * The iterator of the dependency tree will iterate over "higher" dependencies before, and "root" children at the end + * + * @implements \ArrayAccess + * @implements \IteratorAggregate */ final class DependencyTree implements \ArrayAccess, \IteratorAggregate, \Countable, ChildrenCollectionInterface { diff --git a/src/Aggregate/Collection/Level.php b/src/Aggregate/Collection/Level.php index 172c347..2b7adfe 100644 --- a/src/Aggregate/Collection/Level.php +++ b/src/Aggregate/Collection/Level.php @@ -10,6 +10,7 @@ * The dependency tree level * * @internal + * @implements IteratorAggregate */ final class Level implements IteratorAggregate { diff --git a/src/Aggregate/FormBuilder.php b/src/Aggregate/FormBuilder.php index 91221ab..c05ad4f 100644 --- a/src/Aggregate/FormBuilder.php +++ b/src/Aggregate/FormBuilder.php @@ -63,6 +63,8 @@ * * @see Form * @see CustomForm::configure() + * + * @extends AbstractElementBuilder
*/ class FormBuilder extends AbstractElementBuilder implements FormBuilderInterface { diff --git a/src/Aggregate/FormBuilderInterface.php b/src/Aggregate/FormBuilderInterface.php index ec54244..ac2ed8a 100644 --- a/src/Aggregate/FormBuilderInterface.php +++ b/src/Aggregate/FormBuilderInterface.php @@ -35,7 +35,7 @@ * $form = $builder->buildElement(); * * - * @implements ElementBuilderInterface + * @extends ElementBuilderInterface */ interface FormBuilderInterface extends ElementBuilderInterface { diff --git a/src/Aggregate/RootForm.php b/src/Aggregate/RootForm.php index 6678e3e..f43a11e 100644 --- a/src/Aggregate/RootForm.php +++ b/src/Aggregate/RootForm.php @@ -49,6 +49,7 @@ * * * @todo delegation trait + * @implements ChildAggregateInterface */ final class RootForm implements RootElementInterface, ChildAggregateInterface { diff --git a/src/Aggregate/View/ArrayElementView.php b/src/Aggregate/View/ArrayElementView.php index d92f001..f42a6e6 100644 --- a/src/Aggregate/View/ArrayElementView.php +++ b/src/Aggregate/View/ArrayElementView.php @@ -31,6 +31,9 @@ * * * @see ArrayElement::view() + * + * @implements IteratorAggregate + * @implements FieldSetViewInterface */ final class ArrayElementView implements IteratorAggregate, FieldViewInterface, FieldSetViewInterface, Countable { diff --git a/src/Aggregate/View/FormView.php b/src/Aggregate/View/FormView.php index 2cd4dc5..9cd3b7f 100644 --- a/src/Aggregate/View/FormView.php +++ b/src/Aggregate/View/FormView.php @@ -29,6 +29,9 @@ * * * @see Form::view() + * + * @implements IteratorAggregate + * @implements FieldSetViewInterface */ final class FormView implements IteratorAggregate, FieldSetViewInterface { diff --git a/src/Choice/LazzyChoice.php b/src/Choice/LazzyChoice.php index 0c28593..e822d33 100644 --- a/src/Choice/LazzyChoice.php +++ b/src/Choice/LazzyChoice.php @@ -5,6 +5,7 @@ /** * @deprecated Use LazyChoice * @psalm-suppress InvalidExtendClass + * @psalm-suppress MissingTemplateParam */ final class LazzyChoice extends LazyChoice { diff --git a/src/Custom/CustomFormBuilder.php b/src/Custom/CustomFormBuilder.php index 0f2da3f..7ae5ad4 100644 --- a/src/Custom/CustomFormBuilder.php +++ b/src/Custom/CustomFormBuilder.php @@ -27,6 +27,7 @@ * @see CustomForm::configure() * * @mixin FormBuilderInterface + * @implements ElementBuilderInterface */ class CustomFormBuilder implements ElementBuilderInterface { diff --git a/src/Filter/FilterVar.php b/src/Filter/FilterVar.php index e6e6838..f2d37fc 100644 --- a/src/Filter/FilterVar.php +++ b/src/Filter/FilterVar.php @@ -5,6 +5,12 @@ use Attribute; use Bdf\Form\Child\ChildInterface; +use function filter_var; +use function is_array; +use function is_scalar; +use function str_replace; +use function strip_tags; + /** * Adapt filter_var() to FilterInterface * By default, configured to filter HTML values @@ -60,6 +66,8 @@ public function filter($value, ChildInterface $input, $default) private function apply($value) { + $value = is_scalar($value) ? (string) $value : ''; + if ($this->filter !== self::HTML_FILTER) { return filter_var($value, $this->filter, $this->flags); } @@ -74,7 +82,8 @@ private function apply($value) // Encode quotes if (($this->flags & FILTER_FLAG_NO_ENCODE_QUOTES) === 0) { - $value = str_replace(['"', "'"], ['"', '''], $value); + /** @psalm-suppress PossiblyInvalidCast */ + $value = str_replace(['"', "'"], ['"', '''], (string) $value); } return $value; diff --git a/src/Leaf/BooleanStringElement.php b/src/Leaf/BooleanStringElement.php index 6514e7d..b50b3b1 100644 --- a/src/Leaf/BooleanStringElement.php +++ b/src/Leaf/BooleanStringElement.php @@ -23,6 +23,7 @@ class BooleanStringElement extends AbstractBooleanElement * * @return scalar|null * @psalm-suppress ImplementedReturnTypeMismatch + * @psalm-suppress LessSpecificImplementedReturnType */ protected function sanitize($rawValue) { diff --git a/src/Leaf/Date/DateTimeElement.php b/src/Leaf/Date/DateTimeElement.php index bc45da2..8c5c141 100644 --- a/src/Leaf/Date/DateTimeElement.php +++ b/src/Leaf/Date/DateTimeElement.php @@ -134,7 +134,10 @@ protected function toPhp($httpValue): ?DateTimeInterface */ protected function toHttp($phpValue) { + // Because of legacy behavior, the raw value can be saved when a transformer failed + // So the raw string is kept as is if (is_string($phpValue)) { + /** @psalm-suppress NoValue */ return $phpValue; } diff --git a/src/Leaf/Date/DateTimeElementBuilder.php b/src/Leaf/Date/DateTimeElementBuilder.php index 706ad33..6060158 100644 --- a/src/Leaf/Date/DateTimeElementBuilder.php +++ b/src/Leaf/Date/DateTimeElementBuilder.php @@ -131,7 +131,7 @@ public function format(string $format): self * $builder->dateTime('eventDate')->timezone(new DateTimeZone('+0200'); * * - * @param string|DateTimeZone|null $timezone The timezone. If string is given, a new DateTimeZone will be created. + * @param non-empty-string|DateTimeZone|null $timezone The timezone. If string is given, a new DateTimeZone will be created. * * @return $this */ diff --git a/src/Leaf/Helper/EmailElementBuilder.php b/src/Leaf/Helper/EmailElementBuilder.php index 2819899..b2d06a9 100644 --- a/src/Leaf/Helper/EmailElementBuilder.php +++ b/src/Leaf/Helper/EmailElementBuilder.php @@ -139,7 +139,7 @@ public function useConstraint(array $options = []): self /** * @return \Symfony\Component\Validator\Constraint[] */ - protected function createEmailConstraint(): array + protected function createEmailConstraint(RegistryInterface $registry): array { if (!$this->useConstraint) { return []; diff --git a/src/Leaf/Helper/UrlElementBuilder.php b/src/Leaf/Helper/UrlElementBuilder.php index fdc6ee5..f94fa77 100644 --- a/src/Leaf/Helper/UrlElementBuilder.php +++ b/src/Leaf/Helper/UrlElementBuilder.php @@ -150,7 +150,7 @@ public function useConstraint(array $options = []): self /** * @return \Symfony\Component\Validator\Constraint[] */ - protected function createUrlConstraint(): array + protected function createUrlConstraint(RegistryInterface $registry): array { if (!$this->useConstraint) { return []; diff --git a/src/Leaf/NumberElementBuilder.php b/src/Leaf/NumberElementBuilder.php index 6502eb8..58871a8 100644 --- a/src/Leaf/NumberElementBuilder.php +++ b/src/Leaf/NumberElementBuilder.php @@ -132,7 +132,7 @@ protected function defaultTransformerExceptionConstraintOptions(): array */ abstract protected function numberTransformer(): TransformerInterface; - final protected function provideNumberTransformer(): array + final protected function provideNumberTransformer(RegistryInterface $registry): array { if (!$this->raw) { return [$this->numberTransformer()]; diff --git a/src/Leaf/Transformer/LocalizedNumberTransformer.php b/src/Leaf/Transformer/LocalizedNumberTransformer.php index edd9f51..eed0f28 100644 --- a/src/Leaf/Transformer/LocalizedNumberTransformer.php +++ b/src/Leaf/Transformer/LocalizedNumberTransformer.php @@ -139,7 +139,7 @@ private function getNumberFormatter(): NumberFormatter $formatter->setAttribute(NumberFormatter::ROUNDING_MODE, $this->roundingMode); } - $formatter->setAttribute(NumberFormatter::GROUPING_USED, $this->grouping); + $formatter->setAttribute(NumberFormatter::GROUPING_USED, (int) $this->grouping); return $formatter; } diff --git a/src/Leaf/View/SelectHtmlRenderer.php b/src/Leaf/View/SelectHtmlRenderer.php index 3f5503d..72b493a 100644 --- a/src/Leaf/View/SelectHtmlRenderer.php +++ b/src/Leaf/View/SelectHtmlRenderer.php @@ -10,6 +10,8 @@ /** * Renderer for select element * Should be used for element with choices + * + * @implements FieldViewRendererInterface */ final class SelectHtmlRenderer implements FieldViewRendererInterface { diff --git a/src/Leaf/View/SimpleFieldHtmlRenderer.php b/src/Leaf/View/SimpleFieldHtmlRenderer.php index 790eb78..52457a8 100644 --- a/src/Leaf/View/SimpleFieldHtmlRenderer.php +++ b/src/Leaf/View/SimpleFieldHtmlRenderer.php @@ -16,6 +16,8 @@ /** * Default render for @see SimpleElementView + * + * @implements FieldViewRendererInterface */ final class SimpleFieldHtmlRenderer implements FieldViewRendererInterface { diff --git a/src/Phone/PhoneChildBuilder.php b/src/Phone/PhoneChildBuilder.php index a7388ae..1810e09 100644 --- a/src/Phone/PhoneChildBuilder.php +++ b/src/Phone/PhoneChildBuilder.php @@ -89,7 +89,7 @@ public function saveAsString(?int $format = PhoneNumberFormat::E164): self /** * @return PhoneNumberToStringTransformer[] */ - protected function provideModelTransformer(): array + protected function provideModelTransformer(RegistryInterface $registry): array { if ($this->saveFormat === null) { return []; diff --git a/src/Phone/PhoneElementBuilder.php b/src/Phone/PhoneElementBuilder.php index 31108db..e28f065 100644 --- a/src/Phone/PhoneElementBuilder.php +++ b/src/Phone/PhoneElementBuilder.php @@ -236,7 +236,7 @@ protected function createElement(ValueValidatorInterface $validator, Transformer * * @return Constraint[] */ - protected function providePhoneConstraint(): array + protected function providePhoneConstraint(RegistryInterface $registry): array { if ($this->allowInvalidNumber) { return []; diff --git a/src/RootElementInterface.php b/src/RootElementInterface.php index 2682592..2469ab2 100644 --- a/src/RootElementInterface.php +++ b/src/RootElementInterface.php @@ -14,6 +14,8 @@ * * @method void set(string $flag, mixed $value) Define a flag value * @method bool is(string $flag) Check if a flag is defined + * + * @extends ElementInterface */ interface RootElementInterface extends ElementInterface { diff --git a/src/View/FieldSetViewInterface.php b/src/View/FieldSetViewInterface.php index 33c07cf..1583fdd 100644 --- a/src/View/FieldSetViewInterface.php +++ b/src/View/FieldSetViewInterface.php @@ -23,6 +23,11 @@ * * * @see \Bdf\Form\Aggregate\ChildAggregateInterface + * + * @template E + * + * @extends ArrayAccess + * @extends Traversable */ interface FieldSetViewInterface extends ElementViewInterface, ArrayAccess, Traversable { diff --git a/src/View/RenderableTrait.php b/src/View/RenderableTrait.php index 15deadb..3f9b28f 100644 --- a/src/View/RenderableTrait.php +++ b/src/View/RenderableTrait.php @@ -26,7 +26,9 @@ public function __call(string $name, array $arguments) throw new ArgumentCountError('Missing the attribute value.'); } - return $this->set($name, $arguments[0]); + $this->set($name, $arguments[0]); + + return $this; } /** diff --git a/tests/StaticAnalysis/ArrayElementConfigure.php b/tests/StaticAnalysis/ArrayElementConfigure.php index b05c559..b2a7195 100644 --- a/tests/StaticAnalysis/ArrayElementConfigure.php +++ b/tests/StaticAnalysis/ArrayElementConfigure.php @@ -7,6 +7,9 @@ use Bdf\Form\Aggregate\FormBuilderInterface; use Bdf\Form\Custom\CustomForm; +/** + * @extends CustomForm + */ class ArrayElementConfigure extends CustomForm { /** @@ -14,6 +17,12 @@ class ArrayElementConfigure extends CustomForm */ protected function configure(FormBuilderInterface $builder): void { - $builder->array('values')->element(ArrayElement::class, function (ArrayElementBuilder $builder) {}); + $builder->array('values')->element( + ArrayElement::class, + /** + * @param ArrayElementBuilder $builder + */ + function (ArrayElementBuilder $builder) {} + ); } } diff --git a/tests/StaticAnalysis/SubClassChildBuilderForm.php b/tests/StaticAnalysis/SubClassChildBuilderForm.php index a87bd03..8d9796d 100644 --- a/tests/StaticAnalysis/SubClassChildBuilderForm.php +++ b/tests/StaticAnalysis/SubClassChildBuilderForm.php @@ -5,6 +5,9 @@ use Bdf\Form\Aggregate\FormBuilderInterface; use Bdf\Form\Custom\CustomForm; +/** + * @extends CustomForm + */ class SubClassChildBuilderForm extends CustomForm { /**