Completed
Pull Request — master (#2)
by Hans
02:22
created

Parser::parseDefinition()   C

Complexity

Conditions 11
Paths 11

Size

Total Lines 77
Code Lines 45

Duplication

Lines 42
Ratio 54.55 %

Code Coverage

Tests 24
CRAP Score 26.125

Importance

Changes 0
Metric Value
dl 42
loc 77
ccs 24
cts 48
cp 0.5
rs 5.3974
c 0
b 0
f 0
cc 11
eloc 45
nc 11
nop 0
crap 26.125

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace HansOtt\GraphQL\Query;
4
5
use HansOtt\GraphQL\Shared\ScannerTokens;
6
use HansOtt\GraphQL\Shared\ScannerGeneric;
7
use HansOtt\GraphQL\Shared\Parser as ParserShared;
8
9
final class Parser extends ParserShared
10
{
11 6
    protected function getNameFor($tokenType)
12
    {
13 6
        return Token::getNameFor($tokenType);
14
    }
15
16 6 View Code Duplication
    private function parseObject()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
17
    {
18 3
        $location = $this->expect(Token::T_BRACE_LEFT)->location;
19 3
        $fields = array();
20
21 3
        while (true) {
22 3
            if ($this->scanner->eof()) {
23
                throw $this->getParseError('Unclosed brace of object value');
24
            }
25
26 3
            if ($this->accept(Token::T_BRACE_RIGHT)) {
27 6
                break;
28
            }
29
30 3
            $nameToken = $this->expect(Token::T_NAME);
31 3
            $this->expect(Token::T_COLON);
32 3
            $fields[] = new ValueObjectField($nameToken->value, $this->parseValue(), $nameToken->location);
0 ignored issues
show
Documentation introduced by
$nameToken->location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
33 3
            $this->accept(Token::T_COMMA);
34 3
        }
35
36 3
        return new ValueObject($fields, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
37
    }
38
39 6 View Code Duplication
    private function parseList()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
40
    {
41 6
        $location = $this->expect(Token::T_BRACKET_LEFT)->location;
42 6
        $items = array();
43
44 6
        while (true) {
45 6
            if ($this->scanner->eof()) {
46
                throw $this->getParseError('Unclosed bracket of list');
47
            }
48
49 6
            if ($this->accept(Token::T_BRACKET_RIGHT)) {
50 3
                break;
51
            }
52
53 6
            $items[] = $this->parseValue();
54 3
            $this->accept(Token::T_COMMA);
55 3
        }
56
57 3
        return new ValueList($items, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
58
    }
59
60 15
    private function parseVariable()
61
    {
62 15
        $location = $this->expect(Token::T_DOLLAR)->location;
63 15
        $name = $this->expect(Token::T_NAME)->value;
64
65 15
        return new ValueVariable($name, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
66
    }
67
68 30
    private function parseValue()
69
    {
70 30
        if ($this->is(Token::T_DOLLAR)) {
71 12
            return $this->parseVariable();
72
        }
73
74 24
        if ($string = $this->accept(Token::T_STRING)) {
75 18
            return new ValueString($string->value, $string->location);
0 ignored issues
show
Documentation introduced by
$string->location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
76
        }
77
78 21
        if ($true = $this->accept(Token::T_TRUE)) {
79 3
            return new ValueBoolean(true, $true->location);
80
        }
81
82 21
        if ($false = $this->accept(Token::T_FALSE)) {
83 3
            return new ValueBoolean(false, $false->location);
84
        }
85
86 21
        if ($null = $this->accept(Token::T_NULL)) {
87 3
            return new ValueNull($null->location);
88
        }
89
90 21
        if ($int = $this->accept(Token::T_INT)) {
91 18
            return new ValueInt($int->value, $int->location);
92
        }
93
94 6
        if ($float = $this->accept(Token::T_FLOAT)) {
95 3
            return new ValueFloat($float->value, $float->location);
96
        }
97
98 6
        if ($name = $this->accept(Token::T_NAME)) {
99 3
            return new ValueEnum($name->value, $name->location);
100
        }
101
102 6
        if ($this->is(Token::T_BRACKET_LEFT)) {
103 6
            return $this->parseList();
104
        }
105
106 6
        if ($this->is(Token::T_BRACE_LEFT)) {
107 3
            return $this->parseObject();
108
        }
109
110 3
        $message = 'Expected a value';
111
112 3
        if ($this->scanner->eof()) {
113
            throw $this->getParseError($message . ' but instead reached end');
114
        }
115
116 3
        $token = $this->scanner->peek();
117 3
        throw $this->getParseError($message . " but instead found \"{$token->getName()}\" with value \"{$token->value}\"");
118
    }
119
120 36
    private function parseArgument()
121
    {
122 36
        $nameToken = $this->expect(Token::T_NAME);
123 30
        $this->expect(Token::T_COLON);
124 30
        $value = $this->parseValue();
125
126 27
        return new Argument($nameToken->value, $value, $nameToken->location);
0 ignored issues
show
Documentation introduced by
$nameToken->location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
127
    }
128
129 60 View Code Duplication
    private function parseArgumentList()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
130
    {
131 60
        $arguments = array();
132
133 60
        if ($this->is(Token::T_PAREN_LEFT) === false) {
134 30
            return $arguments;
135
        }
136
137 39
        $this->expect(Token::T_PAREN_LEFT);
138
139 39
        while (true) {
140 39
            if ($this->scanner->eof()) {
141
                throw $this->getParseError('Unclosed brace of argument list');
142
            }
143
144 39
            if ($this->accept(Token::T_PAREN_RIGHT)) {
145 30
                break;
146
            }
147
148 36
            $arguments[] = $this->parseArgument();
149 27
            $this->accept(Token::T_COMMA);
150 27
        }
151
152 30
        return $arguments;
153
    }
154
155 60
    private function parseField()
156
    {
157 60
        $nameToken = $this->expect(Token::T_NAME);
158 60
        $name = $nameToken->value;
159
160 60
        $alias = null;
161 60
        if ($this->is(Token::T_COLON)) {
162 3
            $this->expect(Token::T_COLON);
163 3
            $aliasToken = $this->expect(Token::T_NAME);
164 3
            $alias = $name;
165 3
            $name = $aliasToken->value;
166 3
        }
167
168 60
        $arguments = $this->parseArgumentList();
169 51
        $directives = $this->parseDirectiveList();
170
171 51
        $selectionSet = null;
172 51
        if ($this->is(Token::T_BRACE_LEFT)) {
173 21
            $selectionSet = $this->parseSelectionSet();
174 18
        }
175
176 48
        return new SelectionField($alias, $name, $arguments, $directives, $selectionSet, $nameToken->location);
0 ignored issues
show
Documentation introduced by
$nameToken->location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
177
    }
178
179 6
    private function parseFragment()
180
    {
181 6
        $location = $this->expect(Token::T_SPREAD)->location;
182 6
        $fragmentName = $this->expect(Token::T_NAME)->value;
183
184 6
        if ($fragmentName !== 'on') {
185 3
            return new SelectionFragmentSpread($fragmentName, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
186
        }
187
188 3
        $this->scanner->back();
189 3
        $typeCondition = $this->parseTypeCondition();
190 3
        $directives = $this->parseDirectiveList();
191 3
        $selectionSet = $this->parseSelectionSet();
192
193 3
        return new SelectionInlineFragment($typeCondition, $directives, $selectionSet, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
194
    }
195
196 63 View Code Duplication
    private function parseSelection()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
197
    {
198 63
        if ($this->is(Token::T_SPREAD)) {
199 6
            return $this->parseFragment();
200
        }
201
202 63
        if ($this->is(Token::T_NAME)) {
203 60
            return $this->parseField();
204
        }
205
206 3
        $message = 'Expected a field, a fragment spread or an inline fragment';
207
208 3
        if ($this->scanner->eof()) {
209
            throw $this->getParseError($message . ' but instead reached end');
210
        }
211
212 3
        $token = $this->scanner->peek();
213 3
        throw $this->getParseError($message . " but instead found \"{$token->getName()}\" with value \"{$token->value}\"");
214
    }
215
216 66 View Code Duplication
    private function parseSelectionSet()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
217
    {
218 66
        $location = $this->expect(Token::T_BRACE_LEFT)->location;
219
220
        /** @var Selection[] $selections */
221 66
        $selections = array();
222 66
        while (true) {
223 66
            if ($this->scanner->eof()) {
224 9
                throw $this->getParseError('Unclosed brace of selection set');
225
            }
226
227 63
            if ($this->accept(Token::T_BRACE_RIGHT)) {
228 45
                break;
229
            }
230
231 63
            $selections[] = $this->parseSelection();
232 48
        }
233
234 45
        return new SelectionSet($selections, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
235
    }
236
237 6
    private function parseTypeCondition()
238
    {
239 6
        $nameToken = $this->expect(Token::T_NAME);
240 6
        $on = $nameToken->value;
241 6
        if ($on !== 'on') {
242
            $tokenNameName = Token::getNameFor(Token::T_NAME);
243
            throw $this->getParseError("Expected a type condition but instead found \"{$tokenNameName}\" with value \"{$on}\"");
244
        }
245
246 6
        $type = $this->parseNamedType();
247
248 6
        return new TypeCondition($type, $nameToken->location);
0 ignored issues
show
Documentation introduced by
$nameToken->location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
249
    }
250
251 6
    private function parseListType()
252 3
    {
253 6
        $location = $this->expect(Token::T_BRACKET_LEFT)->location;
254 3
        $type = $this->parseType();
255 3
        $this->accept(Token::T_BRACKET_RIGHT);
256
257 3
        return new TypeList($type, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
258
    }
259
260 18
    private function parseNamedType()
261
    {
262 18
        $nameToken = $this->expect(Token::T_NAME);
263 18
        $type = new TypeNamed($nameToken->value, $nameToken->location);
0 ignored issues
show
Documentation introduced by
$nameToken->location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
264
265 18
        return $type;
266
    }
267
268 12
    private function parseType()
269
    {
270 12
        $type = null;
271 12
        if ($this->is(Token::T_BRACKET_LEFT)) {
272 3
            $type = $this->parseListType();
273 12
        } elseif ($this->is(Token::T_NAME)) {
274 12
            $type = $this->parseNamedType();
275 12
        }
276
277 12
        if ($type !== null) {
278 12
            if ($this->accept(Token::T_EXCLAMATION)) {
279 6
                return new TypeNonNull($type, $type->location);
280
            }
281 9
            return $type;
282
        }
283
284
        $message = 'Expected a type';
285
286
        if ($this->scanner->eof()) {
287
            throw $this->getParseError($message . ' but instead reached end');
288
        }
289
290
        $token = $this->scanner->peek();
291
        throw $this->getParseError($message . " but instead found \"{$token->getName()}\" with value \"{$token->value}\"");
292
    }
293
294 6
    private function parseDirective()
295
    {
296 6
        $location = $this->expect(Token::T_AT)->location;
297 6
        $name = $this->expect(Token::T_NAME)->value;
298 6
        $arguments = $this->parseArgumentList();
299
300 6
        return new Directive($name, $arguments, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
301
    }
302
303 51
    private function parseDirectiveList()
304
    {
305 51
        $directives = array();
306 51
        while ($this->is(Token::T_AT)) {
307 6
            $directives[] = $this->parseDirective();
308 6
        }
309
310 51
        return $directives;
311
    }
312
313 12 View Code Duplication
    private function parseVariableDefinition()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
314
    {
315 12
        $variable = $this->parseVariable();
316 12
        $this->expect(Token::T_COLON);
317 12
        $type = $this->parseType();
318 12
        $defaultValue = null;
319
320 12
        if ($this->accept(Token::T_EQUAL)) {
321 3
            $defaultValue = $this->parseValue();
322 3
        }
323
324 12
        return new VariableDefinition($variable, $type, $defaultValue, $variable->location);
0 ignored issues
show
Bug introduced by
It seems like $variable->location can also be of type object<HansOtt\GraphQL\Shared\Location>; however, HansOtt\GraphQL\Query\Va...finition::__construct() does only seem to accept null|object<HansOtt\GraphQL\Query\Location>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
325
    }
326
327 18 View Code Duplication
    private function parseVariableDefinitionList()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
328
    {
329 18
        $definitions = array();
330
331 18
        if ($this->is(Token::T_PAREN_LEFT) === false) {
332 6
            return $definitions;
333
        }
334
335 12
        $this->expect(Token::T_PAREN_LEFT);
336
337 12
        while (true) {
338 12
            if ($this->scanner->eof()) {
339
                throw $this->getParseError('Unclosed parenthesis of variable definition list');
340
            }
341
342 12
            if ($this->accept(Token::T_PAREN_RIGHT)) {
343 12
                break;
344
            }
345
346 12
            $definitions[] = $this->parseVariableDefinition();
347 12
            $this->accept(Token::T_COMMA);
348 12
        }
349
350 12
        return $definitions;
351
    }
352
353 66
    private function parseDefinition()
354
    {
355 66
        if ($this->is(Token::T_FRAGMENT)) {
356 3
            $location = $this->expect(Token::T_FRAGMENT)->location;
357
358 3
            $name = $this->expect(Token::T_NAME)->value;
359 3
            if ($name === 'on') {
360
                throw $this->getParseError('A fragment cannot be named "on"');
361
            }
362
363 3
            $typeCondition = $this->parseTypeCondition();
364 3
            $directives = $this->parseDirectiveList();
365 3
            $selectionSet = $this->parseSelectionSet();
366
367 3
            return new Fragment($name, $typeCondition, $directives, $selectionSet, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
368
        }
369
370 66 View Code Duplication
        if ($this->is(Token::T_MUTATION)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
371
            $location = $this->expect(Token::T_MUTATION)->location;
372
373
            $name = null;
374
            if ($this->is(Token::T_NAME)) {
375
                $name = $this->expect(Token::T_NAME)->value;
376
            }
377
378
            $variables = $this->parseVariableDefinitionList();
379
            $directives = $this->parseDirectiveList();
380
            $selectionSet = $this->parseSelectionSet();
381
382
            return new OperationMutation($name, $variables, $directives, $selectionSet, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
383
        }
384
385 66 View Code Duplication
        if ($this->is(Token::T_SUBSCRIPTION)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
386
            $location = $this->expect(Token::T_SUBSCRIPTION)->location;
387
388
            $name = null;
389
            if ($this->is(Token::T_NAME)) {
390
                $name = $this->expect(Token::T_NAME)->value;
391
            }
392
393
            $variables = $this->parseVariableDefinitionList();
394
            $directives = $this->parseDirectiveList();
395
            $selectionSet = $this->parseSelectionSet();
396
397
            return new OperationSubscription($name, $variables, $directives, $selectionSet, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
398
        }
399
400 66 View Code Duplication
        if ($this->is(Token::T_QUERY)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
401 18
            $location = $this->expect(Token::T_QUERY)->location;
402
403 18
            $name = null;
404 18
            if ($this->is(Token::T_NAME)) {
405 15
                $name = $this->expect(Token::T_NAME)->value;
406 15
            }
407
408 18
            $variables = $this->parseVariableDefinitionList();
409 18
            $directives = $this->parseDirectiveList();
410 18
            $selectionSet = $this->parseSelectionSet();
411
412 18
            return new OperationQuery($name, $variables, $directives, $selectionSet, $location);
0 ignored issues
show
Documentation introduced by
$location is of type object<HansOtt\GraphQL\Shared\Location>, but the function expects a null|object<HansOtt\GraphQL\Query\Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
413
        }
414
415 48
        if ($this->is(Token::T_BRACE_LEFT)) {
416 48
            $selectionSet = $this->parseSelectionSet();
417
418 27
            return new OperationQuery(null, array(), array(), $selectionSet, $selectionSet->location);
0 ignored issues
show
Bug introduced by
It seems like $selectionSet->location can also be of type object<HansOtt\GraphQL\Shared\Location>; however, HansOtt\GraphQL\Query\OperationBase::__construct() does only seem to accept null|object<HansOtt\GraphQL\Query\Location>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
419
        }
420
421
        $message = 'Expected a query, a query shorthand, a mutation or a subscription operation';
422
423
        if ($this->scanner->eof()) {
424
            throw $this->getParseError($message . ' but instead reached end');
425
        }
426
427
        $token = $this->scanner->peek();
428
        throw $this->getParseError($message . " but instead found \"{$token->getName()}\" with value \"{$token->value}\"");
429
    }
430
431 69
    private function parseDocument()
432
    {
433
        /** @var Definition[] $definitions */
434 69
        $definitions = array();
435 69
        while ($this->scanner->eof() === false) {
436 66
            $definitions[] = $this->parseDefinition();
437 45
        }
438
439 48
        return new Document($definitions);
440
    }
441
442
    /**
443
     * @param string $query
444
     *
445
     * @throws \HansOtt\GraphQL\Shared\SyntaxError
446
     *
447
     * @return Document
448
     */
449 96
    public function parse($query)
450
    {
451 96
        $tokens = $this->lexer->lex($query);
452 69
        $scanner = new ScannerGeneric($tokens);
453 69
        $this->scanner = new ScannerTokens($scanner);
454 69
        $document = $this->parseDocument();
455
456 48
        return $document;
457
    }
458
}
459