Skip to content

Commit

Permalink
Check just one callable parameter variant (#293)
Browse files Browse the repository at this point in the history
As suggested in #288 (comment)

Close #288
  • Loading branch information
spaze authored Jan 23, 2025
2 parents 676796f + b4174ee commit eb3841e
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 4 deletions.
10 changes: 6 additions & 4 deletions src/RuleErrors/DisallowedCallableParameterRuleErrors.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ExtendedMethodReflection;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\IdentifierRuleError;
use PHPStan\ShouldNotHappenException;
Expand Down Expand Up @@ -171,10 +170,13 @@ public function getForMethods($class, array $names, CallLike $node, Scope $scope
*/
private function getErrors(CallLike $node, Scope $scope, $reflection): array
{
$variants = $reflection->getVariants();
if (count($variants) !== 1) {
return [];
}
$ruleErrors = [];
$parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $reflection->getVariants());
$reorderedArgs = ArgumentsNormalizer::reorderArgs($parametersAcceptor, $node->getArgs()) ?? $node->getArgs();
foreach ($parametersAcceptor->getParameters() as $key => $parameter) {
$reorderedArgs = ArgumentsNormalizer::reorderArgs($variants[0], $node->getArgs()) ?? $node->getArgs();
foreach ($variants[0]->getParameters() as $key => $parameter) {
if (!TypeCombinator::removeNull($parameter->getType())->isCallable()->yes() || !isset($reorderedArgs[$key])) {
continue;
}
Expand Down
61 changes: 61 additions & 0 deletions tests/Bugs/Bug288DocblockTemplateCallableParamTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
declare(strict_types = 1);

namespace Spaze\PHPStan\Rules\Disallowed\Calls;

use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\Rule;
use PHPStan\ShouldNotHappenException;
use PHPStan\Testing\RuleTestCase;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
use Spaze\PHPStan\Rules\Disallowed\RuleErrors\DisallowedCallableParameterRuleErrors;
use Spaze\PHPStan\Rules\Disallowed\RuleErrors\DisallowedFunctionRuleErrors;
use Spaze\PHPStan\Rules\Disallowed\RuleErrors\DisallowedMethodRuleErrors;
use Spaze\PHPStan\Rules\Disallowed\Type\TypeResolver;

class Bug288DocblockTemplateCallableParamTest extends RuleTestCase
{

/**
* @throws ShouldNotHappenException
*/
protected function getRule(): Rule
{
$container = self::getContainer();
$disallowedCallableParameterRuleErrors = new DisallowedCallableParameterRuleErrors(
$container->getByType(TypeResolver::class),
$container->getByType(DisallowedFunctionRuleErrors::class),
$container->getByType(DisallowedMethodRuleErrors::class),
$container->getByType(DisallowedCallFactory::class),
$container->getByType(ReflectionProvider::class),
[
[
'function' => 'disallowedFunction()',
],
],
[],
[],
);
return new MethodCalls(
$container->getByType(DisallowedMethodRuleErrors::class),
$disallowedCallableParameterRuleErrors,
$container->getByType(DisallowedCallFactory::class),
[],
);
}


public function testRule(): void
{
$this->analyse([__DIR__ . '/../src/bugs/Bug288DocblockTemplateCallableParam.php'], []);
}


public static function getAdditionalConfigFiles(): array
{
return [
__DIR__ . '/../../extension.neon',
];
}

}
28 changes: 28 additions & 0 deletions tests/src/bugs/Bug288DocblockTemplateCallableParam.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
declare(strict_types = 1);

function disallowedFunction()
{
}

class Bug288DocblockTemplateCallableParam
{

public function testItDoesNothing(): void
{
// the $expected param here is a string param, not a callable param, no error should be reported here
$this->assertSame('disallowedFunction', 'whatever');
}

/**
* A copy of PHPUnit\Framework\Assert::assertSame()'s docblock
*
* @template ExpectedType
* @param ExpectedType $expected
* @phpstan-assert =ExpectedType $actual
*/
public function assertSame(mixed $expected, mixed $actual, string $message = ''): void
{
}

}

0 comments on commit eb3841e

Please sign in to comment.