From a24da7e0bd5b4d3b6a9cbb238dc6c84670da7138 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 27 Mar 2022 21:05:56 +0200 Subject: [PATCH] infer non-empty-string on substr() comparison with constant string infer non-empty-string on substr() comparison with constant string try reducing unnecessary work cs --- src/Analyser/TypeSpecifier.php | 21 +++++++ .../Analyser/NodeScopeResolverTest.php | 1 + .../non-empty-string-substr-specifying.php | 63 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 tests/PHPStan/Analyser/data/non-empty-string-substr-specifying.php diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index 6221164a741..56a5ce36d37 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -242,6 +242,27 @@ public function specifyTypesInCondition( } } } + + if ( + $exprNode instanceof FuncCall + && $exprNode->name instanceof Name + && strtolower($exprNode->name->toString()) === 'substr' + && isset($exprNode->getArgs()[0]) + && $constantType instanceof ConstantStringType + && $constantType->getValue() !== '' + ) { + $argType = $scope->getType($exprNode->getArgs()[0]->value); + + if ($argType->isString()->yes() && !$argType->isNonEmptyString()->yes()) { + return $this->create( + $exprNode->getArgs()[0]->value, + TypeCombinator::intersect($argType, new AccessoryNonEmptyStringType()), + $context, + false, + $scope, + ); + } + } } $rightType = $scope->getType($expr->right); diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index b5f4d49854d..06795798a9c 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -911,6 +911,7 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/constant-array-type-identical.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/non-empty-string-str-containing-fns.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6609.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/non-empty-string-substr-specifying.php'); } /** diff --git a/tests/PHPStan/Analyser/data/non-empty-string-substr-specifying.php b/tests/PHPStan/Analyser/data/non-empty-string-substr-specifying.php new file mode 100644 index 00000000000..d6bf60cb279 --- /dev/null +++ b/tests/PHPStan/Analyser/data/non-empty-string-substr-specifying.php @@ -0,0 +1,63 @@ +