Parser::parse()   C
last analyzed

Complexity

Conditions 16
Paths 40

Size

Total Lines 65
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 99.9886

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 65
ccs 18
cts 58
cp 0.3103
rs 5.9197
cc 16
eloc 54
nc 40
nop 1
crap 99.9886

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
 * For licensing information, please see the LICENSE file accompanied with this file.
4
 *
5
 * @author Gerard van Helden <[email protected]>
6
 * @copyright 2012 Gerard van Helden <http://melp.nl>
7
 */
8
9
namespace Zicht\Tool\Script;
10
11
use Symfony\Component\Process\Exception\InvalidArgumentException;
12
13
/**
14
 * Parser for root nodes of the script
15
 */
16
class Parser extends AbstractParser
17
{
18
    /**
19
     * Parses the input tokenstream and returns a Script node
20
     *
21
     * @param TokenStream $input
22
     * @return Node\Script
23
     *
24
     * @throws \Symfony\Component\Process\Exception\InvalidArgumentException
25
     * @throws \UnexpectedValueException
26
     */
27 6
    public function parse(TokenStream $input)
28
    {
29 6
        $exprParser = new Parser\Expression($this);
30 6
        $ret = new Node\Script();
31 6
        if ($input->valid()) {
32
            do {
33 5
                $hasMatch = false;
34 5
                if ($input->match(Token::EXPR_START, '@(')) {
35
                    $input->next();
36
                    $type = $input->expect(Token::IDENTIFIER)->value;
37
38
                    switch ($type) {
39
                        case 'sh':
40
                            $ret->append(new Node\Script\Shell($exprParser->parse($input)));
0 ignored issues
show
Bug introduced by
It seems like $exprParser->parse($input) targeting Zicht\Tool\Script\Parser\Expression::parse() can also be of type null; however, Zicht\Tool\Script\Node\Script\Shell::__construct() does only seem to accept object<Zicht\Tool\Script\Node\Node>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
41
                            break;
42
                        case 'for':
43
                            $key = null;
44
                            $name = $input->expect(Token::IDENTIFIER)->value;
45
                            if ($input->match(',')) {
46
                                $input->next();
47
                                $key = $name;
48
                                $name = $input->expect(Token::IDENTIFIER)->value;
49
                            }
50
                            $input->expect(Token::KEYWORD, 'in');
51
                            $ret->append(new Node\Script\ForIn($exprParser->parse($input), $key, $name));
0 ignored issues
show
Bug introduced by
It seems like $exprParser->parse($input) targeting Zicht\Tool\Script\Parser\Expression::parse() can also be of type null; however, Zicht\Tool\Script\Node\Script\ForIn::__construct() does only seem to accept object<Zicht\Tool\Script\Node\Node>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
52
                            break;
53
                        case 'each':
54
                            $ret->append(new Node\Script\ForIn($exprParser->parse($input), null, null));
0 ignored issues
show
Bug introduced by
It seems like $exprParser->parse($input) targeting Zicht\Tool\Script\Parser\Expression::parse() can also be of type null; however, Zicht\Tool\Script\Node\Script\ForIn::__construct() does only seem to accept object<Zicht\Tool\Script\Node\Node>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
55
                            break;
56
                        case 'with':
57
                            $expr = $exprParser->parse($input);
58
                            $input->expect(Token::KEYWORD, 'as');
59
                            $name = $input->expect(Token::IDENTIFIER)->value;
60
                            $ret->append(new Node\Script\With($expr, $name));
0 ignored issues
show
Bug introduced by
It seems like $expr defined by $exprParser->parse($input) on line 57 can also be of type null; however, Zicht\Tool\Script\Node\Script\With::__construct() does only seem to accept object<Zicht\Tool\Script\Node\Node>, 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...
61
                            break;
62
                        case 'if':
63
                            $ret->append(new Node\Script\Conditional($exprParser->parse($input)));
0 ignored issues
show
Bug introduced by
It seems like $exprParser->parse($input) targeting Zicht\Tool\Script\Parser\Expression::parse() can also be of type null; however, Zicht\Tool\Script\Node\S...ditional::__construct() does only seem to accept object<Zicht\Tool\Script\Node\Node>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
64
                            break;
65
                        default:
66
                            throw new \UnexpectedValueException("Unknown EXPR_START token at this point: {$type}");
67
                    }
68
                    $input->expect(Token::EXPR_END);
69
                    $hasMatch = true;
70
                }
71 5
                while ($input->match(Token::DATA) && preg_match('/^\s+$/', $input->current()->value)) {
72
                    $input->next();
73
                }
74 5
            } while ($hasMatch && $input->valid());
75 5
        }
76 6
        while ($input->valid()) {
77 5
            $cur = $input->current();
78 5
            if ($cur->match(Token::EXPR_START, '$(')) {
79 5
                $input->next();
80 5
                $ret->append(new Node\Expr\Expr($exprParser->parse($input)));
0 ignored issues
show
Bug introduced by
It seems like $exprParser->parse($input) targeting Zicht\Tool\Script\Parser\Expression::parse() can also be of type null; however, Zicht\Tool\Script\Node\Expr\Expr::__construct() does only seem to accept object<Zicht\Tool\Script\Node\Node>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
81 5
                $input->expect(Token::EXPR_END);
82 5
            } elseif ($cur->match(Token::DATA)) {
83
                $ret->append(new Node\Expr\Data($cur->value));
84
                $input->next();
85
            } else {
86
                throw new InvalidArgumentException("Unxpected token: " . $input->current()->type);
87
            }
88 5
        }
89
90 6
        return $ret;
91
    }
92
}
93