Skip to content

Bump PHPStan analysis to level 6 #2272

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

Merged
merged 2 commits into from
Oct 30, 2018
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ jobs:
name: Run PHPStan
command: |-
export PATH="$PATH:$HOME/.composer/vendor/bin"
phpstan analyse -c phpstan.neon -l5 --ansi src tests
phpstan analyse -c phpstan.neon -l6 --ansi src tests

phpunit-coverage:
docker:
Expand Down
6 changes: 5 additions & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ parameters:
- '#Access to an undefined property object::\$isIdentifierComposite.#'
- '#Call to an undefined method Doctrine\\Common\\Persistence\\ObjectManager::getConnection\(\)#'
- '#Call to an undefined method PHPUnit\\Framework\\MockObject\\MockObject::[a-zA-Z0-9_]+\(\)#'
- '#Call to an undefined method Prophecy\\Prophecy\\ObjectProphecy::[a-zA-Z0-9_]+\(\)#'
- '#Call to an undefined method Prophecy\\Prophecy\\ObjectProphecy(|.*)?::[a-zA-Z0-9_]+\(\)#'
- '#Method ApiPlatform\\Core\\Tests\\Bridge\\Doctrine\\Orm\\ItemDataProviderTest::getManagerRegistry\(\) should return Doctrine\\Common\\Persistence\\ManagerRegistry but returns object\.#'
- '#Method ApiPlatform\\Core\\Tests\\Bridge\\Doctrine\\Orm\\Util\\IdentifierManagerTraitTest::getObjectManager\(\) should return Doctrine\\Common\\Persistence\\ObjectManager but returns object\.#'
- '#Parameter \#1 \$function of function call_user_func expects callable, .+ given\.#'
- '#Parameter \#1 \$classes of class ApiPlatform\\Core\\Metadata\\Resource\\ResourceNameCollection constructor expects array<string>, array<int, int\|string> given\.#'
- '#Method ApiPlatform\\Core\\Util\\RequestParser::parseRequestParams\(\) should return array but returns array\|false\.#'
# Temporary fix while the PHPStan extension for Prophecy isn't compatible with 0.10
- '#Parameter .* expects .*, .*object.* given\.#'
- '#Parameter \#[0-9] \$filterLocator of class ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Extension\\FilterExtension constructor expects ApiPlatform\\Core\\Api\\FilterCollection|Psr\\Container\\ContainerInterface(\|null)?, ArrayObject given\.#'
Expand All @@ -25,6 +28,7 @@ parameters:
# https://github.com/doctrine/doctrine2/pull/7298/files
- '#Strict comparison using === between null and int will always evaluate to false\.#'
- '#Strict comparison using !== between null and null will always evaluate to false\.#'
- '#Method ApiPlatform\\Core\\(Serializer\\Abstract|JsonApi\\Serializer\\)ItemNormalizer::normalizeRelation\(\) should return array\|string but returns array\|bool\|float\|int\|string\.#'

# Expected, due to deprecations
- '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Extension\\QueryResult(Item|Collection)ExtensionInterface::getResult\(\) invoked with 4 parameters, 1 required\.#'
Expand Down
2 changes: 1 addition & 1 deletion src/Annotation/ApiFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final class ApiFilter
public $strategy;

/**
* @var string
* @var string|FilterInterface
*/
public $filterClass;

Expand Down
1 change: 1 addition & 0 deletions src/Annotation/AttributesHydratorTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ private function hydrateAttributes(array $values)
}

