protected function expandType(ClassReflection $class, $type)
    {
        $typeWithoutNull = TypeHandling::stripNullableType($type);
        $isNullable = $typeWithoutNull !== $type;
        // expand "SomeType<SomeElementType>" to "\SomeTypeNamespace\SomeType<\ElementTypeNamespace\ElementType>"
        if (strpos($type, '<') !== false) {
            $typeParts = explode('<', $typeWithoutNull);
            $type = $typeParts[0];
            $elementType = rtrim($typeParts[1], '>');

            return $this->expandType($class, $type) . '<' . $this->expandType($class, $elementType) . '>' . ($isNullable ? '|null' : '');
        }

        // expand SomeElementType[]" to "array<\ElementTypeNamespace\SomeElementType>"
        if (substr_compare($typeWithoutNull, '[]', -2, 2) === 0) {
            $elementType = substr($typeWithoutNull, 0, -2);
            return 'array<' . $this->expandType($class, $elementType) . '>' . ($isNullable ? '|null' : '');
        }

        // skip simple types and types with fully qualified namespaces
        if ($type === 'mixed' || $type[0] === '\\' || TypeHandling::isSimpleType($type)) {
            return TypeHandling::normalizeType($type) . ($isNullable ? '|null' : '');
        }

        // we try to find the class relative to the current namespace...
        $possibleFullyQualifiedClassName = sprintf('%s\\%s', $class->getNamespaceName(), $typeWithoutNull);
        if (class_exists($possibleFullyQualifiedClassName) || interface_exists($possibleFullyQualifiedClassName)) {
            return $possibleFullyQualifiedClassName . ($isNullable ? '|null' : '');
        }

        // and then we try to find "use" statements for the class.
        $className = $class->getName();
        if (!isset($this->useStatementsForClassCache[$className])) {
            $this->useStatementsForClassCache[$className] = $this->getDoctrinePhpParser()->parseClass($class);
        }
        $useStatementsForClass = $this->useStatementsForClassCache[$className];

        // ... and try to expand them
        $typeParts = explode('\\', $typeWithoutNull, 2);
        $lowercasedFirstTypePart = strtolower($typeParts[0]);
        if (isset($useStatementsForClass[$lowercasedFirstTypePart])) {
            $typeParts[0] = $useStatementsForClass[$lowercasedFirstTypePart];

            return implode('\\', $typeParts) . ($isNullable ? '|null' : '');
        }

        return $type;
    }
protected function expandType(ClassReflection $class, $type)
    {
        $typeWithoutNull = TypeHandling::stripNullableType($type);
        $isNullable = $typeWithoutNull !== $type;
        // expand "SomeType<SomeElementType>" to "\SomeTypeNamespace\SomeType<\ElementTypeNamespace\ElementType>"
        if (strpos($type, '<') !== false) {
            $typeParts = explode('<', $typeWithoutNull);
            $type = $typeParts[0];
            $elementType = rtrim($typeParts[1], '>');

            return $this->expandType($class, $type) . '<' . $this->expandType($class, $elementType) . '>' . ($isNullable ? '|null' : '');
        }

        // expand SomeElementType[]" to "array<\ElementTypeNamespace\SomeElementType>"
        if (substr_compare($typeWithoutNull, '[]', -2, 2) === 0) {
            $elementType = substr($typeWithoutNull, 0, -2);
            return 'array<' . $this->expandType($class, $elementType) . '>' . ($isNullable ? '|null' : '');
        }

        // skip simple types and types with fully qualified namespaces
        if ($type === 'mixed' || $type[0] === '\\' || TypeHandling::isSimpleType($type)) {
            return TypeHandling::normalizeType($type) . ($isNullable ? '|null' : '');
        }

        // we try to find the class relative to the current namespace...
        $possibleFullyQualifiedClassName = sprintf('%s\\%s', $class->getNamespaceName(), $typeWithoutNull);
        if (class_exists($possibleFullyQualifiedClassName) || interface_exists($possibleFullyQualifiedClassName)) {
            return $possibleFullyQualifiedClassName . ($isNullable ? '|null' : '');
        }

        // and then we try to find "use" statements for the class.
        $className = $class->getName();
        if (!isset($this->useStatementsForClassCache[$className])) {
            $this->useStatementsForClassCache[$className] = $this->getDoctrinePhpParser()->parseClass($class);
        }
        $useStatementsForClass = $this->useStatementsForClassCache[$className];

        // ... and try to expand them
        $typeParts = explode('\\', $typeWithoutNull, 2);
        $lowercasedFirstTypePart = strtolower($typeParts[0]);
        if (isset($useStatementsForClass[$lowercasedFirstTypePart])) {
            $typeParts[0] = $useStatementsForClass[$lowercasedFirstTypePart];

            return implode('\\', $typeParts) . ($isNullable ? '|null' : '');
        }

        return $type;
    }
