Skip to content

Commit

Permalink
Merge pull request #927 from Chance-fyi/phpstan
Browse files Browse the repository at this point in the history
Add static analysis tool PHPStan
  • Loading branch information
walkor authored Jul 4, 2023
2 parents 34a1f08 + 0a8d8c0 commit 240eda9
Show file tree
Hide file tree
Showing 15 changed files with 81 additions and 44 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ jobs:
timeout_minutes: 5
max_attempts: 5
command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
# command: composer install --prefer-dist --no-interaction --no-progress

- name: Static analysis
run: composer analyse

- name: Execute tests
run: vendor/bin/pest --coverage
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,15 @@
"require-dev": {
"pestphp/pest": "2.x-dev",
"mockery/mockery": "2.0.x-dev",
"guzzlehttp/guzzle": "^7.0"
"guzzlehttp/guzzle": "^7.0",
"phpstan/phpstan": "1.11.x-dev"
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
}
},
"scripts": {
"analyse": "phpstan analyse -c phpstan.neon --memory-limit=-1"
}
}
34 changes: 34 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
parameters:
level: 5
paths:
- src
- tests
ignoreErrors:
-
path: src/Events/Revolt.php
messages:
- '#Property Workerman\\Events\\Revolt::\$driver has unknown class Revolt\\EventLoop\\Driver as its type.#'
- '#Call to static method getDriver\(\) on an unknown class Revolt\\EventLoop.#'
- '#Method Workerman\\Events\\Revolt::driver\(\) has invalid return type Revolt\\EventLoop\\Driver.#'
- '#Call to method .* on an unknown class Revolt\\EventLoop\\Driver.#'
-
path: src/Events/Swow.php
messages:
- '#Used function Swow\\Sync\\waitAll not found.#'
- '#Call to static method .* on an unknown class Swow\\.*.#'
- '#Function msleep not found.#'
- '#Function stream_poll_one not found.#'
- '#Caught class Swow\\SignalException not found.#'
- '#Function Swow\\Sync\\waitAll not found.#'
- '#Constant STREAM_POLLHUP not found.#'
- '#Constant STREAM_POLLIN not found.#'
- '#Constant STREAM_POLLNONE not found.#'
- '#Constant STREAM_POLLOUT not found.#'
- '#Property Workerman\\Events\\Swow::.* has unknown class Swow\\Coroutine as its type.#'
- path: src/Timer.php
message: '#Call to static method getSuspension\(\) on an unknown class Revolt\\EventLoop.#'
- path: tests/Pest.php
message: '#Undefined variable: \$this#'
- path: src/Worker.php
message: '#Constant LINE_VERSION_LENGTH not found.#'
- message: '#Parameter \#1 \$callback of function set_error_handler expects \(callable\(int, string, string, int\): bool\)\|null,.*#'
4 changes: 2 additions & 2 deletions src/Connection/TcpConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

