Completed
Pull Request — master (#221)
by personal
04:09
created

ClassParser   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 109
rs 10
c 2
b 0
f 0
wmc 11
lcom 1
cbo 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
C parse() 0 80 10
1
<?php
2
3
/*
4
 * (c) Jean-François Lépine <https://twitter.com/Halleck45>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Hal\Component\Parser\CodeParser;
11
12
use Hal\Component\Reflected\Attribute;
13
use Hal\Component\Reflected\Klass;
14
use Hal\Component\Reflected\KlassAnonymous;
15
use Hal\Component\Reflected\KlassInterface;
16
use Hal\Component\Parser\Resolver\NamespaceResolver;
17
use Hal\Component\Parser\Searcher;
18
use Hal\Component\Token\Token;
19
20
class ClassParser
21
{
22
23
    /**
24
     * @var Searcher
25
     */
26
    private $searcher;
27
28
    /**
29
     * @var NamespaceResolver
30
     */
31
    private $namespaceResolver;
32
33
    /**
34
     * CodeParser constructor.
35
     * @param Searcher $searcher
36
     * @param NamespaceResolver $namespaceResolver
37
     */
38
    public function __construct(Searcher $searcher, NamespaceResolver $namespaceResolver)
39
    {
40
        $this->searcher = $searcher;
41
        $this->namespaceResolver = $namespaceResolver;
42
    }
43
44
    /**
45
     * @param $tokens
46
     * @return Klass
47
     */
48
    public function parse($tokens)
49
    {
50
        // anonymous class
51
        if (Token::T_NEW === $tokens[0]) {
52
            $class = new KlassAnonymous;
53
            $class->setName($tokens[2]);
54
        } elseif (Token::T_INTERFACE === $tokens[1]) {
55
            $class = new KlassInterface();
56
            $class->setName($tokens[2]);
57
        } else {
58
            $class = new Klass();
59
            $class->setName($tokens[2]);
60
        }
61
62
63
        $functions = $attributes = array();
64
        $len = sizeof($tokens);
65
66
        // default values
67
        $isStatic = false;
68
        $visibility = Token::T_VISIBILITY_PUBLIC;
69
70
        for ($i = 1; $i < $len; $i++) {
71
72
            $token = $tokens[$i];
73
74
            // static
75
            if (Token::T_STATIC === $token) {
76
                $isStatic = true;
77
            }
78
79
            // visibility
80
            if (in_array($token, array(Token::T_VISIBILITY_PRIVATE, Token::T_VISIBILITY_PROTECTED, Token::T_VISIBILITY_PUBLIC))) {
81
                $visibility = $token;
82
            }
83
84
            // method
85
            if (Token::T_FUNCTION === $token) {
86
                $functionStart = $i;
87
                $functionEnd = $this->searcher->getPositionOfClosingBrace($tokens, $i);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $functionEnd is correct as $this->searcher->getPosi...osingBrace($tokens, $i) (which targets Hal\Component\Parser\Sea...ositionOfClosingBrace()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
88
                $parser = new MethodParser($this->searcher, $this->namespaceResolver);
89
                $method = $parser->parse(array_slice($tokens, $functionStart, ($functionEnd - $functionStart) + 1));
90
91
                // attribute external informations
92
                $method->setIsStatic($isStatic)->setVisibility($visibility);
93
                $isStatic = false;
94
                $visibility = Token::T_VISIBILITY_PUBLIC;
95
96
                $functions[$method->getName()] = $method;
97
                $i = $functionEnd;
98
            }
99
100
            // attribute
101
            if ('$' === $token[0]) {
102
                $attribute = new Attribute($token, $visibility, $isStatic);
103
                array_push($attributes, $attribute);
104
            }
105
106
            // extends
107
            if (Token::T_EXTENDS === $token) {
108
                $brace = $this->searcher->getNext($tokens, $i, Token::T_BRACE_OPEN);
109
                $parents = array_slice($tokens, $i + 1, ($brace - $i) - 1);
110
                // exclude implements
111
                $split = preg_split('!implements!i', implode(',', $parents));
112
                $parents = array_filter(explode(',', $split[0]));
113
                foreach ($parents as $p => $name) {
114
                    $parents[$p] = $this->namespaceResolver->resolve($name);
115
                }
116
                $class->setParents($parents);
117
            }
118
        }
119
120
        $class
121
            ->setTokens($tokens)
122
            ->setMethods($functions)
123
            ->setAttributes($attributes)
124
            ->setNamespace($this->namespaceResolver->getCurrentNamespace());
125
126
        return $class;
127
    }
128
}