protected function expandType ( ClassReflection $ class , $ type ) { $ typeWithoutNull = TypeHandling :: stripNullableType ( $ type ) ; $ isNullable = $ typeWithoutNull !== $ type ; // expand "SomeType<SomeElementType>" to "\SomeTypeNamespace\SomeType<\ElementTypeNamespace\ElementType>" if ( strpos ( $ type , '<' ) !== false ) { $ typeParts = explode ( '<' , $ typeWithoutNull ) ; $ type = $ typeParts [ 0 ] ; $ elementType = rtrim ( $ typeParts [ 1 ] , '>' ) ; return $ this -> expandType ( $ class , $ type ) . '<' . $ this -> expandType ( $ class , $ elementType ) . '>' . ( $ isNullable ? '|null' : '' ) ; } // expand SomeElementType[]" to "array<\ElementTypeNamespace\SomeElementType>" if ( substr_compare ( $ typeWithoutNull , '[]' , - 2 , 2 ) === 0 ) { $ elementType = substr ( $ typeWithoutNull , 0 , - 2 ) ; return 'array<' . $ this -> expandType ( $ class , $ elementType ) . '>' . ( $ isNullable ? '|null' : '' ) ; } // skip simple types and types with fully qualified namespaces if ( $ type === 'mixed' || $ type [ 0 ] === '\\' || TypeHandling :: isSimpleType ( $ type ) ) { return TypeHandling :: normalizeType ( $ type ) . ( $ isNullable ? '|null' : '' ) ; } // we try to find the class relative to the current namespace... $ possibleFullyQualifiedClassName = sprintf ( '%s\\%s' , $ class -> getNamespaceName ( ) , $ typeWithoutNull ) ; if ( class_exists ( $ possibleFullyQualifiedClassName ) || interface_exists ( $ possibleFullyQualifiedClassName ) ) { return $ possibleFullyQualifiedClassName . ( $ isNullable ? '|null' : '' ) ; } // and then we try to find "use" statements for the class. $ className = $ class -> getName ( ) ; if ( ! isset ( $ this -> useStatementsForClassCache [ $ className ] ) ) { $ this -> useStatementsForClassCache [ $ className ] = $ this -> getDoctrinePhpParser ( ) -> parseClass ( $ class ) ; } $ useStatementsForClass = $ this -> useStatementsForClassCache [ $ className ] ; // ... and try to expand them $ typeParts = explode ( '\\' , $ typeWithoutNull , 2 ) ; $ lowercasedFirstTypePart = strtolower ( $ typeParts [ 0 ] ) ; if ( isset ( $ useStatementsForClass [ $ lowercasedFirstTypePart ] ) ) { $ typeParts [ 0 ] = $ useStatementsForClass [ $ lowercasedFirstTypePart ] ; return implode ( '\\' , $ typeParts ) . ( $ isNullable ? '|null' : '' ) ; } return $ type ; }
Expand shortened class names in "var" and "param" annotations, taking use statements into account.

@param ClassReflection $class
@param string $type the type inside var/param annotation
@return string the possibly expanded type
Expand shortened class names in var and param annotations taking use statements into account .