Completed
Pull Request — master (#102)
by Michele
02:01
created

PhpFunctionsScanner::disableCommentsExtraction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Gettext\Utils;
4
5
use Gettext\Extractors\PhpCode;
6
7
class PhpFunctionsScanner extends FunctionsScanner
8
{
9
    /**
10
     * PHP tokens of the code to be parsed.
11
     *
12
     * @var array
13
     */
14
    protected $tokens;
15
16
    /**
17
     * If not false, comments will be extracted.
18
     *
19
     * @var string|false
20
     */
21
    protected $extractComments = false;
22
23
    /**
24
     * Enable extracting comments that start with a tag (if $tag is empty all the comments will be extracted).
25
     *
26
     * @param string $tag
27
     */
28
    public function enableCommentsExtraction($tag = '')
29
    {
30
        $this->extractComments = (string) $tag;
31
    }
32
33
    /**
34
     * Disable comments extraction.
35
     */
36
    public function disableCommentsExtraction()
37
    {
38
        $this->extractComments = false;
39
    }
40
41
    /**
42
     * Constructor.
43
     *
44
     * @param string $code The php code to scan
45
     */
46
    public function __construct($code)
47
    {
48
        $this->tokens = array_values(
49
            array_filter(
50
                token_get_all($code),
51
                function ($token)
52
                {
53
                    return !is_array($token) || $token[0] !== T_WHITESPACE;
54
                }
55
            )
56
        );
57
        $this->extractComments = false;
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function getFunctions()
64
    {
65
        $count = count($this->tokens);
66
        $bufferFunctions = array();
67
        /* @var ParsedFunction[] $bufferFunctions */
68
        $functions = array();
69
        /* @var ParsedFunction[] $functions */
70
71
        for ($k = 0; $k < $count; ++$k) {
72
            $value = $this->tokens[$k];
73
74
            if (is_string($value)) {
75
                if (isset($bufferFunctions[0])) {
76
                    switch ($value) {
77
                        case ',':
78
                            $bufferFunctions[0]->nextArgument();
79
                            break;
80
                        case ')':
81
                            $functions[] = array_shift($bufferFunctions)->close();
82
                            break;
83
                        case '.':
84
                            break;
85
                        default:
86
                            $bufferFunctions[0]->stopArgument();
87
                            break;
88
                    }
89
                }
90
                continue;
91
            }
92
93
            switch ($value[0]) {
94
                case T_CONSTANT_ENCAPSED_STRING:
95
                    //add an argument to the current function
96
                    if (isset($bufferFunctions[0])) {
97
                        $bufferFunctions[0]->addArgumentChunk(PhpCode::convertString($value[1]));
98
                    }
99
                    break;
100
                case T_STRING:
101
                    if (isset($bufferFunctions[0])) {
102
                        $bufferFunctions[0]->stopArgument();
103
                    }
104
                    //new function found
105
                    for ($j = $k + 1; $j < $count; ++$j) {
106
                        $nextToken = $this->tokens[$j];
107
                        if (is_array($nextToken) && $nextToken[0] === T_COMMENT) {
108
                            continue;
109
                        }
110
                        if ($nextToken === '(') {
111
                            $newFunction = new ParsedFunction($value[1], $value[2]);
112
                            if ($k > 0 && is_array($this->tokens[$k - 1]) && $this->tokens[$k - 1][0] === T_COMMENT) {
113
                                $comment = $this->parsePhpComment($this->tokens[$k - 1][1]);
114
                                if ($comment !== null) {
115
                                    $newFunction->addComment($comment);
116
                                }
117
                            }
118
                            array_unshift($bufferFunctions, $newFunction);
119
                            $k = $j;
120
                        }
121
                        break;
122
                    }
123
                    break;
124
                case T_COMMENT:
125
                    if (isset($bufferFunctions[0])) {
126
                        $comment = $this->parsePhpComment($value[1]);
127
                        if ($comment !== null) {
128
                            $bufferFunctions[0]->addComment($comment);
129
                        }
130
                    }
131
                    break;
132
                default:
133
                    if (isset($bufferFunctions[0])) {
134
                        $bufferFunctions[0]->stopArgument();
135
                    }
136
                    break;
137
            }
138
        }
139
140
        return $functions;
141
    }
142
143
    protected function parsePhpComment($value)
144
    {
145
        $result = null;
146
        if ($this->extractComments !== false) {
147
            if ($value[0] === '#') {
148
                $value = substr($value, 1);
149
            }
150
            elseif ($value[1] === '/') {
151
                $value = substr($value, 2);
152
            } else {
153
                $value = substr($value, 2, -2);
154
            }
155
            $value = trim($value);
156
            if ($value !== '' && ($this->extractComments === '' || strpos($value, $this->extractComments) === 0)) {
157
                $result = $value;
158
            }
159
        }
160
161
        return $result;
162
    }
163
}
164