Parser   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 12

Test Coverage

Coverage 31.03%

Importance

Changes 0
Metric Value
wmc 16
c 0
b 0
f 0
lcom 0
cbo 12
dl 0
loc 77
ccs 18
cts 58
cp 0.3103
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
C parse() 0 65 16
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