Skip to content

Commit

Permalink
Merge pull request #245 from gsteel/attributes-inference-improvement
Browse files Browse the repository at this point in the history
Improve type inference for element attributes
  • Loading branch information
Slamdunk authored Nov 17, 2023
2 parents 943ece1 + 835a72b commit 9382d98
Show file tree
Hide file tree
Showing 73 changed files with 300 additions and 444 deletions.
130 changes: 15 additions & 115 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.13.0@a0a9c27630bcf8301ee78cb06741d2907d8c9fef">
<files psalm-version="5.15.0@5c774aca4746caf3d239d9c8cadb9f882ca29352">
<file src="src/Annotation/AbstractBuilder.php">
<InvalidArrayOffset>
<code><![CDATA[$params['elementSpec']['spec']['type']]]></code>
Expand Down Expand Up @@ -552,9 +552,6 @@
<code><![CDATA[$inputSpec['validators']]]></code>
<code><![CDATA[$inputSpec['validators']]]></code>
</PossiblyUndefinedArrayOffset>
<UndefinedInterfaceMethod>
<code>getValidator</code>
</UndefinedInterfaceMethod>
</file>
<file src="test/Element/MonthSelectTest.php">
<PossiblyInvalidArrayAccess>
Expand Down Expand Up @@ -601,6 +598,14 @@
</UndefinedMethod>
</file>
<file src="test/Element/MultiCheckboxTest.php">
<InvalidArgument>
<code><![CDATA[[
'options' => [
'a' => 'A',
'b' => 'B',
],
]]]></code>
</InvalidArgument>
<PossiblyInvalidArrayAccess>
<code><![CDATA[$inputSpec['validators'][0]]]></code>
<code><![CDATA[$inputSpec['validators'][0]]]></code>
Expand Down Expand Up @@ -689,6 +694,12 @@
</UndefinedInterfaceMethod>
</file>
<file src="test/Element/SelectTest.php">
<InvalidArgument>
<code><![CDATA[[
'multiple' => true,
'options' => $valueOptions,
]]]></code>
</InvalidArgument>
<PossiblyInvalidArrayAccess>
<code><![CDATA[$inputSpec['validators'][0]]]></code>
<code><![CDATA[$inputSpec['validators'][0]]]></code>
Expand Down Expand Up @@ -1101,9 +1112,6 @@
<InvalidArgument>
<code>$element</code>
</InvalidArgument>
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormCaptchaTest.php">
<PossiblyFalseArgument>
Expand All @@ -1120,28 +1128,10 @@
<code>setView</code>
</DeprecatedMethod>
</file>
<file src="test/View/Helper/FormColorTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormDateTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormDateTimeLocalTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormDateTimeTest.php">
<DeprecatedClass>
<code>new FormDateTimeHelper()</code>
</DeprecatedClass>
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormElementTest.php">
<PossiblyInvalidMethodCall>
Expand All @@ -1154,104 +1144,14 @@
<code>getHash</code>
</UndefinedInterfaceMethod>
</file>
<file src="test/View/Helper/FormEmailTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormFileTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormHiddenTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormImageTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormInputTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormLabelTest.php">
<InvalidArgument>
<code>$element</code>
</InvalidArgument>
</file>
<file src="test/View/Helper/FormMonthTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormNumberTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormPasswordTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormRangeTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormResetTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormRowTest.php">
<PossiblyInvalidFunctionCall>
<code>$escapeHelper($label)</code>
</PossiblyInvalidFunctionCall>
</file>
<file src="test/View/Helper/FormSearchTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormSubmitTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormTelTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormTextTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormTextareaTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormTimeTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormUrlTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
<file src="test/View/Helper/FormWeekTest.php">
<PossiblyNullArgument>
<code><![CDATA[$element->getAttribute($attribute)]]></code>
</PossiblyNullArgument>
</file>
</files>
50 changes: 15 additions & 35 deletions src/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Traversable;

use function array_key_exists;
use function assert;
use function is_string;

