Completed
Pull Request — master (#45)
by Christoffer
02:03
created

NoUnusedVariablesRule   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 54
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 54
rs 10
c 0
b 0
f 0
wmc 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
B leaveNode() 0 28 6
A enterNode() 0 11 3
1
<?php
2
3
namespace Digia\GraphQL\Validation\Rule;
4
5
use Digia\GraphQL\Error\ValidationException;
6
use Digia\GraphQL\Language\AST\Node\NodeInterface;
7
use Digia\GraphQL\Language\AST\Node\OperationDefinitionNode;
8
use Digia\GraphQL\Language\AST\Node\VariableDefinitionNode;
9
use Digia\GraphQL\Language\AST\Node\VariableNode;
10
11
/**
12
 * No unused variables
13
 *
14
 * A GraphQL operation is only valid if all variables defined by an operation
15
 * are used, either directly or within a spread fragment.
16
 */
17
class NoUnusedVariablesRule extends AbstractRule
18
{
19
    /**
20
     * @var array|VariableDefinitionNode[]
21
     */
22
    protected $variableDefinitions;
23
24
    /**
25
     * @inheritdoc
26
     */
27
    public function enterNode(NodeInterface $node): ?NodeInterface
28
    {
29
        if ($node instanceof OperationDefinitionNode) {
30
            $this->variableDefinitions = [];
31
        }
32
33
        if ($node instanceof VariableDefinitionNode) {
34
            $this->variableDefinitions[] = $node;
35
        }
36
37
        return $node;
38
    }
39
40
    /**
41
     * @inheritdoc
42
     */
43
    public function leaveNode(NodeInterface $node): ?NodeInterface
44
    {
45
        if ($node instanceof OperationDefinitionNode) {
46
            $variableNamesUsed = [];
47
            $usages            = $this->context->getRecursiveVariableUsages($node);
48
            $operationNameNode = $node->getName();
49
            $operationName     = null !== $operationNameNode ? $operationNameNode->getValue() : null;
50
51
            /** @var VariableNode $variableNode */
52
            foreach ($usages as ['node' => $variableNode]) {
53
                $variableNamesUsed[$variableNode->getNameValue()] = true;
54
            }
55
56
            foreach ($this->variableDefinitions as $variableDefinition) {
57
                $variableName = $variableDefinition->getVariable()->getNameValue();
58
59
                if (!isset($variableNamesUsed[$variableName])) {
60
                    $this->context->reportError(
61
                        new ValidationException(
62
                            unusedVariableMessage($variableName, $operationName),
63
                            [$variableDefinition]
64
                        )
65
                    );
66
                }
67
            }
68
        }
69
70
        return $node;
71
    }
72
73
74
}
75