foreach ($values as $key => $value) {
$key = (string) $key;
if (!property_exists($this, $key)) {
throw new InvalidArgumentException(sprintf('Unknown property "%s" on annotation "%s".', $key, self::class));
}
Expand Down
5 changes: 3 additions & 2 deletions src/Bridge/Doctrine/Orm/Filter/DateFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ protected function filterProperty(string $property, $values, QueryBuilder $query
}

$nullManagement = $this->properties[$property] ?? null;
$type = $this->getDoctrineFieldType($property, $resourceClass);
$type = (string) $this->getDoctrineFieldType($property, $resourceClass);

if (self::EXCLUDE_NULL === $nullManagement) {
$queryBuilder->andWhere($queryBuilder->expr()->isNotNull(sprintf('%s.%s', $alias, $field)));
Expand Down Expand Up @@ -160,6 +160,7 @@ protected function filterProperty(string $property, $values, QueryBuilder $query
*/
protected function addWhere(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $alias, string $field, string $operator, string $value, string $nullManagement = null, $type = null)
{
$type = (string) $type;
try {
$value = false === strpos($type, '_immutable') ? new \DateTime($value) : new \DateTimeImmutable($value);
} catch (\Exception $e) {
Expand Down Expand Up @@ -206,7 +207,7 @@ protected function addWhere(QueryBuilder $queryBuilder, QueryNameGeneratorInterf
*/
protected function isDateField(string $property, string $resourceClass): bool
{
return isset(self::DOCTRINE_DATE_TYPES[$this->getDoctrineFieldType($property, $resourceClass)]);
return isset(self::DOCTRINE_DATE_TYPES[(string) $this->getDoctrineFieldType($property, $resourceClass)]);
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/Bridge/Doctrine/Orm/Filter/NumericFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function getDescription(string $resourceClass): array

$description[$property] = [
'property' => $property,
'type' => $this->getType($this->getDoctrineFieldType($property, $resourceClass)),
'type' => $this->getType((string) $this->getDoctrineFieldType($property, $resourceClass)),
'required' => false,
];
}
Expand Down Expand Up @@ -114,7 +114,7 @@ protected function filterProperty(string $property, $value, QueryBuilder $queryB
list($alias, $field) = $this->addJoinsForNestedProperty($property, $alias, $queryBuilder, $queryNameGenerator, $resourceClass);
}

if (!isset(self::DOCTRINE_NUMERIC_TYPES[$this->getDoctrineFieldType($property, $resourceClass)])) {
if (!isset(self::DOCTRINE_NUMERIC_TYPES[(string) $this->getDoctrineFieldType($property, $resourceClass)])) {
$this->logger->notice('Invalid filter ignored', [
'exception' => new InvalidArgumentException(sprintf('The field "%s" of class "%s" is not a doctrine numeric type.', $field, $resourceClass)),
]);
Expand All @@ -126,7 +126,7 @@ protected function filterProperty(string $property, $value, QueryBuilder $queryB

$queryBuilder
->andWhere(sprintf('%s.%s = :%s', $alias, $field, $valueParameter))
->setParameter($valueParameter, $value, $this->getDoctrineFieldType($property, $resourceClass));
->setParameter($valueParameter, $value, (string) $this->getDoctrineFieldType($property, $resourceClass));
}

/**
Expand All @@ -137,6 +137,6 @@ protected function isNumericField(string $property, string $resourceClass): bool
$propertyParts = $this->splitPropertyParts($property, $resourceClass);
$metadata = $this->getNestedMetadata($resourceClass, $propertyParts['associations']);

return isset(self::DOCTRINE_NUMERIC_TYPES[$metadata->getTypeOfField($propertyParts['field'])]);
return isset(self::DOCTRINE_NUMERIC_TYPES[(string) $metadata->getTypeOfField($propertyParts['field'])]);
}
}
2 changes: 1 addition & 1 deletion src/Bridge/Doctrine/Orm/Filter/SearchFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public function getDescription(string $resourceClass): array
}

if ($metadata->hasField($field)) {
$typeOfField = $this->getType($metadata->getTypeOfField($field));
$typeOfField = $this->getType((string) $metadata->getTypeOfField($field));
$strategy = $this->properties[$property] ?? self::STRATEGY_EXACT;
$filterParameterNames = [$property];

Expand Down
4 changes: 2 additions & 2 deletions src/Bridge/Doctrine/Orm/ItemDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function getItem(string $resourceClass, $id, string $operationName = null
{
$manager = $this->managerRegistry->getManagerForClass($resourceClass);

if (!($context[IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER] ?? false)) {
if (!\is_array($id) && !($context[IdentifierConverterInterface::HAS_IDENTIFIER_CONVERTER] ?? false)) {
$id = $this->normalizeIdentifiers($id, $manager, $resourceClass);
}

Expand All @@ -87,7 +87,7 @@ public function getItem(string $resourceClass, $id, string $operationName = null
$queryNameGenerator = new QueryNameGenerator();
$doctrineClassMetadata = $manager->getClassMetadata($resourceClass);

$this->addWhereForIdentifiers($id, $queryBuilder, $doctrineClassMetadata);
$this->addWhereForIdentifiers((array) $id, $queryBuilder, $doctrineClassMetadata);

foreach ($this->itemExtensions as $extension) {
$extension->applyToItem($queryBuilder, $queryNameGenerator, $resourceClass, $id, $operationName, $context);
Expand Down
2 changes: 1 addition & 1 deletion src/Bridge/Doctrine/Orm/SubresourceDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private function buildQuery(array $identifiers, array $context, QueryNameGenerat
foreach ($normalizedIdentifiers as $key => $value) {
$placeholder = $queryNameGenerator->generateParameterName($key);
$qb->andWhere("$alias.$key = :$placeholder");
$topQueryBuilder->setParameter($placeholder, $value, $classMetadata->getTypeOfField($key));
$topQueryBuilder->setParameter($placeholder, $value, (string) $classMetadata->getTypeOfField($key));
}

// Recurse queries
Expand Down
8 changes: 4 additions & 4 deletions src/Bridge/Symfony/Bundle/Command/SwaggerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ protected function execute(InputInterface $input, OutputInterface $output)
{
$documentation = new Documentation($this->resourceNameCollectionFactory->create(), $this->apiTitle, $this->apiDescription, $this->apiVersion, $this->apiFormats);
$data = $this->documentationNormalizer->normalize($documentation);
$content = $input->getOption('yaml') ? Yaml::dump($data, 6, 4, Yaml::DUMP_OBJECT_AS_MAP | Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE) : json_encode($data, JSON_PRETTY_PRINT);
if (!empty($input->getOption('output'))) {
file_put_contents($input->getOption('output'), $content);
$content = $input->getOption('yaml') ? Yaml::dump($data, 6, 4, Yaml::DUMP_OBJECT_AS_MAP | Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE) : (json_encode($data, JSON_PRETTY_PRINT) ?: '');
if (!empty($filename = $input->getOption('output')) && \is_string($filename)) {
file_put_contents($filename, $content);
$output->writeln(
sprintf('Data written to %s', $input->getOption('output'))
sprintf('Data written to %s', $filename)
);
} else {
$output->writeln($content);
Expand Down
4 changes: 3 additions & 1 deletion src/Bridge/Symfony/Routing/ApiLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ final class ApiLoader extends Loader

public function __construct(KernelInterface $kernel, ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, OperationPathResolverInterface $operationPathResolver, ContainerInterface $container, array $formats, array $resourceClassDirectories = [], SubresourceOperationFactoryInterface $subresourceOperationFactory = null, bool $graphqlEnabled = false, bool $entrypointEnabled = true, bool $docsEnabled = true)
{
$this->fileLoader = new XmlFileLoader(new FileLocator($kernel->locateResource('@ApiPlatformBundle/Resources/config/routing')));
/** @var string[]|string $paths */
$paths = $kernel->locateResource('@ApiPlatformBundle/Resources/config/routing');
$this->fileLoader = new XmlFileLoader(new FileLocator($paths));
$this->resourceNameCollectionFactory = $resourceNameCollectionFactory;
$this->resourceMetadataFactory = $resourceMetadataFactory;
$this->operationPathResolver = $operationPathResolver;
Expand Down
2 changes: 1 addition & 1 deletion src/Bridge/Symfony/Routing/IriConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function getItemFromIri(string $iri, array $context = [])
}

if (isset($attributes['subresource_operation_name'])) {
if ($item = $this->getSubresourceData($identifiers, $attributes, $context)) {
if (($item = $this->getSubresourceData($identifiers, $attributes, $context)) && !\is_array($item)) {
return $item;
}

Expand Down
2 changes: 1 addition & 1 deletion src/DataProvider/OperationDataProviderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private function getItemData($identifiers, array $attributes, array $context)
*
* @throws RuntimeException
*
* @return object|null
* @return array|object|null
*/
private function getSubresourceData($identifiers, array $attributes, array $context)
{
Expand Down
1 change: 1 addition & 0 deletions src/EventListener/AddFormatListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public function onKernelRequest(GetResponseEvent $event)
}

// First, try to guess the format from the Accept header
/** @var string|null $accept */
$accept = $request->headers->get('Accept');
if (null !== $accept) {
if (null === $acceptHeader = $this->negotiator->getBest($accept, $mimeTypes)) {
Expand Down
2 changes: 1 addition & 1 deletion src/Filter/QueryParameterValidateListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private function isRequiredFilterValid(string $name, Request $request): bool
return false;
}

$rootName = array_keys($matches)[0] ?? '';
$rootName = (string) (array_keys($matches)[0] ?? null);
if (!$rootName) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQl/Action/EntrypointAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private function parseRequest(Request $request): array
}

if ('json' === $request->getContentType()) {
$input = \json_decode($request->getContent(), true);
$input = \json_decode((string) $request->getContent(), true);

if (isset($input['query'])) {
$query = $input['query'];
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQl/Serializer/ItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ protected function getAllowedAttributes($classOrObject, array $context, $attribu

if (($context['api_denormalize'] ?? false) && false !== ($indexId = array_search('id', $allowedAttributes, true))) {
$allowedAttributes[] = '_id';
array_splice($allowedAttributes, $indexId, 1);
array_splice($allowedAttributes, (int) $indexId, 1);
}

return $allowedAttributes;
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQl/Type/SchemaBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ private function mergeFilterArgs(array $args, array $parsed, ResourceMetadata $r
if (\is_array($value)) {
$value = $this->mergeFilterArgs($args[$key] ?? [], $value);
if (!isset($value['#name'])) {
$name = (false === $pos = strrpos($original, '[')) ? $original : substr($original, 0, $pos);
$name = (false === $pos = strrpos($original, '[')) ? $original : substr($original, 0, (int) $pos);
$value['#name'] = ($resourceMetadata ? $resourceMetadata->getShortName() : '').'Filter_'.strtr($name, ['[' => '_', ']' => '', '.' => '__']);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Metadata/Extractor/XmlExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ final class XmlExtractor extends AbstractExtractor
protected function extractPath(string $path)
{
try {
/** @var \SimpleXMLElement $xml */
$xml = simplexml_import_dom(XmlUtils::loadFile($path, self::RESOURCE_SCHEMA));
} catch (\InvalidArgumentException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
Expand Down
2 changes: 1 addition & 1 deletion src/Metadata/Extractor/YamlExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class YamlExtractor extends AbstractExtractor
protected function extractPath(string $path)
{
try {
$resourcesYaml = Yaml::parse(file_get_contents($path), Yaml::PARSE_CONSTANT);
$resourcesYaml = Yaml::parse((string) file_get_contents($path), Yaml::PARSE_CONSTANT);
} catch (ParseException $e) {
$e->setParsedFile($path);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ private function normalize(bool $collection, ResourceMetadata $resourceMetadata,
$operation = [];
}

$upperOperationName = strtoupper($operationName);
$upperOperationName = strtoupper((string) $operationName);
if ($collection) {
$supported = isset(self::SUPPORTED_COLLECTION_OPERATION_METHODS[$upperOperationName]);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/Operation/Factory/SubresourceOperationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,10 @@ private function computeSubresourceOperations(string $resourceClass, array &$tre
if (isset($subresourceOperation['path'])) {
$operation['path'] = $subresourceOperation['path'];
} else {
$operation['path'] = str_replace(self::FORMAT_SUFFIX, '', $parentOperation['path']);
$operation['path'] = str_replace(self::FORMAT_SUFFIX, '', (string) $parentOperation['path']);

if ($parentOperation['collection']) {
list($key) = end($operation['identifiers']);
[$key] = end($operation['identifiers']);
$operation['path'] .= sprintf('/{%s}', $key);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Swagger/Serializer/ApiGatewayNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ public function normalize($object, $format = null, array $context = [])

// $data['definitions'] is an instance of \ArrayObject
foreach (array_keys($data['definitions']->getArrayCopy()) as $definition) {
if (!preg_match('/^[A-z]+$/', $definition)) {
$data['definitions'][str_replace(['-', '_'], '', $definition)] = $data['definitions'][$definition];
if (!preg_match('/^[A-z]+$/', (string) $definition)) {
$data['definitions'][str_replace(['-', '_'], '', (string) $definition)] = $data['definitions'][$definition];
unset($data['definitions'][$definition]);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Util/RequestParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private function __construct()
public static function parseAndDuplicateRequest(Request $request): Request
{
$query = self::parseRequestParams(self::getQueryString($request) ?? '');
$body = self::parseRequestParams($request->getContent());
$body = self::parseRequestParams((string) $request->getContent());

return $request->duplicate($query, $body);
}
Expand Down
3 changes: 2 additions & 1 deletion tests/Bridge/Symfony/Bundle/Command/SwaggerCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,12 @@ public function testExecuteWithYaml()

public function testWriteToFile()
{
/** @var string $tmpFile */
$tmpFile = tempnam(sys_get_temp_dir(), 'test_write_to_file');

$this->tester->run(['command' => 'api:swagger:export', '--output' => $tmpFile]);

$this->assertJson(file_get_contents($tmpFile));
$this->assertJson((string) @file_get_contents($tmpFile));
@unlink($tmpFile);
}

Expand Down
1 change: 1 addition & 0 deletions tests/GraphQl/Type/SchemaBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ public function testGetSchema(bool $paginationEnabled)
$this->assertEquals(GraphQLType::nonNull(GraphQLType::int()), $objectPropertyFieldType->getField('totalCount')->getType());
/** @var ListOfType $edgesType */
$edgesType = $objectPropertyFieldType->getFields()['edges']->getType();
/** @var ObjectType $edgeType */
$edgeType = $edgesType->getWrappedType();
$this->assertSame('ShortName1Edge', $edgeType->name);
$this->assertEquals(GraphQLType::nonNull(GraphQLType::string()), $edgeType->getField('cursor')->getType());
Expand Down
2 changes: 1 addition & 1 deletion tests/Swagger/Serializer/ApiGatewayNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class ApiGatewayNormalizerTest extends TestCase
private $documentationNormalizerMock;

/**
* @var ObjectProphecy|\stdClass
* @var ObjectProphecy
*/
private $objectMock;

Expand Down