Subversion Repositories Applications.framework

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 aurelien 1
<?php
2
/**
3
 * A class to handle most of the parsing operations of a doc comment element.
4
 *
5
 * PHP version 5
6
 *
7
 * @category  PHP
8
 * @package   PHP_CodeSniffer
9
 * @author    Greg Sherwood <gsherwood@squiz.net>
10
 * @author    Marc McIntyre <mmcintyre@squiz.net>
11
 * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
12
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
13
 * @version   CVS: $Id: AbstractDocElement.php,v 1.11 2008/12/02 02:38:33 squiz Exp $
14
 * @link      http://pear.php.net/package/PHP_CodeSniffer
15
 */
16
 
17
if (interface_exists('PHP_CodeSniffer_CommentParser_DocElement', true) === false) {
18
    $error = 'Interface PHP_CodeSniffer_CommentParser_DocElement not found';
19
    throw new PHP_CodeSniffer_Exception($error);
20
}
21
 
22
/**
23
 * A class to handle most of the parsing operations of a doc comment element.
24
 *
25
 * Extending classes should implement the getSubElements method to return
26
 * a list of elements that the doc comment element contains, in the order that
27
 * they appear in the element. For example a function parameter element has a
28
 * type, a variable name and a comment. It should therefore implement the method
29
 * as follows:
30
 *
31
 * <code>
32
 *    protected function getSubElements()
33
 *    {
34
 *        return array(
35
 *                'type',
36
 *                'variable',
37
 *                'comment',
38
 *               );
39
 *    }
40
 * </code>
41
 *
42
 * The processSubElement will be called for each of the sub elements to allow
43
 * the extending class to process them. So for the parameter element we would
44
 * have:
45
 *
46
 * <code>
47
 *    protected function processSubElement($name, $content, $whitespaceBefore)
48
 *    {
49
 *        if ($name === 'type') {
50
 *            echo 'The name of the variable was '.$content;
51
 *        }
52
 *        // Process other tags.
53
 *    }
54
 * </code>
55
 *
56
 * @category  PHP
57
 * @package   PHP_CodeSniffer
58
 * @author    Greg Sherwood <gsherwood@squiz.net>
59
 * @author    Marc McIntyre <mmcintyre@squiz.net>
60
 * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
61
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
62
 * @version   Release: 1.2.0RC1
63
 * @link      http://pear.php.net/package/PHP_CodeSniffer
64
 */
