Skip to content

Commit

Permalink
Merge branch refs/heads/1.10.x into 1.11.x
Browse files Browse the repository at this point in the history
  • Loading branch information
phpstan-bot committed Nov 5, 2023
2 parents a894ee6 + c6b09fb commit 990b06f
Show file tree
Hide file tree
Showing 25 changed files with 90 additions and 893 deletions.
7 changes: 0 additions & 7 deletions src/Analyser/EnsuredNonNullabilityResultExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace PHPStan\Analyser;

use PhpParser\Node\Expr;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Type;

class EnsuredNonNullabilityResultExpression
Expand All @@ -13,7 +12,6 @@ public function __construct(
private Expr $expression,
private Type $originalType,
private Type $originalNativeType,
private TrinaryLogic $certainty,
)
{
}
Expand All @@ -33,9 +31,4 @@ public function getOriginalNativeType(): Type
return $this->originalNativeType;
}

public function getCertainty(): TrinaryLogic
{
return $this->certainty;
}

}
49 changes: 15 additions & 34 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -2341,10 +2341,6 @@ public function isSpecified(Expr $node): bool
/** @api */
public function hasExpressionType(Expr $node): TrinaryLogic
{
if ($node instanceof Variable && is_string($node->name)) {
return $this->hasVariableType($node->name);
}

$exprString = $this->getNodeKey($node);
if (!isset($this->expressionTypes[$exprString])) {
return TrinaryLogic::createNo();
Expand Down Expand Up @@ -3437,7 +3433,7 @@ public function unsetExpression(Expr $expr): self
return $scope->invalidateExpression($expr);
}

public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType, ?TrinaryLogic $certainty = null): self
public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType): self
{
if ($expr instanceof ConstFetch) {
$loweredConstName = strtolower($expr->name->toString());
Expand Down Expand Up @@ -3471,31 +3467,23 @@ public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType,
if ($dimType instanceof ConstantIntegerType) {
$types[] = new StringType();
}

$scope = $scope->specifyExpressionType(
$expr->var,
TypeCombinator::intersect(
TypeCombinator::intersect($exprVarType, TypeCombinator::union(...$types)),
new HasOffsetValueType($dimType, $type),
),
$scope->getNativeType($expr->var),
$certainty,
);
}
}
}

if ($certainty === null) {
$certainty = TrinaryLogic::createYes();
} elseif ($certainty->no()) {
throw new ShouldNotHappenException();
}

$exprString = $this->getNodeKey($expr);
$expressionTypes = $scope->expressionTypes;
$expressionTypes[$exprString] = new ExpressionTypeHolder($expr, $type, $certainty);
$expressionTypes[$exprString] = ExpressionTypeHolder::createYes($expr, $type);
$nativeTypes = $scope->nativeExpressionTypes;
$nativeTypes[$exprString] = new ExpressionTypeHolder($expr, $nativeType, $certainty);
$nativeTypes[$exprString] = ExpressionTypeHolder::createYes($expr, $nativeType);

return $this->scopeFactory->create(
$this->context,
Expand Down Expand Up @@ -3833,7 +3821,6 @@ public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self
$specifiedExpressions[$this->getNodeKey($expr)] = ExpressionTypeHolder::createYes($expr, $scope->getType($expr));
}

$conditions = [];
foreach ($scope->conditionalExpressions as $conditionalExprString => $conditionalExpressions) {
foreach ($conditionalExpressions as $conditionalExpression) {
foreach ($conditionalExpression->getConditionExpressionTypeHolders() as $holderExprString => $conditionalTypeHolder) {
Expand All @@ -3842,24 +3829,18 @@ public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self
}
}

$conditions[$conditionalExprString][] = $conditionalExpression;
$specifiedExpressions[$conditionalExprString] = $conditionalExpression->getTypeHolder();
}
}

