Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * tokenizer extension-based lexer for PHP code
4
 *
5
 * phpDocumentor :: automatic documentation generator
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * Copyright (c) 2002-2006 Gregory Beaver
10
 *
11
 * LICENSE:
12
 *
13
 * This library is free software; you can redistribute it
14
 * and/or modify it under the terms of the GNU Lesser General
15
 * Public License as published by the Free Software Foundation;
16
 * either version 2.1 of the License, or (at your option) any
17
 * later version.
18
 *
19
 * This library is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22
 * Lesser General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public
25
 * License along with this library; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
 *
28
 * @category   ToolsAndUtilities
29
 * @package    phpDocumentor
30
 * @subpackage Parsers
31
 * @author     Gregory Beaver <cellog@php.net>
32
 * @copyright  2002-2007 Gregory Beaver
33
 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
34
 * @version    CVS: $Id: phpDocumentorTWordParser.inc 287887 2009-08-30 06:10:55Z ashnazg $
35
 * @link       http://www.phpdoc.org
36
 * @link       http://pear.php.net/PhpDocumentor
37
 * @since      1.2
38
 * @todo       CS cleanup - change package to PhpDocumentor
39
 * @todo       CS cleanup - PHPCS needs to ignore CVS Id length
40
 */
41
 
42
/**
43
 * Like WordParser, but expects an array of tokens from the tokenizer
44
 * instead of a string.
45
 *
46
 * @category   ToolsAndUtilities
47
 * @package    phpDocumentor
48
 * @subpackage WordParsers
49
 * @author     Gregory Beaver <cellog@php.net>
50
 * @copyright  2002-2007 Gregory Beaver
51
 * @license    http://www.opensource.org/licenses/lgpl-license.php LGPL
52
 * @version    Release: 1.4.3
53
 * @link       http://www.phpdoc.org
54
 * @link       http://pear.php.net/PhpDocumentor
55
 * @since      1.2
56
 * @todo       CS cleanup - change package to PhpDocumentor
57
 * @todo       CS cleanup - change classname to PhpDocumentor_*
58
 */
