This repository has been archived by the owner on Jan 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 80
/
TypeGenerator.php
124 lines (104 loc) · 3.13 KB
/
TypeGenerator.php
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
<?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;
final class TypeGenerator implements GeneratorInterface
{
/**
* @var bool
*/
private $isInternalPhpType;
/**
* @var string
*/
private $type;
/**
* @var string[]
*
* @link http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration
*/
private static $internalPhpTypes = ['int', 'float', 'string', 'bool', 'array', 'callable'];
// @codingStandardsIgnoreStart
/**
* @var string a regex pattern to match valid class names or types
*/
private static $validIdentifierMatcher = '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*$/';
// @codingStandardsIgnoreEnd
/**
* @param string $type
*
* @return TypeGenerator
*
* @throws InvalidArgumentException
*/
public static function fromTypeString($type)
{
list($wasTrimmed, $trimmedType) = self::trimType($type);
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
));
}
$instance = new self();
$instance->type = $trimmedType;
$instance->isInternalPhpType = self::isInternalPhpType($trimmedType);
return $instance;
}
private function __construct()
{
}
/**
* {@inheritDoc}
*/
public function generate()
{
if ($this->isInternalPhpType) {
return strtolower($this->type);
}
return '\\' . $this->type;
}
/**
* @return string the cleaned type string
*/
public function __toString()
{
return ltrim($this->generate(), '\\');
}
/**
* @param string $type
*
* @return bool[]|int[] 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);
}
}