65
abstract class PHP_CodeSniffer_CommentParser_AbstractDocElement implements PHP_CodeSniffer_CommentParser_DocElement
66
{
67
 
68
    /**
69
     * The element previous to this element.
70
     *
71
     * @var PHP_CodeSniffer_CommentParser_DocElement
72
     */
73
    protected $previousElement = null;
74
 
75
    /**
76
     * The element proceeding this element.
77
     *
78
     * @var PHP_CodeSniffer_CommentParser_DocElement
79
     */
80
    protected $nextElement = null;
81
 
82
    /**
83
     * The whitespace the occurs after this element and its sub elements.
84
     *
85
     * @var string
86
     */
87
    protected $afterWhitespace = '';
88
 
89
    /**
90
     * The tokens that comprise this element.
91
     *
92
     * @var array(string)
93
     */
94
    protected $tokens = array();
95
 
96
    /**
97
     * The file this element is in.
98
     *
99
     * @var array(string)
100
     */
101
    protected $phpcsFile = null;
102
 
103
    /**
104
     * The tag that this element represents (omiting the @ symbol).
105
     *
106
     * @var string
107
     */
108
    protected $tag = '';
109
 
110
 
111
    /**
112
     * Constructs a Doc Element.
113
     *
114
     * @param PHP_CodeSniffer_CommentParser_DocElement $previousElement The element
115
     *                                                                  that ocurred
116
     *                                                                  before this.
117
     * @param array                                    $tokens          The tokens of
118
     *                                                                  this element.
119
     * @param string                                   $tag             The doc
120
     *                                                                  element tag
121
     *                                                                  this element
122
     *                                                                  represents.
123
     * @param PHP_CodeSniffer_File                     $phpcsFile       The file that
124
     *                                                                  this element
125
     *                                                                  is in.
126
     *
127
     * @throws Exception If $previousElement in not a DocElement or if
128
     *                   getSubElements() does not return an array.
129
     */
130
    public function __construct(
131
        $previousElement,
132
        array $tokens,
133
        $tag,
134
        PHP_CodeSniffer_File $phpcsFile
135
    ) {
136
        if ($previousElement !== null
137
            && ($previousElement instanceof PHP_CodeSniffer_CommentParser_DocElement) === false
138
        ) {
139
            $error = '$previousElement must be an instance of DocElement';
140
            throw new Exception($error);
141
        }
142
 
143
        $this->phpcsFile = $phpcsFile;
144
 
145
        $this->previousElement = $previousElement;
146
        if ($previousElement !== null) {
147
            $this->previousElement->nextElement = $this;
148
        }
149
 
150
        $this->tag    = $tag;
151
        $this->tokens = $tokens;
152
 
153
        $subElements = $this->getSubElements();
154
 
155
        if (is_array($subElements) === false) {
156
            throw new Exception('getSubElements() must return an array');
157
        }
158
 
159
        $whitespace            = '';
160
        $currElem              = 0;
161
        $lastElement           = '';
162
        $lastElementWhitespace = null;
163
        $numSubElements        = count($subElements);
164
 
165
        foreach ($this->tokens as $token) {
166
            if (trim($token) === '') {
167
                $whitespace .= $token;
168
            } else {
169
                if ($currElem < ($numSubElements - 1)) {
170
                    $element = $subElements[$currElem];
171
                    $this->processSubElement($element, $token, $whitespace);
172
                    $whitespace = '';
173
                    $currElem++;
174
                } else {
175
                    if ($lastElementWhitespace === null) {
176
                        $lastElementWhitespace = $whitespace;
177
                    }
178
 
179
                    $lastElement .= $whitespace.$token;
180
                    $whitespace   = '';
181
                }
182
            }
183
        }//end foreach
184
 
185
        $lastElement     = ltrim($lastElement);
186
        $lastElementName = $subElements[($numSubElements - 1)];
187
 
188
        // Process the last element in this tag.
189
        $this->processSubElement(
190
            $lastElementName,
191
            $lastElement,
192
            $lastElementWhitespace
193
        );
194
 
195
        $this->afterWhitespace = $whitespace;
196
 
197
    }//end __construct()
198
 
199
 
200
    /**
201
     * Returns the element that exists before this.
202
     *
203
     * @return PHP_CodeSniffer_CommentParser_DocElement
204
     */
205
    public function getPreviousElement()
206
    {
207
        return $this->previousElement;
208
 
209
    }//end getPreviousElement()
210
 
211
 
212
    /**
213
     * Returns the element that exists after this.
214
     *
215
     * @return PHP_CodeSniffer_CommentParser_DocElement
216
     */
217
    public function getNextElement()
218
    {
219
        return $this->nextElement;
220
 
221
    }//end getNextElement()
222
 
223
 
224
    /**
225
     * Returns the whitespace that exists before this element.
226
     *
227
     * @return string
228
     */
229
    public function getWhitespaceBefore()
230
    {
231
        if ($this->previousElement !== null) {
232
            return $this->previousElement->getWhitespaceAfter();
233
        }
234
 
235
        return '';
236
 
237
    }//end getWhitespaceBefore()
238
 
239
 
240
    /**
241
     * Returns the whitespace that exists after this element.
242
     *
243
     * @return string
244
     */
245
    public function getWhitespaceAfter()
246
    {
247
        return $this->afterWhitespace;
248
 
249
    }//end getWhitespaceAfter()
250
 
251
 
252
    /**
253
     * Returns the order that this element appears in the comment.
254
     *
255
     * @return int
256
     */
257
    public function getOrder()
258
    {
259
        if ($this->previousElement === null) {
260
            return 1;
261
        } else {
262
            return ($this->previousElement->getOrder() + 1);
263
        }
264
 
265
    }//end getOrder()
266
 
267
 
268
    /**
269
     * Returns the tag that this element represents, ommiting the @ symbol.
270
     *
271
     * @return string
272
     */
273
    public function getTag()
274
    {
275
        return $this->tag;
276
 
277
    }//end getTag()
278
 
279
 
280
    /**
281
     * Returns the raw content of this element, ommiting the tag.
282
     *
283
     * @return string
284
     */
285
    public function getRawContent()
286
    {
287
        return implode('', $this->tokens);
288
 
289
    }//end getRawContent()
290
 
291
 
292
    /**
293
     * Returns the line in which this element first occured.
294
     *
295
     * @return int
296
     */
297
    public function getLine()
298
    {
299
        if ($this->previousElement === null) {
300
            // First element is on line one.
301
            return 1;
302
        } else {
303
            $previousContent = $this->previousElement->getRawContent();
304
            $previousLine    = $this->previousElement->getLine();
305
 
306
            return ($previousLine + substr_count($previousContent, $this->phpcsFile->eolChar));
307
        }
308
 
309
    }//end getLine()
310
 
311
 
312
    /**
313
     * Returns the sub element names that make up this element in the order they
314
     * appear in the element.
315
     *
316
     * @return array(string)
317
     * @see processSubElement()
318
     */
319
    abstract protected function getSubElements();
320
 
321
 
322
    /**
323
     * Called to process each sub element as sepcified in the return value
324
     * of getSubElements().
325
     *
326
     * @param string $name             The name of the element to process.
327
     * @param string $content          The content of the the element.
328
     * @param string $whitespaceBefore The whitespace found before this element.
329
     *
330
     * @return void
331
     * @see getSubElements()
332
     */
333
    abstract protected function processSubElement(
334
        $name,
335
        $content,
336
        $whitespaceBefore
337
    );
338
 
339
 
340
}//end class
341
 
342
?>