Skip to content

Commit

Permalink
simplify type projections resolution so that it does not need a new m…
Browse files Browse the repository at this point in the history
…ethod on Type
  • Loading branch information
jiripudil committed Sep 18, 2023
1 parent dee5c88 commit fc00bb9
Show file tree
Hide file tree
Showing 45 changed files with 36 additions and 564 deletions.
25 changes: 18 additions & 7 deletions src/Reflection/ResolvedFunctionVariant.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use PHPStan\Type\Type;
use PHPStan\Type\TypeTraverser;
use PHPStan\Type\TypeUtils;
use PHPStan\Type\VarianceAwareTypeTraverser;
use function array_key_exists;
use function array_map;

Expand Down Expand Up @@ -172,30 +171,42 @@ public function getNativeReturnType(): Type

private function resolveResolvableTemplateTypes(Type $type, TemplateTypeVariance $positionVariance): Type
{
return VarianceAwareTypeTraverser::map($type, $positionVariance, function (Type $type, TemplateTypeVariance $positionVariance, callable $traverse): Type {
$references = $type->getReferencedTemplateTypes($positionVariance);

return TypeTraverser::map($type, function (Type $type, callable $traverse) use ($references): Type {
if ($type instanceof TemplateType && !$type->isArgument()) {
$newType = $this->resolvedTemplateTypeMap->getType($type->getName());
if ($newType === null || $newType instanceof ErrorType) {
return $traverse($type, $positionVariance);
return $traverse($type);
}

$variance = TemplateTypeVariance::createInvariant();
foreach ($references as $reference) {
// this uses identity to distinguish between different occurrences of the same template type
// see https://github.com/phpstan/phpstan-src/pull/2485#discussion_r1328555397 for details
if ($reference->getType() === $type) {
$variance = $reference->getPositionVariance();
break;
}
}

$callSiteVariance = $this->callSiteVarianceMap->getVariance($type->getName());
if ($callSiteVariance === null || $callSiteVariance->invariant()) {
return $newType;
}

if (!$callSiteVariance->covariant() && $positionVariance->covariant()) {
return $traverse($type->getBound(), $positionVariance);
if (!$callSiteVariance->covariant() && $variance->covariant()) {
return $traverse($type->getBound());
}

if (!$callSiteVariance->contravariant() && $positionVariance->contravariant()) {
if (!$callSiteVariance->contravariant() && $variance->contravariant()) {
return new NonAcceptingNeverType();
}

return $newType;
}

return $traverse($type, $positionVariance);
return $traverse($type);
});
}

Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/AccessoryArrayListType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use PHPStan\Type\Constant\ConstantFloatType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\MixedType;
Expand Down Expand Up @@ -446,11 +445,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public static function __set_state(array $properties): Type
{
return new self();
Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/AccessoryLiteralStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use PHPStan\Type\ErrorType;
use PHPStan\Type\FloatType;
use PHPStan\Type\GeneralizePrecision;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntegerType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\MixedType;
Expand Down Expand Up @@ -318,11 +317,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public function generalize(GeneralizePrecision $precision): Type
{
return new StringType();
Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/AccessoryNonEmptyStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use PHPStan\Type\ErrorType;
use PHPStan\Type\FloatType;
use PHPStan\Type\GeneralizePrecision;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntegerType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\ObjectWithoutClassType;
Expand Down Expand Up @@ -314,11 +313,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public function generalize(GeneralizePrecision $precision): Type
{
return new StringType();
Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/AccessoryNonFalsyStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use PHPStan\Type\ErrorType;
use PHPStan\Type\FloatType;
use PHPStan\Type\GeneralizePrecision;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\IntersectionType;
Expand Down Expand Up @@ -314,11 +313,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public function generalize(GeneralizePrecision $precision): Type
{
return new StringType();
Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/AccessoryNumericStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use PHPStan\Type\ErrorType;
use PHPStan\Type\FloatType;
use PHPStan\Type\GeneralizePrecision;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntegerType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\StringType;
Expand Down Expand Up @@ -316,11 +315,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public function generalize(GeneralizePrecision $precision): Type
{
return new StringType();
Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/HasMethodType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use PHPStan\Type\AcceptsResult;
use PHPStan\Type\CompoundType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\StringType;
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
Expand Down Expand Up @@ -186,11 +185,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public function exponentiate(Type $exponent): Type
{
return new ErrorType();
Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/HasOffsetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectWithoutClassType;
Expand Down Expand Up @@ -359,11 +358,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public function exponentiate(Type $exponent): Type
{
return new ErrorType();
Expand Down
11 changes: 0 additions & 11 deletions src/Type/Accessory/HasOffsetValueType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\ConstantScalarType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectWithoutClassType;
Expand Down Expand Up @@ -415,16 +414,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return new self($this->offsetType, $newValueType);
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
$newValueType = $cb($this->valueType, $variance);
if ($newValueType === $this->valueType) {
return $this;
}

return new self($this->offsetType, $newValueType);
}

public function exponentiate(Type $exponent): Type
{
return new ErrorType();
Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/HasPropertyType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use PHPStan\Type\AcceptsResult;
use PHPStan\Type\CompoundType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
use PHPStan\Type\Traits\NonGenericTypeTrait;
Expand Down Expand Up @@ -148,11 +147,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public function exponentiate(Type $exponent): Type
{
return new ErrorType();
Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/NonEmptyArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use PHPStan\Type\Constant\ConstantFloatType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\MixedType;
Expand Down Expand Up @@ -425,11 +424,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public function exponentiate(Type $exponent): Type
{
return new ErrorType();
Expand Down
6 changes: 0 additions & 6 deletions src/Type/Accessory/OversizedArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use PHPStan\Type\Constant\ConstantFloatType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\MixedType;
Expand Down Expand Up @@ -411,11 +410,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
return $this;
}

public function exponentiate(Type $exponent): Type
{
return new ErrorType();
Expand Down
18 changes: 0 additions & 18 deletions src/Type/ArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -659,24 +659,6 @@ public function traverse(callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
$composedVariance = $variance->compose(TemplateTypeVariance::createCovariant());

$newKeyType = $cb($this->keyType, $composedVariance);
$newItemType = $cb($this->itemType, $composedVariance);

if ($newKeyType === $this->keyType && $newItemType === $this->itemType) {
return $this;
}

if ($newKeyType instanceof NeverType && $newItemType instanceof NeverType) {
return new ConstantArrayType([], []);
}

return new self($newKeyType, $newItemType);
}

public function toPhpDocNode(): TypeNode
{
$isMixedKeyType = $this->keyType instanceof MixedType && $this->keyType->describe(VerbosityLevel::precise()) === 'mixed';
Expand Down
21 changes: 0 additions & 21 deletions src/Type/BenevolentUnionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use PHPStan\TrinaryLogic;
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Generic\TemplateTypeVariance;
use function count;

/** @api */
Expand Down Expand Up @@ -167,26 +166,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
return $this;
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
$types = [];
$changed = false;

foreach ($this->getTypes() as $type) {
$newType = $cb($type, $variance);
if ($type !== $newType) {
$changed = true;
}
$types[] = $newType;
}

if ($changed) {
return TypeUtils::toBenevolentUnion(TypeCombinator::union(...$types));
}

return $this;
}

/**
* @param mixed[] $properties
*/
Expand Down
26 changes: 0 additions & 26 deletions src/Type/CallableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -405,32 +405,6 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
);
}

public function traverseWithVariance(TemplateTypeVariance $variance, callable $cb): Type
{
if ($this->isCommonCallable) {
return $this;
}

$parameterVariance = $variance->compose(TemplateTypeVariance::createContravariant());
$parameters = array_map(static function (ParameterReflection $param) use ($cb, $parameterVariance): NativeParameterReflection {
$defaultValue = $param->getDefaultValue();
return new NativeParameterReflection(
$param->getName(),
$param->isOptional(),
$cb($param->getType(), $parameterVariance),
$param->passedByReference(),
$param->isVariadic(),
$defaultValue !== null ? $cb($defaultValue, $parameterVariance) : null,
);
}, $this->getParameters());

return new self(
$parameters,
$cb($this->getReturnType(), $variance->compose(TemplateTypeVariance::createCovariant())),
$this->isVariadic(),
);
}

public function isOversizedArray(): TrinaryLogic
{
return TrinaryLogic::createNo();
Expand Down

0 comments on commit fc00bb9

Please sign in to comment.