Skip to content

Commit

Permalink
Fixed expression assignment throwing away native expression types for…
Browse files Browse the repository at this point in the history
… treatPhpDocTypesAsCertain: false
  • Loading branch information
ondrejmirtes committed Nov 22, 2020
1 parent b01c6c9 commit 64da8f9
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -3171,6 +3171,7 @@ public function invalidateExpression(Expr $expressionToInvalidate, bool $require
{
$exprStringToInvalidate = $this->getNodeKey($expressionToInvalidate);
$moreSpecificTypeHolders = $this->moreSpecificTypes;
$nativeExpressionTypes = $this->nativeExpressionTypes;
foreach (array_keys($moreSpecificTypeHolders) as $exprString) {
$exprString = (string) $exprString;
if (Strings::startsWith($exprString, $exprStringToInvalidate)) {
Expand All @@ -3180,6 +3181,7 @@ public function invalidateExpression(Expr $expressionToInvalidate, bool $require
$nextLetter = substr($exprString, strlen($exprStringToInvalidate), 1);
if (Strings::match($nextLetter, '#[a-zA-Z_0-9\x7f-\xff]#') === null) {
unset($moreSpecificTypeHolders[$exprString]);
unset($nativeExpressionTypes[$exprString]);
continue;
}
}
Expand All @@ -3195,6 +3197,7 @@ public function invalidateExpression(Expr $expressionToInvalidate, bool $require
}

unset($moreSpecificTypeHolders[$exprString]);
unset($nativeExpressionTypes[$exprString]);
}

return $this->scopeFactory->create(
Expand All @@ -3209,7 +3212,7 @@ public function invalidateExpression(Expr $expressionToInvalidate, bool $require
$this->anonymousFunctionReflection,
$this->inFirstLevelStatement,
$this->currentlyAssignedExpressions,
[],
$nativeExpressionTypes,
[],
$this->afterExtractCall,
$this->parentScope
Expand Down Expand Up @@ -3993,6 +3996,10 @@ public function debug(): array
$key = sprintf('const %s', $name);
$descriptions[$key] = $type->describe(VerbosityLevel::precise());
}
foreach ($this->nativeExpressionTypes as $exprString => $nativeType) {
$key = sprintf('native %s', $exprString);
$descriptions[$key] = $nativeType->describe(VerbosityLevel::precise());
}

return $descriptions;
}
Expand Down
6 changes: 6 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10352,6 +10352,11 @@ public function dataBug4099(): array
return $this->gatherAssertTypes(__DIR__ . '/data/bug-4099.php');
}

public function dataBug3760(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/bug-3760.php');
}

/**
* @param string $file
* @return array<string, mixed[]>
Expand Down Expand Up @@ -10535,6 +10540,7 @@ private function gatherAssertTypes(string $file): array
* @dataProvider dataBug3880
* @dataProvider dataIncDecInConditions
* @dataProvider dataBug4099
* @dataProvider dataBug3760
* @param string $assertType
* @param string $file
* @param mixed ...$args
Expand Down
47 changes: 47 additions & 0 deletions tests/PHPStan/Analyser/data/bug-3760.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types = 1);

namespace Bug3760;

use function PHPStan\Analyser\assertNativeType;
use function PHPStan\Analyser\assertType;

class HelloWorld
{
/**
* Whether the type allows covariant matches
*
* @var bool
*/
public $allowsCovariance;

/**
* Whether the type allows contravariant matches
*
* @var bool
*/
public $allowsContravariance;

/**
* @param bool $allowsCovariance
* @param bool $allowsContravariance
*/
protected function __construct($allowsCovariance, $allowsContravariance)
{
assertType('bool', $allowsCovariance);
assertNativeType('mixed', $allowsCovariance);
assertType('bool', $allowsContravariance);
assertNativeType('mixed', $allowsContravariance);
$this->allowsCovariance = (bool)$allowsCovariance;

assertType('bool', $allowsCovariance);
assertNativeType('mixed', $allowsCovariance);
assertType('bool', $allowsContravariance);
assertNativeType('mixed', $allowsContravariance);
$this->allowsContravariance = (bool)$allowsContravariance;

assertType('bool', $allowsCovariance);
assertNativeType('mixed', $allowsCovariance);
assertType('bool', $allowsContravariance);
assertNativeType('mixed', $allowsContravariance);
}
}

0 comments on commit 64da8f9

Please sign in to comment.