Skip to content
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 .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
after_script:
- travis_retry php vendor/bin/php-coveralls -v
- stage: test
php: 7.4snapshot
php: 7.4
env: PREFER_LOWEST=""
before_script:
- *composerupdate
Expand Down
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
"phpunit/phpunit": "^8.2.4",
"php-coveralls/php-coveralls": "^2.1",
"mouf/picotainer": "^1.1",
"phpstan/phpstan": "^0.11",
"phpstan/phpstan": "^0.12.3",
"beberlei/porpaginas": "^1.2",
"myclabs/php-enum": "^1.6.6",
"doctrine/coding-standard": "^6.0",
"phpstan/phpstan-webmozart-assert": "^0.11.2",
"doctrine/coding-standard": "^7.0",
"phpstan/phpstan-webmozart-assert": "^0.12",
"phpstan/extension-installer": "^1.0",
"thecodingmachine/phpstan-strict-rules": "^0.11.2",
"thecodingmachine/phpstan-strict-rules": "^0.12",
"zendframework/zend-diactoros": "^2"
},
"suggest": {
Expand All @@ -58,7 +58,7 @@
}
},
"scripts": {
"phpstan": "phpstan analyse src -c phpstan.neon --level=7 --no-progress -vvv",
"phpstan": "phpstan analyse src -c phpstan.neon --level=8 --no-progress -vvv",
"cs-check": "phpcs",
"cs-fix": "phpcbf",
"test": ["@cs-check", "@phpstan", "phpunit"]
Expand Down
16 changes: 16 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,20 @@
<property name="spacesCountBeforeColon" value="0"/>
</properties>
</rule>

<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint">
<properties>
<property name="enableNativeTypeHint" value="0"/>
</properties>
</rule>

<!-- Require consistent spacing for block structures -->
<rule ref="SlevomatCodingStandard.ControlStructures.BlockControlStructureSpacing">
<exclude name="SlevomatCodingStandard.ControlStructures.BlockControlStructureSpacing.IncorrectLinesCountBeforeControlStructure" />
<exclude name="SlevomatCodingStandard.ControlStructures.BlockControlStructureSpacing.IncorrectLinesCountBeforeFirstControlStructure" />
<exclude name="SlevomatCodingStandard.ControlStructures.BlockControlStructureSpacing.IncorrectLinesCountAfterControlStructure" />
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.JumpStatementsSpacing">
<exclude name="SlevomatCodingStandard.ControlStructures.JumpStatementsSpacing.IncorrectLinesCountBeforeControlStructure" />
</rule>
</ruleset>
6 changes: 6 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ parameters:
-
message: '#Parameter \#2 \$subType of method .* expects#'
path: src/Mappers/Root/IteratorTypeMapper.php
-
message: '#Unreachable statement - code above always terminates.#'
path: src/Http/WebonyxGraphqlMiddleware.php
-
message: '#Property TheCodingMachine\GraphQLite\Annotations\Type::$class \(class-string<object>|null\) does not accept string.#'
path: src/Annotations/Type.php
- '#Call to an undefined method GraphQL\\Error\\ClientAware::getMessage()#'
#-
# message: '#If condition is always true#'
Expand Down
33 changes: 28 additions & 5 deletions src/AnnotationReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use function array_key_exists;
use function array_merge;
use function array_values;
use function assert;
use function in_array;
use function strpos;
use function strrpos;
Expand Down Expand Up @@ -70,11 +71,16 @@ public function __construct(Reader $reader, string $mode = self::STRICT_MODE, ar
$this->strictNamespaces = $strictNamespaces;
}

/**
* @param ReflectionClass<T> $refClass
*
* @template T of object
*/
public function getTypeAnnotation(ReflectionClass $refClass): ?Type
{
try {
/** @var Type|null $type */
$type = $this->getClassAnnotation($refClass, Type::class);
assert($type instanceof Type || $type === null);
if ($type !== null && $type->isSelfType()) {
$type->setClass($refClass->getName());
}
Expand All @@ -85,11 +91,16 @@ public function getTypeAnnotation(ReflectionClass $refClass): ?Type
return $type;
}

/**
* @param ReflectionClass<T> $refClass
*
* @template T of object
*/
public function getExtendTypeAnnotation(ReflectionClass $refClass): ?ExtendType
{
try {
/** @var ExtendType|null $extendType */
$extendType = $this->getClassAnnotation($refClass, ExtendType::class);
assert($extendType instanceof ExtendType || $extendType === null);
} catch (ClassNotFoundException $e) {
throw ClassNotFoundException::wrapExceptionForExtendTag($e, $refClass->getName());
}
Expand All @@ -99,14 +110,18 @@ public function getExtendTypeAnnotation(ReflectionClass $refClass): ?ExtendType

public function getRequestAnnotation(ReflectionMethod $refMethod, string $annotationName): ?AbstractRequest
{
/** @var AbstractRequest|null $queryAnnotation */
$queryAnnotation = $this->getMethodAnnotation($refMethod, $annotationName);
assert($queryAnnotation instanceof AbstractRequest || $queryAnnotation === null);

return $queryAnnotation;
}

/**
* @param ReflectionClass<T> $refClass
*
* @return SourceField[]
*
* @template T of object
*/
public function getSourceFields(ReflectionClass $refClass): array
{
Expand All @@ -118,16 +133,16 @@ public function getSourceFields(ReflectionClass $refClass): array

public function getFactoryAnnotation(ReflectionMethod $refMethod): ?Factory
{
/** @var Factory|null $factoryAnnotation */
$factoryAnnotation = $this->getMethodAnnotation($refMethod, Factory::class);
assert($factoryAnnotation instanceof Factory || $factoryAnnotation === null);

return $factoryAnnotation;
}

public function getDecorateAnnotation(ReflectionMethod $refMethod): ?Decorate
{
/** @var Decorate|null $decorateAnnotation */
$decorateAnnotation = $this->getMethodAnnotation($refMethod, Decorate::class);
assert($decorateAnnotation instanceof Decorate || $decorateAnnotation === null);

return $decorateAnnotation;
}
Expand Down Expand Up @@ -157,6 +172,10 @@ public function getMiddlewareAnnotations(ReflectionMethod $refMethod): Middlewar

/**
* Returns a class annotation. Does not look in the parent class.
*
* @param ReflectionClass<T> $refClass
*
* @template T of object
*/
private function getClassAnnotation(ReflectionClass $refClass, string $annotationClass): ?object
{
Expand Down Expand Up @@ -230,7 +249,11 @@ private function isErrorImportant(string $annotationClass, string $docComment, s
/**
* Returns the class annotations. Finds in the parents too.
*
* @param ReflectionClass<T> $refClass
*
* @return object[]
*
* @template T of object
*/
public function getClassAnnotations(ReflectionClass $refClass, string $annotationClass): array
{
Expand Down
17 changes: 8 additions & 9 deletions src/Annotations/ExtendType.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*/
class ExtendType
{
/** @var string|null */
/** @var class-string<object>|null */
private $class;
/** @var string|null */
private $name;
Expand All @@ -35,24 +35,23 @@ public function __construct(array $attributes = [])
if (! isset($attributes['class']) && ! isset($attributes['name'])) {
throw new BadMethodCallException('In annotation @ExtendType, missing one of the compulsory parameter "class" or "name".');
}
$this->class = $attributes['class'] ?? null;
$class = isset($attributes['class']) ? ltrim($attributes['class'], '\\') : null;
$this->name = $attributes['name'] ?? null;
if ($this->class !== null && ! class_exists($this->class) && ! interface_exists($this->class)) {
throw ClassNotFoundException::couldNotFindClass($this->class);
if ($class !== null && ! class_exists($class) && ! interface_exists($class)) {
throw ClassNotFoundException::couldNotFindClass($class);
}
$this->class = $class;
}

/**
* Returns the name of the GraphQL query/mutation/field.
* If not specified, the name of the method should be used instead.
*
* @return class-string<object>|null
*/
public function getClass(): ?string
{
if ($this->class === null) {
return null;
}

return ltrim($this->class, '\\');
return $this->class;
}

public function getName(): ?string
Expand Down
13 changes: 8 additions & 5 deletions src/Annotations/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/
class Type
{
/** @var string|null */
/** @var class-string<object>|null */
private $class;

/** @var string|null */
Expand Down Expand Up @@ -74,6 +74,8 @@ public function __construct(array $attributes = [])

/**
* Returns the fully qualified class name of the targeted class.
*
* @return class-string<object>
*/
public function getClass(): string
{
Expand All @@ -86,11 +88,12 @@ public function getClass(): string

public function setClass(string $class): void
{
$this->class = ltrim($class, '\\');
$isInterface = interface_exists($this->class);
if (! class_exists($this->class) && ! $isInterface) {
throw ClassNotFoundException::couldNotFindClass($this->class);
$class = ltrim($class, '\\');
$isInterface = interface_exists($class);
if (! class_exists($class) && ! $isInterface) {
throw ClassNotFoundException::couldNotFindClass($class);
}
$this->class = $class;

if (! $isInterface) {
return;
Expand Down
4 changes: 2 additions & 2 deletions src/Containers/BasicAutoWiringContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function __construct(ContainerInterface $container)
* @throws NotFoundExceptionInterface No entry was found for **this** identifier.
* @throws ContainerExceptionInterface Error while retrieving the entry.
*
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint
*/
public function get($id)
{
Expand Down Expand Up @@ -74,7 +74,7 @@ public function get($id)
*
* @param string $id Identifier of the entry to look for.
*
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint
*/
public function has($id): bool
{
Expand Down
4 changes: 2 additions & 2 deletions src/Containers/EmptyContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class EmptyContainer implements ContainerInterface
/**
* @param string $id
*
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint
*/
public function get($id): void
{
Expand All @@ -24,7 +24,7 @@ public function get($id): void
/**
* @param string $id
*
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint
*/
public function has($id): bool
{
Expand Down
3 changes: 2 additions & 1 deletion src/Exceptions/GraphQLAggregateException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use GraphQL\Error\ClientAware;
use Throwable;
use function array_map;
use function assert;
use function count;
use function max;
use function reset;
Expand Down Expand Up @@ -76,8 +77,8 @@ public static function throwExceptions(array $exceptions): void
return;
}
if ($count === 1) {
/** @var Throwable $exception */
$exception = reset($exceptions);
assert($exception instanceof Throwable);
throw $exception;
}
throw new self($exceptions);
Expand Down
Loading