Skip to content

Commit b25a4df

Browse files
committed
Add native types to public API
This changeset adds native types to the public API as discussed in #219. Once merged, I'm planning to add PHPStan in a follow-up PR which would take advantage of these types. Builds on top of #222, #223 and reactphp/cache#60
1 parent d9681b1 commit b25a4df

16 files changed

+71
-45
lines changed

src/Config/Config.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ final class Config
2626
* @return self
2727
* @codeCoverageIgnore
2828
*/
29-
public static function loadSystemConfigBlocking()
29+
public static function loadSystemConfigBlocking(): self
3030
{
3131
// Use WMIC output on Windows
3232
if (DIRECTORY_SEPARATOR === '\\') {
@@ -71,7 +71,7 @@ public static function loadSystemConfigBlocking()
7171
* @return self
7272
* @throws RuntimeException if the path can not be loaded (does not exist)
7373
*/
74-
public static function loadResolvConfBlocking($path = null)
74+
public static function loadResolvConfBlocking(?string $path = null): self
7575
{
7676
if ($path === null) {
7777
$path = '/etc/resolv.conf';
@@ -122,7 +122,7 @@ public static function loadResolvConfBlocking($path = null)
122122
* @return self
123123
* @link https://ss64.com/nt/wmic.html
124124
*/
125-
public static function loadWmicBlocking($command = null)
125+
public static function loadWmicBlocking(?string $command = null): self
126126
{
127127
$contents = shell_exec($command === null ? 'wmic NICCONFIG get "DNSServerSearchOrder" /format:CSV' : $command);
128128
preg_match_all('/(?<=[{;,"])([\da-f.:]{4,})(?=[};,"])/i', $contents, $matches);
@@ -133,5 +133,8 @@ public static function loadWmicBlocking($command = null)
133133
return $config;
134134
}
135135

136+
/**
137+
* @var array<string>
138+
*/
136139
public $nameservers = [];
137140
}

src/Config/HostsFile.php

+15-9
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ class HostsFile
2424
/**
2525
* Returns the default path for the hosts file on this system
2626
*
27-
* @return string
2827
* @codeCoverageIgnore
2928
*/
30-
public static function getDefaultPath()
29+
public static function getDefaultPath(): string
3130
{
3231
// use static path for all Unix-based systems
3332
if (DIRECTORY_SEPARATOR !== '\\') {
@@ -59,7 +58,7 @@ public static function getDefaultPath()
5958
* @return self
6059
* @throws RuntimeException if the path can not be loaded (does not exist)
6160
*/
62-
public static function loadFromPathBlocking($path = null)
61+
public static function loadFromPathBlocking(?string $path = null): self
6362
{
6463
if ($path === null) {
6564
$path = self::getDefaultPath();
@@ -73,16 +72,23 @@ public static function loadFromPathBlocking($path = null)
7372
return new self($contents);
7473
}
7574

75+
/**
76+
* @var string
77+
*/
7678
private $contents;
7779

7880
/**
7981
* Instantiate new hosts file with the given hosts file contents
8082
*
8183
* @param string $contents
8284
*/
83-
public function __construct($contents)
85+
public function __construct(string $contents)
8486
{
85-
// remove all comments from the contents
87+
/**
88+
* remove all comments from the contents
89+
*
90+
* @var string $contents
91+
*/
8692
$contents = preg_replace('/[ \t]*#.*/', '', strtolower($contents));
8793

8894
$this->contents = $contents;
@@ -92,9 +98,9 @@ public function __construct($contents)
9298
* Returns all IPs for the given hostname
9399
*
94100
* @param string $name
95-
* @return string[]
101+
* @return iterable<string>
96102
*/
97-
public function getIpsForHost($name)
103+
public function getIpsForHost(string $name): iterable
98104
{
99105
$name = strtolower($name);
100106

@@ -121,9 +127,9 @@ public function getIpsForHost($name)
121127
* Returns all hostnames for the given IPv4 or IPv6 address
122128
*
123129
* @param string $ip
124-
* @return string[]
130+
* @return iterable<string>
125131
*/
126-
public function getHostsForIp($ip)
132+
public function getHostsForIp(string $ip): iterable
127133
{
128134
// check binary representation of IP to avoid string case and short notation
129135
$ip = @inet_pton($ip);

src/Model/Record.php

+6-6
Original file line numberDiff line numberDiff line change
@@ -131,18 +131,18 @@ final class Record
131131
* considered a BC break. See the format definition of known types above
132132
* for more details.
133133
*
134-
* @var string|string[]|array
134+
* @var string|array<string>
135135
*/
136136
public $data;
137137

138138
/**
139139
* @param string $name
140-
* @param int $type
141-
* @param int $class
142-
* @param int $ttl
143-
* @param string|string[]|array $data
140+
* @param int $type
141+
* @param int $class
142+
* @param int $ttl
143+
* @param string|array<string> $data
144144
*/
145-
public function __construct($name, $type, $class, $ttl, $data)
145+
public function __construct(string $name, int $type, int $class, int $ttl, $data)
146146
{
147147
$this->name = $name;
148148
$this->type = $type;

src/Query/CachingExecutor.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use React\Cache\CacheInterface;
66
use React\Dns\Model\Message;
77
use React\Promise\Promise;
8+
use React\Promise\PromiseInterface;
89

910
final class CachingExecutor implements ExecutorInterface
1011
{
@@ -24,7 +25,7 @@ public function __construct(ExecutorInterface $executor, CacheInterface $cache)
2425
$this->cache = $cache;
2526
}
2627

27-
public function query(Query $query)
28+
public function query(Query $query): PromiseInterface
2829
{
2930
$id = $query->name . ':' . $query->type . ':' . $query->class;
3031

@@ -65,7 +66,7 @@ function (Message $message) use ($id) {
6566
* @return int
6667
* @internal
6768
*/
68-
public function ttl(Message $message)
69+
public function ttl(Message $message): int
6970
{
7071
// select TTL from answers (should all be the same), use smallest value if available
7172
// @link https://tools.ietf.org/html/rfc2181#section-5.2

src/Query/CoopExecutor.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace React\Dns\Query;
44

55
use React\Promise\Promise;
6+
use React\Promise\PromiseInterface;
67

78
/**
89
* Cooperatively resolves hosts via the given base executor to ensure same query is not run concurrently
@@ -45,7 +46,7 @@ public function __construct(ExecutorInterface $base)
4546
$this->executor = $base;
4647
}
4748

48-
public function query(Query $query)
49+
public function query(Query $query): PromiseInterface
4950
{
5051
$key = $this->serializeQueryToIdentity($query);
5152
if (isset($this->pending[$key])) {

src/Query/ExecutorInterface.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace React\Dns\Query;
44

5+
use React\Dns\Model\Message;
6+
use React\Promise\PromiseInterface;
7+
58
interface ExecutorInterface
69
{
710
/**
@@ -36,8 +39,8 @@ interface ExecutorInterface
3639
* ```
3740
*
3841
* @param Query $query
39-
* @return \React\Promise\PromiseInterface<\React\Dns\Model\Message>
42+
* @return PromiseInterface<Message>
4043
* resolves with response message on success or rejects with an Exception on error
4144
*/
42-
public function query(Query $query);
45+
public function query(Query $query): PromiseInterface;
4346
}

src/Query/FallbackExecutor.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace React\Dns\Query;
44

55
use React\Promise\Promise;
6+
use React\Promise\PromiseInterface;
67

78
final class FallbackExecutor implements ExecutorInterface
89
{
@@ -15,7 +16,7 @@ public function __construct(ExecutorInterface $executor, ExecutorInterface $fall
1516
$this->fallback = $fallback;
1617
}
1718

18-
public function query(Query $query)
19+
public function query(Query $query): PromiseInterface
1920
{
2021
$cancelled = false;
2122
$promise = $this->executor->query($query);

src/Query/HostsFileExecutor.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use React\Dns\Config\HostsFile;
66
use React\Dns\Model\Message;
77
use React\Dns\Model\Record;
8+
use React\Promise\PromiseInterface;
89
use function React\Promise\resolve;
910

1011
/**
@@ -25,7 +26,7 @@ public function __construct(HostsFile $hosts, ExecutorInterface $fallback)
2526
$this->fallback = $fallback;
2627
}
2728

28-
public function query(Query $query)
29+
public function query(Query $query): PromiseInterface
2930
{
3031
if ($query->class === Message::CLASS_IN && ($query->type === Message::TYPE_A || $query->type === Message::TYPE_AAAA)) {
3132
// forward lookup for type A or AAAA

src/Query/RetryExecutor.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function __construct(ExecutorInterface $executor, $retries = 2)
1616
$this->retries = $retries;
1717
}
1818

19-
public function query(Query $query)
19+
public function query(Query $query): PromiseInterface
2020
{
2121
return $this->tryQuery($query, $this->retries);
2222
}

src/Query/SelectiveTransportExecutor.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace React\Dns\Query;
44

55
use React\Promise\Promise;
6+
use React\Promise\PromiseInterface;
67

78
/**
89
* Send DNS queries over a UDP or TCP/IP stream transport.
@@ -61,7 +62,7 @@ public function __construct(ExecutorInterface $datagramExecutor, ExecutorInterfa
6162
$this->streamExecutor = $streamExecutor;
6263
}
6364

64-
public function query(Query $query)
65+
public function query(Query $query): PromiseInterface
6566
{
6667
$pending = $this->datagramExecutor->query($query);
6768

src/Query/TcpTransportExecutor.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
use React\Dns\Protocol\Parser;
88
use React\EventLoop\Loop;
99
use React\EventLoop\LoopInterface;
10+
use React\EventLoop\TimerInterface;
1011
use React\Promise\Deferred;
12+
use React\Promise\PromiseInterface;
1113
use function React\Promise\reject;
1214

1315
/**
@@ -153,7 +155,7 @@ public function __construct($nameserver, LoopInterface $loop = null)
153155
$this->dumper = new BinaryDumper();
154156
}
155157

156-
public function query(Query $query)
158+
public function query(Query $query): PromiseInterface
157159
{
158160
$request = Message::createRequestForQuery($query);
159161

@@ -328,8 +330,6 @@ public function handleRead()
328330

329331
/**
330332
* @internal
331-
* @param string $reason
332-
* @param int $code
333333
*/
334334
public function closeError($reason, $code = 0)
335335
{

src/Query/TimeoutExecutor.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,25 @@
55
use React\EventLoop\Loop;
66
use React\EventLoop\LoopInterface;
77
use React\Promise\Promise;
8+
use React\Promise\PromiseInterface;
89

910
final class TimeoutExecutor implements ExecutorInterface
1011
{
1112
private $executor;
1213
private $loop;
1314
private $timeout;
1415

15-
public function __construct(ExecutorInterface $executor, $timeout, LoopInterface $loop = null)
16+
/**
17+
* @param float|int $timeout
18+
*/
19+
public function __construct(ExecutorInterface $executor, $timeout, ?LoopInterface $loop = null)
1620
{
1721
$this->executor = $executor;
1822
$this->loop = $loop ?: Loop::get();
1923
$this->timeout = $timeout;
2024
}
2125

22-
public function query(Query $query)
26+
public function query(Query $query): PromiseInterface
2327
{
2428
$promise = $this->executor->query($query);
2529

src/Query/UdpTransportExecutor.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use React\EventLoop\Loop;
99
use React\EventLoop\LoopInterface;
1010
use React\Promise\Deferred;
11+
use React\Promise\PromiseInterface;
1112
use function React\Promise\reject;
1213

1314
/**
@@ -99,7 +100,7 @@ final class UdpTransportExecutor implements ExecutorInterface
99100
* @param string $nameserver
100101
* @param ?LoopInterface $loop
101102
*/
102-
public function __construct($nameserver, LoopInterface $loop = null)
103+
public function __construct(string $nameserver, ?LoopInterface $loop = null)
103104
{
104105
if (\strpos($nameserver, '[') === false && \substr_count($nameserver, ':') >= 2 && \strpos($nameserver, '://') === false) {
105106
// several colons, but not enclosed in square brackets => enclose IPv6 address in square brackets
@@ -117,7 +118,7 @@ public function __construct($nameserver, LoopInterface $loop = null)
117118
$this->dumper = new BinaryDumper();
118119
}
119120

120-
public function query(Query $query)
121+
public function query(Query $query): PromiseInterface
121122
{
122123
$request = Message::createRequestForQuery($query);
123124

src/Resolver/Factory.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ final class Factory
3232
*
3333
* @param Config|string $config DNS Config object (recommended) or single nameserver address
3434
* @param ?LoopInterface $loop
35-
* @return \React\Dns\Resolver\ResolverInterface
35+
* @return ResolverInterface
3636
* @throws \InvalidArgumentException for invalid DNS server address
3737
* @throws \UnderflowException when given DNS Config object has an empty list of nameservers
3838
*/
39-
public function create($config, LoopInterface $loop = null)
39+
public function create($config, LoopInterface $loop = null): ResolverInterface
4040
{
4141
$executor = $this->decorateHostsFileExecutor($this->createExecutor($config, $loop ?: Loop::get()));
4242

@@ -55,11 +55,11 @@ public function create($config, LoopInterface $loop = null)
5555
* @param Config|string $config DNS Config object (recommended) or single nameserver address
5656
* @param ?LoopInterface $loop
5757
* @param ?CacheInterface $cache
58-
* @return \React\Dns\Resolver\ResolverInterface
58+
* @return ResolverInterface
5959
* @throws \InvalidArgumentException for invalid DNS server address
6060
* @throws \UnderflowException when given DNS Config object has an empty list of nameservers
6161
*/
62-
public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null)
62+
public function createCached($config, LoopInterface $loop = null, CacheInterface $cache = null): ResolverInterface
6363
{
6464
// default to keeping maximum of 256 responses in cache unless explicitly given
6565
if (!($cache instanceof CacheInterface)) {

src/Resolver/Resolver.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use React\Dns\Query\ExecutorInterface;
77
use React\Dns\Query\Query;
88
use React\Dns\RecordNotFoundException;
9+
use React\Promise\PromiseInterface;
910

1011
/**
1112
* @see ResolverInterface for the base interface
@@ -19,14 +20,14 @@ public function __construct(ExecutorInterface $executor)
1920
$this->executor = $executor;
2021
}
2122

22-
public function resolve($domain)
23+
public function resolve(string $domain): PromiseInterface
2324
{
2425
return $this->resolveAll($domain, Message::TYPE_A)->then(function (array $ips) {
2526
return $ips[array_rand($ips)];
2627
});
2728
}
2829

29-
public function resolveAll($domain, $type)
30+
public function resolveAll(string $domain, int $type): PromiseInterface
3031
{
3132
$query = new Query($domain, $type, Message::CLASS_IN);
3233

0 commit comments

Comments
 (0)