[PHPStan] Enable symplify-rules.neon (#2318)

Co-authored-by: Tomas Votruba <tomas.vot@gmail.com>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Abdul Malik Ikhsan 2022-05-15 18:44:09 +07:00 committed by GitHub
parent d61eea4aca
commit 0686f438cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 70 additions and 71 deletions

View File

@ -1,29 +1,5 @@
includes: includes:
- vendor/symplify/phpstan-rules/config/array-rules.neon - vendor/symplify/phpstan-rules/config/symplify-rules.neon
- vendor/symplify/phpstan-rules/config/code-complexity-rules.neon
- vendor/symplify/phpstan-rules/config/doctrine-rules.neon
- vendor/symplify/phpstan-rules/config/forbidden-static-rules.neon
- vendor/symplify/phpstan-rules/config/naming-rules.neon
- vendor/symplify/phpstan-rules/config/regex-rules.neon
- vendor/symplify/phpstan-rules/config/static-rules.neon
- vendor/symplify/phpstan-rules/packages/symfony/config/symfony-rules.neon
- vendor/symplify/phpstan-rules/config/test-rules.neon
services:
-
class: Symplify\PHPStanRules\Rules\Enum\RequireConstantInMethodCallPositionRule
tags: [phpstan.rules.rule]
arguments:
requiredConstantInMethodCall:
Symfony\Component\Console\Command\Command:
addArgument: [0]
addOption: [0]
Symfony\Component\Console\Input\InputInterface:
getOption: [0]
getArgument: [0]
PhpParser\Node:
getAttribute: [0]
setAttribute: [0]
parameters: parameters:
level: 8 level: 8
@ -704,3 +680,30 @@ parameters:
- -
message: '#Creating new PHPStan\\Reflection\\Php\\PhpParameterReflection is not covered by backward compatibility promise\. The class might change in a minor PHPStan version#' message: '#Creating new PHPStan\\Reflection\\Php\\PhpParameterReflection is not covered by backward compatibility promise\. The class might change in a minor PHPStan version#'
path: rules/DowngradePhp80/NodeAnalyzer/NamedToUnnamedArgs.php path: rules/DowngradePhp80/NodeAnalyzer/NamedToUnnamedArgs.php
-
message: '#Do not name "[a-z]", shorter than 2 chars#'
paths:
# override parent method named "p"
- src/PhpParser/Printer/BetterStandardPrinter.php
# regex
- rules/Php70/EregToPcreTransformer.php
# Symfony Finder filter
-
message: '#Instead of "Symfony\\Component\\Finder\\SplFileInfo" class/interface use "Symplify\\SmartFileSystem\\SmartFileInfo"#'
path: src/FileSystem/FilesFinder.php #113
# format specifiers definition rule
-
message: '#Modifier "%s" is not matching passed variable type "array<int, string>"\. The "string" type is expected \- see https\://dibiphp\.com/en/documentation\#toc\-modifiers\-for\-arrays#'
path: rules/CodingStyle/Rector/Encapsed/EncapsedStringsToSprintfRector.php #35
# PropertyFetches inside method are different
-
message: '#Content of method "processGreater(Left|Right)\(\)" is duplicated with method "processGreaterOrEqual(Left|Right)\(\)" in "Rector\\DeadCode\\Rector\\ConstFetch\\RemovePhpVersionIdCheckRector" class\. Use unique content or service instead#'
path: rules/DeadCode/Rector/ConstFetch/RemovePhpVersionIdCheckRector.php
-
message: '#Instead of "DateTime" class/interface use "Nette\\Utils\\DateTime"#'
path: src/Application/VersionResolver.php

View File

@ -5,7 +5,9 @@ declare(strict_types=1);
namespace Rector\CodeQuality\NodeFactory; namespace Rector\CodeQuality\NodeFactory;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\ComplexType;
use PhpParser\Node\Identifier; use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Property; use PhpParser\Node\Stmt\Property;
use PHPStan\Type\ArrayType; use PHPStan\Type\ArrayType;
use PHPStan\Type\MixedType; use PHPStan\Type\MixedType;
@ -38,6 +40,17 @@ final class PropertyTypeDecorator
$this->decoratePropertyWithType($property, $propertyType); $this->decoratePropertyWithType($property, $propertyType);
} }
public function decoratePropertyWithDocBlock(Property $property, ComplexType|Identifier|Name $typeNode): void
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
if ($phpDocInfo->getVarTagValueNode() !== null) {
return;
}
$newType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($typeNode);
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $newType);
}
private function decoratePropertyWithVarDoc(Property $property, Type $propertyType): void private function decoratePropertyWithVarDoc(Property $property, Type $propertyType): void
{ {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property); $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);

