Updated Rector to commit 6d7404c65000caede512a5bc5a993f472e11cd0d

6d7404c650 Home cleaning with Exacat 😎 (#2676)
This commit is contained in:
Tomas Votruba 2022-07-18 15:25:27 +00:00
parent b8d580b548
commit c855f5df1c
59 changed files with 210 additions and 318 deletions

View File

@ -99,11 +99,11 @@ final class BetterPhpDocParser extends PhpDocParser
public function parseTagValue(TokenIterator $tokenIterator, string $tag) : PhpDocTagValueNode
{
$startPosition = $tokenIterator->currentPosition();
$tagValueNode = parent::parseTagValue($tokenIterator, $tag);
$phpDocTagValueNode = parent::parseTagValue($tokenIterator, $tag);
$endPosition = $tokenIterator->currentPosition();
$startAndEnd = new StartAndEnd($startPosition, $endPosition);
$tagValueNode->setAttribute(PhpDocAttributeKey::START_AND_END, $startAndEnd);
return $tagValueNode;
$phpDocTagValueNode->setAttribute(PhpDocAttributeKey::START_AND_END, $startAndEnd);
return $phpDocTagValueNode;
}
/**
* @return PhpDocTextNode|PhpDocTagNode

View File

@ -17,6 +17,7 @@ use PhpParser\Node\Stmt\Interface_;
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
@ -24,7 +25,6 @@ use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer;
use Rector\PhpAttribute\NodeFactory\PhpAttributeGroupFactory;
use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
use Rector\StaticTypeMapper\StaticTypeMapper;
use ReturnTypeWillChange;
/**
@ -60,11 +60,6 @@ final class PhpDocFromTypeDeclarationDecorator
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger
*/
private $phpDocTypeChanger;
/**
* @readonly
* @var \Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper
*/
private $typeUnwrapper;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
@ -80,13 +75,12 @@ final class PhpDocFromTypeDeclarationDecorator
* @var \Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer
*/
private $phpAttributeAnalyzer;
public function __construct(StaticTypeMapper $staticTypeMapper, PhpDocInfoFactory $phpDocInfoFactory, NodeNameResolver $nodeNameResolver, PhpDocTypeChanger $phpDocTypeChanger, TypeUnwrapper $typeUnwrapper, BetterNodeFinder $betterNodeFinder, PhpAttributeGroupFactory $phpAttributeGroupFactory, PhpAttributeAnalyzer $phpAttributeAnalyzer)
public function __construct(StaticTypeMapper $staticTypeMapper, PhpDocInfoFactory $phpDocInfoFactory, NodeNameResolver $nodeNameResolver, PhpDocTypeChanger $phpDocTypeChanger, BetterNodeFinder $betterNodeFinder, PhpAttributeGroupFactory $phpAttributeGroupFactory, PhpAttributeAnalyzer $phpAttributeAnalyzer)
{
$this->staticTypeMapper = $staticTypeMapper;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->nodeNameResolver = $nodeNameResolver;
$this->phpDocTypeChanger = $phpDocTypeChanger;
$this->typeUnwrapper = $typeUnwrapper;
$this->betterNodeFinder = $betterNodeFinder;
$this->phpAttributeGroupFactory = $phpAttributeGroupFactory;
$this->phpAttributeAnalyzer = $phpAttributeAnalyzer;
@ -192,7 +186,7 @@ final class PhpDocFromTypeDeclarationDecorator
$returnType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($typeNode);
// cover nullable union types
if ($returnType instanceof UnionType) {
$returnType = $this->typeUnwrapper->unwrapNullableType($returnType);
$returnType = TypeCombinator::removeNull($returnType);
}
if ($returnType instanceof ObjectType) {
return $returnType->equals($requireType);

View File

@ -68,9 +68,9 @@ final class PlainValueParser
}
$tokenIterator->next();
// normalize value
$constantValue = $this->matchConstantValue($currentTokenValue);
if ($constantValue !== null) {
return $constantValue;
$constExprNode = $this->matchConstantValue($currentTokenValue);
if ($constExprNode !== null) {
return $constExprNode;
}
while ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_DOUBLE_COLON) || $tokenIterator->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) {
$currentTokenValue .= $tokenIterator->currentTokenValue();

View File

@ -107,7 +107,7 @@ final class BetterTokenIterator extends TokenIterator
return $this->privatesAccessor->getPrivateProperty($this, self::INDEX);
}
/**
* @return mixed[]
* @return array<array{0: string, 1: int}>
*/
public function getTokens() : array
{
@ -118,16 +118,11 @@ final class BetterTokenIterator extends TokenIterator
return \count($this->getTokens());
}
/**
* @return mixed[]
* @return array<array{0: string, 1: int}>
*/
public function partialTokens(int $start, int $end) : array
{
$tokens = $this->getTokens();
$chunkTokens = [];
for ($i = $start; $i <= $end; ++$i) {
$chunkTokens[$i] = $tokens[$i];
}
return $chunkTokens;
return \array_slice($this->getTokens(), $start, $end);
}
public function containsTokenType(int $type) : bool
{

View File

@ -179,8 +179,8 @@ final class ArrayCallableMethodMatcher
if (!$hasConstruct) {
return new ObjectType($classConstantReference, null, $classReflection);
}
$methodReflection = $classReflection->getMethod(MethodName::CONSTRUCT, $scope);
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());
$extendedMethodReflection = $classReflection->getMethod(MethodName::CONSTRUCT, $scope);
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($extendedMethodReflection->getVariants());
foreach ($parametersAcceptor->getParameters() as $parameterReflection) {
if ($parameterReflection->getDefaultValue() === null) {
return new MixedType();

View File

@ -11,8 +11,8 @@ final class StaticAnalyzer
public function isStaticMethod(ClassReflection $classReflection, string $methodName) : bool
{
if ($classReflection->hasNativeMethod($methodName)) {
$methodReflection = $classReflection->getNativeMethod($methodName);
if ($methodReflection->isStatic()) {
$extendedMethodReflection = $classReflection->getNativeMethod($methodName);
if ($extendedMethodReflection->isStatic()) {
return \true;
}
}

View File

@ -225,9 +225,9 @@ final class UnionTypeMapper implements TypeMapperInterface
if ($this->boolUnionTypeAnalyzer->isBoolUnionType($unionType)) {
return new Name('bool');
}
$compatibleObjectType = $this->processResolveCompatibleObjectCandidates($unionType);
if ($compatibleObjectType instanceof NullableType || $compatibleObjectType instanceof FullyQualified) {
return $compatibleObjectType;
$compatibleObjectTypeNode = $this->processResolveCompatibleObjectCandidates($unionType);
if ($compatibleObjectTypeNode instanceof NullableType || $compatibleObjectTypeNode instanceof FullyQualified) {
return $compatibleObjectTypeNode;
}
return $this->processResolveCompatibleStringCandidates($unionType);
}

View File

@ -4,18 +4,10 @@ declare (strict_types=1);
namespace Rector\PHPStanStaticTypeMapper\Utils;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
final class TypeUnwrapper
{
/**
* E.g. null|ClassType ClassType
*/
public function unwrapNullableType(Type $type) : Type
{
return TypeCombinator::removeNull($type);
}
public function unwrapFirstObjectTypeFromUnionType(Type $type) : Type
{
if (!$type instanceof UnionType) {

View File

@ -149,13 +149,13 @@ final class NodesToAddCollector implements NodeCollectorInterface
if ($parent instanceof Return_) {
return \spl_object_hash($parent);
}
$foundNode = $this->betterNodeFinder->findParentType($node, Stmt::class);
if (!$foundNode instanceof Stmt) {
$foundStmt = $this->betterNodeFinder->findParentType($node, Stmt::class);
if (!$foundStmt instanceof Stmt) {
$printedNode = $this->nodePrinter->print($node);
$errorMessage = \sprintf('Could not find parent Stmt of "%s" node', $printedNode);
throw new ShouldNotHappenException($errorMessage);
}
return \spl_object_hash($foundNode);
return \spl_object_hash($foundStmt);
}
/**
* @param \PhpParser\Node\Expr|\PhpParser\Node\Stmt $node

View File

@ -45,9 +45,7 @@ final class NullableTypeNodeMapper implements PhpParserNodeMapperInterface
*/
public function mapToPHPStan(Node $node) : Type
{
$types = [];
$types[] = $this->phpParserNodeMapper->mapToPHPStanType($node->type);
$types[] = new NullType();
$types = [$this->phpParserNodeMapper->mapToPHPStanType($node->type), new NullType()];
return $this->typeFactory->createMixedPassedOrUnionType($types);
}
}

View File

@ -6,27 +6,16 @@ namespace Rector\Testing\PHPUnit\Behavior;
use Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector;
use Rector\Core\PhpParser\Printer\NodesWithFileDestinationPrinter;
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
use RectorPrefix202207\Symplify\SmartFileSystem\SmartFileInfo;
use RectorPrefix202207\Webmozart\Assert\Assert;
/**
* @property-read RemovedAndAddedFilesCollector $removedAndAddedFilesCollector
*/
trait MovingFilesTrait
{
protected function assertFileWasNotChanged(SmartFileInfo $smartFileInfo) : void
{
$hasFileInfo = $this->removedAndAddedFilesCollector->isFileRemoved($smartFileInfo);
$this->assertFalse($hasFileInfo);
}
protected function assertFileWasAdded(AddedFileWithContent $addedFileWithContent) : void
{
$this->assertFilesWereAdded([$addedFileWithContent]);
}
protected function assertFileWasRemoved(SmartFileInfo $smartFileInfo) : void
{
$isFileRemoved = $this->removedAndAddedFilesCollector->isFileRemoved($smartFileInfo);
$this->assertTrue($isFileRemoved);
}
/**
* @param AddedFileWithContent[] $expectedAddedFileWithContents
*/

View File

@ -153,8 +153,8 @@ CODE_SAMPLE
if (!$construct) {
return self::DEFAULT_EXCEPTION_ARGUMENT_POSITION;
}
$methodReflection = $classReflection->getConstructor();
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());
$extendedMethodReflection = $classReflection->getConstructor();
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($extendedMethodReflection->getVariants());
foreach ($parametersAcceptor->getParameters() as $position => $parameterReflection) {
$parameterType = $parameterReflection->getType();
if (!$parameterType instanceof TypeWithClassName) {

View File

@ -93,11 +93,11 @@ CODE_SAMPLE
if ($this->shouldSkipAsPartOfOtherLoop($foreach)) {
return \true;
}
$previousDeclaration = $this->nodeUsageFinder->findPreviousForeachNodeUsage($foreach, $assignVariable);
if (!$previousDeclaration instanceof Node) {
$node = $this->nodeUsageFinder->findPreviousForeachNodeUsage($foreach, $assignVariable);
if (!$node instanceof Node) {
return \true;
}
$previousDeclarationParentNode = $previousDeclaration->getAttribute(AttributeKey::PARENT_NODE);
$previousDeclarationParentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
if (!$previousDeclarationParentNode instanceof Assign) {
return \true;
}

View File

@ -84,11 +84,11 @@ CODE_SAMPLE
if (!$twoNodeMatch instanceof TwoNodeMatch) {
return null;
}
$comparedNode = $twoNodeMatch->getSecondExpr();
$comparedExpr = $twoNodeMatch->getSecondExpr();
if (!$this->isIfBodyABoolReturnNode($firstNodeInsideForeach)) {
return null;
}
$funcCall = $this->createInArrayFunction($comparedNode, $ifCondition, $node);
$funcCall = $this->createInArrayFunction($comparedExpr, $ifCondition, $node);
/** @var Return_ $returnToRemove */
$returnToRemove = $node->getAttribute(AttributeKey::NEXT_NODE);
/** @var Return_ $return */

View File

@ -146,9 +146,8 @@ CODE_SAMPLE
return new MixedType();
}
// set in constructor + changed in class
$propertyTypeFromConstructor = $this->resolvePropertyTypeAfterConstructor($classLike, $propertyName);
$resolvedTypes = [];
$resolvedTypes[] = $propertyTypeFromConstructor;
$propertyType = $this->resolvePropertyTypeAfterConstructor($classLike, $propertyName);
$resolvedTypes = [$propertyType];
$defaultValue = $property->props[0]->default;
if ($defaultValue !== null) {
$resolvedTypes[] = $this->getType($defaultValue);

View File

@ -64,15 +64,15 @@ final class GetClassToInstanceOfRector extends AbstractRector
}
/** @var ClassConstFetch|String_ $firstExpr */
$firstExpr = $twoNodeMatch->getFirstExpr();
/** @var FuncCall $funcCall */
$funcCall = $twoNodeMatch->getSecondExpr();
if (!isset($funcCall->args[0])) {
/** @var FuncCall $secondExpr */
$secondExpr = $twoNodeMatch->getSecondExpr();
if (!isset($secondExpr->args[0])) {
return null;
}
if (!$funcCall->args[0] instanceof Arg) {
if (!$secondExpr->args[0] instanceof Arg) {
return null;
}
$varNode = $funcCall->args[0]->value;
$varNode = $secondExpr->args[0]->value;
if ($firstExpr instanceof String_) {
$className = $this->valueResolver->getValue($firstExpr);
} else {

View File

@ -54,9 +54,9 @@ final class SimplifyArraySearchRector extends AbstractRector
if (!$twoNodeMatch instanceof TwoNodeMatch) {
return null;
}
/** @var FuncCall $arraySearchFuncCall */
$arraySearchFuncCall = $twoNodeMatch->getFirstExpr();
$inArrayFuncCall = $this->nodeFactory->createFuncCall('in_array', $arraySearchFuncCall->args);
/** @var FuncCall $funcCallExpr */
$funcCallExpr = $twoNodeMatch->getFirstExpr();
$inArrayFuncCall = $this->nodeFactory->createFuncCall('in_array', $funcCallExpr->args);
if ($node instanceof Identical) {
return new BooleanNot($inArrayFuncCall);
}

View File

@ -76,13 +76,13 @@ final class SimplifyConditionsRector extends AbstractRector
if (!$twoNodeMatch instanceof TwoNodeMatch) {
return $twoNodeMatch;
}
/** @var Identical|NotIdentical $subBinaryOp */
$subBinaryOp = $twoNodeMatch->getFirstExpr();
$otherNode = $twoNodeMatch->getSecondExpr();
if ($this->valueResolver->isFalse($otherNode)) {
return $this->createInversedBooleanOp($subBinaryOp);
/** @var Identical|NotIdentical $firstExpr */
$firstExpr = $twoNodeMatch->getFirstExpr();
$otherExpr = $twoNodeMatch->getSecondExpr();
if ($this->valueResolver->isFalse($otherExpr)) {
return $this->createInversedBooleanOp($firstExpr);
}
return $subBinaryOp;
return $firstExpr;
}
/**
* Skip too nested binary || binary > binary combinations

View File

@ -114,16 +114,16 @@ CODE_SAMPLE
if ($conditionStaticType instanceof BooleanType) {
return null;
}
$newConditionNode = $this->resolveNewConditionNode($conditionNode, $isNegated);
if (!$newConditionNode instanceof BinaryOp) {
$binaryOp = $this->resolveNewConditionNode($conditionNode, $isNegated);
if (!$binaryOp instanceof BinaryOp) {
return null;
}
$nextNode = $node->getAttribute(AttributeKey::NEXT_NODE);
// avoid duplicated ifs when combined with ChangeOrIfReturnToEarlyReturnRector
if ($this->shouldSkip($conditionStaticType, $newConditionNode, $nextNode)) {
if ($this->shouldSkip($conditionStaticType, $binaryOp, $nextNode)) {
return null;
}
$node->cond = $newConditionNode;
$node->cond = $binaryOp;
return $node;
}
private function shouldSkip(Type $conditionStaticType, BinaryOp $binaryOp, ?Node $nextNode) : bool

View File

@ -58,11 +58,11 @@ CODE_SAMPLE
if (!$nextNode instanceof Return_) {
return null;
}
$comparedNode = $this->ifManipulator->matchIfValueReturnValue($node);
if (!$comparedNode instanceof Expr) {
$expr = $this->ifManipulator->matchIfValueReturnValue($node);
if (!$expr instanceof Expr) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($comparedNode, $nextNode->expr)) {
if (!$this->nodeComparator->areNodesEqual($expr, $nextNode->expr)) {
return null;
}
$this->removeNode($nextNode);

View File

@ -54,8 +54,8 @@ CODE_SAMPLE
*/
public function refactor(Node $node) : ?Stmt
{
$comparedNode = $this->ifManipulator->matchIfNotNullReturnValue($node);
if ($comparedNode !== null) {
$expr = $this->ifManipulator->matchIfNotNullReturnValue($node);
if ($expr !== null) {
$insideIfNode = $node->stmts[0];
$nextNode = $node->getAttribute(AttributeKey::NEXT_NODE);
if (!$nextNode instanceof Return_) {

View File

@ -130,8 +130,8 @@ CODE_SAMPLE
if ($propertyName === null) {
return null;
}
$property = $callerType->getProperty($propertyName, $scope);
$propertyType = $property->getReadableType();
$propertyReflection = $callerType->getProperty($propertyName, $scope);
$propertyType = $propertyReflection->getReadableType();
$possibleGetterMethodNames = $this->resolvePossibleGetMethodNames($propertyName);
foreach ($possibleGetterMethodNames as $possibleGetterMethodName) {
if (!$callerType->hasMethod($possibleGetterMethodName)->yes()) {

View File

@ -60,12 +60,12 @@ CODE_SAMPLE
*/
public function refactor(Node $node) : ?Node
{
$expression = $this->betterNodeFinder->resolveCurrentStatement($node);
$currentStmt = $this->betterNodeFinder->resolveCurrentStatement($node);
// unable to analyze
if (!$expression instanceof Expression) {
if (!$currentStmt instanceof Expression) {
return null;
}
$nextNode = $expression->getAttribute(AttributeKey::NEXT_NODE);
$nextNode = $currentStmt->getAttribute(AttributeKey::NEXT_NODE);
if (!$nextNode instanceof Node) {
return null;
}
@ -85,11 +85,11 @@ CODE_SAMPLE
return null;
}
// switch docs
$expression->setDocComment($this->createDocComment($nextNode));
$expressionPhpDocInfo = $this->phpDocInfoFactory->createFromNode($expression);
$expression->setAttribute(AttributeKey::PHP_DOC_INFO, $expressionPhpDocInfo);
$currentStmt->setDocComment($this->createDocComment($nextNode));
$expressionPhpDocInfo = $this->phpDocInfoFactory->createFromNode($currentStmt);
$currentStmt->setAttribute(AttributeKey::PHP_DOC_INFO, $expressionPhpDocInfo);
// invoke override
$expression->setAttribute(AttributeKey::ORIGINAL_NODE, null);
$currentStmt->setAttribute(AttributeKey::ORIGINAL_NODE, null);
// remove otherwise empty node
if ($nextNode instanceof Nop) {
$this->removeNode($nextNode);

View File

@ -35,8 +35,8 @@ final class ParameterDefaultsComparator
}
/** @var Expr $paramDefault */
$paramDefault = $param->default;
$firstParameterValue = $this->defaultParameterValueResolver->resolveFromParameterReflection($parameterReflection);
return !$this->nodeComparator->areNodesEqual($paramDefault, $firstParameterValue);
$defaultValueExpr = $this->defaultParameterValueResolver->resolveFromParameterReflection($parameterReflection);
return !$this->nodeComparator->areNodesEqual($paramDefault, $defaultValueExpr);
}
private function isMutuallyExclusiveNull(ParameterReflection $parameterReflection, Param $param) : bool
{

View File

@ -252,8 +252,8 @@ final class PureFunctionDetector
if (!$hasFunction) {
return \false;
}
$function = $this->reflectionProvider->getFunction($name, $scope);
if (!$function instanceof NativeFunctionReflection) {
$functionReflection = $this->reflectionProvider->getFunction($name, $scope);
if (!$functionReflection instanceof NativeFunctionReflection) {
return \false;
}
return !$this->nodeNameResolver->isNames($funcCall, self::IMPURE_FUNCTIONS);

View File

@ -95,7 +95,7 @@ final class UselessIfCondBeforeForeachDetector
$notIdentical = $if->cond;
return $this->isMatchingNotBinaryOp($notIdentical, $foreachExpr);
}
private function fromPreviousParam(Expr $expr) : ?Node
private function fromPreviousParam(Expr $expr) : ?Param
{
return $this->betterNodeFinder->findFirstPrevious($expr, function (Node $node) use($expr) : bool {
if (!$node instanceof Param) {

View File

@ -23,14 +23,14 @@ final class ConditionInverter
{
// inverse condition
if ($expr instanceof BinaryOp) {
$inversedCondition = $this->binaryOpManipulator->invertCondition($expr);
if (!$inversedCondition instanceof BinaryOp) {
$binaryOp = $this->binaryOpManipulator->invertCondition($expr);
if (!$binaryOp instanceof BinaryOp) {
return new BooleanNot($expr);
}
if ($inversedCondition instanceof BooleanAnd) {
if ($binaryOp instanceof BooleanAnd) {
return new BooleanNot($expr);
}
return $inversedCondition;
return $binaryOp;
}
if ($expr instanceof BooleanNot) {
return $expr->expr;

View File

@ -125,12 +125,12 @@ CODE_SAMPLE
}
private function addInvertedIfStmtWithContinue(If_ $nestedIfWithOnlyReturn, Foreach_ $foreach) : void
{
$invertedCondition = $this->conditionInverter->createInvertedCondition($nestedIfWithOnlyReturn->cond);
$invertedCondExpr = $this->conditionInverter->createInvertedCondition($nestedIfWithOnlyReturn->cond);
// special case
if ($invertedCondition instanceof BooleanNot && $invertedCondition->expr instanceof BooleanAnd) {
$leftExpr = $this->negateOrDeNegate($invertedCondition->expr->left);
if ($invertedCondExpr instanceof BooleanNot && $invertedCondExpr->expr instanceof BooleanAnd) {
$leftExpr = $this->negateOrDeNegate($invertedCondExpr->expr->left);
$foreach->stmts[] = $this->createIfContinue($leftExpr);
$rightExpr = $this->negateOrDeNegate($invertedCondition->expr->right);
$rightExpr = $this->negateOrDeNegate($invertedCondExpr->expr->right);
$foreach->stmts[] = $this->createIfContinue($rightExpr);
return;
}
@ -140,7 +140,7 @@ CODE_SAMPLE
return;
}
$nestedIfWithOnlyReturn->setAttribute(AttributeKey::ORIGINAL_NODE, null);
$nestedIfWithOnlyReturn->cond = $invertedCondition;
$nestedIfWithOnlyReturn->cond = $invertedCondExpr;
$nestedIfWithOnlyReturn->stmts = [new Continue_()];
$foreach->stmts[] = $nestedIfWithOnlyReturn;
}

View File

@ -131,16 +131,16 @@ CODE_SAMPLE
*/
private function createStandaloneIfsWithReturn(If_ $nestedIfWithOnlyReturn, Return_ $return) : array
{
$invertedCondition = $this->conditionInverter->createInvertedCondition($nestedIfWithOnlyReturn->cond);
$invertedCondExpr = $this->conditionInverter->createInvertedCondition($nestedIfWithOnlyReturn->cond);
// special case
if ($invertedCondition instanceof BooleanNot && $invertedCondition->expr instanceof BooleanAnd) {
$booleanNotPartIf = new If_(new BooleanNot($invertedCondition->expr->left));
if ($invertedCondExpr instanceof BooleanNot && $invertedCondExpr->expr instanceof BooleanAnd) {
$booleanNotPartIf = new If_(new BooleanNot($invertedCondExpr->expr->left));
$booleanNotPartIf->stmts = [clone $return];
$secondBooleanNotPartIf = new If_(new BooleanNot($invertedCondition->expr->right));
$secondBooleanNotPartIf = new If_(new BooleanNot($invertedCondExpr->expr->right));
$secondBooleanNotPartIf->stmts = [clone $return];
return [$booleanNotPartIf, $secondBooleanNotPartIf];
}
$nestedIfWithOnlyReturn->cond = $invertedCondition;
$nestedIfWithOnlyReturn->cond = $invertedCondExpr;
$nestedIfWithOnlyReturn->stmts = [$return];
return [$nestedIfWithOnlyReturn];
}

View File

@ -9,13 +9,13 @@ use PHPStan\Type\ObjectType;
use PHPStan\Type\StaticType;
use PHPStan\Type\ThisType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Util\StringUtils;
use Rector\Naming\RectorNamingInflector;
use Rector\Naming\ValueObject\ExpectedName;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
use Rector\StaticTypeMapper\ValueObject\Type\SelfObjectType;
/**
@ -44,11 +44,6 @@ final class PropertyNaming
* @var string
*/
private const GET_PREFIX_REGEX = '#^get(?<root_name>[A-Z].+)#';
/**
* @readonly
* @var \Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper
*/
private $typeUnwrapper;
/**
* @readonly
* @var \Rector\Naming\RectorNamingInflector
@ -59,9 +54,8 @@ final class PropertyNaming
* @var \Rector\NodeTypeResolver\NodeTypeResolver
*/
private $nodeTypeResolver;
public function __construct(TypeUnwrapper $typeUnwrapper, RectorNamingInflector $rectorNamingInflector, NodeTypeResolver $nodeTypeResolver)
public function __construct(RectorNamingInflector $rectorNamingInflector, NodeTypeResolver $nodeTypeResolver)
{
$this->typeUnwrapper = $typeUnwrapper;
$this->rectorNamingInflector = $rectorNamingInflector;
$this->nodeTypeResolver = $nodeTypeResolver;
}
@ -76,7 +70,7 @@ final class PropertyNaming
}
public function getExpectedNameFromType(Type $type) : ?ExpectedName
{
$type = $this->typeUnwrapper->unwrapNullableType($type);
$type = TypeCombinator::removeNull($type);
if (!$type instanceof TypeWithClassName) {
return null;
}

View File

@ -3,16 +3,13 @@
declare (strict_types=1);
namespace Rector\Naming\Rector\Assign;
use RectorPrefix202207\Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt\ClassLike;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer;
use Rector\Naming\Guard\BreakingVariableRenameGuard;
use Rector\Naming\Matcher\VariableAndCallAssignMatcher;
use Rector\Naming\Naming\ExpectedNameResolver;
@ -21,7 +18,6 @@ use Rector\Naming\PhpDoc\VarTagValueNodeRenamer;
use Rector\Naming\ValueObject\VariableAndCallAssign;
use Rector\Naming\VariableRenamer;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
@ -29,6 +25,11 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class RenameVariableToMatchMethodCallReturnTypeRector extends AbstractRector
{
/**
* @var string
* @see https://regex101.com/r/JG5w9j/1
*/
private const OR_BETWEEN_WORDS_REGEX = '#[a-z]Or[A-Z]#';
/**
* @readonly
* @var \Rector\Naming\Guard\BreakingVariableRenameGuard
@ -59,22 +60,7 @@ final class RenameVariableToMatchMethodCallReturnTypeRector extends AbstractRect
* @var \Rector\Naming\VariableRenamer
*/
private $variableRenamer;
/**
* @readonly
* @var \Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper
*/
private $typeUnwrapper;
/**
* @readonly
* @var \PHPStan\Reflection\ReflectionProvider
*/
private $reflectionProvider;
/**
* @readonly
* @var \Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer
*/
private $familyRelationsAnalyzer;
public function __construct(BreakingVariableRenameGuard $breakingVariableRenameGuard, ExpectedNameResolver $expectedNameResolver, NamingConventionAnalyzer $namingConventionAnalyzer, VarTagValueNodeRenamer $varTagValueNodeRenamer, VariableAndCallAssignMatcher $variableAndCallAssignMatcher, VariableRenamer $variableRenamer, TypeUnwrapper $typeUnwrapper, ReflectionProvider $reflectionProvider, FamilyRelationsAnalyzer $familyRelationsAnalyzer)
public function __construct(BreakingVariableRenameGuard $breakingVariableRenameGuard, ExpectedNameResolver $expectedNameResolver, NamingConventionAnalyzer $namingConventionAnalyzer, VarTagValueNodeRenamer $varTagValueNodeRenamer, VariableAndCallAssignMatcher $variableAndCallAssignMatcher, VariableRenamer $variableRenamer)
{
$this->breakingVariableRenameGuard = $breakingVariableRenameGuard;
$this->expectedNameResolver = $expectedNameResolver;
@ -82,9 +68,6 @@ final class RenameVariableToMatchMethodCallReturnTypeRector extends AbstractRect
$this->varTagValueNodeRenamer = $varTagValueNodeRenamer;
$this->variableAndCallAssignMatcher = $variableAndCallAssignMatcher;
$this->variableRenamer = $variableRenamer;
$this->typeUnwrapper = $typeUnwrapper;
$this->reflectionProvider = $reflectionProvider;
$this->familyRelationsAnalyzer = $familyRelationsAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
@ -193,7 +176,8 @@ CODE_SAMPLE
if ($this->namingConventionAnalyzer->isCallMatchingVariableName($variableAndCallAssign->getCall(), $variableAndCallAssign->getVariableName(), $expectedName)) {
return \true;
}
if ($this->isClassTypeWithChildren($variableAndCallAssign->getCall())) {
$isUnionName = Strings::match($variableAndCallAssign->getVariableName(), self::OR_BETWEEN_WORDS_REGEX);
if ($isUnionName !== null) {
return \true;
}
return $this->breakingVariableRenameGuard->shouldSkipVariable($variableAndCallAssign->getVariableName(), $expectedName, $variableAndCallAssign->getFunctionLike(), $variableAndCallAssign->getVariable());
@ -205,24 +189,4 @@ CODE_SAMPLE
$this->varTagValueNodeRenamer->renameAssignVarTagVariableName($assignPhpDocInfo, $variableAndCallAssign->getVariableName(), $expectedName);
$this->variableRenamer->renameVariableInFunctionLike($variableAndCallAssign->getFunctionLike(), $variableAndCallAssign->getVariableName(), $expectedName, $variableAndCallAssign->getAssign());
}
/**
* @param \PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\FuncCall $expr
*/
private function isClassTypeWithChildren($expr) : bool
{
$callStaticType = $this->getType($expr);
$callStaticType = $this->typeUnwrapper->unwrapNullableType($callStaticType);
if (!$callStaticType instanceof ObjectType) {
return \false;
}
if (\is_a($callStaticType->getClassName(), ClassLike::class, \true)) {
return \false;
}
if (!$this->reflectionProvider->hasClass($callStaticType->getClassName())) {
return \false;
}
$classReflection = $this->reflectionProvider->getClass($callStaticType->getClassName());
$childrenClassReflections = $this->familyRelationsAnalyzer->getChildrenOfClassReflection($classReflection);
return $childrenClassReflections !== [];
}
}

View File

@ -117,9 +117,9 @@ final class VariableRenamer
*/
private function resolvePhpDocInfo(Variable $variable) : PhpDocInfo
{
$expression = $this->betterNodeFinder->resolveCurrentStatement($variable);
if ($expression instanceof Node) {
return $this->phpDocInfoFactory->createFromNodeOrEmpty($expression);
$currentStmt = $this->betterNodeFinder->resolveCurrentStatement($variable);
if ($currentStmt instanceof Node) {
return $this->phpDocInfoFactory->createFromNodeOrEmpty($currentStmt);
}
return $this->phpDocInfoFactory->createFromNodeOrEmpty($variable);
}

View File

@ -89,7 +89,7 @@ final class FullyQualifyStmtsAnalyzer
if (!$this->reflectionProvider->hasConstant($name, $scope)) {
return \false;
}
$constantReflection = $this->reflectionProvider->getConstant($name, $scope);
return $constantReflection instanceof RuntimeConstantReflection;
$globalConstantReflection = $this->reflectionProvider->getConstant($name, $scope);
return $globalConstantReflection instanceof RuntimeConstantReflection;
}
}

View File

@ -5,7 +5,6 @@ namespace Rector\Php55\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
@ -94,8 +93,8 @@ CODE_SAMPLE
/** @var Arg $firstArgument */
$firstArgument = $node->args[0];
$firstArgumentValue = $firstArgument->value;
$patternWithoutE = $this->regexMatcher->resolvePatternExpressionWithoutEIfFound($firstArgumentValue);
if (!$patternWithoutE instanceof Expr) {
$patternWithoutEExpr = $this->regexMatcher->resolvePatternExpressionWithoutEIfFound($firstArgumentValue);
if ($patternWithoutEExpr === null) {
return null;
}
/** @var Arg $secondArgument */
@ -106,7 +105,7 @@ CODE_SAMPLE
return null;
}
$node->name = new Name('preg_replace_callback');
$firstArgument->value = $patternWithoutE;
$firstArgument->value = $patternWithoutEExpr;
$secondArgument->value = $anonymousFunction;
return $node;
}

View File

@ -29,7 +29,10 @@ final class RegexMatcher
{
$this->valueResolver = $valueResolver;
}
public function resolvePatternExpressionWithoutEIfFound(Expr $expr) : ?Expr
/**
* @return \PhpParser\Node\Expr\BinaryOp\Concat|\PhpParser\Node\Scalar\String_|null
*/
public function resolvePatternExpressionWithoutEIfFound(Expr $expr)
{
if ($expr instanceof String_) {
$pattern = $this->valueResolver->getValue($expr);
@ -55,7 +58,7 @@ final class RegexMatcher
$modifiersWithoutE = Strings::replace($modifiers, '#e#', '');
return Strings::before($pattern, $delimiter, -1) . $delimiter . $modifiersWithoutE;
}
private function matchConcat(Concat $concat) : ?Expr
private function matchConcat(Concat $concat) : ?Concat
{
$lastItem = $concat->right;
if (!$lastItem instanceof String_) {

View File

@ -36,37 +36,37 @@ final class IsArrayAndDualCheckToAble
if (!$twoNodeMatch instanceof TwoNodeMatch) {
return null;
}
/** @var Instanceof_ $instanceOf */
$instanceOf = $twoNodeMatch->getFirstExpr();
/** @var FuncCall $funcCall */
$funcCall = $twoNodeMatch->getSecondExpr();
$instanceOfClass = $instanceOf->class;
/** @var Instanceof_ $instanceofExpr */
$instanceofExpr = $twoNodeMatch->getFirstExpr();
/** @var FuncCall $funcCallExpr */
$funcCallExpr = $twoNodeMatch->getSecondExpr();
$instanceOfClass = $instanceofExpr->class;
if ($instanceOfClass instanceof Expr) {
return null;
}
if ((string) $instanceOfClass !== $type) {
return null;
}
if (!$this->nodeNameResolver->isName($funcCall, 'is_array')) {
if (!$this->nodeNameResolver->isName($funcCallExpr, 'is_array')) {
return null;
}
if (!isset($funcCall->args[0])) {
if (!isset($funcCallExpr->args[0])) {
return null;
}
if (!$funcCall->args[0] instanceof Arg) {
if (!$funcCallExpr->args[0] instanceof Arg) {
return null;
}
// both use same var
if (!$funcCall->args[0]->value instanceof Variable) {
if (!$funcCallExpr->args[0]->value instanceof Variable) {
return null;
}
/** @var Variable $firstVarNode */
$firstVarNode = $funcCall->args[0]->value;
if (!$instanceOf->expr instanceof Variable) {
$firstVarNode = $funcCallExpr->args[0]->value;
if (!$instanceofExpr->expr instanceof Variable) {
return null;
}
/** @var Variable $secondVarNode */
$secondVarNode = $instanceOf->expr;
$secondVarNode = $instanceofExpr->expr;
// are they same variables
if ($firstVarNode->name !== $secondVarNode->name) {
return null;

View File

@ -145,23 +145,23 @@ final class AnonymousFunctionFactory
}
public function createFromPhpMethodReflection(PhpMethodReflection $phpMethodReflection, Expr $expr) : ?Closure
{
/** @var FunctionVariantWithPhpDocs $functionVariantWithPhpDoc */
$functionVariantWithPhpDoc = ParametersAcceptorSelector::selectSingle($phpMethodReflection->getVariants());
$newParams = $this->createParams($phpMethodReflection, $functionVariantWithPhpDoc->getParameters());
/** @var FunctionVariantWithPhpDocs $parametersAcceptorWithPhpDocs */
$parametersAcceptorWithPhpDocs = ParametersAcceptorSelector::selectSingle($phpMethodReflection->getVariants());
$newParams = $this->createParams($phpMethodReflection, $parametersAcceptorWithPhpDocs->getParameters());
$innerMethodCall = $this->createInnerMethodCall($phpMethodReflection, $expr, $newParams);
if ($innerMethodCall === null) {
return null;
}
$returnTypeNode = null;
if (!$functionVariantWithPhpDoc->getReturnType() instanceof MixedType) {
$returnTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($functionVariantWithPhpDoc->getReturnType(), TypeKind::RETURN);
if (!$parametersAcceptorWithPhpDocs->getReturnType() instanceof MixedType) {
$returnTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($parametersAcceptorWithPhpDocs->getReturnType(), TypeKind::RETURN);
}
$uses = [];
if ($expr instanceof Variable && !$this->nodeNameResolver->isName($expr, 'this')) {
$uses[] = new ClosureUse($expr);
}
// does method return something?
$stmts = $this->resolveStmts($functionVariantWithPhpDoc, $innerMethodCall);
$stmts = $this->resolveStmts($parametersAcceptorWithPhpDocs, $innerMethodCall);
return new Closure(['params' => $newParams, 'returnType' => $returnTypeNode, 'uses' => $uses, 'stmts' => $stmts]);
}
public function createAnonymousFunctionFromExpr(Expr $expr) : ?Closure
@ -195,25 +195,25 @@ final class AnonymousFunctionFactory
return $anonymousFunction;
}
/**
* @param Param[] $paramNodes
* @param Param[] $params
* @return string[]
*/
private function collectParamNames(array $paramNodes) : array
private function collectParamNames(array $params) : array
{
$paramNames = [];
foreach ($paramNodes as $paramNode) {
$paramNames[] = $this->nodeNameResolver->getName($paramNode);
foreach ($params as $param) {
$paramNames[] = $this->nodeNameResolver->getName($param);
}
return $paramNames;
}
/**
* @param Node[] $nodes
* @param Param[] $paramNodes
* @param Param[] $params
* @return array<string, Variable>
*/
private function createUseVariablesFromParams(array $nodes, array $paramNodes) : array
private function createUseVariablesFromParams(array $nodes, array $params) : array
{
$paramNames = $this->collectParamNames($paramNodes);
$paramNames = $this->collectParamNames($params);
/** @var Variable[] $variables */
$variables = $this->betterNodeFinder->findInstanceOf($nodes, Variable::class);
/** @var array<string, Variable> $filteredVariables */

View File

@ -117,8 +117,8 @@ CODE_SAMPLE
*/
private function createDimFetchAssignWithFuncCall(Expr $assignVariable, Expr $eachedVariable, $dimValue, string $functionName) : Assign
{
$dim = BuilderHelpers::normalizeValue($dimValue);
$arrayDimFetch = new ArrayDimFetch($assignVariable, $dim);
$dimExpr = BuilderHelpers::normalizeValue($dimValue);
$arrayDimFetch = new ArrayDimFetch($assignVariable, $dimExpr);
return new Assign($arrayDimFetch, $this->nodeFactory->createFuncCall($functionName, [new Arg($eachedVariable)]));
}
}

View File

@ -57,11 +57,11 @@ CODE_SAMPLE
}
$resultVariable = new Variable('result');
$node->args[1] = new Arg($resultVariable);
$expression = $this->betterNodeFinder->resolveCurrentStatement($node);
if (!$expression instanceof Stmt) {
$currentStmt = $this->betterNodeFinder->resolveCurrentStatement($node);
if (!$currentStmt instanceof Stmt) {
return null;
}
$nextExpression = $expression->getAttribute(AttributeKey::NEXT_NODE);
$nextExpression = $currentStmt->getAttribute(AttributeKey::NEXT_NODE);
if ($nextExpression === null) {
return null;
}

View File

@ -116,13 +116,13 @@ CODE_SAMPLE
}
private function getNextExpression(FuncCall $funcCall) : ?Node
{
$currentExpression = $this->betterNodeFinder->resolveCurrentStatement($funcCall);
if (!$currentExpression instanceof Expression) {
$currentStmt = $this->betterNodeFinder->resolveCurrentStatement($funcCall);
if (!$currentStmt instanceof Expression) {
return null;
}
if ($currentExpression->expr !== $funcCall) {
if ($currentStmt->expr !== $funcCall) {
return null;
}
return $currentExpression->getAttribute(AttributeKey::NEXT_NODE);
return $currentStmt->getAttribute(AttributeKey::NEXT_NODE);
}
}

View File

@ -119,7 +119,7 @@ final class ResourceReturnToObject
private function resolveArgValueTypeFromPreviousAssign(FuncCall $funcCall, Expr $expr, array $collectionFunctionToReturnObject) : ?FullyQualifiedObjectType
{
$objectInstanceCheck = null;
$assign = $this->betterNodeFinder->findFirstPrevious($funcCall, function (Node $subNode) use(&$objectInstanceCheck, $expr, $collectionFunctionToReturnObject) : bool {
$foundNode = $this->betterNodeFinder->findFirstPrevious($funcCall, function (Node $subNode) use(&$objectInstanceCheck, $expr, $collectionFunctionToReturnObject) : bool {
if (!$this->isAssignWithFuncCallExpr($subNode)) {
return \false;
}
@ -135,7 +135,7 @@ final class ResourceReturnToObject
}
return \false;
});
if (!$assign instanceof Assign) {
if (!$foundNode instanceof Assign) {
return null;
}
/** @var string $objectInstanceCheck */

View File

@ -36,7 +36,7 @@ final class ExactCompareFactory
$this->nodeFactory = $nodeFactory;
}
/**
* @return \PhpParser\Node\Expr|null
* @return \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\BinaryOp\BooleanOr|\PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BooleanNot|\PhpParser\Node\Expr\Instanceof_|null
*/
public function createIdenticalFalsyCompare(Type $exprType, Expr $expr, bool $treatAsNonEmpty)
{
@ -61,7 +61,7 @@ final class ExactCompareFactory
return $this->createTruthyFromUnionType($exprType, $expr, $treatAsNonEmpty);
}
/**
* @return \PhpParser\Node\Expr|null
* @return \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\Instanceof_|\PhpParser\Node\Expr\BinaryOp\BooleanOr|\PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\BooleanAnd|null
*/
public function createNotIdenticalFalsyCompare(Type $exprType, Expr $expr, bool $treatAsNotEmpty)
{
@ -80,7 +80,7 @@ final class ExactCompareFactory
return $this->createFromUnionType($exprType, $expr, $treatAsNotEmpty);
}
/**
* @return \PhpParser\Node\Expr|null
* @return \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\Instanceof_|\PhpParser\Node\Expr\BinaryOp\BooleanOr|\PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\BooleanAnd|null
*/
private function createFromUnionType(UnionType $unionType, Expr $expr, bool $treatAsNotEmpty)
{
@ -102,7 +102,10 @@ final class ExactCompareFactory
}
return new BooleanAnd($toNullNotIdentical, $compareExpr);
}
private function resolveFromCleanedNullUnionType(UnionType $unionType, Expr $expr, bool $treatAsNotEmpty) : ?Expr
/**
* @return \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\Instanceof_|\PhpParser\Node\Expr\BinaryOp\BooleanOr|\PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\BooleanAnd|null
*/
private function resolveFromCleanedNullUnionType(UnionType $unionType, Expr $expr, bool $treatAsNotEmpty)
{
$compareExprs = [];
foreach ($unionType->getTypes() as $unionedType) {
@ -111,7 +114,7 @@ final class ExactCompareFactory
return $this->resolveTruthyExpr($compareExprs);
}
/**
* @return array<Expr|null>
* @return array<Identical|BooleanOr|NotIdentical|BooleanNot|Instanceof_|null>
*/
private function collectCompareExprs(UnionType $unionType, Expr $expr, bool $treatAsNonEmpty) : array
{
@ -126,9 +129,10 @@ final class ExactCompareFactory
return \count($unionType->getTypes()) === 2 ? TypeCombinator::removeNull($unionType) : $unionType;
}
/**
* @param array<Expr|null> $compareExprs
* @param array<Identical|BooleanOr|NotIdentical|BooleanAnd|Instanceof_|null> $compareExprs
* @return \PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\Instanceof_|\PhpParser\Node\Expr\BinaryOp\BooleanOr|\PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\BooleanAnd|null
*/
private function resolveTruthyExpr(array $compareExprs) : ?Expr
private function resolveTruthyExpr(array $compareExprs)
{
$truthyExpr = \array_shift($compareExprs);
foreach ($compareExprs as $compareExpr) {
@ -143,7 +147,7 @@ final class ExactCompareFactory
return $truthyExpr;
}
/**
* @return \PhpParser\Node\Expr|null
* @return \PhpParser\Node\Expr\BinaryOp\BooleanOr|\PhpParser\Node\Expr\BinaryOp\NotIdentical|\PhpParser\Node\Expr\BinaryOp\Identical|\PhpParser\Node\Expr\BooleanNot|\PhpParser\Node\Expr\Instanceof_|null
*/
private function createTruthyFromUnionType(UnionType $unionType, Expr $expr, bool $treatAsNonEmpty)
{

View File

@ -73,11 +73,11 @@ CODE_SAMPLE
return null;
}
$exprType = $scope->getType($node->cond);
$falsyIdentical = $this->exactCompareFactory->createNotIdenticalFalsyCompare($exprType, $node->cond, $this->treatAsNonEmpty);
if (!$falsyIdentical instanceof Expr) {
$expr = $this->exactCompareFactory->createNotIdenticalFalsyCompare($exprType, $node->cond, $this->treatAsNonEmpty);
if (!$expr instanceof Expr) {
return null;
}
$node->cond = $falsyIdentical;
$node->cond = $expr;
return $node;
}
}

View File

@ -18,19 +18,14 @@ use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\ValueObject\MethodName;
use Rector\Naming\Naming\PropertyNaming;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
final class TypeProvidingExprFromClassResolver
{
/**
* @readonly
* @var \Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper
*/
private $typeUnwrapper;
/**
* @readonly
* @var \PHPStan\Reflection\ReflectionProvider
@ -46,9 +41,8 @@ final class TypeProvidingExprFromClassResolver
* @var \Rector\Naming\Naming\PropertyNaming
*/
private $propertyNaming;
public function __construct(TypeUnwrapper $typeUnwrapper, ReflectionProvider $reflectionProvider, NodeNameResolver $nodeNameResolver, PropertyNaming $propertyNaming)
public function __construct(ReflectionProvider $reflectionProvider, NodeNameResolver $nodeNameResolver, PropertyNaming $propertyNaming)
{
$this->typeUnwrapper = $typeUnwrapper;
$this->reflectionProvider = $reflectionProvider;
$this->nodeNameResolver = $nodeNameResolver;
$this->propertyNaming = $propertyNaming;
@ -118,7 +112,7 @@ final class TypeProvidingExprFromClassResolver
if ($readableType instanceof MixedType) {
return \false;
}
$readableType = $this->typeUnwrapper->unwrapNullableType($readableType);
$readableType = TypeCombinator::removeNull($readableType);
if (!$readableType instanceof TypeWithClassName) {
return \false;
}

View File

@ -104,17 +104,17 @@ final class NonInformativeReturnTagRemover
if (!$nullabledReturnType instanceof Type) {
return;
}
$nullabledReturnTagValueNode = $this->matchNullabledReturnTagValueNode($returnTagValueNode);
if (!$nullabledReturnTagValueNode instanceof TypeNode) {
$nullableTypeNode = $this->matchNullabledReturnTagValueNode($returnTagValueNode);
if (!$nullableTypeNode instanceof TypeNode) {
return;
}
if (!$nullabledReturnType instanceof FullyQualifiedObjectType) {
return;
}
if (!$nullabledReturnTagValueNode instanceof IdentifierTypeNode) {
if (!$nullableTypeNode instanceof IdentifierTypeNode) {
return;
}
if (\substr_compare($nullabledReturnType->getClassName(), $nullabledReturnTagValueNode->name, -\strlen($nullabledReturnTagValueNode->name)) !== 0) {
if (\substr_compare($nullabledReturnType->getClassName(), $nullableTypeNode->name, -\strlen($nullableTypeNode->name)) !== 0) {
return;
}
$phpDocInfo->removeByType(ReturnTagValueNode::class);

View File

@ -22,6 +22,10 @@ use Rector\TypeDeclaration\AlreadyAssignDetector\NullTypeAssignDetector;
use Rector\TypeDeclaration\AlreadyAssignDetector\PropertyDefaultAssignDetector;
use Rector\TypeDeclaration\Matcher\PropertyAssignMatcher;
use RectorPrefix202207\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
/**
* @deprecated
* @todo Split into many narrow-focused rules
*/
final class AssignToPropertyTypeInferer
{
/**

View File

@ -34,6 +34,10 @@ use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\TypeDeclaration\TypeInferer\AssignToPropertyTypeInferer;
use RectorPrefix202207\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
/**
* @deprecated
* @todo split to more specialized rules with narrow focus
*/
final class TrustedClassMethodPropertyTypeInferer
{
/**

View File

@ -38,6 +38,10 @@ use Rector\TypeDeclaration\Sorter\PriorityAwareSorter;
use Rector\TypeDeclaration\TypeAnalyzer\GenericClassStringTypeNormalizer;
use Rector\TypeDeclaration\TypeNormalizer;
use RectorPrefix202207\Symplify\PackageBuilder\Parameter\ParameterProvider;
/**
* @deprecated
* @todo Split into many narrow-focused rules
*/
final class ReturnTypeInferer
{
/**

View File

@ -28,6 +28,10 @@ use Rector\TypeDeclaration\Contract\TypeInferer\ReturnTypeInfererInterface;
use Rector\TypeDeclaration\TypeInferer\SilentVoidResolver;
use Rector\TypeDeclaration\TypeInferer\SplArrayFixedTypeNarrower;
use RectorPrefix202207\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
/**
* @deprecated
* @todo Split into many narrow-focused rules
*/
final class ReturnedNodesReturnTypeInfererTypeInferer implements ReturnTypeInfererInterface
{
/**

View File

@ -17,12 +17,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'd1f91502773e1cc2de6fc5c7ee7b2077165f6762';
public const PACKAGE_VERSION = '6d7404c65000caede512a5bc5a993f472e11cd0d';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2022-07-18 16:27:06';
public const RELEASE_DATE = '2022-07-18 17:20:13';
/**
* @var int
*/

View File

@ -133,6 +133,8 @@ final class BetterNodeFinder
/**
* @template T of Node
* @param class-string<T> $type
* @return T|null
*
* @param \PhpParser\Node|mixed[] $nodes
*/
public function findFirstInstanceOf($nodes, string $type) : ?Node

View File

@ -17,9 +17,7 @@ use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\Error;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
@ -53,7 +51,6 @@ use Rector\Core\NodeDecorator\PropertyTypeDecorator;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\ValueObject\MethodName;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\PostRector\ValueObject\PropertyMetadata;
@ -90,11 +87,6 @@ final class NodeFactory
* @var \Rector\StaticTypeMapper\StaticTypeMapper
*/
private $staticTypeMapper;
/**
* @readonly
* @var \Rector\NodeNameResolver\NodeNameResolver
*/
private $nodeNameResolver;
/**
* @readonly
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger
@ -110,13 +102,12 @@ final class NodeFactory
* @var \Rector\Core\NodeDecorator\PropertyTypeDecorator
*/
private $propertyTypeDecorator;
public function __construct(BuilderFactory $builderFactory, PhpDocInfoFactory $phpDocInfoFactory, PhpVersionProvider $phpVersionProvider, StaticTypeMapper $staticTypeMapper, NodeNameResolver $nodeNameResolver, PhpDocTypeChanger $phpDocTypeChanger, CurrentNodeProvider $currentNodeProvider, PropertyTypeDecorator $propertyTypeDecorator)
public function __construct(BuilderFactory $builderFactory, PhpDocInfoFactory $phpDocInfoFactory, PhpVersionProvider $phpVersionProvider, StaticTypeMapper $staticTypeMapper, PhpDocTypeChanger $phpDocTypeChanger, CurrentNodeProvider $currentNodeProvider, PropertyTypeDecorator $propertyTypeDecorator)
{
$this->builderFactory = $builderFactory;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->phpVersionProvider = $phpVersionProvider;
$this->staticTypeMapper = $staticTypeMapper;
$this->nodeNameResolver = $nodeNameResolver;
$this->phpDocTypeChanger = $phpDocTypeChanger;
$this->currentNodeProvider = $currentNodeProvider;
$this->propertyTypeDecorator = $propertyTypeDecorator;
@ -170,9 +161,6 @@ final class NodeFactory
*/
public function createArgs(array $values) : array
{
foreach ($values as $value) {
$this->normalizeArgValue($value);
}
return $this->builderFactory->args($values);
}
/**
@ -331,14 +319,6 @@ final class NodeFactory
}
return $previousConcat;
}
public function createClosureFromClassMethod(ClassMethod $classMethod) : Closure
{
$classMethodName = $this->nodeNameResolver->getName($classMethod);
$args = $this->createArgs($classMethod->params);
$methodCall = new MethodCall(new Variable(self::THIS), $classMethodName, $args);
$return = new Return_($methodCall);
return new Closure(['params' => $classMethod->params, 'stmts' => [$return], 'returnType' => $classMethod->returnType]);
}
/**
* @param string[] $names
* @return Use_[]
@ -449,8 +429,8 @@ final class NodeFactory
*/
public function createClassConstant(string $name, Expr $expr, int $modifier) : ClassConst
{
$expr = BuilderHelpers::normalizeValue($expr);
$const = new Const_($name, $expr);
$normalizedExpr = BuilderHelpers::normalizeValue($expr);
$const = new Const_($name, $normalizedExpr);
$classConst = new ClassConst([$const]);
$classConst->flags |= $modifier;
// add @var type by default
@ -493,25 +473,15 @@ final class NodeFactory
$nodeClass = \is_object($item) ? \get_class($item) : $item;
throw new NotImplementedYetException(\sprintf('Not implemented yet. Go to "%s()" and add check for "%s" node.', __METHOD__, (string) $nodeClass));
}
/**
* @return mixed|Error|Variable
* @param mixed $value
*/
private function normalizeArgValue($value)
{
if ($value instanceof Param) {
return $value->var;
}
return $value;
}
/**
* @param int|string|null $key
*/
private function decorateArrayItemWithKey($key, ArrayItem $arrayItem) : void
{
if ($key !== null) {
$arrayItem->key = BuilderHelpers::normalizeValue($key);
if ($key === null) {
return;
}
$arrayItem->key = BuilderHelpers::normalizeValue($key);
}
/**
* @param NotIdentical[]|BooleanAnd[] $exprs

View File

@ -74,11 +74,11 @@ final class NodeTransformer
public function transformConcatToStringArray(Concat $concat) : Array_
{
$arrayItems = $this->transformConcatToItems($concat);
$array = BuilderHelpers::normalizeValue($arrayItems);
if (!$array instanceof Array_) {
$expr = BuilderHelpers::normalizeValue($arrayItems);
if (!$expr instanceof Array_) {
throw new ShouldNotHappenException();
}
return $array;
return $expr;
}
private function splitMessageAndArgs(FuncCall $sprintfFuncCall) : ?SprintfStringAndArgs
{

View File

@ -222,9 +222,9 @@ final class ReflectionResolver
}
$scope = $propertyFetch->getAttribute(AttributeKey::SCOPE);
if ($scope instanceof Scope) {
$propertyRelfection = $classReflection->getProperty($propertyName, $scope);
if ($propertyRelfection instanceof PhpPropertyReflection) {
return $propertyRelfection;
$propertyReflection = $classReflection->getProperty($propertyName, $scope);
if ($propertyReflection instanceof PhpPropertyReflection) {
return $propertyReflection;
}
return null;
}

View File

@ -1,19 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Core\ValueObject;
/**
* @api
*/
final class FrameworkName
{
/**
* @var string
*/
public const NETTE = 'nette';
/**
* @var string
*/
public const SYMFONY = 'symfony';
}

2
vendor/autoload.php vendored
View File

@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit1aee6cbcab381344bbbb62694cb14747::getLoader();
return ComposerAutoloaderInit5049e14e14f7b10d90943ba518db8e91::getLoader();

View File

@ -1652,7 +1652,6 @@ return array(
'Rector\\Core\\ValueObject\\Bootstrap\\BootstrapConfigs' => $baseDir . '/src/ValueObject/Bootstrap/BootstrapConfigs.php',
'Rector\\Core\\ValueObject\\Configuration' => $baseDir . '/src/ValueObject/Configuration.php',
'Rector\\Core\\ValueObject\\Error\\SystemError' => $baseDir . '/src/ValueObject/Error/SystemError.php',
'Rector\\Core\\ValueObject\\FrameworkName' => $baseDir . '/src/ValueObject/FrameworkName.php',
'Rector\\Core\\ValueObject\\MethodName' => $baseDir . '/src/ValueObject/MethodName.php',
'Rector\\Core\\ValueObject\\PhpVersion' => $baseDir . '/src/ValueObject/PhpVersion.php',
'Rector\\Core\\ValueObject\\PhpVersionFeature' => $baseDir . '/src/ValueObject/PhpVersionFeature.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit1aee6cbcab381344bbbb62694cb14747
class ComposerAutoloaderInit5049e14e14f7b10d90943ba518db8e91
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInit1aee6cbcab381344bbbb62694cb14747
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit1aee6cbcab381344bbbb62694cb14747', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit5049e14e14f7b10d90943ba518db8e91', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit1aee6cbcab381344bbbb62694cb14747', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit5049e14e14f7b10d90943ba518db8e91', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit1aee6cbcab381344bbbb62694cb14747::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit5049e14e14f7b10d90943ba518db8e91::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInit1aee6cbcab381344bbbb62694cb14747::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInit5049e14e14f7b10d90943ba518db8e91::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire1aee6cbcab381344bbbb62694cb14747($fileIdentifier, $file);
composerRequire5049e14e14f7b10d90943ba518db8e91($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInit1aee6cbcab381344bbbb62694cb14747
* @param string $file
* @return void
*/
function composerRequire1aee6cbcab381344bbbb62694cb14747($fileIdentifier, $file)
function composerRequire5049e14e14f7b10d90943ba518db8e91($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit1aee6cbcab381344bbbb62694cb14747
class ComposerStaticInit5049e14e14f7b10d90943ba518db8e91
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@ -1959,7 +1959,6 @@ class ComposerStaticInit1aee6cbcab381344bbbb62694cb14747
'Rector\\Core\\ValueObject\\Bootstrap\\BootstrapConfigs' => __DIR__ . '/../..' . '/src/ValueObject/Bootstrap/BootstrapConfigs.php',
'Rector\\Core\\ValueObject\\Configuration' => __DIR__ . '/../..' . '/src/ValueObject/Configuration.php',
'Rector\\Core\\ValueObject\\Error\\SystemError' => __DIR__ . '/../..' . '/src/ValueObject/Error/SystemError.php',
'Rector\\Core\\ValueObject\\FrameworkName' => __DIR__ . '/../..' . '/src/ValueObject/FrameworkName.php',
'Rector\\Core\\ValueObject\\MethodName' => __DIR__ . '/../..' . '/src/ValueObject/MethodName.php',
'Rector\\Core\\ValueObject\\PhpVersion' => __DIR__ . '/../..' . '/src/ValueObject/PhpVersion.php',
'Rector\\Core\\ValueObject\\PhpVersionFeature' => __DIR__ . '/../..' . '/src/ValueObject/PhpVersionFeature.php',
@ -3416,9 +3415,9 @@ class ComposerStaticInit1aee6cbcab381344bbbb62694cb14747
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit1aee6cbcab381344bbbb62694cb14747::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit1aee6cbcab381344bbbb62694cb14747::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit1aee6cbcab381344bbbb62694cb14747::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit5049e14e14f7b10d90943ba518db8e91::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit5049e14e14f7b10d90943ba518db8e91::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit5049e14e14f7b10d90943ba518db8e91::$classMap;
}, null, ClassLoader::class);
}