Skip to content

Commit f4016bf

Browse files
l-youoojacoboo
andauthored
Codebase improvements with php 8.1 features (#548)
* psr/container v2 * Implement replacement for Picotainer * Replace Picotainer with LazyContainer in tests and documentation for version >=6 * Fix tests for phpdocumentor/type-resolver minor update * run cs-fix script * Fix some cs-fixer errors manually * fix return type * abandon psr/container ^1 * Test for LazyContainer * Normalize RootTypeMapperInterface * end-to-end test with enums in mutation and as single-returned field * Bump ecodev/graphql-upload and webonyx/graphql-php" * Fix some tests for webonyx ^15.0 * clearer types to fix tests * clearer types to fix failing tests for webonyx 15 * clearer types to fix failing tests for webonyx 15 * fix failing tests for webonyx 15. Make clearer types. * fix failing tests for webonyx 15. Make clearer types. * fix some breaking changes for webonyx 15 * fix breaking changes for webonyx 15 * Update continuous_integration.yml Remove support for PHP 8.0 test matrix * Specify PHP 8.1 minimum support * Add 'final' keyword to all classes marked with @internal phpdoc * Improve code with php 8.1 features: 'readonly' keyword, native intersection types (OutputType&Type), new functions (str_starts_with,str_ends_with) * Improve code with php 8.1 features: 'readonly' keyword, native intersection types (OutputType&Type) * Improve code with php 8.1 features: 'readonly' keyword, native intersection types (e.g. OutputType&Type), match(){} syntax * Improve code with php 8.1 features: str_starts_with * Improve code with php 8.1 features: readonly modifier * Improve code with php 8.1 features: intersection types * Improve code with php 8.1 features: intersection types and readonly modifier * Improve code with php 8.1 features: intersection types and readonly modifier * Bump phpstan to minimum version 1.9. Fixes failed tests with --prefer-lowest phpstan/phpstan#5906 --------- Co-authored-by: Jacob Thomason <[email protected]>
1 parent 54813c0 commit f4016bf

File tree

63 files changed

+214
-289
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+214
-289
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"myclabs/php-enum": "^1.6.6",
3737
"php-coveralls/php-coveralls": "^2.1",
3838
"phpstan/extension-installer": "^1.1",
39-
"phpstan/phpstan": "^1.0",
39+
"phpstan/phpstan": "^1.9",
4040
"phpunit/phpunit": "^8.5.19 || ^9.5.8",
4141
"symfony/var-dumper": "^5.4 || ^6.0",
4242
"thecodingmachine/phpstan-strict-rules": "^1.0"

src/AggregateControllerQueryProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class AggregateControllerQueryProvider implements QueryProviderInterface
2929
* @param iterable<string> $controllers A list of controllers name in the container.
3030
* @param ContainerInterface $controllersContainer The container we will fetch controllers from.
3131
*/
32-
public function __construct(private iterable $controllers, private FieldsBuilder $fieldsBuilder, private ContainerInterface $controllersContainer)
32+
public function __construct(private readonly iterable $controllers, private readonly FieldsBuilder $fieldsBuilder, private readonly ContainerInterface $controllersContainer)
3333
{
3434
}
3535

src/AggregateControllerQueryProviderFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class AggregateControllerQueryProviderFactory implements QueryProviderFactoryInt
1515
* @param iterable<string> $controllers A list of controllers name in the container.
1616
* @param ContainerInterface $controllersContainer The container we will fetch controllers from.
1717
*/
18-
public function __construct(private iterable $controllers, private ContainerInterface $controllersContainer)
18+
public function __construct(private readonly iterable $controllers, private readonly ContainerInterface $controllersContainer)
1919
{
2020
}
2121

src/AnnotationReader.php

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class AnnotationReader
6767
* @param string $mode One of self::LAX_MODE or self::STRICT_MODE. If true, no exceptions will be thrown for incorrect annotations in code coming from the "vendor/" directory.
6868
* @param array<int,string> $strictNamespaces Classes in those namespaces MUST have valid annotations (otherwise, an error is thrown).
6969
*/
70-
public function __construct(private Reader $reader, private string $mode = self::STRICT_MODE, private array $strictNamespaces = [])
70+
public function __construct(private readonly Reader $reader, private readonly string $mode = self::STRICT_MODE, private readonly array $strictNamespaces = [])
7171
{
7272
if (! in_array($mode, [self::LAX_MODE, self::STRICT_MODE], true)) {
7373
throw new InvalidArgumentException('The mode passed must be one of AnnotationReader::LAX_MODE, AnnotationReader::STRICT_MODE');
@@ -100,20 +100,11 @@ private function getClassAnnotation(ReflectionClass $refClass, string $annotatio
100100
assert($type === null || $type instanceof $annotationClass);
101101
return $type;
102102
} catch (AnnotationException $e) {
103-
switch ($this->mode) {
104-
case self::STRICT_MODE:
105-
throw $e;
106-
107-
case self::LAX_MODE:
108-
if ($this->isErrorImportant($annotationClass, $refClass->getDocComment() ?: '', $refClass->getName())) {
109-
throw $e;
110-
}
111-
112-
return null;
113-
114-
default:
115-
throw new RuntimeException("Unexpected mode '" . $this->mode . "'."); // @codeCoverageIgnore
116-
}
103+
return match ($this->mode) {
104+
self::STRICT_MODE=> throw $e,
105+
self::LAX_MODE=>$this->isErrorImportant($annotationClass, $refClass->getDocComment() ?: '', $refClass->getName()) ? throw $e : null,
106+
default=>throw new RuntimeException("Unexpected mode '" . $this->mode . "'.") // @codeCoverageIgnore
107+
};
117108
}
118109
}
119110

@@ -139,20 +130,11 @@ private function getMethodAnnotation(ReflectionMethod $refMethod, string $annota
139130

140131
return $this->methodAnnotationCache[$cacheKey] = $this->reader->getMethodAnnotation($refMethod, $annotationClass);
141132
} catch (AnnotationException $e) {
142-
switch ($this->mode) {
143-
case self::STRICT_MODE:
144-
throw $e;
145-
146-
case self::LAX_MODE:
147-
if ($this->isErrorImportant($annotationClass, $refMethod->getDocComment() ?: '', $refMethod->getDeclaringClass()->getName())) {
148-
throw $e;
149-
}
150-
151-
return null;
152-
153-
default:
154-
throw new RuntimeException("Unexpected mode '" . $this->mode . "'."); // @codeCoverageIgnore
155-
}
133+
return match ($this->mode) {
134+
self::STRICT_MODE=> throw $e,
135+
self::LAX_MODE=>$this->isErrorImportant($annotationClass, $refMethod->getDocComment() ?: '', $refMethod->getName()) ? throw $e : null,
136+
default=>throw new RuntimeException("Unexpected mode '" . $this->mode . "'.") // @codeCoverageIgnore
137+
};
156138
}
157139
}
158140

src/FactoryContext.php

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,19 @@
1818
final class FactoryContext
1919
{
2020
public function __construct(
21-
private AnnotationReader $annotationReader,
22-
private TypeResolver $typeResolver,
23-
private NamingStrategyInterface $namingStrategy,
24-
private TypeRegistry $typeRegistry,
25-
private FieldsBuilder $fieldsBuilder,
26-
private TypeGenerator $typeGenerator,
27-
private InputTypeGenerator $inputTypeGenerator,
28-
private RecursiveTypeMapperInterface $recursiveTypeMapper,
29-
private ContainerInterface $container,
30-
private CacheInterface $cache,
31-
private InputTypeValidatorInterface|null $inputTypeValidator,
32-
private int|null $globTTL,
33-
private int|null $mapTTL = null,
21+
private readonly AnnotationReader $annotationReader,
22+
private readonly TypeResolver $typeResolver,
23+
private readonly NamingStrategyInterface $namingStrategy,
24+
private readonly TypeRegistry $typeRegistry,
25+
private readonly FieldsBuilder $fieldsBuilder,
26+
private readonly TypeGenerator $typeGenerator,
27+
private readonly InputTypeGenerator $inputTypeGenerator,
28+
private readonly RecursiveTypeMapperInterface $recursiveTypeMapper,
29+
private readonly ContainerInterface $container,
30+
private readonly CacheInterface $cache,
31+
private readonly InputTypeValidatorInterface|null $inputTypeValidator,
32+
private readonly int|null $globTTL,
33+
private readonly int|null $mapTTL = null,
3434
) {
3535
}
3636

src/FieldsBuilder.php

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
use function key;
6363
use function reset;
6464
use function rtrim;
65-
use function strpos;
65+
use function str_starts_with;
6666
use function trim;
6767

6868
use const PHP_EOL;
@@ -75,16 +75,16 @@ class FieldsBuilder
7575
private TypeHandler $typeMapper;
7676

7777
public function __construct(
78-
private AnnotationReader $annotationReader,
79-
private RecursiveTypeMapperInterface $recursiveTypeMapper,
80-
private ArgumentResolver $argumentResolver,
81-
private TypeResolver $typeResolver,
82-
private CachedDocBlockFactory $cachedDocBlockFactory,
83-
private NamingStrategyInterface $namingStrategy,
84-
private RootTypeMapperInterface $rootTypeMapper,
85-
private ParameterMiddlewareInterface $parameterMapper,
86-
private FieldMiddlewareInterface $fieldMiddleware,
87-
private InputFieldMiddlewareInterface $inputFieldMiddleware,
78+
private readonly AnnotationReader $annotationReader,
79+
private readonly RecursiveTypeMapperInterface $recursiveTypeMapper,
80+
private readonly ArgumentResolver $argumentResolver,
81+
private readonly TypeResolver $typeResolver,
82+
private readonly CachedDocBlockFactory $cachedDocBlockFactory,
83+
private readonly NamingStrategyInterface $namingStrategy,
84+
private readonly RootTypeMapperInterface $rootTypeMapper,
85+
private readonly ParameterMiddlewareInterface $parameterMapper,
86+
private readonly FieldMiddlewareInterface $fieldMiddleware,
87+
private readonly InputFieldMiddlewareInterface $inputFieldMiddleware,
8888
)
8989
{
9090
$this->typeMapper = new TypeHandler($this->argumentResolver, $this->rootTypeMapper, $this->typeResolver);
@@ -342,7 +342,7 @@ private function getFieldsByMethodAnnotations(string|object $controller, Reflect
342342
$methodName = $refMethod->getName();
343343

344344
if ($queryAnnotation instanceof Field) {
345-
if (strpos($methodName, 'set') === 0) {
345+
if (str_starts_with($methodName, 'set')) {
346346
continue;
347347
}
348348
$for = $queryAnnotation->getFor();
@@ -673,12 +673,8 @@ private function getMagicGetMethodFromSourceClassOrProxy(ReflectionClass $proxyR
673673
return $sourceRefClass->getMethod($magicGet);
674674
}
675675

676-
/**
677-
* @param ReflectionClass<object> $refClass
678-
*
679-
* @return OutputType&Type
680-
*/
681-
private function resolveOutputType(string $outputType, ReflectionClass $refClass, SourceFieldInterface $sourceField): OutputType
676+
/** @param ReflectionClass<object> $refClass */
677+
private function resolveOutputType(string $outputType, ReflectionClass $refClass, SourceFieldInterface $sourceField): OutputType&Type
682678
{
683679
try {
684680
return $this->typeResolver->mapNameToOutputType($outputType);
@@ -688,12 +684,8 @@ private function resolveOutputType(string $outputType, ReflectionClass $refClass
688684
}
689685
}
690686

691-
/**
692-
* @param ReflectionClass<object> $refClass
693-
*
694-
* @return OutputType&Type
695-
*/
696-
private function resolvePhpType(string $phpTypeStr, ReflectionClass $refClass, ReflectionMethod $refMethod): OutputType
687+
/** @param ReflectionClass<object> $refClass */
688+
private function resolvePhpType(string $phpTypeStr, ReflectionClass $refClass, ReflectionMethod $refMethod): OutputType&Type
697689
{
698690
$typeResolver = new \phpDocumentor\Reflection\TypeResolver();
699691

@@ -850,7 +842,7 @@ private function getInputFieldsByMethodAnnotations(string|object $controller, Re
850842

851843
$docBlockObj = $this->cachedDocBlockFactory->getDocBlock($refMethod);
852844
$methodName = $refMethod->getName();
853-
if (strpos($methodName, 'set') !== 0) {
845+
if (! str_starts_with($methodName, 'set')) {
854846
continue;
855847
}
856848
$name = $fieldAnnotations->getName() ?: $this->namingStrategy->getInputFieldNameFromMethodName($methodName);

src/Http/WebonyxGraphqlMiddleware.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ final class WebonyxGraphqlMiddleware implements MiddlewareInterface
4242
];
4343

4444
public function __construct(
45-
private ServerConfig $config,
46-
private ResponseFactoryInterface $responseFactory,
47-
private StreamFactoryInterface $streamFactory,
48-
private HttpCodeDeciderInterface $httpCodeDecider,
49-
private string $graphqlUri = '/graphql',
45+
private readonly ServerConfig $config,
46+
private readonly ResponseFactoryInterface $responseFactory,
47+
private readonly StreamFactoryInterface $streamFactory,
48+
private readonly HttpCodeDeciderInterface $httpCodeDecider,
49+
private readonly string $graphqlUri = '/graphql',
5050
StandardServer|null $handler = null,
5151
)
5252
{

src/InputField.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* @phpstan-import-type InputObjectFieldConfig from InputObjectField
3030
* @phpstan-import-type ArgumentType from InputObjectField
3131
*/
32-
class InputField extends InputObjectField
32+
final class InputField extends InputObjectField
3333
{
3434
/** @var callable */
3535
private $resolve;

src/InputFieldDescriptor.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class InputFieldDescriptor
2727
{
2828
private string $name;
2929
/** @var (InputType&Type)|(InputType&Type&NullableType) */
30-
private InputType $type;
30+
private InputType&Type $type;
3131
/** @var array<string, ParameterInterface> */
3232
private array $parameters = [];
3333
/** @var callable|null */
@@ -96,13 +96,12 @@ public function setName(string $name): void
9696
}
9797

9898
/** @return ((InputType&Type)|(InputType&Type&NullableType)) */
99-
public function getType(): InputType
99+
public function getType(): InputType&Type
100100
{
101101
return $this->type;
102102
}
103103

104-
/** @param (InputType&Type) $type */
105-
public function setType(InputType $type): void
104+
public function setType(InputType&Type $type): void
106105
{
107106
$this->type = $type;
108107
}

src/InputTypeUtils.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
class InputTypeUtils
3434
{
3535
public function __construct(
36-
private AnnotationReader $annotationReader,
37-
private NamingStrategyInterface $namingStrategy,
36+
private readonly AnnotationReader $annotationReader,
37+
private readonly NamingStrategyInterface $namingStrategy,
3838
)
3939
{
4040
}

0 commit comments

Comments
 (0)