Completed
Pull Request — master (#133)
by
unknown
07:23 queued 05:04
created

PhpFunctionsScanner::enableCommentsExtraction()   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 1
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|array
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 mixed $tag
27
     */
28
    public function enableCommentsExtraction($tag = '')
29
    {
30
        $this->extractComments = $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
                    return !is_array($token) || $token[0] !== T_WHITESPACE;
53
                }
54
            )
55
        );
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    public function getFunctions()
62
    {
63
        $count = count($this->tokens);
64
        $bufferFunctions = [];
65
        /* @var ParsedFunction[] $bufferFunctions */
66
        $functions = [];
67
        /* @var ParsedFunction[] $functions */
68
69
        for ($k = 0; $k < $count; ++$k) {
70
            $value = $this->tokens[$k];
71
72
            if (is_string($value)) {
73
                if (isset($bufferFunctions[0])) {
74
                    switch ($value) {
75
                        case ',':
76
                            $bufferFunctions[0]->nextArgument();
77
                            break;
78
                        case ')':
79
                            $functions[] = array_shift($bufferFunctions)->close();
80
                            break;
81
                        case '.':
82
                            break;
83
                        default:
84
                            $bufferFunctions[0]->stopArgument();
85
                            break;
86
                    }
87
                }
88
                continue;
89
            }
90
91
            switch ($value[0]) {
92
                case T_CONSTANT_ENCAPSED_STRING:
93
                    //add an argument to the current function
94
                    if (isset($bufferFunctions[0])) {
95
                        $bufferFunctions[0]->addArgumentChunk(PhpCode::convertString($value[1]));
96
                    }
97
                    break;
98
                case T_STRING:
99
                    if (isset($bufferFunctions[0])) {
100
                        $bufferFunctions[0]->stopArgument();
101
                    }
102
                    //new function found
103
                    for ($j = $k + 1; $j < $count; ++$j) {
104
                        $nextToken = $this->tokens[$j];
105
                        if (is_array($nextToken) && $nextToken[0] === T_COMMENT) {
106
                            continue;
107
                        }
108
                        if ($nextToken === '(') {
109
                            $newFunction = new ParsedFunction($value[1], $value[2]);
110
                            if ($k > 0 && is_array($this->tokens[$k - 1]) && $this->tokens[$k - 1][0] === T_COMMENT) {
111
                                $comment = $this->parsePhpComment($this->tokens[$k - 1][1]);
112
                                if ($comment !== null) {
113
                                    $newFunction->addComment($comment);
114
                                }
115
                            }
116
                            array_unshift($bufferFunctions, $newFunction);
117
                            $k = $j;
118
                        }
119
                        break;
120
                    }
121
                    break;
122
                case T_COMMENT:
123
                    if (isset($bufferFunctions[0])) {
124
                        $comment = $this->parsePhpComment($value[1]);
125
                        if ($comment !== null) {
126
                            $bufferFunctions[0]->addComment($comment);
127
                        }
128
                    }
129
                    break;
130
                default:
131
                    if (isset($bufferFunctions[0])) {
132
                        $bufferFunctions[0]->stopArgument();
133
                    }
134
                    break;
135
            }
136
        }
137
138
        return $functions;
139
    }
140
141
    protected function parsePhpComment($value)
142
    {
143
        $result = null;
144
        if ($this->extractComments !== false) {
145
            if ($value[0] === '#') {
146
                $value = substr($value, 1);
147
            } elseif ($value[1] === '/') {
148
                $value = substr($value, 2);
149
            } else {
150
                $value = substr($value, 2, -2);
151
            }
152
            $value = trim($value);
153
            if (
154
                $value !== '' 
155
                && (
156
                    $this->extractComments === '' 
157
                    || (
158
                        !is_array($this->extractComments) 
159
                        && strpos($value, $this->extractComments) === 0
160
                    )
161
                    || (
162
                        is_array($this->extractComments) 
163
                        && in_array($value, $this->extractComments)
164
                    )
165
                )
166
            ) {
167
                $result = $value;
168
            }
169
        }
170
        return $result;
171
    }
172
}
173