/**
* TcpConnection.
* @property string websocketType
* @property string $websocketType
*/
class TcpConnection extends ConnectionInterface implements JsonSerializable
{
Expand Down Expand Up @@ -1033,7 +1033,7 @@ public function destroy(): void
/**
* Enable or disable Cache.
*
* @param mixed $value
* @param bool $value
*/
public static function enableCache(bool $value = true): void
{
Expand Down
2 changes: 2 additions & 0 deletions src/Events/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ public function onReadable($stream, callable $func): void
$className = $this->eventClassName;
$fdKey = (int)$stream;
$event = new $this->eventClassName($this->eventBase, $stream, $className::READ | $className::PERSIST, $func, $stream);
// @phpstan-ignore-next-line Negated boolean expression is always false.
if (!$event || !$event->add()) {
return;
}
Expand Down Expand Up @@ -194,6 +195,7 @@ public function onWritable($stream, callable $func): void
$className = $this->eventClassName;
$fdKey = (int)$stream;
$event = new $this->eventClassName($this->eventBase, $stream, $className::WRITE | $className::PERSIST, $func, $stream);
// @phpstan-ignore-next-line Negated boolean expression is always false.
if (!$event || !$event->add()) {
return;
}
Expand Down
1 change: 1 addition & 0 deletions src/Events/Swow.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public function repeat(float $interval, callable $func, array $args = []): int
$t = max($t, 1);
$that = $this;
$coroutine = Coroutine::run(static function () use ($t, $func, $args, $that): void {
// @phpstan-ignore-next-line While loop condition is always true.
while (true) {
msleep($t);
try {
Expand Down
11 changes: 9 additions & 2 deletions src/Protocols/Http/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ class Request
*/
protected static bool $enableCache = true;

/**
* Session id.
*
* @var mixed|string
*/
protected mixed $sid;

/**
* Request constructor.
*
Expand Down Expand Up @@ -296,11 +303,11 @@ public function session(): Session
/**
* Get/Set session id.
*
* @param null $sessionId
* @param string|null $sessionId
* @return string
* @throws Exception
*/
public function sessionId($sessionId = null): string
public function sessionId(string $sessionId = null): string
{
if ($sessionId) {
unset($this->sid);
Expand Down
2 changes: 1 addition & 1 deletion src/Protocols/Http/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ protected function createHeadForFile(array $fileInfo): string

$fileInfo = pathinfo($file);
$extension = $fileInfo['extension'] ?? '';
$baseName = $fileInfo['basename'] ?? 'unknown';
$baseName = $fileInfo['basename'] ?: 'unknown';
if (!isset($headers['Content-Type'])) {
if (isset(self::$mimeTypeMap[$extension])) {
$head .= "Content-Type: " . self::$mimeTypeMap[$extension] . "\r\n";
Expand Down
2 changes: 0 additions & 2 deletions src/Protocols/Http/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
namespace Workerman\Protocols\Http;

use Exception;
use JetBrains\PhpStorm\ArrayShape;
use RuntimeException;
use Workerman\Protocols\Http\Session\FileSessionHandler;
use Workerman\Protocols\Http\Session\SessionHandlerInterface;
Expand Down Expand Up @@ -381,7 +380,6 @@ public static function handlerClass(mixed $className = null, mixed $config = nul
*
* @return array
*/
#[ArrayShape(['lifetime' => "int", 'path' => "string", 'domain' => "string", 'secure' => "bool", 'httponly' => "bool", 'samesite' => "string"])]
public static function getCookieParams(): array
{
return [
Expand Down
16 changes: 4 additions & 12 deletions src/Protocols/Ws.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,17 +233,13 @@ public static function input(string $buffer, AsyncTcpConnection $connection): bo
/**
* Websocket encode.
*
* @param mixed $payload
* @param string $payload
* @param AsyncTcpConnection $connection
* @return string
* @throws Throwable
*/
public static function encode(mixed $payload, AsyncTcpConnection $connection): string
public static function encode(string $payload, AsyncTcpConnection $connection): string
{
if (!is_scalar($payload)) {
throw new Exception("You can't send(" . gettype($payload) . ") to client, you need to convert it to string. ");
}

if (empty($connection->websocketType)) {
$connection->websocketType = self::BINARY_TYPE_BLOB;
}
Expand Down Expand Up @@ -371,12 +367,8 @@ public static function sendHandshake(AsyncTcpConnection $connection): void
$userHeader = $connection->headers ?? null;
$userHeaderStr = '';
if (!empty($userHeader)) {
if (is_array($userHeader)) {
foreach ($userHeader as $k => $v) {
$userHeaderStr .= "$k: $v\r\n";
}
} else {
$userHeaderStr .= $userHeader;
foreach ($userHeader as $k => $v) {
$userHeaderStr .= "$k: $v\r\n";
}
$userHeaderStr = "\r\n" . trim($userHeaderStr);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Timer.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public static function signalHandle(): void
*
* @param float $timeInterval
* @param callable $func
* @param mixed|array $args
* @param null|array $args
* @param bool $persistent
* @return int
*/
Expand Down
35 changes: 14 additions & 21 deletions src/Worker.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class Worker
/**
* Emitted when data is received.
*
* @var callable
* @var ?callable
*/
public $onMessage = null;

Expand Down Expand Up @@ -312,7 +312,7 @@ class Worker
/**
* EventLoopClass
*
* @var class-string
* @var string|class-string
*/
public static string $eventLoopClass = '';

Expand Down Expand Up @@ -340,7 +340,7 @@ class Worker
/**
* Listening socket.
*
* @var resource
* @var ?resource
*/
protected $mainSocket = null;

Expand Down Expand Up @@ -534,7 +534,7 @@ class Worker

/**
* Standard output stream
* @var resource
* @var ?resource
*/
protected static $outputStream = null;

Expand Down Expand Up @@ -1279,7 +1279,7 @@ public static function resetStd(bool $throwException = true): void
}
// change output stream
static::$outputStream = null;
static::outputStream($STDOUT);
self::outputStream($STDOUT);
restore_error_handler();
return;
}
Expand Down Expand Up @@ -1516,14 +1516,10 @@ public static function checkWorkerStatusForWindows(): void
$process = $processData[0];
$startFile = $processData[1];
$status = proc_get_status($process);
if (isset($status['running'])) {
if (!$status['running']) {
static::safeEcho("process $startFile terminated and try to restart\n");
proc_close($process);
static::forkOneWorkerForWindows($startFile);
}
} else {
static::safeEcho("proc_get_status fail\n");
if (!$status['running']) {
static::safeEcho("process $startFile terminated and try to restart\n");
proc_close($process);
static::forkOneWorkerForWindows($startFile);
}
}
}
Expand Down Expand Up @@ -1686,6 +1682,7 @@ protected static function monitorWorkers(): void
protected static function monitorWorkersForLinux(): void
{
static::$status = static::STATUS_RUNNING;
// @phpstan-ignore-next-line While loop condition is always true.
while (1) {
// Calls signal handlers for pending signals.
pcntl_signal_dispatch();
Expand Down Expand Up @@ -1918,11 +1915,7 @@ public static function stopAll(int $code = 0, mixed $log = ''): void
static::$workers = [];
static::$globalEvent?->stop();

try {
exit($code);
} catch (Exception $e) {

}
exit($code);
}
}
}
Expand Down Expand Up @@ -1972,7 +1965,6 @@ protected static function writeStatisticsToStatusFile(): void
if (static::$masterPid === posix_getpid()) {
$allWorkerInfo = [];
foreach (static::$pidMap as $workerId => $pidArray) {
/** @var /Workerman/Worker $worker */
$worker = static::$workers[$workerId];
foreach ($pidArray as $pid) {
$allWorkerInfo[$pid] = ['name' => $worker->name, 'listen' => $worker->getSocketName()];
Expand Down Expand Up @@ -2086,7 +2078,6 @@ protected static function writeConnectionsStatisticsToStatusFile(): void
$currentWorker = current(static::$workers);
$defaultWorkerName = $currentWorker->name;

/** @var static $worker */
foreach (TcpConnection::$connections as $connection) {
/** @var TcpConnection $connection */
$transport = $connection->transport;
Expand Down Expand Up @@ -2180,7 +2171,7 @@ public static function log(mixed $msg, bool $decorated = false): void
*/
public static function safeEcho(string $msg, bool $decorated = false): bool
{
$stream = static::outputStream();
$stream = self::outputStream();
if (!$stream) {
return false;
}
Expand Down Expand Up @@ -2213,6 +2204,7 @@ private static function outputStream($stream = null)
if (!$stream) {
$stream = static::$outputStream ?: STDOUT;
}
// @phpstan-ignore-next-line Negated boolean expression is always false.
if (!$stream || !is_resource($stream) || 'stream' !== get_resource_type($stream)) {
return false;
}
Expand Down Expand Up @@ -2552,6 +2544,7 @@ public function acceptUdpConnection($socket): bool
if ($this->protocol !== null) {
/** @var ProtocolInterface $parser */
$parser = $this->protocol;
// @phpstan-ignore-next-line Left side of && is always true.
if ($parser && method_exists($parser, 'input')) {
while ($recvBuffer !== '') {
$len = $parser::input($recvBuffer, $connection);
Expand Down
2 changes: 1 addition & 1 deletion tests/Feature/UdpConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

it('tests udp connection', function () use ($serverAddress) {
$socket = stream_socket_client($serverAddress, $errno, $errstr, 1);
expect($errno)->toBeInt(0);
expect($errno)->toBeInt()->toBe(0);
fwrite($socket, 'xiami');
$data = fread($socket, 1024);
expect($data)->toBeString('received: xiami');
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Protocols/HttpTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
});

it('tests ::encode for non-object response', function () {
/** @var TcpConnection $tcpConnection */
$tcpConnection = Mockery::mock(TcpConnection::class);
$tcpConnection->headers = [
'foo' => 'bar',
Expand All @@ -73,6 +74,7 @@
});

it('tests ::encode for ' . Response::class, function () {
/** @var TcpConnection $tcpConnection */
$tcpConnection = Mockery::mock(TcpConnection::class);
$tcpConnection->headers = [
'foo' => 'bar',
Expand All @@ -93,6 +95,7 @@
});

it('tests ::decode', function () {
/** @var TcpConnection $tcpConnection */
$tcpConnection = Mockery::mock(TcpConnection::class);

//example request from ChatGPT :)
Expand Down
1 change: 1 addition & 0 deletions tests/Unit/Protocols/TextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use Workerman\Protocols\Text;

test(Text::class, function () {
/** @var ConnectionInterface $connection */
$connection = Mockery::mock(ConnectionInterface::class);

//::input
Expand Down

0 comments on commit 240eda9

Please sign in to comment.