Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Psalm 5 #293

Merged
merged 10 commits into from
Dec 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/integrate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ jobs:
- 8.1

symfony-version:
- 4
- 5
- 6

Expand Down
12 changes: 6 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@
"require": {
"php": "^7.4 || ^8.0",
"ext-simplexml": "*",
"symfony/framework-bundle": "^4.0 || ^5.0 || ^6.0",
"vimeo/psalm": "^4.12"
"symfony/framework-bundle": "^5.0 || ^6.0",
"vimeo/psalm": "^5.1"
},
"require-dev": {
"symfony/form": "^4.0 || ^5.0 || ^6.0",
"symfony/form": "^5.0 || ^6.0",
"doctrine/annotations": "^1.8",
"doctrine/orm": "^2.7",
"doctrine/orm": "^2.9",
"phpunit/phpunit": "~7.5 || ~9.5",
"symfony/cache-contracts": "^1.0 || ^2.0",
"symfony/console": "*",
"symfony/messenger": "^4.2 || ^5.0 || ^6.0",
"symfony/messenger": "^5.0 || ^6.0",
"symfony/security-guard": "*",
"symfony/serializer": "^4.0 || ^5.0 || ^6.0",
"symfony/serializer": "^5.0 || ^6.0",
"symfony/validator": "*",
"twig/twig": "^2.10 || ^3.0",
"weirdan/codeception-psalm-module": "dev-master"
Expand Down
21 changes: 11 additions & 10 deletions src/Handler/ConsoleHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\MutableUnion;
use Psalm\Type\Union;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -31,11 +32,11 @@ class ConsoleHandler implements AfterMethodCallAnalysisInterface
/**
* @var Union[]
*/
private static $arguments = [];
private static array $arguments = [];
/**
* @var Union[]
*/
private static $options = [];
private static array $options = [];

/**
* {@inheritdoc}
Expand Down Expand Up @@ -149,11 +150,11 @@ private static function analyseArgument(array $args, StatementsSource $statement
}

if ($mode & InputArgument::IS_ARRAY) {
$returnTypes = new Union([new TArray([new Union([new TInt()]), new Union([new TString()])])]);
$returnTypes = new MutableUnion([new TArray([new Union([new TInt()]), new Union([new TString()])])]);
} elseif ($mode & InputArgument::REQUIRED) {
$returnTypes = new Union([new TString()]);
$returnTypes = new MutableUnion([new TString()]);
} else {
$returnTypes = new Union([new TString(), new TNull()]);
$returnTypes = new MutableUnion([new TString(), new TNull()]);
}

$defaultParam = $normalizedParams['default'];
Expand All @@ -164,7 +165,7 @@ private static function analyseArgument(array $args, StatementsSource $statement
}
}

self::$arguments[$identifier] = $returnTypes;
self::$arguments[$identifier] = $returnTypes->freeze();
}

/**
Expand Down Expand Up @@ -199,7 +200,7 @@ private static function analyseOption(array $args, StatementsSource $statements_
$mode = InputOption::VALUE_OPTIONAL;
}

$returnTypes = new Union([new TString(), new TNull()]);
$returnTypes = new MutableUnion([new TString(), new TNull()]);

$defaultParam = $normalizedParams['default'];
if ($defaultParam) {
Expand All @@ -221,18 +222,18 @@ private static function analyseOption(array $args, StatementsSource $statements_
}

if ($mode & InputOption::VALUE_NONE) {
$returnTypes = new Union([new TBool()]);
$returnTypes = new MutableUnion([new TBool()]);
}

if ($mode & InputOption::VALUE_REQUIRED && $mode & InputOption::VALUE_IS_ARRAY) {
$returnTypes->removeType('null');
}

if ($mode & InputOption::VALUE_IS_ARRAY) {
$returnTypes = new Union([new TArray([new Union([new TInt()]), $returnTypes])]);
$returnTypes = new MutableUnion([new TArray([new Union([new TInt()]), $returnTypes->freeze()])]);
}

self::$options[$identifier] = $returnTypes;
self::$options[$identifier] = $returnTypes->freeze();
}

/**
Expand Down
4 changes: 1 addition & 3 deletions src/Handler/ContainerHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace Psalm\SymfonyPsalmPlugin\Handler;

use function constant;

use PhpParser\Node\Arg;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Identifier;
Expand Down Expand Up @@ -105,7 +103,7 @@ public static function afterMethodCallAnalysis(AfterMethodCallAnalysisEvent $eve
$serviceId = $className;
} else {
try {
$serviceId = constant($className.'::'.$idArgument->name->name);
$serviceId = \constant($className.'::'.$idArgument->name->name);
} catch (\Exception $e) {
return;
}
Expand Down
8 changes: 3 additions & 5 deletions src/Handler/DoctrineRepositoryHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
use Psalm\SymfonyPsalmPlugin\Issue\RepositoryStringShortcut;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use ReflectionClass;
use ReflectionException;

class DoctrineRepositoryHandler implements AfterMethodCallAnalysisInterface, AfterClassLikeVisitInterface
{
Expand Down Expand Up @@ -51,9 +49,9 @@ public static function afterMethodCallAnalysis(AfterMethodCallAnalysisEvent $eve
}

try {
$reflectionClass = new ReflectionClass($className);
$reflectionClass = new \ReflectionClass($className);

if (\PHP_VERSION_ID >= 80000 && method_exists(ReflectionClass::class, 'getAttributes')) {
if (\PHP_VERSION_ID >= 80000 && method_exists(\ReflectionClass::class, 'getAttributes')) {
$entityAttributes = $reflectionClass->getAttributes(EntityAnnotation::class);

foreach ($entityAttributes as $entityAttribute) {
Expand All @@ -76,7 +74,7 @@ public static function afterMethodCallAnalysis(AfterMethodCallAnalysisEvent $eve
$event->setReturnTypeCandidate(new Union([new TNamedObject($entityAnnotation->repositoryClass)]));
}
}
} catch (ReflectionException $e) {
} catch (\ReflectionException $e) {
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
use Psalm\SymfonyPsalmPlugin\Twig\CachedTemplatesMapping;
use Psalm\SymfonyPsalmPlugin\Twig\CachedTemplatesTainter;
use Psalm\SymfonyPsalmPlugin\Twig\TemplateFileAnalyzer;
use SimpleXMLElement;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\HttpKernel\Kernel;

Expand All @@ -33,7 +32,7 @@ class Plugin implements PluginEntryPointInterface
/**
* {@inheritdoc}
*/
public function __invoke(RegistrationInterface $api, SimpleXMLElement $config = null): void
public function __invoke(RegistrationInterface $api, \SimpleXMLElement $config = null): void
{
require_once __DIR__.'/Handler/HeaderBagHandler.php';
require_once __DIR__.'/Handler/ContainerHandler.php';
Expand Down

This file was deleted.

28 changes: 0 additions & 28 deletions src/Stubs/4/Component/HttpFoundation/ParameterBag.stubphp

This file was deleted.

This file was deleted.

15 changes: 0 additions & 15 deletions src/Stubs/4/Component/Serializer/SerializerInterface.stubphp

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ interface DenormalizerInterface
/**
* @template TObject of object
* @template TType of string|class-string<TObject>
* @psalm-param mixed $data
*
* @psalm-param TType $type
* @psalm-return (TType is class-string<TObject> ? TObject : mixed)
*/
public function denormalize($data, string $type, string $format = null, array $context = []);
public function denormalize(mixed $data, string $type, string $format = null, array $context = []);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ interface DenormalizerInterface
/**
* @template TObject of object
* @template TType of string|class-string<TObject>
* @psalm-param mixed $data
*
* @psalm-param TType $type
* @psalm-return (TType is class-string<TObject> ? TObject : mixed)
*/
public function denormalize($data, string $type, string $format = null, array $context = []);
public function denormalize(mixed $data, string $type, string $format = null, array $context = []);
}
6 changes: 6 additions & 0 deletions src/Stubs/common/Component/HttpFoundation/HeaderBag.stubphp
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ class HeaderBag implements \IteratorAggregate, \Countable
* @psalm-taint-source input
*/
public function __toString() {}

/**
* @psalm-taint-source input
* @psalm-mutation-free
*/
public function get(string $key, string $default = null): ?string {}
}
8 changes: 3 additions & 5 deletions src/Stubs/common/Component/HttpFoundation/Request.stubphp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ class Request
*
* @throws \LogicException
*
* @psalm-return (
* $asResource is true
* ? resource
* : string
* )
* @psalm-template TAsResource as bool
* @psalm-param TAsResource $asResource
* @psalm-return (TAsResource is true ? resource : string)
*/
public function getContent($asResource = false) {}

