nodeTypeResolver = $nodeTypeResolver; $this->typeUnwrapper = $typeUnwrapper; $this->staticTypeAnalyzer = $staticTypeAnalyzer; $this->nodeFactory = $nodeFactory; } public function boolCastOrNullCompareIfNeeded(Expr $expr) : Expr { $exprStaticType = $this->nodeTypeResolver->getType($expr); if (!TypeCombinator::containsNull($exprStaticType)) { if (!$this->isBoolCastNeeded($expr, $exprStaticType)) { return $expr; } return new Bool_($expr); } // if we remove null type, still has to be trueable if ($exprStaticType instanceof UnionType) { $unionTypeWithoutNullType = $this->typeUnwrapper->removeNullTypeFromUnionType($exprStaticType); if ($this->staticTypeAnalyzer->isAlwaysTruableType($unionTypeWithoutNullType)) { return new NotIdentical($expr, $this->nodeFactory->createNull()); } } elseif ($this->staticTypeAnalyzer->isAlwaysTruableType($exprStaticType)) { return new NotIdentical($expr, $this->nodeFactory->createNull()); } if (!$this->isBoolCastNeeded($expr, $exprStaticType)) { return $expr; } return new Bool_($expr); } private function isBoolCastNeeded(Expr $expr, Type $exprType) : bool { if ($expr instanceof BooleanNot) { return \false; } if ($exprType->isBoolean()->yes()) { return \false; } return !$expr instanceof BinaryOp; } }