foreach ($conditions as $conditionalExprString => $expressions) {
$certainty = TrinaryLogic::lazyExtremeIdentity($expressions, static fn (ConditionalExpressionHolder $holder) => $holder->getTypeHolder()->getCertainty());
$type = TypeCombinator::union(...array_map(static fn (ConditionalExpressionHolder $holder) => $holder->getTypeHolder()->getType(), $expressions));
if ($certainty->no()) {
unset($scope->expressionTypes[$conditionalExprString]);
} else {
$scope->expressionTypes[$conditionalExprString] = array_key_exists($conditionalExprString, $scope->expressionTypes)
? new ExpressionTypeHolder(
$scope->expressionTypes[$conditionalExprString]->getExpr(),
TypeCombinator::intersect($scope->expressionTypes[$conditionalExprString]->getType(), $type),
TrinaryLogic::maxMin($scope->expressionTypes[$conditionalExprString]->getCertainty(), $certainty),
)
: $expressions[0]->getTypeHolder();
if ($conditionalExpression->getTypeHolder()->getCertainty()->no()) {
unset($scope->expressionTypes[$conditionalExprString]);
} else {
$scope->expressionTypes[$conditionalExprString] = array_key_exists($conditionalExprString, $scope->expressionTypes)
? new ExpressionTypeHolder(
$scope->expressionTypes[$conditionalExprString]->getExpr(),
TypeCombinator::intersect($scope->expressionTypes[$conditionalExprString]->getType(), $conditionalExpression->getTypeHolder()->getType()),
TrinaryLogic::maxMin($scope->expressionTypes[$conditionalExprString]->getCertainty(), $conditionalExpression->getTypeHolder()->getCertainty()),
)
: $conditionalExpression->getTypeHolder();
$specifiedExpressions[$conditionalExprString] = $conditionalExpression->getTypeHolder();
}
}
}

Expand Down
37 changes: 5 additions & 32 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -1753,22 +1753,14 @@ private function ensureShallowNonNullability(MutatingScope $scope, Scope $origin
if ($isNull->yes()) {
return new EnsuredNonNullabilityResult($scope, []);
}

// keep certainty
$certainty = TrinaryLogic::createYes();
$hasExpressionType = $originalScope->hasExpressionType($exprToSpecify);
if (!$hasExpressionType->no()) {
$certainty = $hasExpressionType;
}

$exprTypeWithoutNull = TypeCombinator::removeNull($exprType);
if ($exprType->equals($exprTypeWithoutNull)) {
$originalExprType = $originalScope->getType($exprToSpecify);
if (!$originalExprType->equals($exprTypeWithoutNull)) {
$originalNativeType = $originalScope->getNativeType($exprToSpecify);

return new EnsuredNonNullabilityResult($scope, [
new EnsuredNonNullabilityResultExpression($exprToSpecify, $originalExprType, $originalNativeType, $certainty),
new EnsuredNonNullabilityResultExpression($exprToSpecify, $originalExprType, $originalNativeType),
]);
}
return new EnsuredNonNullabilityResult($scope, []);
Expand All @@ -1784,7 +1776,7 @@ private function ensureShallowNonNullability(MutatingScope $scope, Scope $origin
return new EnsuredNonNullabilityResult(
$scope,
[
new EnsuredNonNullabilityResultExpression($exprToSpecify, $exprType, $nativeType, $certainty),
new EnsuredNonNullabilityResultExpression($exprToSpecify, $exprType, $nativeType),
],
);
}
Expand Down Expand Up @@ -1814,7 +1806,6 @@ private function revertNonNullability(MutatingScope $scope, array $specifiedExpr
$specifiedExpressionResult->getExpression(),
$specifiedExpressionResult->getOriginalType(),
$specifiedExpressionResult->getOriginalNativeType(),
$specifiedExpressionResult->getCertainty(),
);
}

Expand Down Expand Up @@ -3740,30 +3731,11 @@ private function processAssignVar(
$throwPoints = $result->getThrowPoints();
$assignedExpr = $this->unwrapAssign($assignedExpr);
$type = $scope->getType($assignedExpr);

$conditionalExpressions = [];
if ($assignedExpr instanceof Ternary) {
$if = $assignedExpr->if;
if ($if === null) {
$if = $assignedExpr->cond;
}
$condScope = $this->processExprNode($assignedExpr->cond, $scope, static function (): void {
}, ExpressionContext::createDeep())->getScope();
$truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($condScope, $assignedExpr->cond, TypeSpecifierContext::createTruthy());
$falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($condScope, $assignedExpr->cond, TypeSpecifierContext::createFalsey());
$truthyScope = $condScope->filterBySpecifiedTypes($truthySpecifiedTypes);
$falsyScope = $condScope->filterBySpecifiedTypes($falseySpecifiedTypes);
$truthyType = $truthyScope->getType($if);
$falseyType = $falsyScope->getType($assignedExpr->else);
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
}

$truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createTruthy());
$falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createFalsey());

$conditionalExpressions = [];

$truthyType = TypeCombinator::removeFalsey($type);
$falseyType = TypeCombinator::intersect($type, StaticTypeFactory::falsey());

Expand All @@ -3772,6 +3744,7 @@ private function processAssignVar(
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);

// TODO conditional expressions for native type should be handled too
$scope = $result->getScope()->assignVariable($var->name, $type, $scope->getNativeType($assignedExpr));
foreach ($conditionalExpressions as $exprString => $holders) {
$scope = $scope->addConditionalExpressions($exprString, $holders);
Expand Down
Loading

0 comments on commit 990b06f

Please sign in to comment.