Expand Down
2 changes: 1 addition & 1 deletion src/Stubs/common/Component/HttpFoundation/Response.stubphp
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ class Response
* @throws \InvalidArgumentException When the HTTP status code is not valid
* @psalm-taint-sink html $content
*/
public function __construct($content = '', int $status = 200, array $headers = []) {}
public function __construct(?string $content = '', int $status = 200, array $headers = []) {}
}
3 changes: 1 addition & 2 deletions src/Test/CodeceptionModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Codeception\Exception\ModuleRequireException;
use Codeception\Module as BaseModule;
use Codeception\TestInterface;
use InvalidArgumentException;
use Psalm\SymfonyPsalmPlugin\Twig\CachedTemplatesMapping;
use Twig\Cache\FilesystemCache;
use Twig\Environment;
Expand Down Expand Up @@ -182,7 +181,7 @@ private function loadTemplate(string $templateName, string $rootDirectory, strin
{
if (null === $this->twigCache) {
if (!is_dir($cacheDirectory)) {
throw new InvalidArgumentException(sprintf('The %s twig cache directory does not exist or is not readable.', $cacheDirectory));
throw new \InvalidArgumentException(sprintf('The %s twig cache directory does not exist or is not readable.', $cacheDirectory));
}
$this->twigCache = new FilesystemCache($cacheDirectory);
}
Expand Down
5 changes: 2 additions & 3 deletions src/Twig/AnalyzedTemplatesTainter.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Psalm\StatementsSource;
use Psalm\SymfonyPsalmPlugin\Exception\TemplateNameUnresolvedException;
use Psalm\Type\Atomic\TKeyedArray;
use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Twig\Environment;

Expand Down Expand Up @@ -86,7 +85,7 @@ private static function generateTemplateParameters(Expr $templateParameters, Sta
{
$type = $source->getNodeTypeProvider()->getType($templateParameters);
if (null === $type) {
throw new RuntimeException(sprintf('Can not retrieve type for the given expression (%s)', get_class($templateParameters)));
throw new \RuntimeException(sprintf('Can not retrieve type for the given expression (%s)', get_class($templateParameters)));
}

if ($templateParameters instanceof Array_) {
Expand All @@ -112,6 +111,6 @@ private static function generateTemplateParameters(Expr $templateParameters, Sta
return $parameters;
}

throw new RuntimeException(sprintf('Can not retrieve template parameters from given expression (%s)', get_class($templateParameters)));
throw new \RuntimeException(sprintf('Can not retrieve template parameters from given expression (%s)', get_class($templateParameters)));
}
}
4 changes: 1 addition & 3 deletions src/Twig/CachedTemplateNotFoundException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

namespace Psalm\SymfonyPsalmPlugin\Twig;

use Exception;

class CachedTemplateNotFoundException extends Exception
class CachedTemplateNotFoundException extends \Exception
{
public function __construct()
{
Expand Down
3 changes: 1 addition & 2 deletions src/Twig/CachedTemplatesMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use Psalm\Plugin\EventHandler\AfterCodebasePopulatedInterface;
use Psalm\Plugin\EventHandler\Event\AfterCodebasePopulatedEvent;
use RuntimeException;

/**
* This class is used to store a mapping of all analyzed twig template cache files with their corresponding actual templates.
Expand Down Expand Up @@ -66,7 +65,7 @@ public static function setCachePath(string $cachePath): void
public static function getCacheClassName(string $templateName): string
{
if (null === self::$cacheRegistry) {
throw new RuntimeException(sprintf('Can not load template %s, because no cache registry is provided.', $templateName));
throw new \RuntimeException(sprintf('Can not load template %s, because no cache registry is provided.', $templateName));
}

return self::$cacheRegistry->getCacheClassName($templateName);
Expand Down