59
class phpDocumentorTWordParser extends WordParser
60
{
61
    /**#@+
62
     * @access private
63
     */
64
    /**
65
     * tokenized array from {@link token_get_all()}
66
     * @var array
67
     */
68
    var $_all;
69
    /**
70
     * List of tokens that can contain a newline
71
     * @var array
72
     */
73
    var $_nl_check = array(
74
        T_WHITESPACE,
75
        T_ENCAPSED_AND_WHITESPACE,
76
        T_CONSTANT_ENCAPSED_STRING,
77
        T_COMMENT,
78
        T_DOC_COMMENT,
79
        T_OPEN_TAG,
80
        T_CLOSE_TAG,
81
        T_INLINE_HTML,
82
        T_START_HEREDOC,
83
    );
84
    /**
85
     * @var array
86
     */
87
    var $_global_search;
88
    /**
89
     * current source line number (relative)
90
     * @var integer
91
     */
92
    var $_sourceline;
93
    /**
94
     * Source of the entire file, parsed into arrays of tokens on each line
95
     * @var array
96
     */
97
    var $_file_source = array();
98
    /**
99
     * Line number the last comment was on
100
     * @var integer
101
     */
102
    var $_docblock_linenum;
103
    /**#@-*/
104
 
105
    /**
106
     * Uses {@link token_get_all()} to tokenize the source code.
107
     * {@internal
108
     * Also, it divides the source tokens into separate lines for use by
109
     * the @filesource tag.
110
     *
111
     * {@source}}}
112
     *
113
     * @param string &$input source code
114
     *
115
     * @return void
116
     */
117
    function setup(&$input)
118
    {
119
        $input      = rtrim(ltrim($input, "\r\n"));
120
        $this->data = &$input;
121
        // fix php warnings on invalid source code
122
        $this->_all         = @token_get_all($input);
123
        $this->_file_source = array();
124
        $this->addFileSource($this->_all);
125
        $this->_sourceline = 0;
126
        $this->pos         = 0;
127
        $this->linenum     = 0;
128
    }
129
 
130
    /**
131
     * loads up next set of source code
132
     *
133
     * @return array source code array
134
     */
135
    function getSource()
136
    {
137
        $source          = $this->source;
138
        $this->source    = array();
139
        $this->getsource = false;
140
        return $source;
141
    }
142
 
143
    /**
144
     * gets the source code tokens
145
     *
146
     * @return array source code tokens split up by line number
147
     */
148
    function getFileSource()
149
    {
150
        return $this->_file_source;
151
    }
152
 
153
    /**
154
     * Begin retrieving source code
155
     *
156
     * @param string $word word to add the beginning of source code
157
     *
158
     * @return void
159
     * @access private
160
     * @todo   CS cleanup - rename to retrieveSource for camelCase rule
161
     */
162
    function retrievesource($word = '')
163
    {
164
        $this->source      = array(array($word));
165
        $this->_sourceline = 0;
166
        $this->getsource   = true;
167
    }
168
 
169
    /**
170
     * Utility function to determine whether two tokens from the tokenizer are equal
171
     *
172
     * @param mixed $a first token
173
     * @param mixed $b second token
174
     *
175
     * @return bool whether or not the tokens are equal
176
     * @static
177
     */
178
    function tokenEquals($a, $b)
179
    {
180
        if (is_array($a)) $a = $a[1];
181
        if (is_array($b)) $b = $b[1];
182
        return $a == $b;
183
    }
184
 
185
    /**
186
     * Utility function to convert a series of tokens into a string
187
     *
188
     * @param array $a array of tokens
189
     *
190
     * @return string the resulting string
191
     * @static
192
     */
193
    function concatTokens($a)
194
    {
195
        $b = '';
196
        foreach ($a as $c) {
197
            if (is_array($c)) {
198
                $c = $c[1];
199
            }
200
            $b .= $c;
201
        }
202
        return $b;
203
    }
204
 
205
    /**
206
     * Retrieve a token for the phpDocumentorTParser
207
     * {@internal
208
     * This method adds source code to the array for a function to be returned
209
     * to a {@}source} tag, and will return the token unless it is T_WHITESPACE
210
     * and {@link $returnWhiteSpace} is false.
211
     *
212
     * The global variable search is more complicated than it is in the
213
     * WordParser, as we have to compare an array of tokens to each other, and
214
     * that is what this code does}}
215
     *
216
     * @return string|array token from tokenizer
217
     */
218
    function getWord()
219
    {
220
        if (!isset($this->_all[$this->pos])) {
221
            return false;
222
        }
223
 
224
        $oldlinenum = $this->linenum;
225
        $word       = $this->_all[$this->pos++];
226
 
227
        // if we're looking for a global variable declaration, then this section
228
        // will search the upcoming tokens to see if they match the tokens
229
        // that define the global variable
230
        if (isset($this->_global_search)) {
231
            $pos   = $this->pos;
232
            $gpos  = 0;
233
            $found = false;
234
            if ($this->tokenEquals($word, $this->_global_search[$gpos++])) {
235
                $found = true;
236
                for (;$gpos<count($this->_global_search);$gpos++, $pos++) {
237
                    if (isset($this->_all[$pos]) &&
238
                        !$this->tokenEquals($this->_global_search[$gpos],
239
                            $this->_all[$pos])
240
                    ) {
241
                        $found = false;
242
                    }
243
                }
244
            }
245
            if ($found) {
246
                $a          = $this->concatTokens($this->_global_search);
247
                $this->pos += count($this->_global_search) - 1;
248
                unset($this->_global_search);
249
                return $a;
250
            }
251
        }
252
        if ($this->getsource) {
253
            $this->addSource($word);
254
        }
255
        if (is_array($word)) {
256
            if (in_array($word[0], $this->_nl_check)) {
257
                $this->linenum += substr_count($word[1], "\n");
258
            }
259
            if ($word[0] == T_WHITESPACE && !$this->returnWhiteSpace) {
260
                return $this->getWord();
261
            }
262
            // seeing if we can get line numbers out of the beast
263
        }
264
        if (is_array($word) && $word[0] == T_COMMENT) {
265
            $this->_docblock_linenum = $oldlinenum;
266
        }
267
        return $word;
268
    }
269
 
270
    /**
271
     * Wrapper for {@link addSource()} used to retrieve the entire source code
272
     * organized by line number in setup()
273
     *
274
     * @param array $word full file source code
275
     *
276
     * @return void
277
     */
278
    function addFileSource($word)
279
    {
280
        $this->_sourceline = 0;
281
        foreach ($word as $token) {
282
            $this->addSource($token, true);
283
        }
284
        // var_dump($this->_file_source);
285
    }
286
 
287
    /**
288
     * Generate source token arrays organized by line number
289
     *
290
     * This code will split up tokens that contain "\n" and add them to the
291
     * source code as separate tokens on different lines.
292
     *
293
     * @param array|string $word token to add
294
     * @param bool         $file true if this should be added
295
     *                           to {@link $_file_source}
296
     *
297
     * @return void
298
     * @uses _set_sars()
299
     */
300
    function addSource($word, $file = false)
301
    {
302
        if (is_array($word)) {
303
            $lines = str_replace("\r", '', explode("\n", $word[1]));
304
            foreach ($lines as $i => $line) {
305
                $this->_set_sars($file, array($word[0], $line));
306
                if ($i < count($lines) - 1) {
307
                    // increment sourceline
308
                    $this->_sourceline++;
309
                }
310
            }
311
        } else {
312
            $this->_set_sars($file, $word);
313
        }
314
    }
315
 
316
    /**
317
     * Add tokens to source code
318
     *
319
     * {@source}
320
     *
321
     * @param bool         $type true if this is file source,
322
     *                           otherwise it is function source
323
     * @param string|array $word token to add
324
     *
325
     * @return void
326
     * @access private
327
     * @todo CS cleanup - rename to _setSars for camelCasing rule
328
     */
329
    function _set_sars($type, $word)
330
    {
331
        if ($type) {
332
            $this->_file_source[$this->_sourceline][] = $word;
333
        } else {
334
            $this->source[$this->_sourceline][] = $word;
335
        }
336
    }
337
 
338
    /**
339
     * Tell the phpDocumentorTWordParser to return the entire global variable
340
     * if it is found.
341
     *
342
     * @param array $tokens tokens that represent the global variable definition
343
     *
344
     * @return void
345
     * @uses $_global_search
346
     */
347
    function findGlobal($tokens)
348
    {
349
        if (!$tokens) {
350
            unset($this->_global_search);
351
        } else {
352
            $this->_global_search = $tokens;
353
        }
354
    }
355
 
356
    /**
357
     * backs the parser up to the previous position
358
     *
359
     * @return int|void can return a word
360
     */
361
    function backupPos()
362
    {
363
        $this->pos--;
364
        $word = $this->_all[$this->pos];
365
        if ($this->getsource) {
366
            unset($this->source[$this->_sourceline]
367
                [count($this->source[$this->_sourceline]) - 1]);
368
            if (empty($this->source[$this->_sourceline])) {
369
                unset($this->source[$this->_sourceline]);
370
            } else {
371
                $this->source[$this->_sourceline]
372
                    = array_values($this->source[$this->_sourceline]);
373
            }
374
        }
375
        if (is_array($word)) {
376
            if ($word[0] == T_WHITESPACE && !$this->returnWhiteSpace) {
377
                return $this->getWord();
378
            }
379
            // seeing if we can get line numbers out of the beast
380
            if (in_array($word[0], $this->_nl_check)) {
381
                $this->linenum -= substr_count($word[1], "\n");
382
            }
383
        }
384
    }
385
}
386
?>