Skip to content
This repository has been archived by the owner on Mar 8, 2023. It is now read-only.

Commit

Permalink
Merge d2cdb29 into 57e2845
Browse files Browse the repository at this point in the history
  • Loading branch information
crisu83 committed Mar 9, 2018
2 parents 57e2845 + d2cdb29 commit 59e6bc2
Show file tree
Hide file tree
Showing 37 changed files with 2,127 additions and 277 deletions.
2 changes: 1 addition & 1 deletion .idea/php.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
},
"autoload": {
"files": [
"./src/Error/formatError.php",
"./src/Execution/values.php",
"./src/Language/blockStringValue.php",
"./src/Language/helpers.php",
Expand All @@ -30,8 +31,12 @@
"./src/Util/coercers.php",
"./src/Util/helpers.php",
"./src/Util/invariant.php",
"./src/Util/orList.php",
"./src/Util/suggestionList.php",
"./src/Util/typeFromAST.php",
"./src/Util/valueFromAST.php",
"./src/Validation/rules.php",
"./src/Validation/Rule/messages.php",
"./src/facades.php"
],
"psr-4": {
Expand All @@ -47,7 +52,11 @@
"autoload-dev": {
"files": [
"./tests/Functional/Language/SchemaParserTest.php",
"./tests/Functional/Language/testSchema.php"
"./tests/Functional/Validation/Rule/ExecutableDefinitionsRuleTest.php",
"./tests/Functional/Validation/Rule/FieldOnCorrectTypeRuleTest.php",
"./tests/Functional/Validation/Rule/FragmentsOnCompositeTypesRuleTest.php",
"./tests/Functional/Validation/Rule/KnownArgumentNamesRuleTest.php",
"./tests/Functional/Validation/harness.php"
],
"psr-4": {
"Digia\\GraphQL\\Test\\": "./tests"
Expand Down
7 changes: 7 additions & 0 deletions src/Error/ValidationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Digia\GraphQL\Error;

class ValidationException extends GraphQLException
{
}
21 changes: 21 additions & 0 deletions src/Error/formatError.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Digia\GraphQL\Error;

use function Digia\GraphQL\Util\invariant;

/**
* @param GraphQLException $error
* @return array
* @throws InvariantException
*/
function formatError(GraphQLException $error): array
{
invariant(null !== $error, 'Received null error.');

return array_merge($error->getExtensions() ?? [], [
'message' => $error->getMessage(),
'locations' => $error->getLocations(),
'path' => $error->getPath(),
]);
}
4 changes: 4 additions & 0 deletions src/GraphQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
use Digia\GraphQL\Provider\IntrospectionTypesProvider;
use Digia\GraphQL\Provider\ParserProvider;
use Digia\GraphQL\Provider\PrinterProvider;
use Digia\GraphQL\Provider\RulesProvider;
use Digia\GraphQL\Provider\ScalarTypesProvider;
use Digia\GraphQL\Provider\SchemaBuilderProvider;
use Digia\GraphQL\Provider\ValidationProvider;
use League\Container\Container;
use League\Container\ContainerInterface;

Expand Down Expand Up @@ -45,6 +47,8 @@ class GraphQL
IntrospectionTypesProvider::class,
ScalarTypesProvider::class,
DirectivesProvider::class,
ValidationProvider::class,
RulesProvider::class,
];

/**
Expand Down
5 changes: 4 additions & 1 deletion src/Language/AST/Node/ExecutableDefinitionNodeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@

interface ExecutableDefinitionNodeInterface extends DefinitionNodeInterface
{

/**
* @return null|string
*/
public function getNameValue(): ?string;
}
8 changes: 8 additions & 0 deletions src/Language/AST/Node/NameTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,12 @@ public function setName(?NameNode $name)
$this->name = $name;
return $this;
}

/**
* @inheritdoc
*/
public function __toString(): string
{
return $this->getNameValue() ?? '';
}
}
110 changes: 95 additions & 15 deletions src/Language/AST/Visitor/AcceptVisitorTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,57 @@ trait AcceptVisitorTrait
*/
protected $visitor;

/**
* @var string|int|null
*/
protected $key;

/**
* @var NodeInterface|null
*/
protected $parent;

/**
* @var array
*/
protected $path;

/**
* @var array
*/
protected $ancestors = [];

/**
* @var boolean
*/
protected $isEdited = false;

/**
* @param VisitorInterface $visitor
* @param string|int||null $key
* @param NodeInterface|null $parent
* @param array $path
* @param VisitorInterface $visitor
* @param string|int|null $key
* @param NodeInterface|null $parent
* @param array $path
* @param array|NodeInterface[] $ancestors
* @return NodeInterface|AcceptVisitorTrait|SerializationInterface|null
*/
public function accept(
VisitorInterface $visitor,
$key = null,
?NodeInterface $parent = null,
array $path = []
array $path = [],
array $ancestors = []
): ?NodeInterface {
$this->visitor = $visitor;
$this->path = $path;
$this->visitor = $visitor;
$this->key = $key;
$this->parent = $parent;
$this->path = $path;
$this->ancestors = $ancestors;

/** @var NodeInterface|AcceptVisitorTrait|null $newNode */
$newNode = clone $this; // TODO: Benchmark cloning

// If the result was null, it means that we should not traverse this branch.
if (null === ($newNode = $visitor->enterNode($newNode, $key, $parent, $this->path))) {
if (null === ($newNode = $visitor->enterNode($newNode))) {
return null;
}

Expand Down Expand Up @@ -73,7 +93,11 @@ public function accept(
}
}

return $visitor->leaveNode($newNode, $key, $parent, $this->path);
if (null !== $parent) {
$this->removeAncestor();
}

return $visitor->leaveNode($newNode);
}

