Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jun 6, 2020
1 parent 414784c commit 41ab4a7
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 22 deletions.
6 changes: 3 additions & 3 deletions src/Reflection/Native/NativeMethodReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class NativeMethodReflection implements MethodReflection

private BuiltinMethodReflection $reflection;

/** @var \PHPStan\Reflection\ParametersAcceptor[] */
/** @var \PHPStan\Reflection\ParametersAcceptorWithPhpDocs[] */
private array $variants;

private TrinaryLogic $hasSideEffects;
Expand All @@ -31,7 +31,7 @@ class NativeMethodReflection implements MethodReflection
* @param \PHPStan\Reflection\ReflectionProvider $reflectionProvider
* @param \PHPStan\Reflection\ClassReflection $declaringClass
* @param BuiltinMethodReflection $reflection
* @param \PHPStan\Reflection\ParametersAcceptor[] $variants
* @param \PHPStan\Reflection\ParametersAcceptorWithPhpDocs[] $variants
* @param TrinaryLogic $hasSideEffects
* @param string|null $stubPhpDocString
*/
Expand Down Expand Up @@ -104,7 +104,7 @@ public function getName(): string
}

/**
* @return \PHPStan\Reflection\ParametersAcceptor[]
* @return \PHPStan\Reflection\ParametersAcceptorWithPhpDocs[]
*/
public function getVariants(): array
{
Expand Down
118 changes: 118 additions & 0 deletions src/Reflection/Native/NativeParameterWithPhpDocsReflection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php declare(strict_types = 1);

namespace PHPStan\Reflection\Native;

use PHPStan\Reflection\ParameterReflectionWithPhpDocs;
use PHPStan\Reflection\PassedByReference;
use PHPStan\Type\ArrayType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\Type;

class NativeParameterWithPhpDocsReflection implements ParameterReflectionWithPhpDocs
{

private string $name;

private bool $optional;

private \PHPStan\Type\Type $type;

private \PHPStan\Type\Type $phpDocType;

private \PHPStan\Type\Type $nativeType;

private \PHPStan\Reflection\PassedByReference $passedByReference;

private bool $variadic;

private ?\PHPStan\Type\Type $defaultValue;

private bool $variadicParameterAlreadyExpanded;

public function __construct(
string $name,
bool $optional,
Type $type,
Type $phpDocType,
Type $nativeType,
PassedByReference $passedByReference,
bool $variadic,
?Type $defaultValue,
bool $variadicParameterAlreadyExpanded = false
)
{
$this->name = $name;
$this->optional = $optional;
$this->type = $type;
$this->phpDocType = $phpDocType;
$this->nativeType = $nativeType;
$this->passedByReference = $passedByReference;
$this->variadic = $variadic;
$this->defaultValue = $defaultValue;
$this->variadicParameterAlreadyExpanded = $variadicParameterAlreadyExpanded;
}

public function getName(): string
{
return $this->name;
}

public function isOptional(): bool
{
return $this->optional;
}

public function getType(): Type
{
$type = $this->type;
if ($this->variadic && !$this->variadicParameterAlreadyExpanded) {
$type = new ArrayType(new IntegerType(), $type);
}

return $type;
}

public function getPhpDocType(): Type
{
return $this->phpDocType;
}

public function getNativeType(): Type
{
return $this->nativeType;
}

public function passedByReference(): PassedByReference
{
return $this->passedByReference;
}

public function isVariadic(): bool
{
return $this->variadic;
}

public function getDefaultValue(): ?Type
{
return $this->defaultValue;
}

/**
* @param mixed[] $properties
* @return self
*/
public static function __set_state(array $properties): self
{
return new self(
$properties['name'],
$properties['optional'],
$properties['type'],
$properties['phpDocType'],
$properties['nativeType'],
$properties['passedByReference'],
$properties['variadic'],
$properties['defaultValue']
);
}

}
16 changes: 10 additions & 6 deletions src/Reflection/Php/PhpClassReflectionExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
use PHPStan\Reflection\Annotations\AnnotationsMethodsClassReflectionExtension;
use PHPStan\Reflection\Annotations\AnnotationsPropertiesClassReflectionExtension;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\FunctionVariant;
use PHPStan\Reflection\FunctionVariantWithPhpDocs;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\MethodsClassReflectionExtension;
use PHPStan\Reflection\Native\NativeMethodReflection;
use PHPStan\Reflection\Native\NativeParameterReflection;
use PHPStan\Reflection\Native\NativeParameterWithPhpDocsReflection;
use PHPStan\Reflection\PropertiesClassReflectionExtension;
use PHPStan\Reflection\PropertyReflection;
use PHPStan\Reflection\ReflectionProvider;
Expand Down Expand Up @@ -444,22 +444,26 @@ private function createMethod(
}
}
}
$variants[] = new FunctionVariant(
$variants[] = new FunctionVariantWithPhpDocs(
TemplateTypeMap::createEmpty(),
null,
array_map(static function (ParameterSignature $parameterSignature) use ($stubPhpDocParameterTypes, $stubPhpDocParameterVariadicity): NativeParameterReflection {
return new NativeParameterReflection(
array_map(static function (ParameterSignature $parameterSignature) use ($stubPhpDocParameterTypes, $stubPhpDocParameterVariadicity): NativeParameterWithPhpDocsReflection {
return new NativeParameterWithPhpDocsReflection(
$parameterSignature->getName(),
$parameterSignature->isOptional(),
$stubPhpDocParameterTypes[$parameterSignature->getName()] ?? $parameterSignature->getType(),
$stubPhpDocParameterTypes[$parameterSignature->getName()] ?? new MixedType(),
new MixedType(true), // todo
$parameterSignature->passedByReference(),
$stubPhpDocParameterVariadicity[$parameterSignature->getName()] ?? $parameterSignature->isVariadic(),
null,
isset($stubPhpDocParameterTypes[$parameterSignature->getName()])
);
}, $methodSignature->getParameters()),
$methodSignature->isVariadic(),
$phpDocReturnType ?? $methodSignature->getReturnType()
$phpDocReturnType ?? $methodSignature->getReturnType(),
$phpDocReturnType ?? new MixedType(),
new MixedType(true) // todo $methodSignature->getNativeReturnType()
);
}

Expand Down
19 changes: 8 additions & 11 deletions src/Rules/Methods/OverridingMethodRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
use PHPStan\Php\PhpVersion;
use PHPStan\Reflection\FunctionVariantWithPhpDocs;
use PHPStan\Reflection\MethodPrototypeReflection;
use PHPStan\Reflection\Native\NativeParameterReflection;
use PHPStan\Reflection\ParameterReflectionWithPhpDocs;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Reflection\Php\PhpMethodFromParserNodeReflection;
use PHPStan\Reflection\Php\PhpParameterReflection;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Type\ArrayType;
Expand Down Expand Up @@ -212,14 +211,12 @@ public function processNode(Node $node, Scope $scope): array

$methodParameterType = $methodParameter->getNativeType();

if ($prototypeParameter instanceof PhpParameterReflection) {
$prototypeParameterType = $prototypeParameter->getNativeType();
} elseif ($prototypeParameter instanceof NativeParameterReflection) {
$prototypeParameterType = $prototypeParameter->getType();
} else {
if (!$prototypeParameter instanceof ParameterReflectionWithPhpDocs) {
continue;
}

$prototypeParameterType = $prototypeParameter->getNativeType();

if ($this->isTypeCompatible($methodParameterType, $prototypeParameterType, $this->phpVersion->supportsParameterContravariance())) {
continue;
}
Expand Down Expand Up @@ -279,12 +276,12 @@ public function processNode(Node $node, Scope $scope): array

$methodReturnType = $methodVariant->getNativeReturnType();

if ($prototypeVariant instanceof FunctionVariantWithPhpDocs) {
$prototypeReturnType = $prototypeVariant->getNativeReturnType();
} else {
$prototypeReturnType = $prototypeVariant->getReturnType();
if (!$prototypeVariant instanceof FunctionVariantWithPhpDocs) {
return $messages;
}

$prototypeReturnType = $prototypeVariant->getNativeReturnType();

if (!$this->isTypeCompatible($prototypeReturnType, $methodReturnType, $this->phpVersion->supportsReturnCovariance())) {
if ($this->phpVersion->supportsReturnCovariance()) {
$messages[] = RuleErrorBuilder::message(sprintf(
Expand Down
2 changes: 1 addition & 1 deletion tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function testOverridingFinalMethod(int $phpVersion, string $message): voi
115,
],
[
'Parameter #1 $size (string) of method OverridingFinalMethod\FixedArray::setSize() is not ' . $message . ' with parameter #1 $size (int) of method SplFixedArray::setSize().',
'Parameter #1 $size (int) of method OverridingFinalMethod\FixedArray::setSize() is not ' . $message . ' with parameter #1 $size (mixed) of method SplFixedArray::setSize().',
125,
],
[
Expand Down
17 changes: 16 additions & 1 deletion tests/PHPStan/Rules/Methods/data/overriding-method.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public function doFoo()
class FixedArray extends \SplFixedArray
{

public function setSize(string $size): bool
public function setSize(int $size): bool
{

}
Expand Down Expand Up @@ -238,3 +238,18 @@ public function doFoo(int $i, int $j = null)
}

}

/**
* @implements \IteratorAggregate<int, Foo>
*/
class SomeIterator implements \IteratorAggregate
{
/**
* @return \Traversable<int, Foo>
*/
public function getIterator()
{
yield new Foo;
}

}

0 comments on commit 41ab4a7

Please sign in to comment.