Skip to content

Commit b0fbe29

Browse files
authored
Merge branch refs/heads/1.9.x into 1.10.x
2 parents 7380ed0 + ed14b2a commit b0fbe29

38 files changed

+539
-74
lines changed

phpstan-baseline.neon

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,6 @@ parameters:
297297
count: 1
298298
path: src/Reflection/InitializerExprTypeResolver.php
299299

300-
-
301-
message: "#^Binary operation \"\\*\\*\" between bool\\|float\\|int\\|string\\|null and bool\\|float\\|int\\|string\\|null results in an error\\.$#"
302-
count: 1
303-
path: src/Reflection/InitializerExprTypeResolver.php
304-
305300
-
306301
message: "#^Binary operation \"\\+\" between bool\\|float\\|int\\|string\\|null and bool\\|float\\|int\\|string\\|null results in an error\\.$#"
307302
count: 1

src/Reflection/InitializerExprTypeResolver.php

Lines changed: 32 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,57 +1170,17 @@ public function getPowType(Expr $left, Expr $right, callable $getTypeCallback):
11701170
$leftType = $getTypeCallback($left);
11711171
$rightType = $getTypeCallback($right);
11721172

1173-
if ($leftType instanceof MixedType || $rightType instanceof MixedType) {
1174-
return new BenevolentUnionType([
1175-
new FloatType(),
1176-
new IntegerType(),
1177-
]);
1173+
$exponentiatedTyped = $leftType->exponentiate($rightType);
1174+
if (!$exponentiatedTyped instanceof ErrorType) {
1175+
return $exponentiatedTyped;
11781176
}
11791177

1180-
$object = new ObjectWithoutClassType();
1181-
if (
1182-
!$leftType instanceof NeverType &&
1183-
!$rightType instanceof NeverType &&
1184-
(
1185-
!$object->isSuperTypeOf($leftType)->no()
1186-
|| !$object->isSuperTypeOf($rightType)->no()
1187-
)
1188-
) {
1189-
return TypeCombinator::union($leftType, $rightType);
1178+
$extensionSpecified = $this->callOperatorTypeSpecifyingExtensions(new BinaryOp\Pow($left, $right), $leftType, $rightType);
1179+
if ($extensionSpecified !== null) {
1180+
return $extensionSpecified;
11901181
}
11911182

1192-
$leftTypes = TypeUtils::getConstantScalars($leftType);
1193-
$rightTypes = TypeUtils::getConstantScalars($rightType);
1194-
$leftTypesCount = count($leftTypes);
1195-
$rightTypesCount = count($rightTypes);
1196-
if ($leftTypesCount > 0 && $rightTypesCount > 0) {
1197-
$resultTypes = [];
1198-
$generalize = $leftTypesCount * $rightTypesCount > self::CALCULATE_SCALARS_LIMIT;
1199-
foreach ($leftTypes as $leftTypeInner) {
1200-
foreach ($rightTypes as $rightTypeInner) {
1201-
$leftNumberType = $leftTypeInner->toNumber();
1202-
$rightNumberType = $rightTypeInner->toNumber();
1203-
1204-
if ($leftNumberType instanceof ErrorType || $rightNumberType instanceof ErrorType) {
1205-
return new ErrorType();
1206-
}
1207-
1208-
if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) {
1209-
throw new ShouldNotHappenException();
1210-
}
1211-
1212-
$resultType = $this->getTypeFromValue($leftNumberType->getValue() ** $rightNumberType->getValue());
1213-
if ($generalize) {
1214-
$resultType = $resultType->generalize(GeneralizePrecision::lessSpecific());
1215-
}
1216-
$resultTypes[] = $resultType;
1217-
}
1218-
}
1219-
1220-
return TypeCombinator::union(...$resultTypes);
1221-
}
1222-
1223-
return $this->resolveCommonMath(new BinaryOp\Pow($left, $right), $leftType, $rightType);
1183+
return new ErrorType();
12241184
}
12251185

