Completed
Push — master ( 8a6821...f9deab )
by Andreas
04:47
created

PhpParser::parseClass()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 23
rs 9.8666
c 0
b 0
f 0
cc 4
nc 4
nop 1
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\Common\Annotations;
21
22
use SplFileObject;
23
24
/**
25
 * Parses a file for namespaces/use/class declarations.
26
 *
27
 * @author Fabien Potencier <[email protected]>
28
 * @author Christian Kaps <[email protected]>
29
 */
30
final class PhpParser
31
{
32
    /**
33
     * Parses a class.
34
     *
35
     * @param \ReflectionClass $class A <code>ReflectionClass</code> object.
36
     *
37
     * @return array A list with use statements in the form (Alias => FQN).
38
     */
39
    public function parseClass(\ReflectionClass $class)
40
    {
41
        if (method_exists($class, 'getUseStatements')) {
42
            return $class->getUseStatements();
43
        }
44
45
        if (false === $filename = $class->getFileName()) {
46
            return [];
47
        }
48
49
        $content = $this->getFileContent($filename, $class->getStartLine());
50
51
        if (null === $content) {
52
            return [];
53
        }
54
55
        $namespace = preg_quote($class->getNamespaceName());
56
        $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content);
57
        $tokenizer = new TokenParser('<?php ' . $content);
58
59
        $statements = $tokenizer->parseUseStatements($class->getNamespaceName());
60
61
        return $statements;
62
    }
63
64
    /**
65
     * Gets the content of the file right up to the given line number.
66
     *
67
     * @param string  $filename   The name of the file to load.
68
     * @param integer $lineNumber The number of lines to read from file.
69
     *
70
     * @return string|null The content of the file or null if the file does not exist.
71
     */
72
    private function getFileContent($filename, $lineNumber)
73
    {
74
        if ( ! is_file($filename)) {
75
            return null;
76
        }
77
78
        $content = '';
79
        $lineCnt = 0;
80
        $file = new SplFileObject($filename);
81
        while (!$file->eof()) {
82
            if ($lineCnt++ == $lineNumber) {
83
                break;
84
            }
85
86
            $content .= $file->fgets();
87
        }
88
89
        return $content;
90
    }
91
}
92