/**
Expand All @@ -94,6 +118,38 @@ public function setIsEdited(bool $isEdited)
return $this;
}

/**
* @return NodeInterface|null
*/
public function getClosestAncestor(): ?NodeInterface
{
return !empty($this->ancestors) ? $this->ancestors[\count($this->ancestors) - 1] : null;
}

/**
* @return int|null|string
*/
public function getKey()
{
return $this->key;
}

/**
* @return NodeInterface|null
*/
public function getParent(): ?NodeInterface
{
return $this->parent;
}

/**
* @return array
*/
public function getPath(): array
{
return $this->path;
}

/**
* @param string|int $key
* @return array|NodeInterface|NodeInterface[]|null
Expand All @@ -110,14 +166,21 @@ protected function getNodeOrNodes($key)
*/
protected function visitNodeOrNodes($nodeOrNodes, $key)
{
return \is_array($nodeOrNodes)
$this->addAncestor($this);

$newNodeOrNodes = \is_array($nodeOrNodes)
? $this->visitNodes($nodeOrNodes, $key)
: $this->visitNode($nodeOrNodes, $key, $this);

$this->removeAncestor();

return $newNodeOrNodes;
}

/**
* @param NodeInterface[] $nodes
* @param string|int $key
* @param NodeInterface[] $nodes
* @param string|int $key
* @param NodeInterface|null $parent
* @return NodeInterface[]
*/
protected function visitNodes(array $nodes, $key): array
Expand Down Expand Up @@ -151,12 +214,12 @@ protected function visitNode(NodeInterface $node, $key, ?NodeInterface $parent):
{
$this->addOneToPath($key);

$newNode = $node->accept($this->visitor, $key, $parent, $this->path);
$newNode = $node->accept($this->visitor, $key, $parent, $this->path, $this->ancestors);

// If the node was edited, we need to revisit it
// to produce the expected result.
if (null !== $newNode && $newNode->isEdited()) {
$newNode = $newNode->accept($this->visitor, $key, $parent, $this->path);
$newNode = $newNode->accept($this->visitor, $key, $parent, $this->path, $this->ancestors);
}

$this->removeOneFromPath();
Expand Down Expand Up @@ -198,7 +261,24 @@ protected function addOneToPath(string $key)
*/
protected function removeOneFromPath()
{
$this->path = \array_slice($this->path, 0, count($this->path) - 1);
$this->path = \array_slice($this->path, 0, -1);
}

/**
* Adds an ancestor.
* @param NodeInterface $node
*/
protected function addAncestor(NodeInterface $node)
{
$this->ancestors[] = $node;
}

/**
* Removes the last ancestor.
*/
protected function removeAncestor()
{
$this->ancestors = \array_slice($this->ancestors, 0, -1);
}

/**
Expand Down
33 changes: 8 additions & 25 deletions src/Language/AST/Visitor/ParallelVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace Digia\GraphQL\Language\AST\Visitor;

use Digia\GraphQL\Language\AST\Node\NodeInterface;
use Digia\GraphQL\Util\SerializationInterface;

class ParallelVisitor implements VisitorInterface
{
Expand All @@ -27,24 +26,16 @@ public function __construct($visitors)
}

/**
* @param NodeInterface|AcceptVisitorTrait $node
* @param string|int|null $key
* @param NodeInterface|null $parent
* @param array $path
* @return NodeInterface|SerializationInterface|null
* @inheritdoc
*/
public function enterNode(
NodeInterface $node,
$key = null,
?NodeInterface $parent = null,
array $path = []
): ?NodeInterface {
public function enterNode(NodeInterface $node): ?NodeInterface
{
$newNode = null;

foreach ($this->visitors as $i => $visitor) {
if (!isset($this->_skipping[$i])) {
try {
$newNode = $visitor->enterNode($node, $key, $parent, $path);
$newNode = $visitor->enterNode($node);
} catch (VisitorBreak $break) {
$this->_skipping[$i] = $break;
continue;
Expand All @@ -62,24 +53,16 @@ public function enterNode(
}

/**
* @param NodeInterface|AcceptVisitorTrait $node
* @param string|int|null $key
* @param NodeInterface|null $parent
* @param array $path
* @return NodeInterface|SerializationInterface|null
* @inheritdoc
*/
public function leaveNode(
NodeInterface $node,
$key = null,
?NodeInterface $parent = null,
array $path = []
): ?NodeInterface {
public function leaveNode(NodeInterface $node): ?NodeInterface
{
$newNode = null;

foreach ($this->visitors as $i => $visitor) {
if (!isset($this->_skipping[$i])) {
try {
$newNode = $visitor->leaveNode($node, $key, $parent, $path);
$newNode = $visitor->leaveNode($node);
} catch (VisitorBreak $break) {
$this->_skipping[$i] = $break;
continue;
Expand Down
Loading

0 comments on commit 59e6bc2

Please sign in to comment.