12261186
/**
@@ -1469,14 +1429,33 @@ private function resolveConstantArrayTypeComparison(ConstantArrayType $leftType,
14691429
return $resultType->toBoolean();
14701430
}
14711431

1432+
private function callOperatorTypeSpecifyingExtensions(Expr\BinaryOp $expr, Type $leftType, Type $rightType): ?Type
1433+
{
1434+
$operatorSigil = $expr->getOperatorSigil();
1435+
$operatorTypeSpecifyingExtensions = $this->operatorTypeSpecifyingExtensionRegistryProvider->getRegistry()->getOperatorTypeSpecifyingExtensions($operatorSigil, $leftType, $rightType);
1436+
1437+
/** @var Type[] $extensionTypes */
1438+
$extensionTypes = [];
1439+
1440+
foreach ($operatorTypeSpecifyingExtensions as $extension) {
1441+
$extensionTypes[] = $extension->specifyType($operatorSigil, $leftType, $rightType);
1442+
}
1443+
1444+
if (count($extensionTypes) > 0) {
1445+
return TypeCombinator::union(...$extensionTypes);
1446+
}
1447+
1448+
return null;
1449+
}
1450+
14721451
/**
1473-
* @param BinaryOp\Plus|BinaryOp\Minus|BinaryOp\Mul|BinaryOp\Pow|BinaryOp\Div $expr
1452+
* @param BinaryOp\Plus|BinaryOp\Minus|BinaryOp\Mul|BinaryOp\Div $expr
14741453
*/
14751454
private function resolveCommonMath(Expr\BinaryOp $expr, Type $leftType, Type $rightType): Type
14761455
{
14771456
if (($leftType instanceof IntegerRangeType || $leftType instanceof ConstantIntegerType || $leftType instanceof UnionType) &&
1478-
($rightType instanceof IntegerRangeType || $rightType instanceof ConstantIntegerType || $rightType instanceof UnionType) &&
1479-
!$expr instanceof BinaryOp\Pow) {
1457+
($rightType instanceof IntegerRangeType || $rightType instanceof ConstantIntegerType || $rightType instanceof UnionType)
1458+
) {
14801459

14811460
if ($leftType instanceof ConstantIntegerType) {
14821461
return $this->integerRangeMath(
@@ -1507,18 +1486,9 @@ private function resolveCommonMath(Expr\BinaryOp $expr, Type $leftType, Type $ri
15071486
return $this->integerRangeMath($leftType, $expr, $rightType);
15081487
}
15091488

1510-
$operatorSigil = $expr->getOperatorSigil();
1511-
$operatorTypeSpecifyingExtensions = $this->operatorTypeSpecifyingExtensionRegistryProvider->getRegistry()->getOperatorTypeSpecifyingExtensions($operatorSigil, $leftType, $rightType);
1512-
1513-
/** @var Type[] $extensionTypes */
1514-
$extensionTypes = [];
1515-
1516-
foreach ($operatorTypeSpecifyingExtensions as $extension) {
1517-
$extensionTypes[] = $extension->specifyType($operatorSigil, $leftType, $rightType);
1518-
}
1519-
1520-
if (count($extensionTypes) > 0) {
1521-
return TypeCombinator::union(...$extensionTypes);
1489+
$specifiedTypes = $this->callOperatorTypeSpecifyingExtensions($expr, $leftType, $rightType);
1490+
if ($specifiedTypes !== null) {
1491+
return $specifiedTypes;
15221492
}
15231493

15241494
$types = TypeCombinator::union($leftType, $rightType);
@@ -1546,13 +1516,6 @@ private function resolveCommonMath(Expr\BinaryOp $expr, Type $leftType, Type $ri
15461516
return new FloatType();
15471517
}
15481518

1549-
if ($expr instanceof Expr\BinaryOp\Pow) {
1550-
return new BenevolentUnionType([
1551-
new FloatType(),
1552-
new IntegerType(),
1553-
]);
1554-
}
1555-
15561519
$resultType = TypeCombinator::union($leftNumberType, $rightNumberType);
15571520
if ($expr instanceof Expr\BinaryOp\Div) {
15581521
if ($types instanceof MixedType || $resultType->isInteger()->yes()) {

src/Type/Accessory/AccessoryArrayListType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,4 +392,9 @@ public static function intersectWith(Type $type): Type
392392
return $type;
393393
}
394394

395+
public function exponentiate(Type $exponent): Type
396+
{
397+
return new ErrorType();
398+
}
399+
395400
}

src/Type/Accessory/AccessoryLiteralStringType.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Accessory;
44

55
use PHPStan\TrinaryLogic;
6+
use PHPStan\Type\BenevolentUnionType;
67
use PHPStan\Type\BooleanType;
78
use PHPStan\Type\CompoundType;
89
use PHPStan\Type\Constant\ConstantArrayType;
@@ -256,4 +257,12 @@ public static function __set_state(array $properties): Type
256257
return new self();
257258
}
258259

260+
public function exponentiate(Type $exponent): Type
261+
{
262+
return new BenevolentUnionType([
263+
new FloatType(),
264+
new IntegerType(),
265+
]);
266+
}
267+
259268
}

src/Type/Accessory/AccessoryNonEmptyStringType.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Accessory;
44

55
use PHPStan\TrinaryLogic;
6+
use PHPStan\Type\BenevolentUnionType;
67
use PHPStan\Type\CompoundType;
78
use PHPStan\Type\Constant\ConstantArrayType;
89
use PHPStan\Type\Constant\ConstantIntegerType;
@@ -265,4 +266,12 @@ public function tryRemove(Type $typeToRemove): ?Type
265266
return null;
266267
}
267268

269+
public function exponentiate(Type $exponent): Type
270+
{
271+
return new BenevolentUnionType([
272+
new FloatType(),
273+
new IntegerType(),
274+
]);
275+
}
276+
268277
}

src/Type/Accessory/AccessoryNonFalsyStringType.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Accessory;
44

55
use PHPStan\TrinaryLogic;
6+
use PHPStan\Type\BenevolentUnionType;
67
use PHPStan\Type\CompoundType;
78
use PHPStan\Type\Constant\ConstantArrayType;
89
use PHPStan\Type\Constant\ConstantIntegerType;
@@ -256,4 +257,12 @@ public static function __set_state(array $properties): Type
256257
return new self();
257258
}
258259

