Skip to content

Commit c6e8ce5

Browse files
rvanvelzenjiripudil
authored andcommitted
Implement template default types
1 parent d300e74 commit c6e8ce5

31 files changed

+170
-29
lines changed

src/Analyser/MutatingScope.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5606,6 +5606,11 @@ private function exactInstantiation(New_ $node, string $className): ?Type
56065606
$list[] = $templateType;
56075607
continue;
56085608
}
5609+
$default = $tag->getDefault();
5610+
if ($default !== null) {
5611+
$list[] = $default;
5612+
continue;
5613+
}
56095614
$bound = $tag->getBound();
56105615
if ($bound instanceof MixedType && $bound->isExplicitMixed()) {
56115616
$bound = new MixedType(false);

src/PhpDoc/PhpDocNodeResolver.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,12 @@ public function resolveTemplateTags(PhpDocNode $phpDocNode, NameScope $nameScope
327327
}
328328
}
329329

330+
$nameScopeWithoutCurrent = $nameScope->unsetTemplateType($valueNode->name);
331+
330332
$resolved[$valueNode->name] = new TemplateTag(
331333
$valueNode->name,
332-
$valueNode->bound !== null ? $this->typeNodeResolver->resolve($valueNode->bound, $nameScope->unsetTemplateType($valueNode->name)) : new MixedType(true),
334+
$valueNode->bound !== null ? $this->typeNodeResolver->resolve($valueNode->bound, $nameScopeWithoutCurrent) : new MixedType(true),
335+
$valueNode->default !== null ? $this->typeNodeResolver->resolve($valueNode->default, $nameScopeWithoutCurrent) : null,
333336
$variance,
334337
);
335338
$resolvedPrefix[$valueNode->name] = $prefix;

src/PhpDoc/Tag/TemplateTag.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class TemplateTag
1515
/**
1616
* @param non-empty-string $name
1717
*/
18-
public function __construct(private string $name, private Type $bound, private TemplateTypeVariance $variance)
18+
public function __construct(private string $name, private Type $bound, private ?Type $default, private TemplateTypeVariance $variance)
1919
{
2020
}
2121

@@ -32,6 +32,11 @@ public function getBound(): Type
3232
return $this->bound;
3333
}
3434

35+
public function getDefault(): ?Type
36+
{
37+
return $this->default;
38+
}
39+
3540
public function getVariance(): TemplateTypeVariance
3641
{
3742
return $this->variance;

src/Reflection/ClassReflection.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,7 @@ public function typeMapFromList(array $types): TemplateTypeMap
14421442
$map = [];
14431443
$i = 0;
14441444
foreach ($resolvedPhpDoc->getTemplateTags() as $tag) {
1445-
$map[$tag->getName()] = $types[$i] ?? $tag->getBound();
1445+
$map[$tag->getName()] = $types[$i] ?? $tag->getDefault() ?? $tag->getBound();
14461446
$i++;
14471447
}
14481448

@@ -1479,7 +1479,7 @@ public function typeMapToList(TemplateTypeMap $typeMap): array
14791479

14801480
$list = [];
14811481
foreach ($resolvedPhpDoc->getTemplateTags() as $tag) {
1482-
$list[] = $typeMap->getType($tag->getName()) ?? $tag->getBound();
1482+
$list[] = $typeMap->getType($tag->getName()) ?? $tag->getDefault() ?? $tag->getBound();
14831483
}
14841484

14851485
return $list;

src/Rules/FunctionCallParametersCheck.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ static function (Type $type, callable $traverse) use (&$returnTemplateTypes): Ty
432432
$type = $type->resolve();
433433
}
434434