View File

@ -129,7 +129,7 @@ CODE_SAMPLE
if (! $node instanceof Assign) { if (! $node instanceof Assign) {
return ! (bool) $this->betterNodeFinder->find( return ! (bool) $this->betterNodeFinder->find(
$node, $node,
fn (Node $n): bool => $this->nodeComparator->areNodesEqual($expr, $n) fn (Node $subNode): bool => $this->nodeComparator->areNodesEqual($expr, $subNode)
); );
} }

View File

@ -130,7 +130,7 @@ CODE_SAMPLE
$newVariable = new Variable($newVariableName); $newVariable = new Variable($newVariableName);
$isFoundInPrevious = (bool) $this->betterNodeFinder->findFirstPrevious( $isFoundInPrevious = (bool) $this->betterNodeFinder->findFirstPrevious(
$node, $node,
fn (Node $n): bool => $this->nodeComparator->areNodesEqual($n, $newVariable) fn (Node $subNode): bool => $this->nodeComparator->areNodesEqual($subNode, $newVariable)
); );
if ($isFoundInPrevious) { if ($isFoundInPrevious) {

View File

@ -5,13 +5,10 @@ declare(strict_types=1);
namespace Rector\DowngradePhp74\Rector\Property; namespace Rector\DowngradePhp74\Rector\Property;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\ComplexType;
use PhpParser\Node\Expr; use PhpParser\Node\Expr;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType; use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\Property; use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; use Rector\CodeQuality\NodeFactory\PropertyTypeDecorator;
use Rector\Core\Rector\AbstractRector; use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -22,7 +19,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
final class DowngradeTypedPropertyRector extends AbstractRector final class DowngradeTypedPropertyRector extends AbstractRector
{ {
public function __construct( public function __construct(
private readonly PhpDocTypeChanger $phpDocTypeChanger private readonly PropertyTypeDecorator $propertyTypeDecorator
) { ) {
} }
@ -72,20 +69,9 @@ CODE_SAMPLE
$node->props[0]->default = null; $node->props[0]->default = null;
} }
$this->decoratePropertyWithDocBlock($node, $node->type); $this->propertyTypeDecorator->decoratePropertyWithDocBlock($node, $node->type);
$node->type = null; $node->type = null;
return $node; return $node;
} }
private function decoratePropertyWithDocBlock(Property $property, ComplexType|Identifier|Name $typeNode): void
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
if ($phpDocInfo->getVarTagValueNode() !== null) {
return;
}
$newType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($typeNode);
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $newType);
}
} }

View File

@ -5,12 +5,9 @@ declare(strict_types=1);
namespace Rector\DowngradePhp80\Rector\Property; namespace Rector\DowngradePhp80\Rector\Property;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\ComplexType;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Property; use PhpParser\Node\Stmt\Property;
use PhpParser\Node\UnionType; use PhpParser\Node\UnionType;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; use Rector\CodeQuality\NodeFactory\PropertyTypeDecorator;
use Rector\Core\Rector\AbstractRector; use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -21,7 +18,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
final class DowngradeUnionTypeTypedPropertyRector extends AbstractRector final class DowngradeUnionTypeTypedPropertyRector extends AbstractRector
{ {
public function __construct( public function __construct(
private readonly PhpDocTypeChanger $phpDocTypeChanger private readonly PropertyTypeDecorator $propertyTypeDecorator
) { ) {
} }
@ -70,23 +67,12 @@ CODE_SAMPLE
return null; return null;
} }
$this->decoratePropertyWithDocBlock($node, $node->type); $this->propertyTypeDecorator->decoratePropertyWithDocBlock($node, $node->type);
$node->type = null; $node->type = null;
return $node; return $node;
} }
private function decoratePropertyWithDocBlock(Property $property, ComplexType|Identifier|Name $typeNode): void
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
if ($phpDocInfo->getVarTagValueNode() !== null) {
return;
}
$newType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($typeNode);
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $newType);
}
private function shouldRemoveProperty(Property $property): bool private function shouldRemoveProperty(Property $property): bool
{ {
if ($property->type === null) { if ($property->type === null) {

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Rector\Php81\Rector\ClassMethod; namespace Rector\Php81\Rector\ClassMethod;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\Coalesce; use PhpParser\Node\Expr\BinaryOp\Coalesce;
use PhpParser\Node\Expr\New_; use PhpParser\Node\Expr\New_;
use PhpParser\Node\NullableType; use PhpParser\Node\NullableType;
@ -101,7 +102,10 @@ CODE_SAMPLE
$paramName = $this->getName($param->var); $paramName = $this->getName($param->var);
$toPropertyAssigns = $this->betterNodeFinder->findClassMethodAssignsToLocalProperty($node, $paramName); $toPropertyAssigns = $this->betterNodeFinder->findClassMethodAssignsToLocalProperty($node, $paramName);
$toPropertyAssigns = array_filter($toPropertyAssigns, fn ($v): bool => $v->expr instanceof Coalesce); $toPropertyAssigns = array_filter(
$toPropertyAssigns,
fn (Assign $assign): bool => $assign->expr instanceof Coalesce
);
foreach ($toPropertyAssigns as $toPropertyAssign) { foreach ($toPropertyAssigns as $toPropertyAssign) {
/** @var Coalesce $coalesce */ /** @var Coalesce $coalesce */
@ -191,6 +195,6 @@ CODE_SAMPLE
return []; return [];
} }
return array_filter($classMethod->params, fn ($v): bool => $v->type instanceof NullableType); return array_filter($classMethod->params, fn (Param $param): bool => $param->type instanceof NullableType);
} }
} }

