Skip to content

Commit

Permalink
Detect parameter type widening violation before PHP 7.2
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Nov 13, 2020
1 parent 3616400 commit 456f443
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Php/PhpVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,9 @@ public function supportsPromotedProperties(): bool
return $this->versionId >= 80000;
}

public function supportsParameterTypeWidening(): bool
{
return $this->versionId >= 70200;
}

}
18 changes: 18 additions & 0 deletions src/Rules/Methods/OverridingMethodRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,24 @@ public function processNode(Node $node, Scope $scope): array
}

$prototypeParameterType = $prototypeParameter->getNativeType();
if (!$this->phpVersion->supportsParameterTypeWidening()) {
if (!$methodParameterType->equals($prototypeParameterType)) {
$messages[] = RuleErrorBuilder::message(sprintf(
'Parameter #%d $%s (%s) of method %s::%s() does not match parameter #%d $%s (%s) of method %s::%s().',
$i + 1,
$methodParameter->getName(),
$methodParameterType->describe(VerbosityLevel::typeOnly()),
$method->getDeclaringClass()->getDisplayName(),
$method->getName(),
$i + 1,
$prototypeParameter->getName(),
$prototypeParameterType->describe(VerbosityLevel::typeOnly()),
$prototype->getDeclaringClass()->getDisplayName(),
$prototype->getName()
))->nonIgnorable()->build();
}
continue;
}

if ($this->isTypeCompatible($methodParameterType, $prototypeParameterType, $this->phpVersion->supportsParameterContravariance())) {
continue;
Expand Down
33 changes: 33 additions & 0 deletions tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -460,4 +460,37 @@ public function testLessOverridenParametersWithVariadic(int $phpVersionId, array
$this->analyse([__DIR__ . '/data/less-parameters-variadics.php'], $errors);
}

public function dataParameterTypeWidening(): array
{
return [
[
70100,
[
[
'Parameter #1 $foo (mixed) of method ParameterTypeWidening\Bar::doFoo() does not match parameter #1 $foo (string) of method ParameterTypeWidening\Foo::doFoo().',
18,
],
],
],
[
70200,
[],
],
];
}

/**
* @dataProvider dataParameterTypeWidening
* @param int $phpVersionId
* @param mixed[] $errors
*/
public function testParameterTypeWidening(int $phpVersionId, array $errors): void
{
if (!self::$useStaticReflectionProvider) {
$this->markTestSkipped('Test requires static reflection.');
}
$this->phpVersionId = $phpVersionId;
$this->analyse([__DIR__ . '/data/parameter-type-widening.php'], $errors);
}

}
23 changes: 23 additions & 0 deletions tests/PHPStan/Rules/Methods/data/parameter-type-widening.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace ParameterTypeWidening;

class Foo
{

public function doFoo(string $foo): void
{

}

}

class Bar extends Foo
{

public function doFoo($foo): void
{

}

}

0 comments on commit 456f443

Please sign in to comment.