Skip to content

Commit

Permalink
Implement SocketCreateReturnTypeExtension
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed Nov 25, 2024
1 parent 2d637da commit bbdfcb4
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
5 changes: 5 additions & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1820,6 +1820,11 @@ services:
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension

-
class: PHPStan\Type\Php\SocketCreateReturnTypeExtension
tags:
- phpstan.broker.dynamicFunctionReturnTypeExtension

-
class: PHPStan\Type\Php\StrSplitFunctionReturnTypeExtension
tags:
Expand Down
5 changes: 5 additions & 0 deletions src/Php/PhpVersions.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ public function producesWarningForFinalPrivateMethods(): TrinaryLogic
return IntegerRangeType::fromInterval(80000, null)->isSuperTypeOf($this->phpVersions)->result;
}

public function socketCreateUsesResource(): TrinaryLogic
{
return IntegerRangeType::fromInterval(null, 80000)->isSuperTypeOf($this->phpVersions)->result;
}

}
42 changes: 42 additions & 0 deletions src/Type/Php/SocketCreateReturnTypeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php declare(strict_types = 1);

namespace PHPStan\Type\Php;

use PhpParser\Node\Expr\FuncCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ResourceType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Socket;
use function count;

final class SocketCreateReturnTypeExtension implements DynamicFunctionReturnTypeExtension
{

public function isFunctionSupported(FunctionReflection $functionReflection): bool
{
return $functionReflection->getName() === 'socket_create';
}

public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): ?Type
{
if (count($functionCall->getArgs()) < 3) {
return null;
}

if ($scope->getPhpVersion()->socketCreateUsesResource()->no()) {
return new UnionType([new ConstantBooleanType(false), new ObjectType(Socket::class)]);

Check failure on line 32 in src/Type/Php/SocketCreateReturnTypeExtension.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, ubuntu-latest)

Class Socket not found.

Check failure on line 32 in src/Type/Php/SocketCreateReturnTypeExtension.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, windows-latest)

Class Socket not found.
}

if ($scope->getPhpVersion()->socketCreateUsesResource()->yes()) {
return new UnionType([new ConstantBooleanType(false), new ResourceType()]);
}

return null;
}

}
19 changes: 19 additions & 0 deletions tests/PHPStan/Analyser/nsrt/socket-create.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php // lint >= 7.4

declare(strict_types=1);

namespace SocketCreate;

use function PHPStan\Testing\assertType;

class HelloWorld
{
public function sayHello(): void
{
if (PHP_VERSION_ID < 80000) {
assertType('resource|false', socket_create(AF_INET, SOCK_DGRAM, SOL_UDP));
return;
}
assertType('Socket|false', socket_create(AF_INET, SOCK_DGRAM, SOL_UDP));
}
}

0 comments on commit bbdfcb4

Please sign in to comment.