Seditio Source
Root |
./othercms/phpBB3/vendor/zendframework/zend-code/src/Generator/TypeGenerator.php
<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/zf2 for the canonical source repository
 * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace Zend\Code\Generator;

use
Zend\Code\Generator\Exception\InvalidArgumentException;

use function
in_array;
use function
ltrim;
use function
preg_match;
use function
sprintf;
use function
strpos;
use function
strtolower;
use function
substr;

final class
TypeGenerator implements GeneratorInterface
{
   
/**
     * @var bool
     */
   
private $isInternalPhpType;

   
/**
     * @var string
     */
   
private $type;

   
/**
     * @var bool
     */
   
private $nullable;

   
/**
     * @var string[]
     *
     * @link http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration
     */
   
private static $internalPhpTypes = [
       
'void',
       
'int',
       
'float',
       
'string',
       
'bool',
       
'array',
       
'callable',
       
'iterable',
       
'object'
   
];

   
/**
     * @var string a regex pattern to match valid class names or types
     */
   
private static $validIdentifierMatcher = '/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*'
       
. '(\\\\[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)*$/';

   
/**
     * @param string $type
     *
     * @return TypeGenerator
     *
     * @throws InvalidArgumentException
     */
   
public static function fromTypeString($type)
    {
        list(
$nullable, $trimmedNullable) = self::trimNullable($type);
        list(
$wasTrimmed, $trimmedType) = self::trimType($trimmedNullable);

        if (!
preg_match(self::$validIdentifierMatcher, $trimmedType)) {
            throw new
InvalidArgumentException(sprintf(
               
'Provided type "%s" is invalid: must conform "%s"',
               
$type,
               
self::$validIdentifierMatcher
           
));
        }

       
$isInternalPhpType = self::isInternalPhpType($trimmedType);

        if (
$wasTrimmed && $isInternalPhpType) {
            throw new
InvalidArgumentException(sprintf(
               
'Provided type "%s" is an internal PHP type, but was provided with a namespace separator prefix',
               
$type
           
));
        }

        if (
$nullable && $isInternalPhpType && 'void' === strtolower($trimmedType)) {
            throw new
InvalidArgumentException(sprintf('Provided type "%s" cannot be nullable', $type));
        }

       
$instance = new self();

       
$instance->type              = $trimmedType;
       
$instance->nullable          = $nullable;
       
$instance->isInternalPhpType = $isInternalPhpType;

        return
$instance;
    }

    private function
__construct()
    {
    }

   
/**
     * {@inheritDoc}
     */
   
public function generate()
    {
       
$nullable = $this->nullable ? '?' : '';

        if (
$this->isInternalPhpType) {
            return
$nullable . strtolower($this->type);
        }

        return
$nullable . '\\' . $this->type;
    }

   
/**
     * @return string the cleaned type string
     */
   
public function __toString()
    {
        return
ltrim($this->generate(), '?\\');
    }

   
/**
     * @param string $type
     *
     * @return bool[]|string[] ordered tuple, first key represents whether the type is nullable, second is the
     *                         trimmed string
     */
   
private static function trimNullable($type)
    {
        if (
0 === strpos($type, '?')) {
            return [
true, substr($type, 1)];
        }

        return [
false, $type];
    }

   
/**
     * @param string $type
     *
     * @return bool[]|string[] ordered tuple, first key represents whether the values was trimmed, second is the
     *                         trimmed string
     */
   
private static function trimType($type)
    {
        if (
0 === strpos($type, '\\')) {
            return [
true, substr($type, 1)];
        }

        return [
false, $type];
    }

   
/**
     * @param string $type
     *
     * @return bool
     */
   
private static function isInternalPhpType($type)
    {
        return
in_array(strtolower($type), self::$internalPhpTypes, true);
    }
}