This file is indexed.

/usr/share/php/phpDocumentor/Reflection/DocBlock/Type/Collection.php is in php-phpdocumentor-reflection-docblock 2.0.4-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
<?php
/**
 * phpDocumentor
 *
 * PHP Version 5.3
 *
 * @author    Mike van Riel <mike.vanriel@naenius.com>
 * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
 * @link      http://phpdoc.org
 */

namespace phpDocumentor\Reflection\DocBlock\Type;

use phpDocumentor\Reflection\DocBlock\Context;

/**
 * Collection
 *
 * @author    Mike van Riel <mike.vanriel@naenius.com>
 * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
 * @link      http://phpdoc.org
 */
class Collection extends \ArrayObject
{
    /** @var string Definition of the OR operator for types */
    const OPERATOR_OR = '|';

    /** @var string Definition of the ARRAY operator for types */
    const OPERATOR_ARRAY = '[]';

    /** @var string Definition of the NAMESPACE operator in PHP */
    const OPERATOR_NAMESPACE = '\\';

    /** @var string[] List of recognized keywords */
    protected static $keywords = array(
        'string', 'int', 'integer', 'bool', 'boolean', 'float', 'double',
        'object', 'mixed', 'array', 'resource', 'void', 'null', 'scalar',
        'callback', 'callable', 'false', 'true', 'self', '$this', 'static'
    );

    /**
     * Current invoking location.
     *
     * This is used to prepend to type with a relative location.
     * May also be 'default' or 'global', in which case they are ignored.
     *
     * @var Context
     */
    protected $context = null;

    /**
     * Registers the namespace and aliases; uses that to add and expand the
     * given types.
     *
     * @param string[] $types    Array containing a list of types to add to this
     *     container.
     * @param Context  $location The current invoking location.
     */
    public function __construct(
        array $types = array(),
        Context $context = null
    ) {
        $this->context = null === $context ? new Context() : $context;

        foreach ($types as $type) {
            $this->add($type);
        }
    }

    /**
     * Returns the current invoking location.
     *
     * @return Context
     */
    public function getContext()
    {
        return $this->context;
    }

    /**
     * Adds a new type to the collection and expands it if it contains a
     * relative namespace.
     *
     * If a class in the type contains a relative namespace than this collection
     * will try to expand that into a FQCN.
     *
     * @param string $type A 'Type' as defined in the phpDocumentor
     *     documentation.
     *
     * @throws \InvalidArgumentException if a non-string argument is passed.
     *
     * @see http://phpdoc.org/docs/latest/for-users/types.html for the
     *     definition of a type.
     *
     * @return void
     */
    public function add($type)
    {
        if (!is_string($type)) {
            throw new \InvalidArgumentException(
                'A type should be represented by a string, received: '
                .var_export($type, true)
            );
        }

        // separate the type by the OR operator
        $type_parts = explode(self::OPERATOR_OR, $type);
        foreach ($type_parts as $part) {
            $expanded_type = $this->expand($part);
            if ($expanded_type) {
                $this[] = $expanded_type;
            }
        }
    }
    
    /**
     * Returns a string representation of the collection.
     * 
     * @return string The resolved types across the collection, separated with
     *     {@link self::OPERATOR_OR}.
     */
    public function __toString()
    {
        return implode(self::OPERATOR_OR, $this->getArrayCopy());
    }

    /**
     * Analyzes the given type and returns the FQCN variant.
     *
     * When a type is provided this method checks whether it is not a keyword or
     * Fully Qualified Class Name. If so it will use the given namespace and
     * aliases to expand the type to a FQCN representation.
     *
     * This method only works as expected if the namespace and aliases are set;
     * no dynamic reflection is being performed here.
     *
     * @param string $type The relative or absolute type.
     *
     * @uses getNamespace to determine with what to prefix the type name.
     * @uses getNamespaceAliases to check whether the first part of the relative
     *     type name should not be replaced with another namespace.
     *
     * @return string
     */
    protected function expand($type)
    {
        $type = trim($type);
        if (!$type) {
            return '';
        }

        if ($this->isTypeAnArray($type)) {
            return $this->expand(substr($type, 0, -2)) . self::OPERATOR_ARRAY;
        }

        if ($this->isRelativeType($type) && !$this->isTypeAKeyword($type)) {
            $type_parts = explode(self::OPERATOR_NAMESPACE, $type, 2);

            $namespace_aliases = $this->context->getNamespaceAliases();
            // if the first segment is not an alias; prepend namespace name and
            // return
            if (!isset($namespace_aliases[$type_parts[0]])) {
                $namespace = $this->context->getNamespace();
                if ('' !== $namespace) {
                    $namespace .= self::OPERATOR_NAMESPACE;
                }
                return self::OPERATOR_NAMESPACE . $namespace . $type;
            }

            $type_parts[0] = $namespace_aliases[$type_parts[0]];
            $type = implode(self::OPERATOR_NAMESPACE, $type_parts);
        }

        return $type;
    }

    /**
     * Detects whether the given type represents an array.
     *
     * @param string $type A relative or absolute type as defined in the
     *     phpDocumentor documentation.
     *
     * @return bool
     */
    protected function isTypeAnArray($type)
    {
        return substr($type, -2) === self::OPERATOR_ARRAY;
    }

    /**
     * Detects whether the given type represents a PHPDoc keyword.
     *
     * @param string $type A relative or absolute type as defined in the
     *     phpDocumentor documentation.
     *
     * @return bool
     */
    protected function isTypeAKeyword($type)
    {
        return in_array(strtolower($type), static::$keywords, true);
    }

    /**
     * Detects whether the given type represents a relative or absolute path.
     *
     * This method will detect keywords as being absolute; even though they are
     * not preceeded by a namespace separator.
     *
     * @param string $type A relative or absolute type as defined in the
     *     phpDocumentor documentation.
     *
     * @return bool
     */
    protected function isRelativeType($type)
    {
        return ($type[0] !== self::OPERATOR_NAMESPACE)
            || $this->isTypeAKeyword($type);
    }
}