Skip to content

Commit df76fe8

Browse files
xepozzgithub-actions
andauthored
feat: improve static analysis, part 1 (#728)
* feat: improve static analysis, part 1 * style(php-cs-fixer): fix coding standards * feat: enhance compatibility and static analysis for testing - Added `testing/src` to `psalm.xml` for better coverage. - Unified OS constants using `OperatingSystem` across mappings. - Improved handling of environment variables and type safety in `SystemInfo` and `Environment`. - Refactored `RoadRunnerActivityInvocationCache` and `WorkerMock` for cleaner interfaces. - Adjusted `Downloader` to use a working directory for asset management. * style(php-cs-fixer): fix coding standards * refactor: adjust attribute declarations for NamedArgumentConstructor compatibility - Updated attribute declarations across Workflow and Activity classes for better compatibility with `NamedArgumentConstructor`. - Removed unnecessary property and constructor in `LocalActivityInterface`. - Updated `psalm-baseline.xml` to reflect changes and deprecations. --------- Co-authored-by: github-actions <github-actions@users.noreply.github.com>
1 parent 3eaec0e commit df76fe8

38 files changed

Lines changed: 233 additions & 247 deletions

psalm-baseline.xml

Lines changed: 21 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<files psalm-version="6.14.3@d0b040a91f280f071c1abcb1b77ce3822058725a">
3-
<file src="src/Activity.php">
4-
<ImplicitToStringCast>
5-
<code><![CDATA[$type]]></code>
6-
</ImplicitToStringCast>
7-
</file>
83
<file src="src/Activity/ActivityInterface.php">
94
<DeprecatedClass>
105
<code><![CDATA[NamedArgumentConstructor]]></code>
@@ -15,21 +10,11 @@
1510
<code><![CDATA[NamedArgumentConstructor]]></code>
1611
</DeprecatedClass>
1712
</file>
18-
<file src="src/Activity/ActivityOptions.php">
19-
<PossiblyNullReference>
20-
<code><![CDATA[mergeWith]]></code>
21-
</PossiblyNullReference>
22-
</file>
2313
<file src="src/Activity/LocalActivityInterface.php">
2414
<DeprecatedClass>
2515
<code><![CDATA[NamedArgumentConstructor]]></code>
2616
</DeprecatedClass>
2717
</file>
28-
<file src="src/Activity/LocalActivityOptions.php">
29-
<PossiblyNullReference>
30-
<code><![CDATA[mergeWith]]></code>
31-
</PossiblyNullReference>
32-
</file>
3318
<file src="src/Client/ActivityCompletionClientInterface.php">
3419
<MissingParamType>
3520
<code><![CDATA[$details]]></code>
@@ -40,17 +25,6 @@
4025
<code><![CDATA[recordHeartbeatByToken]]></code>
4126
</MissingReturnType>
4227
</file>
43-
<file src="src/Client/Common/Paginator.php">
44-
<PossiblyNullPropertyAssignmentValue>
45-
<code><![CDATA[$loader->current()]]></code>
46-
</PossiblyNullPropertyAssignmentValue>
47-
</file>
48-
<file src="src/Client/Common/RpcRetryOptions.php">
49-
<TypeDoesNotContainType>
50-
<code><![CDATA[withInitialInterval]]></code>
51-
<code><![CDATA[withMaximumInterval]]></code>
52-
</TypeDoesNotContainType>
53-
</file>
5428
<file src="src/Client/GRPC/Context.php">
5529
<ArgumentTypeCoercion>
5630
<code><![CDATA[$format]]></code>
@@ -274,62 +248,16 @@
274248
<code><![CDATA[$parts[1]]]></code>
275249
</PossiblyUndefinedArrayOffset>
276250
</file>
277-
<file src="src/DataConverter/DataConverter.php">
278-
<MissingImmutableAnnotation>
279-
<code><![CDATA[DataConverter]]></code>
280-
</MissingImmutableAnnotation>
281-
<PossiblyNullArgument>
282-
<code><![CDATA[$type]]></code>
283-
</PossiblyNullArgument>
284-
</file>
285251
<file src="src/DataConverter/EncodedCollection.php">
286252
<InvalidArgument>
287253
<code><![CDATA[$name]]></code>
288254
<code><![CDATA[$value]]></code>
289255
</InvalidArgument>
290-
<MoreSpecificImplementedParamType>
291-
<code><![CDATA[$type]]></code>
292-
</MoreSpecificImplementedParamType>
293-
</file>
294-
<file src="src/DataConverter/EncodedValues.php">
295-
<PossiblyNullIterator>
296-
<code><![CDATA[$this->values]]></code>
297-
</PossiblyNullIterator>
298-
<UnsafeInstantiation>
299-
<code><![CDATA[new static()]]></code>
300-
<code><![CDATA[new static()]]></code>
301-
<code><![CDATA[new static()]]></code>
302-
</UnsafeInstantiation>
303256
</file>
304257
<file src="src/DataConverter/JsonConverter.php">
305-
<ArgumentTypeCoercion>
306-
<code><![CDATA[$type->getName()]]></code>
307-
</ArgumentTypeCoercion>
308258
<DeprecatedClass>
309259
<code><![CDATA[new AnnotationReader()]]></code>
310260
</DeprecatedClass>
311-
<PossiblyInvalidArgument>
312-
<code><![CDATA[$e->getCode()]]></code>
313-
<code><![CDATA[$e->getCode()]]></code>
314-
</PossiblyInvalidArgument>
315-
<PossiblyInvalidPropertyFetch>
316-
<code><![CDATA[$data->name]]></code>
317-
</PossiblyInvalidPropertyFetch>
318-
</file>
319-
<file src="src/DataConverter/ProtoConverter.php">
320-
<ArgumentTypeCoercion>
321-
<code><![CDATA[$type->getName()]]></code>
322-
</ArgumentTypeCoercion>
323-
</file>
324-
<file src="src/DataConverter/ProtoJsonConverter.php">
325-
<ArgumentTypeCoercion>
326-
<code><![CDATA[$type->getName()]]></code>
327-
</ArgumentTypeCoercion>
328-
</file>
329-
<file src="src/DataConverter/ValuesInterface.php">
330-
<MissingReturnType>
331-
<code><![CDATA[setDataConverter]]></code>
332-
</MissingReturnType>
333261
</file>
334262
<file src="src/Exception/Client/ActivityCompletionException.php">
335263
<PossiblyNullReference>
@@ -638,25 +566,6 @@
638566
<code><![CDATA[$updateValidator]]></code>
639567
</PropertyNotSetInConstructor>
640568
</file>
641-
<file src="src/Internal/Events/EventEmitterInterface.php">
642-
<InvalidTemplateParam>
643-
<code><![CDATA[T]]></code>
644-
</InvalidTemplateParam>
645-
</file>
646-
<file src="src/Internal/Events/EventEmitterTrait.php">
647-
<LessSpecificImplementedReturnType>
648-
<code><![CDATA[self]]></code>
649-
<code><![CDATA[self]]></code>
650-
</LessSpecificImplementedReturnType>
651-
<PossiblyNullFunctionCall>
652-
<code><![CDATA[$callback(...$arguments)]]></code>
653-
</PossiblyNullFunctionCall>
654-
</file>
655-
<file src="src/Internal/Events/EventListenerInterface.php">
656-
<InvalidTemplateParam>
657-
<code><![CDATA[T]]></code>
658-
</InvalidTemplateParam>
659-
</file>
660569
<file src="src/Internal/Interceptor/Pipeline.php">
661570
<ImpureFunctionCall>
662571
<code><![CDATA[$this->last]]></code>
@@ -1079,9 +988,6 @@
1079988
<MoreSpecificImplementedParamType>
1080989
<code><![CDATA[$method]]></code>
1081990
</MoreSpecificImplementedParamType>
1082-
<PossiblyNullArgument>
1083-
<code><![CDATA[$handler?->getReturnType()]]></code>
1084-
</PossiblyNullArgument>
1085991
</file>
1086992
<file src="src/Internal/Workflow/ChildWorkflowStub.php">
1087993
<ArgumentTypeCoercion>
@@ -1105,9 +1011,6 @@
11051011
<code><![CDATA[$this->start(...$args)->then(fn() => $this->getResult($returnType))]]></code>
11061012
<code><![CDATA[EncodedValues::decodePromise($started)]]></code>
11071013
</LessSpecificReturnStatement>
1108-
<MissingParamType>
1109-
<code><![CDATA[$returnType]]></code>
1110-
</MissingParamType>
11111014
<MoreSpecificReturnType>
11121015
<code><![CDATA[PromiseInterface]]></code>
11131016
<code><![CDATA[PromiseInterface]]></code>
@@ -1258,9 +1161,6 @@
12581161
<code><![CDATA[$cacheName]]></code>
12591162
<code><![CDATA[$host]]></code>
12601163
</ArgumentTypeCoercion>
1261-
<MissingParamType>
1262-
<code><![CDATA[$value]]></code>
1263-
</MissingParamType>
12641164
<PossiblyUndefinedStringArrayOffset>
12651165
<code><![CDATA[$request->getOptions()['name']]]></code>
12661166
</PossiblyUndefinedStringArrayOffset>
@@ -1462,9 +1362,6 @@
14621362
<PossiblyUndefinedStringArrayOffset>
14631363
<code><![CDATA[$headers[self::HEADER_TASK_QUEUE]]]></code>
14641364
</PossiblyUndefinedStringArrayOffset>
1465-
<PropertyNotSetInConstructor>
1466-
<code><![CDATA[$codec]]></code>
1467-
</PropertyNotSetInConstructor>
14681365
<UndefinedInterfaceMethod>
14691366
<code><![CDATA[dispatch]]></code>
14701367
<code><![CDATA[dispatch]]></code>
@@ -1483,16 +1380,6 @@
14831380
<code><![CDATA[getUpdateContext]]></code>
14841381
</UndefinedInterfaceMethod>
14851382
</file>
1486-
<file src="src/Workflow/ChildWorkflowOptions.php">
1487-
<PossiblyNullReference>
1488-
<code><![CDATA[mergeWith]]></code>
1489-
</PossiblyNullReference>
1490-
</file>
1491-
<file src="src/Workflow/ChildWorkflowStubInterface.php">
1492-
<MissingParamType>
1493-
<code><![CDATA[$returnType]]></code>
1494-
</MissingParamType>
1495-
</file>
14961383
<file src="src/Workflow/QueryMethod.php">
14971384
<DeprecatedClass>
14981385
<code><![CDATA[NamedArgumentConstructor]]></code>
@@ -1503,11 +1390,6 @@
15031390
<code><![CDATA[NamedArgumentConstructor]]></code>
15041391
</DeprecatedClass>
15051392
</file>
1506-
<file src="src/Workflow/Saga.php">
1507-
<PossiblyInvalidArgument>
1508-
<code><![CDATA[$e->getCode()]]></code>
1509-
</PossiblyInvalidArgument>
1510-
</file>
15111393
<file src="src/Workflow/SignalMethod.php">
15121394
<DeprecatedClass>
15131395
<code><![CDATA[NamedArgumentConstructor]]></code>
@@ -1538,4 +1420,25 @@
15381420
<code><![CDATA[NamedArgumentConstructor]]></code>
15391421
</DeprecatedClass>
15401422
</file>
1423+
<file src="testing/src/Downloader.php">
1424+
<PossiblyUndefinedStringArrayOffset>
1425+
<code><![CDATA[$asset['browser_download_url']]]></code>
1426+
<code><![CDATA[$response->toArray()['assets']]]></code>
1427+
</PossiblyUndefinedStringArrayOffset>
1428+
</file>
1429+
<file src="testing/src/Replay/WorkflowReplayer.php">
1430+
<UndefinedMethod>
1431+
<code><![CDATA[getWorkflowType]]></code>
1432+
</UndefinedMethod>
1433+
</file>
1434+
<file src="testing/src/TestService.php">
1435+
<UndefinedClass>
1436+
<code><![CDATA[ChannelCredentials]]></code>
1437+
</UndefinedClass>
1438+
</file>
1439+
<file src="testing/src/WorkerMock.php">
1440+
<DeprecatedMethod>
1441+
<code><![CDATA[registerActivityImplementations]]></code>
1442+
</DeprecatedMethod>
1443+
</file>
15411444
</files>

psalm.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
>
1818
<projectFiles>
1919
<directory name="src" />
20+
<directory name="testing/src" />
2021
<ignoreFiles>
2122
<directory name="vendor" />
2223
</ignoreFiles>

src/Activity.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
use Temporal\Exception\OutOfContextException;
2020
use Temporal\Internal\Support\Facade;
2121

22+
/**
23+
* @psalm-import-type TType from Type
24+
*/
2225
final class Activity extends Facade
2326
{
2427
/**
@@ -92,7 +95,8 @@ public static function hasHeartbeatDetails(): bool
9295
*
9396
* This method retrieves the payload that was passed into the last call of the {@see Activity::heartbeat()} method.
9497
*
95-
* @param Type|string|\ReflectionType|\ReflectionClass|null $type
98+
* @param null|mixed $type
99+
* @psalm-param TType $type
96100
* @throws OutOfContextException in the absence of the activity execution context.
97101
*/
98102
public static function getHeartbeatDetails($type = null): mixed

src/Activity/ActivityContextInterface.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
use Temporal\Exception\Client\ActivityCompletionException;
1919
use Temporal\Exception\Client\ActivityPausedException;
2020

21+
/**
22+
* @psalm-import-type TType from Type
23+
*/
2124
interface ActivityContextInterface
2225
{
2326
/**
@@ -46,7 +49,8 @@ public function hasHeartbeatDetails(): bool;
4649
*
4750
* @see Activity::getHeartbeatDetails()
4851
*
49-
* @param Type|string $type
52+
* @param null|mixed $type
53+
* @psalm-param TType $type
5054
*/
5155
public function getLastHeartbeatDetails($type = null): mixed;
5256

src/Activity/ActivityOptions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public function mergeWith(?MethodRetry $retry = null): self
154154
$self = clone $this;
155155

156156
if ($retry !== null && $this->diff->isPresent($self, 'retryOptions')) {
157-
$self->retryOptions = $this->retryOptions->mergeWith($retry);
157+
$self->retryOptions = $this->retryOptions?->mergeWith($retry);
158158
}
159159

160160
return $self;

src/Activity/LocalActivityInterface.php

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Temporal\Activity;
1313

1414
use Doctrine\Common\Annotations\Annotation\Target;
15-
use JetBrains\PhpStorm\Immutable;
1615
use Spiral\Attributes\NamedArgumentConstructor;
1716

1817
/**
@@ -33,24 +32,4 @@
3332
* @Target({ "CLASS" })
3433
*/
3534
#[\Attribute(\Attribute::TARGET_CLASS), NamedArgumentConstructor]
36-
final class LocalActivityInterface extends ActivityInterface
37-
{
38-
/**
39-
* Prefix to prepend to method names to generate activity types. Default is
40-
* empty string which means that method names are used as activity types.
41-
*
42-
* Note that this value is ignored if a name of an activity is specified
43-
* explicitly through {@see ActivityMethod::$name}.
44-
*
45-
* Be careful about names that contain special characters. These names can
46-
* be used as metric tags. And systems like prometheus ignore metrics which
47-
* have tags with unsupported characters.
48-
*/
49-
#[Immutable]
50-
public string $prefix = '';
51-
52-
public function __construct(string $prefix = '')
53-
{
54-
$this->prefix = $prefix;
55-
}
56-
}
35+
final class LocalActivityInterface extends ActivityInterface {}

src/Activity/LocalActivityOptions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public function mergeWith(?MethodRetry $retry = null): self
9494
$self = clone $this;
9595

9696
if ($retry !== null && $this->diff->isPresent($self, 'retryOptions')) {
97-
$self->retryOptions = $this->retryOptions->mergeWith($retry);
97+
$self->retryOptions = $this->retryOptions?->mergeWith($retry);
9898
}
9999

100100
return $self;

src/Client/Common/Paginator.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,16 @@ private function __construct(
3030
private readonly int $pageNumber,
3131
private ?\Closure $counter,
3232
) {
33-
$this->collection = $loader->current();
33+
$current = $loader->current();
34+
if (!\is_array($current)) {
35+
throw new \InvalidArgumentException(
36+
\sprintf(
37+
'Generator must return an array of items, %s returned.',
38+
\get_debug_type($current),
39+
),
40+
);
41+
}
42+
$this->collection = $current;
3443
}
3544

3645
/**

src/Common/RetryOptions.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ public function mergeWith(?MethodRetry $retry = null): self
130130
*
131131
* @param mixed $interval parseable string, null, int|float in seconds, {@see \DateInterval}, or {@see Duration}
132132
* @return static
133-
* @psalm-assert DateIntervalValue|null $interval
134133
*/
135134
#[Pure]
136135
public function withInitialInterval(mixed $interval): self
@@ -162,7 +161,6 @@ public function withBackoffCoefficient(float $coefficient): self
162161
*
163162
* @param mixed $interval parseable string, null, int|float in seconds, {@see \DateInterval}, or {@see Duration}
164163
* @return static
165-
* @psalm-assert DateIntervalValue|null $interval
166164
*/
167165
#[Pure]
168166
public function withMaximumInterval(mixed $interval): self

src/DataConverter/DataConverter.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
use Temporal\Api\Common\V1\Payload;
1515
use Temporal\Exception\DataConverterException;
1616

17+
/**
18+
* @psalm-import-type TType from Type
19+
*/
1720
final class DataConverter implements DataConverterInterface
1821
{
1922
/**
@@ -40,7 +43,7 @@ public static function createDefault(): DataConverterInterface
4043
}
4144

4245
/**
43-
* @param string|\ReflectionClass|\ReflectionType|Type|null $type
46+
* @param TType $type
4447
*/
4548
public function fromPayload(Payload $payload, $type): mixed
4649
{

0 commit comments

Comments
 (0)