Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed Dec 4, 2023
1 parent cb3d887 commit 7b2ac0c
Showing 1 changed file with 37 additions and 26 deletions.
63 changes: 37 additions & 26 deletions src/Type/ExponentiateHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PHPStan\Type\Constant\ConstantIntegerType;
use function is_float;
use function is_int;
use function pow;

final class ExponentiateHelper
{
Expand All @@ -25,28 +26,9 @@ public static function exponentiate(Type $base, Type $exponent): Type
return new NeverType();
}

$allowedOperandTypes = new UnionType([
new IntegerType(),
new FloatType(),
new IntersectionType([
new StringType(),
new AccessoryNumericStringType(),
]),
new BooleanType(),
new NullType(),
]);
if (!$allowedOperandTypes->isSuperTypeOf($exponent)->yes()) {
return new ErrorType();
}
if (!$allowedOperandTypes->isSuperTypeOf($base)->yes()) {
return new ErrorType();
}

if ($base instanceof ConstantScalarType) {
$result = self::exponentiateConstantScalar($base, $exponent);
if ($result !== null) {
return $result;
}
$result = self::exponentiateConstantScalar($base, $exponent);
if ($result !== null) {
return $result;
}

// exponentiation of a float, stays a float
Expand Down Expand Up @@ -84,16 +66,37 @@ public static function exponentiate(Type $base, Type $exponent): Type
]);
}

private static function exponentiateConstantScalar(ConstantScalarType $base, Type $exponent): ?Type
private static function exponentiateConstantScalar(Type $base, Type $exponent): ?Type
{
$allowedOperandTypes = new UnionType([
new IntegerType(),
new FloatType(),
new IntersectionType([
new StringType(),
new AccessoryNumericStringType(),
]),
new BooleanType(),
new NullType(),
]);
if (!$allowedOperandTypes->isSuperTypeOf($exponent)->yes()) {
return new ErrorType();
}
if (!$allowedOperandTypes->isSuperTypeOf($base)->yes()) {
return new ErrorType();
}

if (!$base instanceof ConstantScalarType) {
return null;
}

if ($exponent instanceof IntegerRangeType) {
$min = null;
$max = null;
if ($exponent->getMin() !== null) {
$min = $base->getValue() ** $exponent->getMin();
$min = self::pow($base->getValue(), $exponent->getMin());
}
if ($exponent->getMax() !== null) {
$max = $base->getValue() ** $exponent->getMax();
$max = self::pow($base->getValue(), $exponent->getMax());
}

if (!is_float($min) && !is_float($max)) {
Expand All @@ -102,7 +105,7 @@ private static function exponentiateConstantScalar(ConstantScalarType $base, Typ
}

if ($exponent instanceof ConstantScalarType) {
$result = $base->getValue() ** $exponent->getValue();
$result = self::pow($base->getValue(), $exponent->getValue());
if (is_int($result)) {
return new ConstantIntegerType($result);
}
Expand All @@ -112,4 +115,12 @@ private static function exponentiateConstantScalar(ConstantScalarType $base, Typ
return null;
}

/**
* @return float|int
*/
private static function pow(mixed $base, mixed $exp)
{
return pow($base, $exp);
}

}

0 comments on commit 7b2ac0c

Please sign in to comment.