class Element implements
Expand All @@ -17,19 +18,19 @@ class Element implements
InitializableInterface,
LabelAwareInterface
{
/** @var array */
/** @var array<string, scalar|null> */
protected $attributes = [];

/** @var null|string */
protected $label;

/** @var array */
/** @var array<string, scalar|null> */
protected $labelAttributes = [];

/**
* Label specific options
*
* @var array
* @var array<string, mixed>
*/
protected $labelOptions = [];

Expand Down Expand Up @@ -87,7 +88,10 @@ public function setName(string $name)
*/
public function getName(): ?string
{
return $this->getAttribute('name');
$name = $this->getAttribute('name');
assert(is_string($name) || $name === null);

return $name;
}

/**
Expand Down Expand Up @@ -158,12 +162,7 @@ public function setOption(string $key, $value)
return $this;
}

/**
* Set a single element attribute
*
* @param mixed $value
* @return $this
*/
/** @inheritDoc */
public function setAttribute(string $key, $value)
{
// Do not include the value in the list of attributes
Expand All @@ -175,11 +174,7 @@ public function setAttribute(string $key, $value)
return $this;
}

/**
* Retrieve a single element attribute
*
* @return mixed|null
*/
/** @inheritDoc */
public function getAttribute(string $key)
{
if (! isset($this->attributes[$key])) {
Expand Down Expand Up @@ -209,11 +204,7 @@ public function hasAttribute(string $key): bool
}

/**
* Set many attributes at once
*
* Implementation will decide if this will overwrite or merge.
*
* @return $this
* @inheritDoc
* @throws Exception\InvalidArgumentException
*/
public function setAttributes(iterable $arrayOrTraversable)
Expand All @@ -224,9 +215,7 @@ public function setAttributes(iterable $arrayOrTraversable)
return $this;
}

/**
* Retrieve all attributes at once
*/
/** @inheritDoc */
public function getAttributes(): array
{
return $this->attributes;
Expand All @@ -235,7 +224,7 @@ public function getAttributes(): array
/**
* Remove many attributes at once
*
* @param array $keys
* @param list<string> $keys
* @return $this
*/
public function removeAttributes(array $keys)
Expand Down Expand Up @@ -304,23 +293,14 @@ public function getLabel(): ?string
return $this->label;
}

/**
* Set the attributes to use with the label
*
* @param array $labelAttributes
* @return $this
*/
/** @inheritDoc */
public function setLabelAttributes(array $labelAttributes)
{
$this->labelAttributes = $labelAttributes;
return $this;
}

/**
* Get the attributes to use with the label
*
* @return array
*/
/** @inheritDoc */
public function getLabelAttributes(): array
{
return $this->labelAttributes;
Expand Down
12 changes: 6 additions & 6 deletions src/Element/AbstractDateTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,41 +106,41 @@ protected function getValidators(): array

if (
isset($this->attributes['min'])
&& $this->valueIsValidDateTimeFormat($this->attributes['min'])
&& $this->valueIsValidDateTimeFormat((string) $this->attributes['min'])
) {
$validators[] = new GreaterThanValidator([
'min' => $this->attributes['min'],
'inclusive' => true,
]);
} elseif (
isset($this->attributes['min'])
&& ! $this->valueIsValidDateTimeFormat($this->attributes['min'])
&& ! $this->valueIsValidDateTimeFormat((string) $this->attributes['min'])
) {
throw new InvalidArgumentException(sprintf(
'%1$s expects "min" to conform to %2$s; received "%3$s"',
__METHOD__,
$this->format,
$this->attributes['min']
(string) $this->attributes['min']
));
}

if (
isset($this->attributes['max'])
&& $this->valueIsValidDateTimeFormat($this->attributes['max'])
&& $this->valueIsValidDateTimeFormat((string) $this->attributes['max'])
) {
$validators[] = new LessThanValidator([
'max' => $this->attributes['max'],
'inclusive' => true,
]);
} elseif (
isset($this->attributes['max'])
&& ! $this->valueIsValidDateTimeFormat($this->attributes['max'])
&& ! $this->valueIsValidDateTimeFormat((string) $this->attributes['max'])
) {
throw new InvalidArgumentException(sprintf(
'%1$s expects "max" to conform to %2$s; received "%3$s"',
__METHOD__,
$this->format,
$this->attributes['max']
(string) $this->attributes['max']
));
}
if (
Expand Down
6 changes: 1 addition & 5 deletions src/Element/Button.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@

class Button extends Element
{
/**
* Seed attributes
*
* @var array
*/
/** @var array<string, scalar|null> */
protected $attributes = [
'type' => 'button',
];
Expand Down
6 changes: 1 addition & 5 deletions src/Element/Checkbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@

class Checkbox extends Element implements InputProviderInterface
{
/**
* Seed attributes
*
* @var array
*/
/** @var array<string, scalar|null> */
protected $attributes = [
'type' => 'checkbox',
];
Expand Down
Loading

0 comments on commit 9382d98

Please sign in to comment.