1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of phpDocumentor.
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 *
11 * @link      http://phpdoc.org
12 */
13
14namespace phpDocumentor\Reflection\DocBlock\Tags;
15
16use phpDocumentor\Reflection\Type;
17use function in_array;
18use function strlen;
19use function substr;
20use function trim;
21
22abstract class TagWithType extends BaseTag
23{
24    /** @var ?Type */
25    protected $type;
26
27    /**
28     * Returns the type section of the variable.
29     */
30    public function getType() : ?Type
31    {
32        return $this->type;
33    }
34
35    /**
36     * @return string[]
37     */
38    protected static function extractTypeFromBody(string $body) : array
39    {
40        $type         = '';
41        $nestingLevel = 0;
42        for ($i = 0, $iMax = strlen($body); $i < $iMax; $i++) {
43            $character = $body[$i];
44
45            if ($nestingLevel === 0 && trim($character) === '') {
46                break;
47            }
48
49            $type .= $character;
50            if (in_array($character, ['<', '(', '[', '{'])) {
51                $nestingLevel++;
52                continue;
53            }
54
55            if (in_array($character, ['>', ')', ']', '}'])) {
56                $nestingLevel--;
57                continue;
58            }
59        }
60
61        $description = trim(substr($body, strlen($type)));
62
63        return [$type, $description];
64    }
65}
66