Skip to content

Commit a773a0d

Browse files
authored
fix: correct static analysis types inference (#717)
* fix: correct static analysis types inference * chore: clean * test: fix failed tests * fix: handle non-backed enums parsing errors properly * test: add coverage for EnumType parsing edge cases
1 parent 37b55c3 commit a773a0d

41 files changed

Lines changed: 2704 additions & 96 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

psalm-baseline.xml

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -705,18 +705,21 @@
705705
<file src="src/Internal/Marshaller/Type/ArrayType.php">
706706
<MoreSpecificImplementedParamType>
707707
<code><![CDATA[$current]]></code>
708-
<code><![CDATA[$value]]></code>
709708
</MoreSpecificImplementedParamType>
710709
</file>
711710
<file src="src/Internal/Marshaller/Type/DateIntervalType.php">
712711
<ArgumentTypeCoercion>
713712
<code><![CDATA[$this->format]]></code>
714713
<code><![CDATA[$this->format]]></code>
715714
</ArgumentTypeCoercion>
715+
<DeprecatedConstant>
716+
<code><![CDATA[DateInterval::FORMAT_MONTHS]]></code>
717+
<code><![CDATA[DateInterval::FORMAT_YEARS]]></code>
718+
</DeprecatedConstant>
716719
<InvalidOperand>
720+
<code><![CDATA[$interval->totalMicroseconds * 1000]]></code>
717721
<code><![CDATA[$value * 1000000000]]></code>
718722
<code><![CDATA[($value * 1000000000) % 1000000000]]></code>
719-
<code><![CDATA[DateInterval::parse($value, $this->format)->totalMicroseconds * 1000]]></code>
720723
</InvalidOperand>
721724
</file>
722725
<file src="src/Internal/Marshaller/Type/DurationJsonType.php">
@@ -725,15 +728,6 @@
725728
<code><![CDATA[($value * 1000000000) % 1000000000]]></code>
726729
</InvalidOperand>
727730
</file>
728-
<file src="src/Internal/Marshaller/Type/EnumType.php">
729-
<PropertyTypeCoercion>
730-
<code><![CDATA[$class]]></code>
731-
</PropertyTypeCoercion>
732-
<UndefinedMethod>
733-
<code><![CDATA[$this->classFQCN::from($value)]]></code>
734-
<code><![CDATA[$this->classFQCN::from($value['value'])]]></code>
735-
</UndefinedMethod>
736-
</file>
737731
<file src="src/Internal/Marshaller/Type/ObjectType.php">
738732
<InvalidPropertyAssignmentValue>
739733
<code><![CDATA[new \ReflectionClass($class ?? \stdClass::class)]]></code>
@@ -747,11 +741,6 @@
747741
<code><![CDATA[TClass]]></code>
748742
</InvalidReturnType>
749743
</file>
750-
<file src="src/Internal/Marshaller/Type/OneOfType.php">
751-
<InvalidReturnType>
752-
<code><![CDATA[array]]></code>
753-
</InvalidReturnType>
754-
</file>
755744
<file src="src/Internal/Marshaller/Type/Type.php">
756745
<ArgumentTypeCoercion>
757746
<code><![CDATA[$typeClass]]></code>

src/Internal/Marshaller/Type/ActivityCancellationType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Converts a boolean value to an activity cancellation policy.
1111
*
1212
* @see Policy
13-
* @extends Type<bool>
13+
* @extends Type<bool, int>
1414
* @internal
1515
*/
1616
final class ActivityCancellationType extends Type

src/Internal/Marshaller/Type/ArrayType.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use Temporal\Internal\Marshaller\MarshallingRule;
1616

1717
/**
18-
* @extends Type<array>
18+
* @extends Type<array, array>
1919
*/
2020
class ArrayType extends Type implements DetectableTypeInterface, RuleFactoryInterface
2121
{
@@ -57,7 +57,6 @@ public static function makeRule(\ReflectionProperty $property): ?MarshallingRule
5757
}
5858

5959
/**
60-
* @psalm-assert array $value
6160
* @param mixed $value
6261
* @param array $current
6362
*/

src/Internal/Marshaller/Type/AssocArrayType.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
/**
1818
* Force the value to be an associative array (object) on serialization.
1919
*
20-
* @extends Type<object>
20+
* @extends Type<object, mixed>
2121
*/
2222
class AssocArrayType extends Type
2323
{
@@ -40,17 +40,13 @@ public function __construct(MarshallerInterface $marshaller, MarshallingRule|str
4040
parent::__construct($marshaller);
4141
}
4242

43-
/**
44-
* @psalm-assert array $value
45-
* @psalm-assert array $current
46-
* @param mixed $value
47-
* @param mixed $current
48-
*/
4943
public function parse($value, $current): array
5044
{
51-
\is_array($value) or throw new \InvalidArgumentException(
52-
\sprintf(self::ERROR_INVALID_TYPE, \get_debug_type($value)),
53-
);
45+
if (!\is_array($value)) {
46+
throw new \InvalidArgumentException(
47+
\sprintf(self::ERROR_INVALID_TYPE, \get_debug_type($value)),
48+
);
49+
}
5450

5551
if ($this->type) {
5652
$result = [];

src/Internal/Marshaller/Type/ChildWorkflowCancellationType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
* @see Policy
1313
*
14-
* @extends Type<bool>
14+
* @extends Type<bool, int>
1515
* @internal
1616
*/
1717
final class ChildWorkflowCancellationType extends Type

src/Internal/Marshaller/Type/CronType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
namespace Temporal\Internal\Marshaller\Type;
1313

1414
/**
15-
* @extends Type<string>
15+
* @psalm-type TValue = null|string|\Stringable
16+
* @extends Type<string, TValue>
1617
*/
1718
class CronType extends Type
1819
{

src/Internal/Marshaller/Type/DateIntervalType.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
/**
2222
* @psalm-import-type DateIntervalFormat from DateInterval
23-
* @extends Type<int|Duration>
23+
* @psalm-import-type DateIntervalValue from DateInterval
24+
* @extends Type<int|Duration, DateIntervalValue>
2425
*/
2526
class DateIntervalType extends Type implements DetectableTypeInterface, RuleFactoryInterface
2627
{
@@ -53,10 +54,6 @@ public static function makeRule(\ReflectionProperty $property): ?MarshallingRule
5354

5455
public function serialize($value): int|Duration
5556
{
56-
if ($this->format === DateInterval::FORMAT_NANOSECONDS) {
57-
return (int) (DateInterval::parse($value, $this->format)->totalMicroseconds * 1000);
58-
}
59-
6057
if ($this->format === Duration::class) {
6158
return match (true) {
6259
$value instanceof \DateInterval => DateInterval::toDuration($value),
@@ -69,8 +66,27 @@ public function serialize($value): int|Duration
6966
};
7067
}
7168

72-
$method = 'total' . \ucfirst($this->format);
73-
return (int) (DateInterval::parse($value, $this->format)->$method);
69+
$interval = DateInterval::parse($value, $this->format);
70+
71+
return (int) match ($this->format) {
72+
DateInterval::FORMAT_YEARS => $interval->totalYears,
73+
DateInterval::FORMAT_MONTHS => $interval->totalMonths,
74+
DateInterval::FORMAT_WEEKS => $interval->totalWeeks,
75+
DateInterval::FORMAT_DAYS => $interval->totalDays,
76+
DateInterval::FORMAT_HOURS => $interval->totalHours,
77+
DateInterval::FORMAT_MINUTES => $interval->totalMinutes,
78+
DateInterval::FORMAT_SECONDS => $interval->totalSeconds,
79+
DateInterval::FORMAT_MILLISECONDS => $interval->totalMilliseconds,
80+
DateInterval::FORMAT_MICROSECONDS => $interval->totalMicroseconds,
81+
DateInterval::FORMAT_NANOSECONDS => (int) \round($interval->totalMicroseconds * 1000),
82+
default => throw new \InvalidArgumentException(
83+
\sprintf(
84+
'Unsupported format: "%s". See %s for available formats.',
85+
$this->format,
86+
DateInterval::class,
87+
),
88+
),
89+
};
7490
}
7591

7692
public function parse($value, $current): CarbonInterval

src/Internal/Marshaller/Type/DateTimeType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use Temporal\Internal\Support\Inheritance;
2020

2121
/**
22-
* @extends Type<Timestamp|non-empty-string>
22+
* @extends Type<Timestamp|string, mixed>
2323
*/
2424
class DateTimeType extends Type implements DetectableTypeInterface, RuleFactoryInterface
2525
{

src/Internal/Marshaller/Type/DurationJsonType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
/**
2222
* @psalm-import-type DateIntervalFormat from DateInterval
23-
* @extends Type<int|Duration>
23+
* @psalm-import-type DateIntervalValue from DateInterval
24+
* @extends Type<int|Duration, DateIntervalValue>
2425
*/
2526
class DurationJsonType extends Type implements DetectableTypeInterface, RuleFactoryInterface
2627
{

src/Internal/Marshaller/Type/EncodedCollectionType.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
/**
2525
* Read only type.
26-
* @extends Type<array|Message>
26+
* @extends Type<array|Message, EncodedCollection>
2727
*/
2828
final class EncodedCollectionType extends Type implements DetectableTypeInterface, RuleFactoryInterface
2929
{
@@ -52,9 +52,6 @@ public static function makeRule(\ReflectionProperty $property): ?MarshallingRule
5252
return new MarshallingRule($property->getName(), self::class, $type->getName());
5353
}
5454

55-
/**
56-
* @psalm-assert string $value
57-
*/
5855
public function parse(mixed $value, mixed $current): EncodedCollection
5956
{
6057
return match (true) {

0 commit comments

Comments
 (0)