435-
if ($type instanceof TemplateType) {
435+
if ($type instanceof TemplateType && $type->getDefault() === null) {
436436
$returnTemplateTypes[$type->getName()] = true;
437437
return $type;
438438
}

src/Type/Generic/TemplateArrayType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\Type\ArrayType;
66
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
7+
use PHPStan\Type\Type;
78

89
/** @api */
910
final class TemplateArrayType extends ArrayType implements TemplateType
@@ -22,6 +23,7 @@ public function __construct(
2223
TemplateTypeVariance $templateTypeVariance,
2324
string $name,
2425
ArrayType $bound,
26+
?Type $default,
2527
)
2628
{
2729
parent::__construct($bound->getKeyType(), $bound->getItemType());
@@ -30,6 +32,7 @@ public function __construct(
3032
$this->variance = $templateTypeVariance;
3133
$this->name = $name;
3234
$this->bound = $bound;
35+
$this->default = $default;
3336
}
3437

3538
protected function shouldGeneralizeInferredType(): bool

src/Type/Generic/TemplateBenevolentUnionType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public function __construct(
2121
TemplateTypeVariance $templateTypeVariance,
2222
string $name,
2323
BenevolentUnionType $bound,
24+
?Type $default,
2425
)
2526
{
2627
parent::__construct($bound->getTypes());
@@ -30,6 +31,7 @@ public function __construct(
3031
$this->variance = $templateTypeVariance;
3132
$this->name = $name;
3233
$this->bound = $bound;
34+
$this->default = $default;
3335
}
3436

3537
/** @param Type[] $types */
@@ -41,6 +43,7 @@ public function withTypes(array $types): self
4143
$this->variance,
4244
$this->name,
4345
new BenevolentUnionType($types),
46+
$this->default,
4447
);
4548
}
4649

src/Type/Generic/TemplateBooleanType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\Type\BooleanType;
66
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
7+
use PHPStan\Type\Type;
78

89
/** @api */
910
final class TemplateBooleanType extends BooleanType implements TemplateType
@@ -22,6 +23,7 @@ public function __construct(
2223
TemplateTypeVariance $templateTypeVariance,
2324
string $name,
2425
BooleanType $bound,
26+
?Type $default,
2527
)
2628
{
2729
parent::__construct();
@@ -30,6 +32,7 @@ public function __construct(
3032
$this->variance = $templateTypeVariance;
3133
$this->name = $name;
3234
$this->bound = $bound;
35+
$this->default = $default;
3336
}
3437

3538
protected function shouldGeneralizeInferredType(): bool

src/Type/Generic/TemplateConstantArrayType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\Type\Constant\ConstantArrayType;
66
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
7+
use PHPStan\Type\Type;
78

89
/** @api */
910
final class TemplateConstantArrayType extends ConstantArrayType implements TemplateType
@@ -22,6 +23,7 @@ public function __construct(
2223
TemplateTypeVariance $templateTypeVariance,
2324
string $name,
2425
ConstantArrayType $bound,
26+
?Type $default,
2527
)
2628
{
2729
parent::__construct($bound->getKeyTypes(), $bound->getValueTypes(), $bound->getNextAutoIndexes(), $bound->getOptionalKeys(), $bound->isList());
@@ -30,6 +32,7 @@ public function __construct(
3032
$this->variance = $templateTypeVariance;
3133
$this->name = $name;
3234
$this->bound = $bound;
35+
$this->default = $default;
3336
}
3437

3538
protected function shouldGeneralizeInferredType(): bool

src/Type/Generic/TemplateConstantIntegerType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\Type\Constant\ConstantIntegerType;
66
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
7+
use PHPStan\Type\Type;
78

89
/** @api */
910
final class TemplateConstantIntegerType extends ConstantIntegerType implements TemplateType
@@ -22,6 +23,7 @@ public function __construct(
2223
TemplateTypeVariance $templateTypeVariance,
2324
string $name,
2425
ConstantIntegerType $bound,
26+
?Type $default,
2527
)
2628
{
2729
parent::__construct($bound->getValue());
@@ -30,6 +32,7 @@ public function __construct(
3032
$this->variance = $templateTypeVariance;
3133
$this->name = $name;
3234
$this->bound = $bound;
35+
$this->default = $default;
3336
}
3437

3538
protected function shouldGeneralizeInferredType(): bool

0 commit comments

Comments
 (0)