Skip to content

Commit b102ff5

Browse files
Static analysis fixes (#203)
* Fixed bug in the cookie plugin * Fixed typo in phpdoc * Clarified plugin client factory type information * Added extra type information to help phpstan * Don't temprarily violate property types in the flexible http client * Removed redundent information * Cast null to string for date parsing * Added additional type to help phpstan * Run phpstan on actions
1 parent 788697e commit b102ff5

17 files changed

+111
-47
lines changed

.gitattributes

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
.editorconfig export-ignore
2-
.gitattributes export-ignore
3-
/.github/ export-ignore
4-
.gitignore export-ignore
5-
/.php_cs export-ignore
6-
/.scrutinizer.yml export-ignore
7-
/.styleci.yml export-ignore
8-
/behat.yml.dist export-ignore
9-
/features/ export-ignore
10-
/phpspec.ci.yml export-ignore
11-
/phpspec.yml.dist export-ignore
12-
/phpunit.xml.dist export-ignore
13-
/spec/ export-ignore
14-
/tests/ export-ignore
1+
.editorconfig export-ignore
2+
.gitattributes export-ignore
3+
/.github/ export-ignore
4+
.gitignore export-ignore
5+
/.php_cs export-ignore
6+
/.scrutinizer.yml export-ignore
7+
/.styleci.yml export-ignore
8+
/behat.yml.dist export-ignore
9+
/features/ export-ignore
10+
/phpspec.ci.yml export-ignore
11+
/phpspec.yml.dist export-ignore
12+
/phpunit.xml.dist export-ignore
13+
/phpstan.neon.dist export-ignore
14+
/spec/ export-ignore
15+
/tests/ export-ignore

.github/workflows/static.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: static
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
phpstan:
9+
name: PHPStan
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v2
15+
16+
- name: PHPStan
17+
uses: OskarStark/[email protected]
18+
env:
19+
REQUIRE_DEV: false
20+
with:
21+
args: analyze --no-progress

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
/composer.lock
66
/phpspec.yml
77
/phpunit.xml
8+
/phpstan.neon
89
/vendor/

.php_cs.dist

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ return PhpCsFixer\Config::create()
1818
'syntax' => 'short',
1919
],
2020
'no_empty_phpdoc' => true,
21-
'no_superfluous_phpdoc_tags' => true,
21+
'phpdoc_to_comment' => false,
2222
'single_line_throw' => false,
2323
])
2424
->setFinder($finder);

phpstan.neon.dist

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
parameters:
2+
level: max
3+
checkMissingIterableValueType: false
4+
treatPhpDocTypesAsCertain: false
5+
paths:
6+
- src
7+
ignoreErrors:
8+
-
9+
message: "#^Strict comparison using \\!\\=\\= between null and null will always evaluate to false\\.$#"
10+
count: 1
11+
path: src/HttpMethodsClient.php
12+
13+
-
14+
message: "#^Cannot call method createStream\\(\\) on Psr\\\\Http\\\\Message\\\\StreamFactoryInterface\\|null\\.$#"
15+
count: 1
16+
path: src/HttpMethodsClient.php
17+
18+
-
19+
message: "#^Method Http\\\\Client\\\\Common\\\\Plugin\\\\Journal\\:\\:addSuccess\\(\\) has no return typehint specified\\.$#"
20+
count: 1
21+
path: src/Plugin/Journal.php
22+
23+
-
24+
message: "#^Method Http\\\\Client\\\\Common\\\\Plugin\\\\Journal\\:\\:addFailure\\(\\) has no return typehint specified\\.$#"
25+
count: 1
26+
path: src/Plugin/Journal.php
27+
28+
-
29+
message: "#^Call to an undefined method Http\\\\Client\\\\HttpAsyncClient\\:\\:sendRequest\\(\\)\\.$#"
30+
count: 1
31+
path: src/PluginClient.php

src/Deferred.php

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ public function wait($unwrap = true)
146146
return $this->value;
147147
}
148148

149+
/** @var ClientExceptionInterface */
149150
throw $this->failure;
150151
}
151152
}

src/Exception/HttpClientNoMatchException.php

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
*/
1515
final class HttpClientNoMatchException extends TransferException
1616
{
17+
/**
18+
* @var RequestInterface
19+
*/
1720
private $request;
1821

1922
public function __construct(string $message, RequestInterface $request, \Exception $previous = null)

src/FlexibleHttpClient.php

+2-10
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,7 @@ public function __construct($client)
3030
);
3131
}
3232

