Skip to content

Commit

Permalink
Support arrays with union value-types in implode()
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed Jan 5, 2025
1 parent fd7bad3 commit f7e6e74
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1367,11 +1367,6 @@ parameters:
count: 1
path: src/Type/Php/FunctionExistsFunctionTypeSpecifyingExtension.php

-
message: "#^Doing instanceof PHPStan\\\\Type\\\\ConstantScalarType is error\\-prone and deprecated\\. Use Type\\:\\:isConstantScalarValue\\(\\) or Type\\:\\:getConstantScalarTypes\\(\\) or Type\\:\\:getConstantScalarValues\\(\\) instead\\.$#"
count: 1
path: src/Type/Php/ImplodeFunctionReturnTypeExtension.php

-
message: """
#^Call to deprecated method getConstantScalars\\(\\) of class PHPStan\\\\Type\\\\TypeUtils\\:
Expand Down
12 changes: 8 additions & 4 deletions src/Type/Php/ImplodeFunctionReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use PhpParser\Node\Expr\FuncCall;
use PHPStan\Analyser\Scope;
use PHPStan\Internal\CombinationsHelper;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Type\Accessory\AccessoryLiteralStringType;
use PHPStan\Type\Accessory\AccessoryLowercaseStringType;
Expand All @@ -12,7 +13,6 @@
use PHPStan\Type\Accessory\AccessoryUppercaseStringType;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\ConstantScalarType;
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\StringType;
Expand Down Expand Up @@ -115,13 +115,17 @@ private function inferConstantType(ConstantArrayType $arrayType, ConstantStringT

$arrayValues = [];
foreach ($valueTypes as $valueType) {
if (!$valueType instanceof ConstantScalarType) {
$constScalars = $valueType->getConstantScalarValues();
if (count($constScalars) === 0) {
return null;
}
$arrayValues[] = $valueType->getValue();
$arrayValues[] = $constScalars;
}

$strings[] = new ConstantStringType(implode($separatorType->getValue(), $arrayValues));
$combinations = CombinationsHelper::combinations($arrayValues);
foreach ($combinations as $combination) {
$strings[] = new ConstantStringType(implode($separatorType->getValue(), $combination));
}
}

return TypeCombinator::union(...$strings);
Expand Down
25 changes: 25 additions & 0 deletions tests/PHPStan/Analyser/nsrt/implode.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,29 @@ public function constants() {
assertType("'x,345'", join(',', [self::X, '345']));
assertType("'1,345'", join(',', [self::ONE, '345']));
}

/** @param array{0: 1|2, 1: 'a'|'b'} $constArr */
public function constArrays($constArr) {
assertType("'1a'|'1b'|'2a'|'2b'", implode('', $constArr));
}

/** @param array{0: 1|2|3, 1: 'a'|'b'|'c'} $constArr */
public function constArrays2($constArr) {
assertType("'1a'|'1b'|'1c'|'2a'|'2b'|'2c'|'3a'|'3b'|'3c'", implode('', $constArr));
}

/** @param array{0: 1, 1: 'a'|'b', 2: 'x'|'y'} $constArr */
public function constArrays3($constArr) {
assertType("'1ax'|'1ay'|'1bx'|'1by'", implode('', $constArr));
}

/** @param array{0: 1, 1: 'a'|'b', 2?: 'x'|'y'} $constArr */
public function constArrays4($constArr) {
assertType("'1a'|'1ax'|'1ay'|'1b'|'1bx'|'1by'", implode('', $constArr));
}

/** @param array{10: 1|2|3, xy: 'a'|'b'|'c'} $constArr */
public function constArrays5($constArr) {
assertType("'1a'|'1b'|'1c'|'2a'|'2b'|'2c'|'3a'|'3b'|'3c'", implode('', $constArr));
}
}

0 comments on commit f7e6e74

Please sign in to comment.