260+
public function exponentiate(Type $exponent): Type
261+
{
262+
return new BenevolentUnionType([
263+
new FloatType(),
264+
new IntegerType(),
265+
]);
266+
}
267+
259268
}

src/Type/Accessory/AccessoryNumericStringType.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Accessory;
44

55
use PHPStan\TrinaryLogic;
6+
use PHPStan\Type\BenevolentUnionType;
67
use PHPStan\Type\CompoundType;
78
use PHPStan\Type\Constant\ConstantArrayType;
89
use PHPStan\Type\Constant\ConstantIntegerType;
@@ -268,4 +269,12 @@ public function tryRemove(Type $typeToRemove): ?Type
268269
return null;
269270
}
270271

272+
public function exponentiate(Type $exponent): Type
273+
{
274+
return new BenevolentUnionType([
275+
new FloatType(),
276+
new IntegerType(),
277+
]);
278+
}
279+
271280
}

src/Type/Accessory/HasMethodType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ public function traverse(callable $cb): Type
153153
return $this;
154154
}
155155

156+
public function exponentiate(Type $exponent): Type
157+
{
158+
return new ErrorType();
159+
}
160+
156161
public static function __set_state(array $properties): Type
157162
{
158163
return new self($properties['methodName']);

src/Type/Accessory/HasOffsetType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,11 @@ public function traverse(callable $cb): Type
294294
return $this;
295295
}
296296

297+
public function exponentiate(Type $exponent): Type
298+
{
299+
return new ErrorType();
300+
}
301+
297302
public static function __set_state(array $properties): Type
298303
{
299304
return new self($properties['offsetType']);

src/Type/Accessory/HasOffsetValueType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,11 @@ public function traverse(callable $cb): Type
340340
return new self($this->offsetType, $newValueType);
341341
}
342342

343+
public function exponentiate(Type $exponent): Type
344+
{
345+
return new ErrorType();
346+
}
347+
343348
public static function __set_state(array $properties): Type
344349
{
345350
return new self($properties['offsetType'], $properties['valueType']);

src/Type/Accessory/HasPropertyType.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Reflection\TrivialParametersAcceptor;
77
use PHPStan\TrinaryLogic;
88
use PHPStan\Type\CompoundType;
9+
use PHPStan\Type\ErrorType;
910
use PHPStan\Type\IntersectionType;
1011
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
1112
use PHPStan\Type\Traits\NonGenericTypeTrait;
@@ -114,6 +115,11 @@ public function traverse(callable $cb): Type
114115
return $this;
115116
}
116117

118+
public function exponentiate(Type $exponent): Type
119+
{
120+
return new ErrorType();
121+
}
122+
117123
public static function __set_state(array $properties): Type
118124
{
119125
return new self($properties['propertyName']);

src/Type/Accessory/NonEmptyArrayType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ public function traverse(callable $cb): Type
347347
return $this;
348348
}
349349

350+
public function exponentiate(Type $exponent): Type
351+
{
352+
return new ErrorType();
353+
}
354+
350355
public static function __set_state(array $properties): Type
351356
{
352357
return new self();

src/Type/Accessory/OversizedArrayType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,11 @@ public function traverse(callable $cb): Type
346346
return $this;
347347
}
348348

349+
public function exponentiate(Type $exponent): Type
350+
{
351+
return new ErrorType();
352+
}
353+
349354
public static function __set_state(array $properties): Type
350355
{
351356
return new self();

src/Type/ArrayType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,11 @@ public function tryRemove(Type $typeToRemove): ?Type
612612
return null;
613613
}
614614

615+
public function exponentiate(Type $exponent): Type
616+
{
617+
return new ErrorType();
618+
}
619+
615620
/**
616621
* @param mixed[] $properties
617622
*/

src/Type/BooleanType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ public function tryRemove(Type $typeToRemove): ?Type
127127
return null;
128128
}
129129

130+
public function exponentiate(Type $exponent): Type
131+
{
132+
return ExponentiateHelper::exponentiate($this, $exponent);
133+
}
134+
130135
/**
131136
* @param mixed[] $properties
132137
*/

src/Type/CallableType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,11 @@ public function isCommonCallable(): bool
407407
return $this->isCommonCallable;
408408
}
409409

410+
public function exponentiate(Type $exponent): Type
411+
{
412+
return new ErrorType();
413+
}
414+
410415
/**
411416
* @param mixed[] $properties
412417
*/

src/Type/ClosureType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,11 @@ public function isScalar(): TrinaryLogic
471471
return TrinaryLogic::createNo();
472472
}
473473

474+
public function exponentiate(Type $exponent): Type
475+
{
476+
return new ErrorType();
477+
}
478+
474479
/**
475480
* @param mixed[] $properties
476481
*/

0 commit comments

Comments
 (0)