33-
$this->httpClient = $client;
34-
$this->httpAsyncClient = $client;
35-
36-
if (!($this->httpClient instanceof ClientInterface)) {
37-
$this->httpClient = new EmulatedHttpClient($this->httpClient);
38-
}
39-
40-
if (!($this->httpAsyncClient instanceof HttpAsyncClient)) {
41-
$this->httpAsyncClient = new EmulatedHttpAsyncClient($this->httpAsyncClient);
42-
}
33+
$this->httpClient = $client instanceof ClientInterface ? $client : new EmulatedHttpClient($client);
34+
$this->httpAsyncClient = $client instanceof HttpAsyncClient ? $client : new EmulatedHttpAsyncClient($client);
4335
}
4436
}

src/HttpClientPool/HttpClientPool.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ abstract class HttpClientPool implements HttpClientPoolInterface
2525
/**
2626
* Add a client to the pool.
2727
*
28-
* @param ClientInterface|HttpAsyncClient|HttpClientPoolItem $client
28+
* @param ClientInterface|HttpAsyncClient $client
2929
*/
3030
public function addHttpClient($client): void
3131
{
32-
if (!$client instanceof ClientInterface && !$client instanceof HttpAsyncClient && !$client instanceof HttpClientPoolItem) {
32+
// no need to check for HttpClientPoolItem here, since it extends the other interfaces
33+
if (!$client instanceof ClientInterface && !$client instanceof HttpAsyncClient) {
3334
throw new \TypeError(
34-
sprintf('%s::addHttpClient(): Argument #1 ($client) must be of type %s|%s|%s, %s given', self::class, ClientInterface::class, HttpAsyncClient::class, HttpClientPoolItem::class, get_debug_type($client))
35+
sprintf('%s::addHttpClient(): Argument #1 ($client) must be of type %s|%s, %s given', self::class, ClientInterface::class, HttpAsyncClient::class, get_debug_type($client))
3536
);
3637
}
3738

src/HttpClientRouter.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
final class HttpClientRouter implements HttpClientRouterInterface
2020
{
2121
/**
22-
* @var array
22+
* @var (array{matcher: RequestMatcher, client: FlexibleHttpClient})[]
2323
*/
2424
private $clients = [];
2525

@@ -60,10 +60,8 @@ public function addClient($client, RequestMatcher $requestMatcher): void
6060

6161
/**
6262
* Choose an HTTP client given a specific request.
63-
*
64-
* @return ClientInterface|HttpAsyncClient
6563
*/
66-
private function chooseHttpClient(RequestInterface $request)
64+
private function chooseHttpClient(RequestInterface $request): FlexibleHttpClient
6765
{
6866
foreach ($this->clients as $client) {
6967
if ($client['matcher']->matches($request)) {

src/HttpMethodsClient.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ final class HttpMethodsClient implements HttpMethodsClientInterface
3131
private $streamFactory;
3232

3333
/**
34-
* @param RequestFactory|RequestFactoryInterface
34+
* @param RequestFactory|RequestFactoryInterface $requestFactory
3535
*/
3636
public function __construct(ClientInterface $httpClient, $requestFactory, StreamFactoryInterface $streamFactory = null)
3737
{

src/Plugin/CookiePlugin.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private function createCookie(RequestInterface $request, string $setCookieHeader
117117
switch (strtolower($key)) {
118118
case 'expires':
119119
try {
120-
$expires = CookieUtil::parseDate($value);
120+
$expires = CookieUtil::parseDate((string) $value);
121121
} catch (UnexpectedValueException $e) {
122122
throw new TransferException(
123123
sprintf(
@@ -167,13 +167,13 @@ private function createCookie(RequestInterface $request, string $setCookieHeader
167167
*
168168
* @param string $part A single cookie value in format key=value
169169
*
170-
* @return string[]
170+
* @return array{0:string, 1:?string}
171171
*/
172172
private function createValueKey(string $part): array
173173
{
174174
$parts = explode('=', $part, 2);
175175
$key = trim($parts[0]);
176-
$value = isset($parts[1]) ? trim($parts[1]) : true;
176+
$value = isset($parts[1]) ? trim($parts[1]) : null;
177177

178178
return [$key, $value];
179179
}

src/Plugin/SeekableBodyPlugin.php

+6
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@
1212
*/
1313
abstract class SeekableBodyPlugin implements Plugin
1414
{
15+
/**
16+
* @var bool
17+
*/
1518
protected $useFileBuffer;
1619

20+
/**
21+
* @var int
22+
*/
1723
protected $memoryBufferSize;
1824

1925
/**

src/PluginChain.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ final class PluginChain
1414
/** @var Plugin[] */
1515
private $plugins;
1616

17-
/** @var callable */
17+
/** @var callable(RequestInterface): Promise */
1818
private $clientCallable;
1919

2020
/** @var int */
@@ -24,9 +24,9 @@ final class PluginChain
2424
private $restarts = 0;
2525

2626
/**
27-
* @param Plugin[] $plugins A plugin chain
28-
* @param callable $clientCallable Callable making the HTTP call
29-
* @param array $options {
27+
* @param Plugin[] $plugins A plugin chain
28+
* @param callable(RequestInterface): Promise $clientCallable Callable making the HTTP call
29+
* @param array $options {
3030
*
3131
* @var int $max_restarts
3232
* }

src/PluginClient.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Http\Client\HttpClient;
1010
use Http\Client\Promise\HttpFulfilledPromise;
1111
use Http\Client\Promise\HttpRejectedPromise;
12+
use Http\Promise\Promise;
1213
use Psr\Http\Client\ClientInterface;
1314
use Psr\Http\Message\RequestInterface;
1415
use Psr\Http\Message\ResponseInterface;
@@ -24,7 +25,7 @@ final class PluginClient implements HttpClient, HttpAsyncClient
2425
/**
2526
* An HTTP async client.
2627
*
27-
* @var HttpAsyncClient|HttpClient
28+
* @var HttpAsyncClient
2829
*/
2930
private $client;
3031

@@ -71,13 +72,13 @@ public function __construct($client, array $plugins = [], array $options = [])
7172
*/
7273
public function sendRequest(RequestInterface $request): ResponseInterface
7374
{
74-
// If we don't have an http client, use the async call
75-
if (!($this->client instanceof ClientInterface)) {
75+
// If the client doesn't support sync calls, call async
76+
if (!$this->client instanceof ClientInterface) {
7677
return $this->sendAsyncRequest($request)->wait();
7778
}
7879

79-
// Else we want to use the synchronous call of the underlying client, and not the async one in the case
80-
// we have both an async and sync call
80+
// Else we want to use the synchronous call of the underlying client,
81+
// and not the async one in the case we have both an async and sync call
8182
$pluginChain = $this->createPluginChain($this->plugins, function (RequestInterface $request) {
8283
try {
8384
return new HttpFulfilledPromise($this->client->sendRequest($request));
@@ -121,9 +122,12 @@ private function configure(array $options = []): array
121122
*
122123
* @param Plugin[] $plugins A plugin chain
123124
* @param callable $clientCallable Callable making the HTTP call
125+
*
126+
* @return callable(RequestInterface): Promise
124127
*/
125128
private function createPluginChain(array $plugins, callable $clientCallable): callable
126129
{
130+
/** @var callable(RequestInterface): Promise */
127131
return new PluginChain($plugins, $clientCallable, $this->options);
128132
}
129133
}

src/PluginClientBuilder.php

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ public function addPlugin(Plugin $plugin, int $priority = 0): self
3030
return $this;
3131
}
3232

33+
/**
34+
* @param mixed $value
35+
*/
3336
public function setOption(string $name, $value): self
3437
{
3538
$this->options[$name] = $value;

src/PluginClientFactory.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
final class PluginClientFactory
1717
{
1818
/**
19-
* @var callable|null
19+
* @var (callable(ClientInterface|HttpAsyncClient, Plugin[], array): PluginClient)|null
2020
*/
2121
private static $factory;
2222

@@ -28,8 +28,10 @@ final class PluginClientFactory
2828
* application execution.
2929
*
3030
* @internal
31+
*
32+
* @param callable(ClientInterface|HttpAsyncClient, Plugin[], array): PluginClient $factory
3133
*/
32-
public static function setFactory(callable $factory)
34+
public static function setFactory(callable $factory): void
3335
{
3436
static::$factory = $factory;
3537
}

0 commit comments

Comments
 (0)