View File

@ -102,14 +102,14 @@ CODE_SAMPLE
} }
/** @var Return_[] $returns */ /** @var Return_[] $returns */
$returns = $this->betterNodeFinder->find((array) $node->stmts, function (Node $n) use ($node): bool { $returns = $this->betterNodeFinder->find((array) $node->stmts, function (Node $subNode) use ($node): bool {
$currentFunctionLike = $this->betterNodeFinder->findParentType($n, FunctionLike::class); $currentFunctionLike = $this->betterNodeFinder->findParentType($subNode, FunctionLike::class);
if ($currentFunctionLike === $node) { if ($currentFunctionLike === $node) {
return $n instanceof Return_; return $subNode instanceof Return_;
} }
$currentReturn = $this->betterNodeFinder->findParentType($n, Return_::class); $currentReturn = $this->betterNodeFinder->findParentType($subNode, Return_::class);
if (! $currentReturn instanceof Return_) { if (! $currentReturn instanceof Return_) {
return false; return false;
} }
@ -119,7 +119,7 @@ CODE_SAMPLE
return false; return false;
} }
return $n instanceof Return_; return $subNode instanceof Return_;
}); });
$returnedStrictTypes = $this->returnStrictTypeAnalyzer->collectStrictReturnTypes($returns); $returnedStrictTypes = $this->returnStrictTypeAnalyzer->collectStrictReturnTypes($returns);

View File

@ -201,7 +201,7 @@ final class ReturnTypeInferer
} }
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($functionLike, Return_::class); $returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($functionLike, Return_::class);
$returnsWithExpr = array_filter($returns, fn ($v): bool => $v->expr instanceof Expr); $returnsWithExpr = array_filter($returns, fn (Return_ $return): bool => $return->expr instanceof Expr);
if ($returns !== $returnsWithExpr) { if ($returns !== $returnsWithExpr) {
return $unionType; return $unionType;

View File

@ -83,6 +83,11 @@ final class Option
*/ */
public const CLEAR_CACHE = 'clear-cache'; public const CLEAR_CACHE = 'clear-cache';
/**
* @var string
*/
public const WORKING_DIR = 'working-dir';
/** /**
* @deprecated Use @see \Rector\Config\RectorConfig::parallel() instead * @deprecated Use @see \Rector\Config\RectorConfig::parallel() instead
* @var string * @var string

View File

@ -156,7 +156,7 @@ final class ConsoleApplication extends Application
)); ));
$inputDefinition->addOption(new InputOption( $inputDefinition->addOption(new InputOption(
'working-dir', Option::WORKING_DIR,
null, null,
InputOption::VALUE_REQUIRED, InputOption::VALUE_REQUIRED,
'If specified, use the given directory as working directory.' 'If specified, use the given directory as working directory.'

View File

@ -142,7 +142,9 @@ final class NodeFactory
*/ */
public function createArgs(array $values): array public function createArgs(array $values): array
{ {
array_walk($values, fn ($value) => $this->normalizeArgValue($value)); foreach ($values as $value) {
$this->normalizeArgValue($value);
}
return $this->builderFactory->args($values); return $this->builderFactory->args($values);
} }