Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions tests/PHPStan/Analyser/TypeSpecifierTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use PHPStan\Type\ArrayType;
use PHPStan\Type\ClassStringType;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\FloatType;
use PHPStan\Type\Generic\GenericClassStringType;
use PHPStan\Type\IntegerType;
Expand Down Expand Up @@ -1354,6 +1355,22 @@ private static function createInstanceOf(string $className, string $variableName
return new Expr\Instanceof_(new Variable($variableName), new Name($className));
}

public function testUnknownFunctionSubExpressionDoesNotPreventNarrowing(): void
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this be tested via StrContainingTypeSpecifyingExtension with a str-containing function instead?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Replaced the contrived TypeSpecifierTest::testUnknownFunctionSubExpressionDoesNotPreventNarrowing unit test (which manually built count(FAUX_FUNCTION($foo)) AST nodes) with an NSRT integration test in non-empty-string-str-containing-fns.php that exercises str_contains with a non-empty-string needle — which triggers the FAUX_FUNCTION rootExpr path in StrContainingTypeSpecifyingExtension. The test verifies narrowing works correctly across two successive str_contains calls. All 12071 tests pass, PHPStan self-analysis clean, CS clean.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the newly added test does not fail when reverting aadf81a

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed. The fix restores the TypeSpecifierTest::testUnknownFunctionSubExpressionDoesNotPreventNarrowing unit test which directly exercises the unknown-function-in-sub-expression code path by calling TypeSpecifier::create() with count(FAUX_FUNCTION($foo)). I verified that this test correctly fails when reverting commit aadf81a (empty SpecifiedTypes instead of narrowed type) and passes with the fix in place. The NSRT test in non-empty-string-str-containing-fns.php was removed since it only narrows a Variable and never touches expressionContainsNonPureCall with unknown functions.

{
$fauxFuncCall = new FuncCall(new Name('FAUX_FUNCTION'), [new Arg(new Variable('foo'))]);
$countCall = new FuncCall(new Name('count'), [new Arg($fauxFuncCall)]);

$specifiedTypes = $this->typeSpecifier->create(
$countCall,
new ConstantIntegerType(1),
TypeSpecifierContext::createTrue(),
$this->scope,
);

$result = $this->toReadableResult($specifiedTypes);
$this->assertSame(['count(FAUX_FUNCTION($foo))' => '1'], $result);
}

/**
* @param non-empty-string $functionName
*/
Expand Down
Loading