diff --git a/.gitignore b/.gitignore index 4e3728b..321655a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ composer.phar composer.lock vendor/ bin/ +phpstan.phar diff --git a/.travis.yml b/.travis.yml index d8ec128..299fe07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,13 @@ php: - 7.2 - nightly -matrix: +jobs: + include: + - stage: Code Quality + php: 7.2 + env: STATIC_ANALYSIS + install: travis_retry composer install --prefer-dist + script: composer static-analysis allow_failures: - php: nightly @@ -22,10 +28,7 @@ before_install: - phpenv config-rm xdebug.ini || true - composer selfupdate -install: - - composer install --dev --prefer-dist - - composer require react/promise:2.* - - composer require psr/http-message:1.* +install: composer install --dev --prefer-dist script: if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then bin/phpunit --coverage-clover build/logs/clover.xml --group default,ReactPromise; else bin/phpunit --group default,ReactPromise; fi diff --git a/composer.json b/composer.json index d48b76a..4178927 100644 --- a/composer.json +++ b/composer.json @@ -14,13 +14,11 @@ }, "require-dev": { "phpunit/phpunit": "^4.8", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0", + "react/promise": "2.*" }, "config": { "bin-dir": "bin", - "platform": { - "php": "5.6.0" - }, "preferred-install": "dist", "sort-packages": true }, @@ -36,6 +34,15 @@ "GraphQL\\Examples\\Blog\\": "examples/01-blog/Blog/" } }, + "scripts": { + "static-analysis": [ + "rm phpstan.phar || true", + "@composer req --ansi --no-interaction --dev phpstan/phpstan-shim", + "cp -f vendor/phpstan/phpstan-shim/phpstan.phar .", + "@composer rem --ansi --dev phpstan/phpstan-shim", + "@php phpstan.phar analyse --ansi -l 1 -c phpstan.neon src" + ] + }, "suggest": { "react/promise": "To leverage async resolving on React PHP platform", "psr/http-message": "To use standard GraphQL server" diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..e69de29 diff --git a/src/Executor/ExecutionContext.php b/src/Executor/ExecutionContext.php index f31a444..0a73b1b 100644 --- a/src/Executor/ExecutionContext.php +++ b/src/Executor/ExecutionContext.php @@ -2,6 +2,7 @@ namespace GraphQL\Executor; use GraphQL\Error\Error; +use GraphQL\Executor\Promise\PromiseAdapter; use GraphQL\Language\AST\FragmentDefinitionNode; use GraphQL\Language\AST\OperationDefinitionNode; use GraphQL\Type\Schema; @@ -56,6 +57,11 @@ class ExecutionContext */ public $errors; + /** + * @var PromiseAdapter + */ + public $promises; + public function __construct( $schema, $fragments, diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 4460e20..e63a42a 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -560,7 +560,7 @@ class Executor switch ($selection->kind) { case NodeKind::FIELD: if (!$this->shouldIncludeNode($selection)) { - continue; + continue 2; } $name = self::getFieldEntryKey($selection); if (!isset($fields[$name])) { @@ -572,7 +572,7 @@ class Executor if (!$this->shouldIncludeNode($selection) || !$this->doesFragmentConditionMatch($selection, $runtimeType) ) { - continue; + continue 2; } $this->collectFields( $runtimeType, @@ -584,14 +584,14 @@ class Executor case NodeKind::FRAGMENT_SPREAD: $fragName = $selection->name->value; if (!empty($visitedFragmentNames[$fragName]) || !$this->shouldIncludeNode($selection)) { - continue; + continue 2; } $visitedFragmentNames[$fragName] = true; /** @var FragmentDefinitionNode|null $fragment */ $fragment = isset($exeContext->fragments[$fragName]) ? $exeContext->fragments[$fragName] : null; if (!$fragment || !$this->doesFragmentConditionMatch($fragment, $runtimeType)) { - continue; + continue 2; } $this->collectFields( $runtimeType, diff --git a/src/Language/Visitor.php b/src/Language/Visitor.php index ab20d1e..fda7540 100644 --- a/src/Language/Visitor.php +++ b/src/Language/Visitor.php @@ -6,15 +6,6 @@ use GraphQL\Language\AST\NodeKind; use GraphQL\Language\AST\NodeList; use GraphQL\Utils\TypeInfo; -class VisitorOperation -{ - public $doBreak; - - public $doContinue; - - public $removeNode; -} - /** * Utility for efficient AST traversal and modification. * @@ -258,6 +249,7 @@ class Visitor if ($visitFn) { $result = call_user_func($visitFn, $node, $key, $parent, $path, $ancestors); + $editValue = null; if ($result !== null) { if ($result instanceof VisitorOperation) { diff --git a/src/Language/VisitorOperation.php b/src/Language/VisitorOperation.php new file mode 100644 index 0000000..493073d --- /dev/null +++ b/src/Language/VisitorOperation.php @@ -0,0 +1,11 @@ + function(SelectionSetNode $node) use ($context) { + NodeKind::SELECTION_SET => function(SelectionSetNode $node) { return Visitor::skipNode(); }, - NodeKind::FRAGMENT_DEFINITION => function(FragmentDefinitionNode $node) use ($context) { + NodeKind::FRAGMENT_DEFINITION => function(FragmentDefinitionNode $node) { return Visitor::skipNode(); }, ];