forked from phpstan/phpstan-src
-
Notifications
You must be signed in to change notification settings - Fork 1
/
TemplateTypeFactory.php
110 lines (86 loc) · 4.36 KB
/
TemplateTypeFactory.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
<?php declare(strict_types = 1);
namespace PHPStan\Type\Generic;
use PHPStan\PhpDoc\Tag\TemplateTag;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BenevolentUnionType;
use PHPStan\Type\BooleanType;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\KeyOfType;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ObjectWithoutClassType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use function get_class;
final class TemplateTypeFactory
{
public static function create(TemplateTypeScope $scope, string $name, ?Type $bound, TemplateTypeVariance $variance): TemplateType
{
$strategy = new TemplateTypeParameterStrategy();
if ($bound === null) {
return new TemplateMixedType($scope, $strategy, $variance, $name, new MixedType(true));
}
$boundClass = get_class($bound);
if ($bound instanceof ObjectType && ($boundClass === ObjectType::class || $bound instanceof TemplateType)) {
return new TemplateObjectType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof GenericObjectType && ($boundClass === GenericObjectType::class || $bound instanceof TemplateType)) {
return new TemplateGenericObjectType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof ObjectWithoutClassType && ($boundClass === ObjectWithoutClassType::class || $bound instanceof TemplateType)) {
return new TemplateObjectWithoutClassType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof ArrayType && ($boundClass === ArrayType::class || $bound instanceof TemplateType)) {
return new TemplateArrayType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof ConstantArrayType && ($boundClass === ConstantArrayType::class || $bound instanceof TemplateType)) {
return new TemplateConstantArrayType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof StringType && ($boundClass === StringType::class || $bound instanceof TemplateType)) {
return new TemplateStringType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof ConstantStringType && ($boundClass === ConstantStringType::class || $bound instanceof TemplateType)) {
return new TemplateConstantStringType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof IntegerType && ($boundClass === IntegerType::class || $bound instanceof TemplateType)) {
return new TemplateIntegerType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof ConstantIntegerType && ($boundClass === ConstantIntegerType::class || $bound instanceof TemplateType)) {
return new TemplateConstantIntegerType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof FloatType && ($boundClass === FloatType::class || $bound instanceof TemplateType)) {
return new TemplateFloatType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof BooleanType && ($boundClass === BooleanType::class || $bound instanceof TemplateType)) {
return new TemplateBooleanType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof MixedType && ($boundClass === MixedType::class || $bound instanceof TemplateType)) {
return new TemplateMixedType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof UnionType) {
if ($boundClass === UnionType::class || $bound instanceof TemplateUnionType) {
return new TemplateUnionType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof BenevolentUnionType) {
return new TemplateBenevolentUnionType($scope, $strategy, $variance, $name, $bound);
}
}
if ($bound instanceof IntersectionType) {
return new TemplateIntersectionType($scope, $strategy, $variance, $name, $bound);
}
if ($bound instanceof KeyOfType && ($boundClass === KeyOfType::class || $bound instanceof TemplateType)) {
return new TemplateKeyOfType($scope, $strategy, $variance, $name, $bound);
}
return new TemplateMixedType($scope, $strategy, $variance, $name, new MixedType(true));
}
public static function fromTemplateTag(TemplateTypeScope $scope, TemplateTag $tag): TemplateType
{
return self::create($scope, $tag->getName(), $tag->getBound(), $tag->getVariance());
}
}