mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-01 08:50:50 +00:00
[CI] Add type-declaration set (#4089)
* [CI] Add type-declaration set * [rector] [CI] Add type-declaration set * [cs] [CI] Add type-declaration set * skip nullable void * add anonymous parent/interface support * refactor MultiExceptionCatchRector to use Catch_ over integers * type fixes * fix unoin array type override * remove unused test cases * drop overcomplicated InlineValidationRulesToArrayDefinitionRector * skip assign on var * [rector] skip assign on var * [cs] skip assign on var * [rector] [cs] skip assign on var * skip assign on var * fixes * [rector] fixes * [cs] fixes Co-authored-by: rector-bot <tomas@getrector.org>
This commit is contained in:
parent
02e703b9b9
commit
7ac228c638
3
.github/workflows/rector_ci.yaml
vendored
3
.github/workflows/rector_ci.yaml
vendored
|
@ -32,7 +32,8 @@ jobs:
|
|||
-
|
||||
uses: shivammathur/setup-php@v1
|
||||
with:
|
||||
php-version: 7.3
|
||||
# PHP 7.2 is required, so Rector's code is PHP 7.2 compatible even after refactoring
|
||||
php-version: 7.2
|
||||
coverage: none
|
||||
|
||||
- run: composer install --no-progress --ansi
|
||||
|
|
|
@ -84,6 +84,9 @@ final class ComposerJsonManipulator
|
|||
$this->smartFileSystem->dumpFile($composerJsonFile, $this->originalComposerJsonFileContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function removeDevKeys(array $json): array
|
||||
{
|
||||
foreach (self::KEYS_TO_REMOVE as $keyToRemove) {
|
||||
|
@ -94,6 +97,7 @@ final class ComposerJsonManipulator
|
|||
|
||||
/**
|
||||
* Use phpstan/phpstan-src, because the phpstan.phar cannot be packed into rector.phar
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function replacePHPStanWithPHPStanSrc(array $json): array
|
||||
{
|
||||
|
@ -124,6 +128,9 @@ final class ComposerJsonManipulator
|
|||
return $this->allowDevDependencies($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function addDevDependenciesFromPHPStan(array $json, string $phpstanVersion): array
|
||||
{
|
||||
// add dev dependencies from PHPStan composer.json
|
||||
|
@ -143,6 +150,10 @@ final class ComposerJsonManipulator
|
|||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $json
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function allowDevDependencies(array $json): array
|
||||
{
|
||||
$json['minimum-stability'] = 'dev';
|
||||
|
@ -151,6 +162,9 @@ final class ComposerJsonManipulator
|
|||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
private function readRemoteFileToJson(string $jsonFilePath): array
|
||||
{
|
||||
$jsonFileContent = $this->smartFileSystem->readFile($jsonFilePath);
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\CodingStyle\Rector\ClassMethod\ReturnArrayClassMethodToYieldRector;
|
||||
use Rector\PHPUnit\Rector\Class_\AddSeeTestAnnotationRector;
|
||||
use Rector\PHPUnit\Rector\MethodCall\RemoveExpectAnyFromMockRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->set(RemoveExpectAnyFromMockRector::class);
|
||||
|
||||
$services->set(AddSeeTestAnnotationRector::class);
|
||||
$services->set(ReturnArrayClassMethodToYieldRector::class);
|
||||
};
|
||||
|
|
|
@ -14,14 +14,10 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->set(ParamTypeDeclarationRector::class);
|
||||
|
||||
$services->set(ReturnTypeDeclarationRector::class);
|
||||
|
||||
$services->set(PropertyTypeDeclarationRector::class);
|
||||
|
||||
$services->set(AddClosureReturnTypeRector::class);
|
||||
|
||||
$services->set(AddArrayParamDocTypeRector::class);
|
||||
|
||||
$services->set(AddArrayReturnDocTypeRector::class);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# All 565 Rectors Overview
|
||||
# All 564 Rectors Overview
|
||||
|
||||
- [Projects](#projects)
|
||||
---
|
||||
|
@ -20,7 +20,7 @@
|
|||
- [FileSystemRector](#filesystemrector) (1)
|
||||
- [Generic](#generic) (38)
|
||||
- [JMS](#jms) (2)
|
||||
- [Laravel](#laravel) (4)
|
||||
- [Laravel](#laravel) (3)
|
||||
- [Legacy](#legacy) (4)
|
||||
- [MagicDisclosure](#magicdisclosure) (8)
|
||||
- [MockeryToProphecy](#mockerytoprophecy) (2)
|
||||
|
@ -5998,30 +5998,6 @@ Removes JMS\DiExtraBundle\Annotation\Services annotation
|
|||
|
||||
## Laravel
|
||||
|
||||
### `InlineValidationRulesToArrayDefinitionRector`
|
||||
|
||||
- class: [`Rector\Laravel\Rector\ArrayItem\InlineValidationRulesToArrayDefinitionRector`](/../master/rules/laravel/src/Rector/ArrayItem/InlineValidationRulesToArrayDefinitionRector.php)
|
||||
- [test fixtures](/../master/rules/laravel/tests/Rector/ArrayItem/InlineValidationRulesToArrayDefinitionRector/Fixture)
|
||||
|
||||
Transforms inline validation rules to array definition
|
||||
|
||||
```diff
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SomeClass extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
- 'someAttribute' => 'required|string|exists:' . SomeModel::class . 'id',
|
||||
+ 'someAttribute' => ['required', 'string', \Illuminate\Validation\Rule::exists(SomeModel::class, 'id')],
|
||||
];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `MinutesToSecondsInCacheRector`
|
||||
|
||||
- class: [`Rector\Laravel\Rector\StaticCall\MinutesToSecondsInCacheRector`](/../master/rules/laravel/src/Rector/StaticCall/MinutesToSecondsInCacheRector.php)
|
||||
|
@ -14073,7 +14049,7 @@ return function (ContainerConfigurator $containerConfigurator) : void {
|
|||
$services->set(PropertyAssignToMethodCallRector::class)
|
||||
->call('configure', [[
|
||||
PropertyAssignToMethodCallRector::PROPERTY_ASSIGNS_TO_METHODS_CALLS => [
|
||||
\Rector\SymfonyPhpConfig\inline_value_object(new Rector\Transform\ValueObject\PropertyAssignToMethodCall('SomeClass', 'oldPropertyName', 'oldProperty')), \Rector\SymfonyPhpConfig\inline_value_object(new Rector\Transform\ValueObject\PropertyAssignToMethodCall('SomeClass', 'newMethodName', 'newMethodCall'))]
|
||||
\Rector\SymfonyPhpConfig\inline_value_object(new Rector\Transform\ValueObject\PropertyAssignToMethodCall('SomeClass', 'oldProperty', 'newMethodCall'))]
|
||||
]]);
|
||||
};
|
||||
```
|
||||
|
@ -14576,9 +14552,9 @@ Change @return types and type from static analysis to type declarations if not a
|
|||
|
||||
class SomeClass
|
||||
{
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
- /**
|
||||
- * @return int
|
||||
- */
|
||||
- public function getCount()
|
||||
+ public function getCount(): int
|
||||
{
|
||||
|
|
3
ecs.php
3
ecs.php
|
@ -64,7 +64,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
$parameters->set(Option::EXCLUDE_PATHS, [
|
||||
'*/Source/*',
|
||||
'*/Fixture/*', '*/Expected/*',
|
||||
'*/Fixture/*',
|
||||
'*/Expected/*',
|
||||
# generated from /vendor
|
||||
__DIR__ . '/packages/doctrine-annotation-generated/src/ConstantPreservingDocParser.php',
|
||||
__DIR__ . '/packages/doctrine-annotation-generated/src/ConstantPreservingAnnotationReader.php',
|
||||
|
|
|
@ -12,5 +12,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->public();
|
||||
|
||||
$services->load('Rector\AttributeAwarePhpDoc\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Ast/*']);
|
||||
->exclude([__DIR__ . '/../src/Ast']);
|
||||
};
|
||||
|
|
|
@ -35,7 +35,6 @@ final class AttributeAwareArrayShapeItemNodeFactory implements AttributeNodeAwar
|
|||
public function create(Node $node, string $docContent): AttributeAwareNodeInterface
|
||||
{
|
||||
$node->valueType = $this->attributeAwareNodeFactory->createFromNode($node->valueType, $docContent);
|
||||
|
||||
return new AttributeAwareArrayShapeItemNode($node->keyName, $node->optional, $node->valueType, $docContent);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,11 +36,12 @@ final class AttributeAwareGenericTypeNodeFactory implements AttributeNodeAwareFa
|
|||
{
|
||||
$node->type = $this->attributeAwareNodeFactory->createFromNode($node->type, $docContent);
|
||||
|
||||
foreach ($node->genericTypes as $key => $genericType) {
|
||||
$node->genericTypes[$key] = $this->attributeAwareNodeFactory->createFromNode($genericType, $docContent);
|
||||
$genericTypes = [];
|
||||
foreach ($node->genericTypes as $genericType) {
|
||||
$genericTypes[] = $this->attributeAwareNodeFactory->createFromNode($genericType, $docContent);
|
||||
}
|
||||
|
||||
return new AttributeAwareGenericTypeNode($node->type, $node->genericTypes);
|
||||
return new AttributeAwareGenericTypeNode($node->type, $genericTypes);
|
||||
}
|
||||
|
||||
public function setAttributeAwareNodeFactory(AttributeAwareNodeFactory $attributeAwareNodeFactory): void
|
||||
|
|
|
@ -51,10 +51,7 @@ final class NodeAnnotationReader
|
|||
$this->constantReferenceIdentifierRestorer = $constantReferenceIdentifierRestorer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object|null
|
||||
*/
|
||||
public function readAnnotation(Node $node, string $annotationClass)
|
||||
public function readAnnotation(Node $node, string $annotationClass): ?object
|
||||
{
|
||||
if ($node instanceof Property) {
|
||||
return $this->readPropertyAnnotation($node, $annotationClass);
|
||||
|
@ -71,10 +68,7 @@ final class NodeAnnotationReader
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object|null
|
||||
*/
|
||||
public function readClassAnnotation(Class_ $class, string $annotationClassName)
|
||||
public function readClassAnnotation(Class_ $class, string $annotationClassName): ?object
|
||||
{
|
||||
$classReflection = $this->createClassReflectionFromNode($class);
|
||||
|
||||
|
@ -90,10 +84,7 @@ final class NodeAnnotationReader
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object|null
|
||||
*/
|
||||
public function readPropertyAnnotation(Property $property, string $annotationClassName)
|
||||
public function readPropertyAnnotation(Property $property, string $annotationClassName): ?object
|
||||
{
|
||||
$propertyReflection = $this->createPropertyReflectionFromPropertyNode($property);
|
||||
if ($propertyReflection === null) {
|
||||
|
@ -112,10 +103,7 @@ final class NodeAnnotationReader
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object|null
|
||||
*/
|
||||
private function readMethodAnnotation(ClassMethod $classMethod, string $annotationClassName)
|
||||
private function readMethodAnnotation(ClassMethod $classMethod, string $annotationClassName): ?object
|
||||
{
|
||||
/** @var string $className */
|
||||
$className = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\BetterPhpDocParser\Attributes\Attribute;
|
||||
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartEndValueObject;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
|
||||
|
||||
final class Attribute
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ final class Attribute
|
|||
* @experiment
|
||||
* @var string
|
||||
*/
|
||||
public const START_END = StartEndValueObject::class;
|
||||
public const START_END = StartAndEnd::class;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
|
|
|
@ -21,7 +21,6 @@ use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwareParamTagValueNode;
|
|||
use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwarePhpDocNode;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwarePhpDocTagNode;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwareReturnTagValueNode;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwareVarTagValueNode;
|
||||
use Rector\BetterPhpDocParser\Annotation\StaticAnnotationNaming;
|
||||
use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\SpacelessPhpDocTagNode;
|
||||
use Rector\BetterPhpDocParser\Contract\PhpDocNode\AttributeAwareNodeInterface;
|
||||
|
@ -147,7 +146,7 @@ final class PhpDocInfo
|
|||
return count($this->tokens);
|
||||
}
|
||||
|
||||
public function getVarTagValue(): ?AttributeAwareVarTagValueNode
|
||||
public function getVarTagValue(): ?VarTagValueNode
|
||||
{
|
||||
return $this->phpDocNode->getVarTagValues()[0] ?? null;
|
||||
}
|
||||
|
@ -166,7 +165,11 @@ final class PhpDocInfo
|
|||
return $tag->name === $name;
|
||||
});
|
||||
|
||||
return array_values($tags);
|
||||
// @todo add dynamic function type resolver to PHPStan, the same type on input is on output
|
||||
$tags = array_values($tags);
|
||||
|
||||
/** @var PhpDocTagNode[]|AttributeAwareNodeInterface[] $tags */
|
||||
return $tags;
|
||||
}
|
||||
|
||||
public function getParamType(string $name): Type
|
||||
|
|
|
@ -15,7 +15,7 @@ use Rector\BetterPhpDocParser\Contract\PhpDocNode\AttributeAwareNodeInterface;
|
|||
use Rector\BetterPhpDocParser\Contract\PhpDocNodeFactoryInterface;
|
||||
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocRemover;
|
||||
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartEndValueObject;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
|
||||
use Rector\Core\Configuration\CurrentNodeProvider;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
|
@ -129,11 +129,11 @@ final class PhpDocInfoFactory
|
|||
/** @var AttributeAwareNodeInterface $lastChildNode */
|
||||
$lastChildNode = array_pop($phpDocChildNodes);
|
||||
|
||||
/** @var StartEndValueObject $startEndValueObject */
|
||||
$startEndValueObject = $lastChildNode->getAttribute(Attribute::START_END);
|
||||
/** @var StartAndEnd $startAndEnd */
|
||||
$startAndEnd = $lastChildNode->getAttribute(Attribute::START_END);
|
||||
|
||||
if ($startEndValueObject !== null) {
|
||||
$attributeAwarePhpDocNode->setAttribute(Attribute::LAST_TOKEN_POSITION, $startEndValueObject->getEnd());
|
||||
if ($startAndEnd !== null) {
|
||||
$attributeAwarePhpDocNode->setAttribute(Attribute::LAST_TOKEN_POSITION, $startAndEnd->getEnd());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,8 +98,8 @@ final class PhpDocTypeChanger
|
|||
|
||||
// override existing type
|
||||
$newPHPStanPhpDocType = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType);
|
||||
|
||||
$currentReturnTagValueNode = $phpDocInfo->getReturnTagValue();
|
||||
|
||||
if ($currentReturnTagValueNode !== null) {
|
||||
// only change type
|
||||
$currentReturnTagValueNode->type = $newPHPStanPhpDocType;
|
||||
|
|
|
@ -21,7 +21,7 @@ final class IndexTagValueNode extends AbstractDoctrineTagValueNode implements Ta
|
|||
parent::__construct($items, $content);
|
||||
}
|
||||
|
||||
public function getTag(): ?string
|
||||
public function getTag(): string
|
||||
{
|
||||
return $this->tag ?: $this->getShortName();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ final class UniqueConstraintTagValueNode extends AbstractDoctrineTagValueNode im
|
|||
parent::__construct($items, $content);
|
||||
}
|
||||
|
||||
public function getTag(): ?string
|
||||
public function getTag(): string
|
||||
{
|
||||
return $this->tag ?: $this->getShortName();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ final class JoinColumnTagValueNode extends AbstractDoctrineTagValueNode implemen
|
|||
return $this->items['nullable'];
|
||||
}
|
||||
|
||||
public function getTag(): ?string
|
||||
public function getTag(): string
|
||||
{
|
||||
return $this->tag ?: $this->shortName;
|
||||
}
|
||||
|
|
|
@ -103,10 +103,9 @@ final class JoinTablePhpDocNodeFactory extends AbstractPhpDocNodeFactory impleme
|
|||
}
|
||||
|
||||
/**
|
||||
* @param JoinTable $joinTable
|
||||
* @return JoinColumnTagValueNode[]
|
||||
*/
|
||||
private function createJoinColumnTagValues(string $annotationContent, $joinTable, string $type): array
|
||||
private function createJoinColumnTagValues(string $annotationContent, JoinTable $joinTable, string $type): array
|
||||
{
|
||||
$joinColumnContents = $this->matchJoinColumnContents($annotationContent);
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ declare(strict_types=1);
|
|||
namespace Rector\BetterPhpDocParser\PhpDocNodeFactory;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use PHPStan\PhpDocParser\Parser\ParserException;
|
||||
|
@ -63,10 +62,10 @@ final class ParamPhpDocNodeFactory
|
|||
{
|
||||
try {
|
||||
$tokenIterator->pushSavePoint();
|
||||
$tagValue = $this->parseParamTagValue($tokenIterator);
|
||||
$attributeAwareParamTagValueNode = $this->parseParamTagValue($tokenIterator);
|
||||
$tokenIterator->dropSavePoint();
|
||||
|
||||
return $tagValue;
|
||||
return $attributeAwareParamTagValueNode;
|
||||
} catch (ParserException $parserException) {
|
||||
$tokenIterator->rollback();
|
||||
$description = $this->privatesCaller->callPrivateMethod(
|
||||
|
@ -87,7 +86,7 @@ final class ParamPhpDocNodeFactory
|
|||
/**
|
||||
* Override of parent private method to allow reference: https://github.com/rectorphp/rector/pull/1735
|
||||
*/
|
||||
private function parseParamTagValue(TokenIterator $tokenIterator): ParamTagValueNode
|
||||
private function parseParamTagValue(TokenIterator $tokenIterator): AttributeAwareParamTagValueNode
|
||||
{
|
||||
$originalTokenIterator = clone $tokenIterator;
|
||||
$annotationContent = $this->annotationContentResolver->resolveFromTokenIterator($originalTokenIterator);
|
||||
|
|
|
@ -23,7 +23,7 @@ use Rector\BetterPhpDocParser\Contract\SpecificPhpDocNodeFactoryInterface;
|
|||
use Rector\BetterPhpDocParser\PhpDocNodeFactory\ParamPhpDocNodeFactory;
|
||||
use Rector\BetterPhpDocParser\PhpDocNodeFactory\PHPUnitDataProviderDocNodeFactory;
|
||||
use Rector\BetterPhpDocParser\Printer\MultilineSpaceFormatPreserver;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartEndValueObject;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
|
||||
use Rector\Core\Configuration\CurrentNodeProvider;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Symplify\PackageBuilder\Reflection\PrivatesAccessor;
|
||||
|
@ -238,10 +238,10 @@ final class BetterPhpDocParser extends PhpDocParser
|
|||
|
||||
$tokenEnd = $this->resolveTokenEnd($tokenIterator);
|
||||
|
||||
$startEndValueObject = new StartEndValueObject($tokenStart, $tokenEnd);
|
||||
$startAndEnd = new StartAndEnd($tokenStart, $tokenEnd);
|
||||
|
||||
$attributeAwareNode = $this->attributeAwareNodeFactory->createFromNode($phpDocNode, $docContent);
|
||||
$attributeAwareNode->setAttribute(Attribute::START_END, $startEndValueObject);
|
||||
$attributeAwareNode->setAttribute(Attribute::START_END, $startAndEnd);
|
||||
|
||||
$possibleMultilineText = $this->multilineSpaceFormatPreserver->resolveCurrentPhpDocNodeText(
|
||||
$attributeAwareNode
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace Rector\BetterPhpDocParser\Printer;
|
|||
|
||||
use Nette\Utils\Strings;
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartEndValueObject;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
|
||||
|
||||
final class OriginalSpacingRestorer
|
||||
{
|
||||
|
@ -27,9 +27,9 @@ final class OriginalSpacingRestorer
|
|||
Node $node,
|
||||
string $nodeOutput,
|
||||
array $tokens,
|
||||
StartEndValueObject $startEndValueObject
|
||||
StartAndEnd $startAndEnd
|
||||
): string {
|
||||
$oldWhitespaces = $this->whitespaceDetector->detectOldWhitespaces($node, $tokens, $startEndValueObject);
|
||||
$oldWhitespaces = $this->whitespaceDetector->detectOldWhitespaces($node, $tokens, $startAndEnd);
|
||||
|
||||
// no original whitespaces, return
|
||||
if ($oldWhitespaces === []) {
|
||||
|
|
|
@ -18,7 +18,7 @@ use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwarePhpDocTagNode;
|
|||
use Rector\BetterPhpDocParser\Attributes\Attribute\Attribute;
|
||||
use Rector\BetterPhpDocParser\Contract\PhpDocNode\AttributeAwareNodeInterface;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartEndValueObject;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
|
||||
/**
|
||||
|
@ -47,7 +47,7 @@ final class PhpDocInfoPrinter
|
|||
private $tokens = [];
|
||||
|
||||
/**
|
||||
* @var StartEndValueObject[]
|
||||
* @var StartAndEnd[]
|
||||
*/
|
||||
private $removedNodePositions = [];
|
||||
|
||||
|
@ -170,45 +170,45 @@ final class PhpDocInfoPrinter
|
|||
|
||||
private function printNode(
|
||||
AttributeAwareNodeInterface $attributeAwareNode,
|
||||
?StartEndValueObject $startEndValueObject = null,
|
||||
?StartAndEnd $startAndEnd = null,
|
||||
int $key = 0,
|
||||
int $nodeCount = 0
|
||||
): string {
|
||||
$output = '';
|
||||
|
||||
/** @var StartEndValueObject|null $startEndValueObject */
|
||||
$startEndValueObject = $attributeAwareNode->getAttribute(Attribute::START_END) ?: $startEndValueObject;
|
||||
/** @var StartAndEnd|null $startAndEnd */
|
||||
$startAndEnd = $attributeAwareNode->getAttribute(Attribute::START_END) ?: $startAndEnd;
|
||||
$attributeAwareNode = $this->multilineSpaceFormatPreserver->fixMultilineDescriptions($attributeAwareNode);
|
||||
|
||||
if ($startEndValueObject !== null) {
|
||||
if ($startAndEnd !== null) {
|
||||
$isLastToken = ($nodeCount === $key);
|
||||
|
||||
$output = $this->addTokensFromTo(
|
||||
$output,
|
||||
$this->currentTokenPosition,
|
||||
$startEndValueObject->getStart(),
|
||||
$startAndEnd->getStart(),
|
||||
$isLastToken
|
||||
);
|
||||
|
||||
$this->currentTokenPosition = $startEndValueObject->getEnd();
|
||||
$this->currentTokenPosition = $startAndEnd->getEnd();
|
||||
}
|
||||
|
||||
if ($attributeAwareNode instanceof PhpDocTagNode) {
|
||||
if ($startEndValueObject !== null) {
|
||||
return $this->printPhpDocTagNode($attributeAwareNode, $startEndValueObject, $output);
|
||||
if ($startAndEnd !== null) {
|
||||
return $this->printPhpDocTagNode($attributeAwareNode, $startAndEnd, $output);
|
||||
}
|
||||
|
||||
return $output . self::NEWLINE_ASTERISK . $this->printAttributeWithAsterisk($attributeAwareNode);
|
||||
}
|
||||
|
||||
if (! $attributeAwareNode instanceof PhpDocTextNode && ! $attributeAwareNode instanceof GenericTagValueNode && $startEndValueObject) {
|
||||
if (! $attributeAwareNode instanceof PhpDocTextNode && ! $attributeAwareNode instanceof GenericTagValueNode && $startAndEnd) {
|
||||
$nodeContent = (string) $attributeAwareNode;
|
||||
|
||||
return $this->originalSpacingRestorer->restoreInOutputWithTokensStartAndEndPosition(
|
||||
$attributeAwareNode,
|
||||
$nodeContent,
|
||||
$this->tokens,
|
||||
$startEndValueObject
|
||||
$startAndEnd
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ final class PhpDocInfoPrinter
|
|||
*/
|
||||
private function printPhpDocTagNode(
|
||||
PhpDocTagNode $phpDocTagNode,
|
||||
StartEndValueObject $startEndValueObject,
|
||||
StartAndEnd $startAndEnd,
|
||||
string $output
|
||||
): string {
|
||||
$output .= $phpDocTagNode->name;
|
||||
|
@ -267,7 +267,7 @@ final class PhpDocInfoPrinter
|
|||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$nodeOutput = $this->printNode($phpDocTagNodeValue, $startEndValueObject);
|
||||
$nodeOutput = $this->printNode($phpDocTagNodeValue, $startAndEnd);
|
||||
$tagSpaceSeparator = $this->resolveTagSpaceSeparator($phpDocTagNode);
|
||||
|
||||
// space is handled by $tagSpaceSeparator
|
||||
|
@ -301,7 +301,7 @@ final class PhpDocInfoPrinter
|
|||
}
|
||||
|
||||
/**
|
||||
* @return StartEndValueObject[]
|
||||
* @return StartAndEnd[]
|
||||
*/
|
||||
private function getRemovedNodesPositions(): array
|
||||
{
|
||||
|
@ -316,7 +316,7 @@ final class PhpDocInfoPrinter
|
|||
);
|
||||
|
||||
foreach ($removedNodes as $removedNode) {
|
||||
/** @var StartEndValueObject $removedPhpDocNodeInfo */
|
||||
/** @var StartAndEnd $removedPhpDocNodeInfo */
|
||||
$removedPhpDocNodeInfo = $removedNode->getAttribute(Attribute::START_END);
|
||||
|
||||
// change start position to start of the line, so the whole line is removed
|
||||
|
@ -325,10 +325,7 @@ final class PhpDocInfoPrinter
|
|||
--$seekPosition;
|
||||
}
|
||||
|
||||
$this->removedNodePositions[] = new StartEndValueObject(
|
||||
$seekPosition - 1,
|
||||
$removedPhpDocNodeInfo->getEnd()
|
||||
);
|
||||
$this->removedNodePositions[] = new StartAndEnd($seekPosition - 1, $removedPhpDocNodeInfo->getEnd());
|
||||
}
|
||||
|
||||
return $this->removedNodePositions;
|
||||
|
|
|
@ -10,7 +10,7 @@ use PHPStan\PhpDocParser\Ast\Node;
|
|||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use Rector\BetterPhpDocParser\Contract\Doctrine\DoctrineTagNodeInterface;
|
||||
use Rector\BetterPhpDocParser\Contract\PhpDocNode\ShortNameAwareTagInterface;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartEndValueObject;
|
||||
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
|
||||
|
||||
final class WhitespaceDetector
|
||||
{
|
||||
|
@ -18,18 +18,18 @@ final class WhitespaceDetector
|
|||
* @param mixed[] $tokens
|
||||
* @return string[]
|
||||
*/
|
||||
public function detectOldWhitespaces(Node $node, array $tokens, StartEndValueObject $startEndValueObject): array
|
||||
public function detectOldWhitespaces(Node $node, array $tokens, StartAndEnd $startAndEnd): array
|
||||
{
|
||||
$oldWhitespaces = [];
|
||||
|
||||
$start = $startEndValueObject->getStart();
|
||||
$start = $startAndEnd->getStart();
|
||||
// this is needed, because of 1 token taken from tokens and added annotation name: "ORM" + "\X" → "ORM\X"
|
||||
// todo, this might be needed to be dynamic, based on taken tokens count (some Collector?)
|
||||
if ($node instanceof DoctrineTagNodeInterface) {
|
||||
--$start;
|
||||
}
|
||||
|
||||
for ($i = $start; $i < $startEndValueObject->getEnd(); ++$i) {
|
||||
for ($i = $start; $i < $startAndEnd->getEnd(); ++$i) {
|
||||
/** @var string $tokenValue */
|
||||
$tokenValue = $tokens[$i][0];
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\BetterPhpDocParser\ValueObject;
|
||||
|
||||
final class StartEndValueObject
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
|
||||
final class StartAndEnd
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
|
@ -18,6 +20,10 @@ final class StartEndValueObject
|
|||
|
||||
public function __construct(int $start, int $end)
|
||||
{
|
||||
if ($end < $start) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->start = $start;
|
||||
$this->end = $end;
|
||||
}
|
|
@ -13,6 +13,9 @@ use Rector\BetterPhpDocParser\PhpDocNode\Symfony\SymfonyRouteTagValueNode;
|
|||
use Rector\BetterPhpDocParser\Utils\ArrayItemStaticHelper;
|
||||
use Rector\BetterPhpDocParser\ValueObject\TagValueNodeConfiguration;
|
||||
|
||||
/**
|
||||
* @see \Rector\BetterPhpDocParser\Tests\ValueObjectFactory\TagValueNodeConfigurationFactoryTest
|
||||
*/
|
||||
final class TagValueNodeConfigurationFactory
|
||||
{
|
||||
public function createFromOriginalContent(
|
||||
|
|
|
@ -16,6 +16,7 @@ use Symplify\SmartFileSystem\SmartFileInfo;
|
|||
|
||||
/**
|
||||
* Inspired by https://github.com/symplify/easy-coding-standard/blob/e598ab54686e416788f28fcfe007fd08e0f371d9/packages/changed-files-detector/src/FileHashComputer.php
|
||||
* @see \Rector\Caching\Tests\Config\FileHashComputerTest
|
||||
*/
|
||||
final class FileHashComputer
|
||||
{
|
||||
|
|
|
@ -13,5 +13,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->public();
|
||||
|
||||
$services->load('Rector\ChangesReporting\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Contract/*', __DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/Contract', __DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -36,7 +36,7 @@ final class RectorChangeCollector
|
|||
{
|
||||
return array_filter(
|
||||
$this->rectorWithFileAndLineChanges,
|
||||
function (RectorWithFileAndLineChange $rectorWithFileAndLineChange) use ($smartFileInfo) {
|
||||
function (RectorWithFileAndLineChange $rectorWithFileAndLineChange) use ($smartFileInfo): bool {
|
||||
return $rectorWithFileAndLineChange->getRealPath() === $smartFileInfo->getRealPath();
|
||||
}
|
||||
);
|
||||
|
|
|
@ -12,5 +12,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->public();
|
||||
|
||||
$services->load('Rector\DynamicTypeAnalysis\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector/*']);
|
||||
->exclude([__DIR__ . '/../src/Rector']);
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ use Rector\DynamicTypeAnalysis\ProbeStorage\StaticFileSystemProbeStorage;
|
|||
|
||||
/**
|
||||
* @see https://stackoverflow.com/a/39525458/1348344
|
||||
* @see \Rector\DynamicTypeAnalysis\Tests\Probe\TypeStaticProbeTest
|
||||
*/
|
||||
final class TypeStaticProbe
|
||||
{
|
||||
|
|
|
@ -74,7 +74,7 @@ final class PropertyUsageAnalyzer
|
|||
|
||||
$isPropertyFetched = (bool) $this->betterNodeFinder->findFirst(
|
||||
(array) $childClass->stmts,
|
||||
function (Node $node) use ($propertyName) {
|
||||
function (Node $node) use ($propertyName): bool {
|
||||
return $this->isLocalPropertyFetchNamed($node, $propertyName);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -16,5 +16,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->autowire();
|
||||
|
||||
$services->load('Rector\FileSystemRector\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector/*']);
|
||||
->exclude([__DIR__ . '/../src/Rector']);
|
||||
};
|
||||
|
|
|
@ -13,5 +13,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->autoconfigure();
|
||||
|
||||
$services->load('Rector\NodeCollector\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -196,7 +196,7 @@ final class ParsedFunctionLikeNodeCollector
|
|||
{
|
||||
$calls = Arrays::flatten($this->methodsCallsByTypeAndMethod);
|
||||
|
||||
return array_filter($calls, function (Node $node) {
|
||||
return array_filter($calls, function (Node $node): bool {
|
||||
return $node instanceof MethodCall;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use PhpParser\Node\Expr\StaticCall;
|
|||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassConst;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
|
@ -58,11 +59,6 @@ final class ParsedNodeCollector
|
|||
*/
|
||||
private $constantsByType = [];
|
||||
|
||||
/**
|
||||
* @var array<array<TNodeType>>
|
||||
*/
|
||||
private $simpleParsedNodesByType = [];
|
||||
|
||||
/**
|
||||
* @var Interface_[]
|
||||
*/
|
||||
|
@ -73,6 +69,26 @@ final class ParsedNodeCollector
|
|||
*/
|
||||
private $traits = [];
|
||||
|
||||
/**
|
||||
* @var StaticCall[]
|
||||
*/
|
||||
private $staticCalls = [];
|
||||
|
||||
/**
|
||||
* @var New_[]
|
||||
*/
|
||||
private $news = [];
|
||||
|
||||
/**
|
||||
* @var Param[]
|
||||
*/
|
||||
private $params = [];
|
||||
|
||||
/**
|
||||
* @var ClassConstFetch[]
|
||||
*/
|
||||
private $classConstFetches = [];
|
||||
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
|
@ -83,15 +99,6 @@ final class ParsedNodeCollector
|
|||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string<TNodeType> $type
|
||||
* @return array<TNodeType>
|
||||
*/
|
||||
public function getNodesByType(string $type): array
|
||||
{
|
||||
return $this->simpleParsedNodesByType[$type] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Interface_[]
|
||||
*/
|
||||
|
@ -160,25 +167,13 @@ final class ParsedNodeCollector
|
|||
|
||||
public function collect(Node $node): void
|
||||
{
|
||||
$nodeClass = get_class($node);
|
||||
|
||||
if ($node instanceof Class_) {
|
||||
$this->addClass($node);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof Interface_ || $node instanceof Trait_) {
|
||||
$name = $this->nodeNameResolver->getName($node);
|
||||
if ($name === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
if ($node instanceof Interface_) {
|
||||
$this->interfaces[$name] = $node;
|
||||
} elseif ($node instanceof Trait_) {
|
||||
$this->traits[$name] = $node;
|
||||
}
|
||||
|
||||
$this->collectInterfaceOrTrait($node);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -187,28 +182,42 @@ final class ParsedNodeCollector
|
|||
return;
|
||||
}
|
||||
|
||||
// simple collect
|
||||
$this->simpleParsedNodesByType[$nodeClass][] = $node;
|
||||
if ($node instanceof StaticCall) {
|
||||
$this->staticCalls[] = $node;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof New_) {
|
||||
$this->news[] = $node;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof Param) {
|
||||
$this->params[] = $node;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof ClassConstFetch) {
|
||||
$this->classConstFetches[] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return New_[]
|
||||
*/
|
||||
public function findNewNodesByClass(string $className): array
|
||||
public function findNewsByClass(string $className): array
|
||||
{
|
||||
$newNodesByClass = [];
|
||||
$newsByClass = [];
|
||||
|
||||
$news = $this->getNodesByType(New_::class);
|
||||
|
||||
foreach ($news as $new) {
|
||||
foreach ($this->news as $new) {
|
||||
if (! $this->nodeNameResolver->isName($new->class, $className)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newNodesByClass[] = $new;
|
||||
$newsByClass[] = $new;
|
||||
}
|
||||
|
||||
return $newNodesByClass;
|
||||
return $newsByClass;
|
||||
}
|
||||
|
||||
public function findClassConstantByClassConstFetch(ClassConstFetch $classConstFetch): ?ClassConst
|
||||
|
@ -229,6 +238,38 @@ final class ParsedNodeCollector
|
|||
return $this->findClassConstant($class, $constantName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClassConstFetch[]
|
||||
*/
|
||||
public function getClassConstFetches(): array
|
||||
{
|
||||
return $this->classConstFetches;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Param[]
|
||||
*/
|
||||
public function getParams(): array
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return New_[]
|
||||
*/
|
||||
public function getNews(): array
|
||||
{
|
||||
return $this->news;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return StaticCall[]
|
||||
*/
|
||||
public function getStaticCalls(): array
|
||||
{
|
||||
return $this->staticCalls;
|
||||
}
|
||||
|
||||
private function addClass(Class_ $class): void
|
||||
{
|
||||
if ($this->isClassAnonymous($class)) {
|
||||
|
@ -243,6 +284,23 @@ final class ParsedNodeCollector
|
|||
$this->classes[$className] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Interface_|Trait_ $classLike
|
||||
*/
|
||||
private function collectInterfaceOrTrait(ClassLike $classLike): void
|
||||
{
|
||||
$name = $this->nodeNameResolver->getName($classLike);
|
||||
if ($name === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
if ($classLike instanceof Interface_) {
|
||||
$this->interfaces[$name] = $classLike;
|
||||
} elseif ($classLike instanceof Trait_) {
|
||||
$this->traits[$name] = $classLike;
|
||||
}
|
||||
}
|
||||
|
||||
private function addClassConstant(ClassConst $classConst): void
|
||||
{
|
||||
$className = $classConst->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
|
|
@ -45,9 +45,6 @@ final class NodeCollectorNodeVisitor extends NodeVisitorAbstract
|
|||
$this->parsedClassConstFetchNodeCollector = $parsedClassConstFetchNodeCollector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|Node|void|null
|
||||
*/
|
||||
public function enterNode(Node $node)
|
||||
{
|
||||
if ($this->parsedNodeCollector->isCollectableNode($node)) {
|
||||
|
@ -57,5 +54,7 @@ final class NodeCollectorNodeVisitor extends NodeVisitorAbstract
|
|||
$this->parsedFunctionLikeNodeCollector->collect($node);
|
||||
$this->parsedPropertyFetchNodeCollector->collect($node);
|
||||
$this->parsedClassConstFetchNodeCollector->collect($node);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,5 +12,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->autowire();
|
||||
|
||||
$services->load('Rector\NodeNameResolver\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Contract/*']);
|
||||
->exclude([__DIR__ . '/../src/Contract']);
|
||||
};
|
||||
|
|
|
@ -13,5 +13,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->autoconfigure();
|
||||
|
||||
$services->load('Rector\NodeNestingScope\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ final class ScopeAwareNodeFinder
|
|||
*/
|
||||
public function findParentType(Node $node, array $allowedTypes): ?Node
|
||||
{
|
||||
$callable = function (Node $node) use ($allowedTypes) {
|
||||
$callable = function (Node $node) use ($allowedTypes): bool {
|
||||
foreach ($allowedTypes as $allowedType) {
|
||||
if (! is_a($node, $allowedType)) {
|
||||
continue;
|
||||
|
@ -58,7 +58,7 @@ final class ScopeAwareNodeFinder
|
|||
$foundNode = $this->betterNodeFinder->findFirstPrevious($node, function (Node $node) use (
|
||||
$callable,
|
||||
$parentNestingBreakTypes
|
||||
) {
|
||||
): bool {
|
||||
if ($callable($node)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->autowire();
|
||||
|
||||
$services->load('Rector\NodeTypeResolver\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Contract/*', __DIR__ . '/../src/PHPStan/TypeExtension/*']);
|
||||
->exclude([__DIR__ . '/../src/Contract', __DIR__ . '/../src/PHPStan/TypeExtension']);
|
||||
|
||||
$services->set(TypeAnalyzer::class);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Rector\NodeTypeResolver;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\NodeTraverser;
|
||||
use PhpParser\NodeVisitor\CloningVisitor;
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
|
@ -154,8 +155,8 @@ final class NodeScopeAndMetadataDecorator
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $nodes
|
||||
* @return Node[]
|
||||
* @param Stmt[] $nodes
|
||||
* @return Stmt[]
|
||||
*/
|
||||
public function decorateNodesFromString(array $nodes): array
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@ use PhpParser\Node\Expr\MethodCall;
|
|||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Scalar;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Type\Accessory\NonEmptyArrayType;
|
||||
use PHPStan\Type\ArrayType;
|
||||
|
@ -32,6 +33,8 @@ use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
|
|||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeCorrector\ParentClassesInterfacesAndUsedTraitsCorrector;
|
||||
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
use Rector\PHPStan\TypeFactoryStaticHelper;
|
||||
use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
|
||||
use Rector\TypeDeclaration\PHPStan\Type\ObjectTypeSpecifier;
|
||||
|
||||
|
@ -175,7 +178,7 @@ final class NodeTypeResolver
|
|||
}
|
||||
|
||||
if ($node instanceof New_ && $this->classNodeAnalyzer->isAnonymousClass($node->class)) {
|
||||
return new ObjectWithoutClassType();
|
||||
return $this->resolveAnonymousClassType($node);
|
||||
}
|
||||
|
||||
$staticType = $nodeScope->getType($node);
|
||||
|
@ -364,6 +367,38 @@ final class NodeTypeResolver
|
|||
return new ArrayType(new MixedType(), new MixedType());
|
||||
}
|
||||
|
||||
private function resolveAnonymousClassType(New_ $new): ObjectWithoutClassType
|
||||
{
|
||||
if (! $new->class instanceof Class_) {
|
||||
return new ObjectWithoutClassType();
|
||||
}
|
||||
|
||||
$types = [];
|
||||
|
||||
/** @var Class_ $class */
|
||||
$class = $new->class;
|
||||
if ($class->extends !== null) {
|
||||
$parentClass = (string) $class->extends;
|
||||
$types[] = new FullyQualifiedObjectType($parentClass);
|
||||
}
|
||||
|
||||
foreach ((array) $class->implements as $implement) {
|
||||
$parentClass = (string) $implement;
|
||||
$types[] = new FullyQualifiedObjectType($parentClass);
|
||||
}
|
||||
|
||||
if (count($types) > 1) {
|
||||
$unionType = TypeFactoryStaticHelper::createUnionObjectType($types);
|
||||
return new ObjectWithoutClassType($unionType);
|
||||
}
|
||||
|
||||
if (count($types) === 1) {
|
||||
return new ObjectWithoutClassType($types[0]);
|
||||
}
|
||||
|
||||
return new ObjectWithoutClassType();
|
||||
}
|
||||
|
||||
private function resolveByNodeTypeResolvers(Node $node): ?Type
|
||||
{
|
||||
foreach ($this->nodeTypeResolvers as $nodeClass => $nodeTypeResolver) {
|
||||
|
|
|
@ -15,6 +15,9 @@ use PhpParser\NodeVisitorAbstract;
|
|||
use Rector\CodingStyle\Naming\ClassNaming;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* @see \Rector\NodeTypeResolver\Tests\NodeVisitor\FunctionMethodAndClassNodeVisitor\FunctionMethodAndClassNodeVisitorTest
|
||||
*/
|
||||
final class FunctionMethodAndClassNodeVisitor extends NodeVisitorAbstract
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,7 @@ use PHPStan\Type\StringType;
|
|||
use PHPStan\Type\Type;
|
||||
use Rector\PHPStan\Type\AliasedObjectType;
|
||||
use Rector\PHPStan\Type\ShortenedObjectType;
|
||||
use Rector\TypeDeclaration\TypeNormalizer;
|
||||
|
||||
final class TypeComparator
|
||||
{
|
||||
|
@ -21,9 +22,15 @@ final class TypeComparator
|
|||
*/
|
||||
private $typeHasher;
|
||||
|
||||
public function __construct(TypeHasher $typeHasher)
|
||||
/**
|
||||
* @var TypeNormalizer
|
||||
*/
|
||||
private $typeNormalizer;
|
||||
|
||||
public function __construct(TypeHasher $typeHasher, TypeNormalizer $typeNormalizer)
|
||||
{
|
||||
$this->typeHasher = $typeHasher;
|
||||
$this->typeNormalizer = $typeNormalizer;
|
||||
}
|
||||
|
||||
public function areTypesEquals(Type $firstType, Type $secondType): bool
|
||||
|
@ -37,6 +44,9 @@ final class TypeComparator
|
|||
return true;
|
||||
}
|
||||
|
||||
$firstType = $this->typeNormalizer->normalizeArrayOfUnionToUnionArray($firstType);
|
||||
$secondType = $this->typeNormalizer->normalizeArrayOfUnionToUnionArray($secondType);
|
||||
|
||||
if ($this->typeHasher->areTypesEqual($firstType, $secondType)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -53,9 +53,7 @@ final class TypeHasher
|
|||
}
|
||||
|
||||
if ($type instanceof UnionType) {
|
||||
$types = $type->getTypes();
|
||||
sort($types);
|
||||
$type = new UnionType($types);
|
||||
return $this->createUnionTypeHash($type);
|
||||
}
|
||||
|
||||
return $this->phpStanStaticTypeMapper->mapToDocString($type);
|
||||
|
@ -65,4 +63,17 @@ final class TypeHasher
|
|||
{
|
||||
return $this->createTypeHash($firstType) === $this->createTypeHash($secondType);
|
||||
}
|
||||
|
||||
private function createUnionTypeHash(UnionType $unionType): string
|
||||
{
|
||||
$unionedTypesHashes = [];
|
||||
foreach ($unionType->getTypes() as $unionedType) {
|
||||
$unionedTypesHashes[] = $this->createTypeHash($unionedType);
|
||||
}
|
||||
|
||||
sort($unionedTypesHashes);
|
||||
$unionedTypesHashes = array_unique($unionedTypesHashes);
|
||||
|
||||
return implode('|', $unionedTypesHashes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,5 +13,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->autoconfigure();
|
||||
|
||||
$services->load('Rector\PhpAttribute\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Contract/*', __DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/Contract', __DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -12,5 +12,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->autowire();
|
||||
|
||||
$services->load('Rector\PHPStanStaticTypeMapper\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -25,6 +25,9 @@ use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
|
|||
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
|
||||
use Rector\TypeDeclaration\TypeNormalizer;
|
||||
|
||||
/**
|
||||
* @see \Rector\PHPStanStaticTypeMapper\Tests\TypeMapper\ArrayTypeMapperTest
|
||||
*/
|
||||
final class ArrayTypeMapper implements TypeMapperInterface
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -13,15 +13,22 @@ use PHPStan\Type\VerbosityLevel;
|
|||
use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareIdentifierTypeNode;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\PHPStanStaticTypeMapperAwareInterface;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
|
||||
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
|
||||
|
||||
final class ObjectWithoutClassTypeMapper implements TypeMapperInterface
|
||||
final class ObjectWithoutClassTypeMapper implements TypeMapperInterface, PHPStanStaticTypeMapperAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var PhpVersionProvider
|
||||
*/
|
||||
private $phpVersionProvider;
|
||||
|
||||
/**
|
||||
* @var PHPStanStaticTypeMapper
|
||||
*/
|
||||
private $phpStanStaticTypeMapper;
|
||||
|
||||
public function __construct(PhpVersionProvider $phpVersionProvider)
|
||||
{
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
|
@ -45,6 +52,11 @@ final class ObjectWithoutClassTypeMapper implements TypeMapperInterface
|
|||
*/
|
||||
public function mapToPhpParserNode(Type $type, ?string $kind = null): ?Node
|
||||
{
|
||||
$subtractedType = $type->getSubtractedType();
|
||||
if ($subtractedType !== null) {
|
||||
return $this->phpStanStaticTypeMapper->mapToPhpParserNode($subtractedType);
|
||||
}
|
||||
|
||||
if (! $this->phpVersionProvider->isAtLeast(PhpVersionFeature::OBJECT_TYPE)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -56,4 +68,9 @@ final class ObjectWithoutClassTypeMapper implements TypeMapperInterface
|
|||
{
|
||||
return $type->describe(VerbosityLevel::typeOnly());
|
||||
}
|
||||
|
||||
public function setPHPStanStaticTypeMapper(PHPStanStaticTypeMapper $phpStanStaticTypeMapper): void
|
||||
{
|
||||
$this->phpStanStaticTypeMapper = $phpStanStaticTypeMapper;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,9 @@ use Rector\Core\Php\PhpVersionProvider;
|
|||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
|
||||
|
||||
/**
|
||||
* @see \Rector\NodeTypeResolver\Tests\StaticTypeMapper\StaticTypeMapperTest
|
||||
*/
|
||||
final class StaticTypeMapper implements TypeMapperInterface
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -16,6 +16,7 @@ use PHPStan\Type\NullType;
|
|||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use PHPStan\Type\UnionType;
|
||||
use PHPStan\Type\VoidType;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareUnionTypeNode;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
|
@ -109,6 +110,11 @@ final class UnionTypeMapper implements TypeMapperInterface
|
|||
return $this->matchTypeForUnionedObjectTypes($type);
|
||||
}
|
||||
|
||||
// void cannot be nullable
|
||||
if ($nullabledType instanceof VoidType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$nullabledTypeNode = $this->phpStanStaticTypeMapper->mapToPhpParserNode($nullabledType);
|
||||
if ($nullabledTypeNode === null) {
|
||||
return null;
|
||||
|
|
|
@ -88,7 +88,7 @@ final class UseNodesToAddCollector implements NodeCollectorInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @return FullyQualifiedObjectType[]|AliasedObjectType[]
|
||||
* @return AliasedObjectType[]|FullyQualifiedObjectType[]
|
||||
*/
|
||||
public function getUseImportTypesByNode(Node $node): array
|
||||
{
|
||||
|
@ -156,7 +156,7 @@ final class UseNodesToAddCollector implements NodeCollectorInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @return FullyQualifiedObjectType[]|AliasedObjectType[]
|
||||
* @return AliasedObjectType[]|FullyQualifiedObjectType[]
|
||||
*/
|
||||
public function getObjectImportsByFileInfo(SmartFileInfo $smartFileInfo): array
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ final class NodeAddingPostRector extends AbstractPostRector
|
|||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]|Node
|
||||
* @return array<int|string, Node>|Node
|
||||
*/
|
||||
public function leaveNode(Node $node)
|
||||
{
|
||||
|
|
|
@ -59,7 +59,7 @@ final class RectorRecipe
|
|||
private $nodeTypes = [];
|
||||
|
||||
/**
|
||||
* @var mixed[]
|
||||
* @var string[]
|
||||
*/
|
||||
private $resources = [];
|
||||
|
||||
|
@ -123,6 +123,9 @@ final class RectorRecipe
|
|||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return $this->nodeTypes;
|
||||
|
@ -143,6 +146,9 @@ final class RectorRecipe
|
|||
return $this->codeAfter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getResources(): array
|
||||
{
|
||||
return $this->resources;
|
||||
|
|
|
@ -22,6 +22,9 @@ final class __Name__Test extends AbstractRectorTestCase
|
|||
yield [__DIR__ . '/Fixture/fixture.php.inc', '__ExtraFileName__', __DIR__ . '/Source/extra_file.php'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -21,6 +21,9 @@ final class __Name__Test extends AbstractRectorTestCase
|
|||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -21,6 +21,9 @@ final class WhateverRectorTest extends AbstractRectorTestCase
|
|||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -21,6 +21,9 @@ final class WhateverRectorTest extends AbstractRectorTestCase
|
|||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -13,5 +13,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->autoconfigure();
|
||||
|
||||
$services->load('Rector\Reporting\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -56,7 +56,7 @@ final class PrintReportCollectorEventSubscriber implements EventSubscriberInterf
|
|||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
|
|
|
@ -13,5 +13,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->autoconfigure();
|
||||
|
||||
$services->load('Rector\Set\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -31,7 +31,7 @@ final class NameScopeFactory
|
|||
|
||||
/**
|
||||
* @param Use_[] $useNodes
|
||||
* @return string[]
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function resolveUseNamesByAlias(array $useNodes): array
|
||||
{
|
||||
|
@ -47,7 +47,10 @@ final class NameScopeFactory
|
|||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$useNamesByAlias[$aliasName] = $useName;
|
||||
// uses must be lowercase, as PHPStan lowercases it
|
||||
$lowercasedAliasName = strtolower($aliasName);
|
||||
|
||||
$useNamesByAlias[$lowercasedAliasName] = $useName;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ use PHPStan\Type\Type;
|
|||
use Rector\StaticTypeMapper\Contract\PhpDocParser\PhpDocTypeMapperInterface;
|
||||
use Rector\StaticTypeMapper\PhpDoc\PhpDocTypeMapper;
|
||||
|
||||
/**
|
||||
* @see \Rector\PHPStanStaticTypeMapper\Tests\TypeMapper\ArrayTypeMapperTest
|
||||
*/
|
||||
final class ArrayTypeMapper implements PhpDocTypeMapperInterface
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,7 @@ use Rector\StaticTypeMapper\PHPStan\NameScopeFactory;
|
|||
|
||||
/**
|
||||
* Maps PhpParser <=> PHPStan <=> PHPStan doc <=> string type nodes between all possible formats
|
||||
* @see \Rector\NodeTypeResolver\Tests\StaticTypeMapper\StaticTypeMapperTest
|
||||
*/
|
||||
final class StaticTypeMapper
|
||||
{
|
||||
|
|
|
@ -87,7 +87,7 @@ abstract class AbstractNodeVendorLockResolver
|
|||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @return class-string[]
|
||||
*/
|
||||
protected function getChildrenClassesByClass(Class_ $class): array
|
||||
{
|
||||
|
|
|
@ -2,30 +2,14 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Rector\CodingStyle\Rector\ClassMethod\ReturnArrayClassMethodToYieldRector;
|
||||
use Rector\CodingStyle\Rector\String_\SplitStringClassConstantToClassConstFetchRector;
|
||||
use Rector\CodingStyle\ValueObject\MethodToYield;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\DeadCode\Rector\ClassConst\RemoveUnusedClassConstantRector;
|
||||
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
use function Rector\SymfonyPhpConfig\inline_value_objects;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->set(ReturnArrayClassMethodToYieldRector::class)
|
||||
->call('configure', [[
|
||||
ReturnArrayClassMethodToYieldRector::METHODS_TO_YIELDS => inline_value_objects([
|
||||
new MethodToYield(TestCase::class, 'provideData'),
|
||||
new MethodToYield(TestCase::class, 'provideData*'),
|
||||
new MethodToYield(TestCase::class, 'dataProvider'),
|
||||
new MethodToYield(TestCase::class, 'dataProvider*'),
|
||||
]),
|
||||
]]);
|
||||
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::SETS, [
|
||||
|
@ -38,6 +22,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
SetList::NAMING,
|
||||
SetList::ORDER,
|
||||
SetList::DEFLUENT,
|
||||
SetList::TYPE_DECLARATION,
|
||||
SetList::PHPUNIT_CODE_QUALITY,
|
||||
]);
|
||||
|
||||
$parameters->set(Option::PATHS, [
|
||||
|
@ -72,4 +58,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
// false positives on constants used in rector-ci.php
|
||||
RemoveUnusedClassConstantRector::class,
|
||||
]);
|
||||
|
||||
# so Rector code is still PHP 7.2 compatible
|
||||
$parameters->set(Option::PHP_VERSION_FEATURES, '7.2');
|
||||
};
|
||||
|
|
431
rector-temp-phpstan103667.neon
Normal file
431
rector-temp-phpstan103667.neon
Normal file
|
@ -0,0 +1,431 @@
|
|||
includes:
|
||||
- utils/phpstan-extensions/config/phpstan-extensions.neon
|
||||
- vendor/slam/phpstan-extensions/conf/slam-rules.neon
|
||||
- vendor/symplify/phpstan-extensions/config/config.neon
|
||||
- vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon
|
||||
|
||||
# see https://github.com/symplify/coding-standard
|
||||
- vendor/symplify/coding-standard/config/symplify-rules.neon
|
||||
|
||||
rules:
|
||||
# should be fixed in next part of symplify CS release
|
||||
- Symplify\CodingStandard\Rules\NoClassWithStaticMethodWithoutStaticNameRule
|
||||
- Symplify\CodingStandard\Rules\SeeAnnotationToTestRule
|
||||
- Symplify\CodingStandard\Rules\NoReferenceRule
|
||||
|
||||
parameters:
|
||||
level: max
|
||||
|
||||
# see https://github.com/symplify/coding-standard
|
||||
symplify:
|
||||
# this rule prevents bug in phar like these: https://github.com/rectorphp/rector/pull/3692/files
|
||||
string_arg_by_method_by_type:
|
||||
Rector\Core\Rector\AbstractRector:
|
||||
isObjectType: [1]
|
||||
|
||||
max_cognitive_complexity: 9 # default: 8
|
||||
max_class_cognitive_complexity: 50
|
||||
|
||||
parent_classes:
|
||||
- Rector
|
||||
|
||||
required_see_types:
|
||||
- PHPStan\Rules\Rule
|
||||
- Rector\Core\Rector\AbstractRector
|
||||
- Rector\FileSystemRector\Rector\AbstractFileSystemRector
|
||||
|
||||
old_to_preffered_classes:
|
||||
# prevent PHPStorm autocomplete mess
|
||||
'Symfony\Component\DependencyInjection\Variable': 'PhpParser\Node\Expr\Variable'
|
||||
'phpDocumentor\Reflection\Types\Expression': 'PhpParser\Node\Stmt\Expression'
|
||||
'phpDocumentor\Reflection\DocBlock\Tags\Param': 'PhpParser\Node\Param'
|
||||
'phpDocumentor\Reflection\DocBlock\Tags\Return_': 'PhpParser\Node\Stmt\Return_'
|
||||
'Closure': 'PhpParser\Node\Expr\Closure'
|
||||
'PHPUnit\TextUI\Configuration\Variable': 'PhpParser\Node\Expr\Variable'
|
||||
'PhpCsFixer\FixerDefinition\CodeSample': 'Rector\Core\RectorDefinition\CodeSample'
|
||||
'SebastianBergmann\Type\MixedType': 'PHPStan\Type\MixedType'
|
||||
'Hoa\Protocol\Node\Node': 'PhpParser\Node'
|
||||
|
||||
# to allow installing with various phsptan versions without reporting old errors here
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
|
||||
checkGenericClassInNonGenericObjectType: false
|
||||
|
||||
scanDirectories:
|
||||
- stubs
|
||||
|
||||
bootstrapFiles:
|
||||
- vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php
|
||||
|
||||
paths:
|
||||
- bin
|
||||
- src
|
||||
- rules
|
||||
- packages
|
||||
- tests
|
||||
- compiler/src
|
||||
- utils
|
||||
# this cannot be put it, because it wipes PHPStan cache on each run :( - must run in separate
|
||||
#- config/set
|
||||
|
||||
excludes_analyse:
|
||||
# iterable types
|
||||
- '#with no value type specified in iterable type array#'
|
||||
- '#type specified in iterable type (array|iterable)#'
|
||||
|
||||
# phsptan bug
|
||||
- utils/phpstan-extensions/src/Rule/PreventParentMethodVisibilityOverrideRule.php
|
||||
- utils/phpstan-extensions/src/Rule/KeepRectorNamespaceForRectorRule.php
|
||||
- packages/rector-generator/templates/*
|
||||
|
||||
# generated files
|
||||
- 'packages/doctrine-annotation-generated/src/ConstantPreservingDocParser.php'
|
||||
- 'packages/doctrine-annotation-generated/src/ConstantPreservingAnnotationReader.php'
|
||||
|
||||
- "*/Expected/*"
|
||||
# complex printer
|
||||
- '*tests/Rector/MethodCall/RenameMethodRector/**/SomeClass.php'
|
||||
# tests files
|
||||
- '*tests/*/Fixture/*'
|
||||
- '*tests/*/Source/*'
|
||||
- '*tests/Source/*'
|
||||
# part of composer
|
||||
- '*/tests/Rector/Psr4/MultipleClassFileToPsr4ClassesRector/Expected/Just*ExceptionWithoutNamespace.php'
|
||||
|
||||
# tests
|
||||
- tests/DependencyInjection/config
|
||||
|
||||
ignoreErrors:
|
||||
# @todo remove
|
||||
# iterable types
|
||||
- '#with no value type specified in iterable type array#'
|
||||
- '#type specified in iterable type (array|iterable)#'
|
||||
|
||||
# false positive
|
||||
- '#PHPDoc tag \@param for parameter \$node with type float is incompatible with native type PhpParser\\Node#'
|
||||
|
||||
# misuse of interface and class
|
||||
- '#Parameter \#1 (.*?) expects Symfony\\Component\\DependencyInjection\\ContainerBuilder, Symfony\\Component\\DependencyInjection\\ContainerInterface given#'
|
||||
- '#Strict comparison using === between string and null will always evaluate to false#'
|
||||
|
||||
# false positive - type is set by annotation above
|
||||
- '#Array \(array<PhpParser\\Node\\Stmt>\) does not accept PhpParser\\Node#'
|
||||
|
||||
# irrelevant
|
||||
- '#Call to function in_array\(\) with arguments string, (.*?) and true will always evaluate to false#'
|
||||
|
||||
# known values
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr::\$right#'
|
||||
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\\MethodCall\|PhpParser\\Node\\Stmt\\ClassMethod::\$params#'
|
||||
- '#Cannot call method getName\(\) on PHPStan\\Reflection\\ClassReflection\|null#'
|
||||
|
||||
# false positive, has annotation type above
|
||||
- '#Method Rector\\CodeQuality\\Rector\\Foreach_\\SimplifyForeachToCoalescingRector\:\:matchReturnOrAssignNode\(\) should return PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Stmt\\Return_\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Access to an undefined property PhpParser\\Node::\$(\w+)#'
|
||||
|
||||
# intentionally incorrect - part of the test
|
||||
- '#Parameter \#2 \$codeSamples of class Rector\\Core\\RectorDefinition\\RectorDefinition constructor expects array<Rector\\Core\\Contract\\RectorDefinition\\CodeSampleInterface>, array<int, stdClass> given#'
|
||||
|
||||
# known values
|
||||
- '#Cannot access property \$value on PhpParser\\Node\\Expr\\ArrayItem\|null#'
|
||||
|
||||
# known values
|
||||
- '#Strict comparison using === between PhpParser\\Node\\Expr and null will always evaluate to false#'
|
||||
|
||||
- '#Access to an undefined property PhpParser\\Node\\Stmt\:\:\$expr#'
|
||||
- '#Cannot access property \$stmts on PhpParser\\Node\\Stmt\\Else_\|null#'
|
||||
|
||||
# node finder
|
||||
- '#Method Rector\\(.*?) should return array<PhpParser\\Node\\(.*?)> but returns array<PhpParser\\Node\>#'
|
||||
|
||||
# part of test
|
||||
- '#(.*?)(AttributeAwareNodeInterface|AttributeAware(.*?)TagValueNode)(.*?)#'
|
||||
|
||||
- '#Parameter \#1 \$children of class PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocNode constructor expects array<PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocChildNode\>, array<int, PHPStan\\PhpDocParser\\Ast\\Node\> given#'
|
||||
- '#Method Rector\\PHPUnit\\Rector\\MethodCall\\ReplaceAssertArraySubsetRector\:\:matchArray\(\) should return PhpParser\\Node\\Expr\\Array_\|null but returns PhpParser\\Node\\Expr#'
|
||||
|
||||
- '#(.*?)PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Expr\\Variable given#'
|
||||
|
||||
# false positive 0.11.5
|
||||
- '#Unreachable statement \- code above always terminates#'
|
||||
- '#Negated boolean expression is always true#'
|
||||
- '#Strict comparison using \=\=\= between PhpParser\\Node and null will always evaluate to false#'
|
||||
|
||||
# known types
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Expr\\Variable\:\:\$name#'
|
||||
- '#Strict comparison using \=\=\= between PhpParser\\Node\\Expr\\ArrayItem and null will always evaluate to false#'
|
||||
- '#Parameter \#2 \.\.\.\$args of function array_merge expects array, array<int, string\>\|false given#'
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$args#'
|
||||
|
||||
- '#Parameter \#2 \$name of method Rector\\Core\\Rector\\AbstractRector\:\:isName\(\) expects string, string\|null given#'
|
||||
# cascade irrelevant
|
||||
- '#Parameter (.*?) expects array<PhpParser\\Node\\Stmt\>, array<PhpParser\\Node\> given#'
|
||||
|
||||
# known value
|
||||
- '#Cannot cast array<string\>\|bool\|string\|null to string#'
|
||||
|
||||
|
||||
# array is callable
|
||||
- '#If condition is always true#'
|
||||
|
||||
- '#Ternary operator condition is always true#'
|
||||
|
||||
- '#Access to an undefined property PhpParser\\Node\\FunctionLike\|PhpParser\\Node\\Stmt\\ClassLike\:\:\$stmts#'
|
||||
|
||||
- '#Property Rector\\TypeDeclaration\\TypeInferer\\(.*?)\:\:\$(.*?)TypeInferers \(array<Rector\\TypeDeclaration\\Contract\\TypeInferer\\(.*?)TypeInfererInterface\>\) does not accept array<Rector\\TypeDeclaration\\Contract\\TypeInferer\\PriorityAwareTypeInfererInterface\>#'
|
||||
# sense-less errors
|
||||
|
||||
# 3rd party
|
||||
-
|
||||
message: '#Use default null value and nullable compare instead of isset on object#'
|
||||
path: 'rules/symfony/src/ServiceMapProvider.php'
|
||||
|
||||
# PHP 7.4 1_000 support
|
||||
- '#Property PhpParser\\Node\\Scalar\\DNumber\:\:\$value \(float\) does not accept string#'
|
||||
- '#Call to function is_string\(\) with float will always evaluate to false#'
|
||||
|
||||
- '#Method Rector\\Doctrine\\Rector\\MethodCall\\ChangeSetIdToUuidValueRector\:\:getSetUuidMethodCallOnSameVariable\(\) should return PhpParser\\Node\\Expr\\MethodCall\|null but returns PhpParser\\Node\|null#'
|
||||
|
||||
# known value
|
||||
- '#Method Rector\\StrictCodeQuality\\Rector\\Stmt\\VarInlineAnnotationToAssertRector\:\:findVariableByName\(\) should return PhpParser\\Node\\Expr\\Variable\|null but returns PhpParser\\Node\|null#'
|
||||
|
||||
- '#Method Rector\\NodeTypeResolver\\PHPStan\\Type\\TypeFactory\:\:createUnionOrSingleType\(\) should return PHPStan\\Type\\MixedType\|PHPStan\\Type\\UnionType but returns PHPStan\\Type\\Type#'
|
||||
|
||||
# test
|
||||
- '#Class Rector\\DynamicTypeAnalysis\\Tests\\Rector\\ClassMethod\\AddArgumentTypeWithProbeDataRector\\Fixture\\SomeClass not found#'
|
||||
|
||||
-
|
||||
message: '#Class Rector\\Generic\\Tests\\Rector\\StaticCall\\SwapClassMethodArgumentsRector\\Fixture\\SomeClass not found#'
|
||||
path: rules/generic/tests/Rector/StaticCall/SwapClassMethodArgumentsRector/SwapClassMethodArgumentsRectorTest.php
|
||||
|
||||
# internal rule
|
||||
- '#Class "Rector\\Utils\\(.*?)" is missing @see annotation with test case class reference#'
|
||||
|
||||
# mixed
|
||||
- '#Offset int\|string\|null does not exist on array<PhpParser\\Node\\Stmt>\|null#'
|
||||
- '#class-string<T of object>\|T of object#'
|
||||
|
||||
# known values
|
||||
- '#Offset 0 does not exist on array<PhpParser\\Node\\Stmt>\|null#'
|
||||
- '#Parameter \#1 \$left of class PhpParser\\Node\\Expr\\BinaryOp\\Spaceship constructor expects PhpParser\\Node\\Expr, PhpParser\\Node\\Expr\|null given#'
|
||||
- '#Parameter \#2 \$right of class PhpParser\\Node\\Expr\\BinaryOp\\Spaceship constructor expects PhpParser\\Node\\Expr, PhpParser\\Node\\Expr\|null given#'
|
||||
|
||||
# false positive
|
||||
- '#Comparison operation "<" between 0 and 2 is always true#'
|
||||
|
||||
- '#Method Rector\\Symfony\\Rector\\MethodCall\\AbstractToConstructorInjectionRector\:\:getServiceTypeFromMethodCallArgument\(\) should return PHPStan\\Type\\Type but returns PHPStan\\Type\\Type\|null#'
|
||||
|
||||
- '#Parameter \#1 \$expected of method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) expects class\-string<object\>, string given#'
|
||||
- '#Unable to resolve the template type ExpectedType in call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\)#'
|
||||
|
||||
# fix Symplify 7.2 later
|
||||
- '#Method (.*?) returns bool type, so the name should start with is/has/was#'
|
||||
|
||||
- '#In method "Rector\\BetterPhpDocParser\\AnnotationReader\\NodeAnnotationReader\:\:createPropertyReflectionFromPropertyNode", caught "Throwable" must be rethrown\. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception\. More info\: http\://bit\.ly/failloud#'
|
||||
# doc is not enough
|
||||
- '#Result of \|\| is always true#'
|
||||
|
||||
# known value
|
||||
- '#Parameter \#2 \$name of class PhpParser\\Node\\Expr\\MethodCall constructor expects PhpParser\\Node\\Expr\|PhpParser\\Node\\Identifier\|string, string\|null given#'
|
||||
|
||||
- '#Parameter \#1 \$eventListenerTag of method Rector\\SymfonyCodeQuality\\Rector\\Class_\\EventListenerToEventSubscriberRector\:\:createEventItem\(\) expects Rector\\Symfony\\ValueObject\\Tag\\EventListenerTag, Rector\\Symfony\\Contract\\Tag\\TagInterface given#'
|
||||
- '#Method Rector\\BetterPhpDocParser\\PhpDocInfo\\PhpDocInfoFactory\:\:parseTokensToPhpDocNode\(\) should return Rector\\AttributeAwarePhpDoc\\Ast\\PhpDoc\\AttributeAwarePhpDocNode but returns PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocNode#'
|
||||
|
||||
- '#Property PhpParser\\Node\\Stmt\\Expression\:\:\$expr \(PhpParser\\Node\\Expr\) does not accept PhpParser\\Node\\Expr\|null#'
|
||||
- '#Call to an undefined method PHPStan\\Type\\Type\:\:getClassName\(\)#'
|
||||
- '#Parameter \#1 \$typeNode of method Rector\\StaticTypeMapper\\StaticTypeMapper\:\:mapPHPStanPhpDocTypeNodeToPHPStanType\(\) expects PHPStan\\PhpDocParser\\Ast\\Type\\TypeNode, PHPStan\\PhpDocParser\\Ast\\Node given#'
|
||||
|
||||
- '#Parameter \#1 \$sprintfFuncCall of method Rector\\Core\\PhpParser\\NodeTransformer\:\:transformSprintfToArray\(\) expects PhpParser\\Node\\Expr\\FuncCall, PhpParser\\Node given#'
|
||||
- '#Parameter \#1 \$nodes of method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:find\(\) expects array<PhpParser\\Node\>\|PhpParser\\Node, array<PhpParser\\Node\\Stmt\>\|null given#'
|
||||
- '#Method Rector\\SOLID\\Reflection\\ParentConstantReflectionResolver\:\:(.*?)\(\) should return ReflectionClassConstant\|null but returns ReflectionClassConstant\|false#'
|
||||
- '#Parameter \#1 \$firstStmt of method Rector\\Generic\\Rector\\ClassMethod\\NormalToFluentRector\:\:isBothMethodCallMatch\(\) expects PhpParser\\Node\\Stmt\\Expression, PhpParser\\Node\\Stmt given#'
|
||||
- '#Method Rector\\Core\\Rector\\AbstractRector\:\:wrapToArg\(\) should return array<PhpParser\\Node\\Arg\> but returns array<PhpParser\\Node\\Arg\|PhpParser\\Node\\Expr\>#'
|
||||
|
||||
- '#Method Rector\\FileSystemRector\\Rector\\AbstractFileSystemRector\:\:wrapToArg\(\) should return array<PhpParser\\Node\\Arg\> but returns array<PhpParser\\Node\\Arg\|PhpParser\\Node\\Expr\>#'
|
||||
- '#Cannot call method (.*?)\(\) on Rector\\BetterPhpDocParser\\PhpDocInfo\\PhpDocInfo\|null#'
|
||||
|
||||
- '#Parameter \#(.*?) (.*?) of class PhpParser\\Node\\Expr\\BinaryOp\\(.*?) constructor expects PhpParser\\Node\\Expr, PhpParser\\Node given#'
|
||||
|
||||
- '#Access to an undefined property PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode\:\:\$description#'
|
||||
|
||||
- '#Method Rector\\Php80\\Rector\\NotIdentical\\StrContainsRector\:\:matchNotIdenticalToFalse\(\) should return PhpParser\\Node\\Expr\\FuncCall\|null but returns PhpParser\\Node\\Expr#'
|
||||
|
||||
- '#Parameter \#2 \$name of method Rector\\Core\\Rector\\AbstractRector\:\:isVariableName\(\) expects string, string\|null given#'
|
||||
|
||||
# node finder
|
||||
- '#Method Rector\\Core\\PhpParser\\Node\\Manipulator\\MethodCallManipulator\:\:findAssignToVariableName\(\) should return PhpParser\\Node\\Expr\\Assign\|null but returns PhpParser\\Node\|null#'
|
||||
|
||||
# broken
|
||||
- '#Cannot call method getParentNode\(\) on Rector\\DeadCode\\ValueObject\\VariableNodeUse\|null#'
|
||||
- '#Method Rector\\DeadCode\\NodeFinder\\PreviousVariableAssignNodeFinder\:\:find\(\) should return PhpParser\\Node\\Expr\\Assign\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Parameter \#2 \$name of method Rector\\NodeNameResolver\\NodeNameResolver\:\:isName\(\) expects string, string\|null given#'
|
||||
- '#Method Rector\\PHPOffice\\Rector\\MethodCall\\IncreaseColumnIndexRector\:\:findVariableAssignName\(\) should return PhpParser\\Node\\Expr\\Assign\|null but returns PhpParser\\Node\|null#'
|
||||
|
||||
- '#Parameter \#1 \$keyName of method Rector\\AttributeAwarePhpDoc\\Ast\\Type\\AttributeAwareArrayShapeItemNode\:\:createKeyWithSpacePattern\(\) expects PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprIntegerNode\|PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode\|null, PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprIntegerNode\|PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprStringNode\|PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode\|null given#'
|
||||
- '#Method Rector\\Caching\\ChangedFilesDetector\:\:hashFile\(\) should return string but returns string\|false#'
|
||||
|
||||
- '#If condition is always false#'
|
||||
|
||||
- '#Parameter \#1 \$funcCall of method Rector\\Php80\\MatchAndRefactor\\StrStartsWithMatchAndRefactor\\AbstractMatchAndRefactor\:\:createStrStartsWithValueObjectFromFuncCall\(\) expects PhpParser\\Node\\Expr\\FuncCall, PhpParser\\Node\\Expr given#'
|
||||
|
||||
# mostly strings in tests
|
||||
- '#Class (.*?) should be written with \:\:class notation, string found#'
|
||||
- '#Method Rector\\Naming\\Naming\\PropertyNaming\:\:resolveShortClassName\(\) should return string but returns string\|null#'
|
||||
|
||||
-
|
||||
message: "#in iterable type Iterator#"
|
||||
paths:
|
||||
- *Test.php
|
||||
- *TestCase.php
|
||||
|
||||
-
|
||||
message: "#^Cognitive complexity for \"Rector\\\\BetterPhpDocParser\\\\Printer\\\\WhitespaceDetector\\:\\:detectOldWhitespaces\\(\\)\" is 18, keep it under 9$#"
|
||||
count: 1
|
||||
path: packages/better-php-doc-parser/src/Printer/WhitespaceDetector.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$input of function array_splice expects array, array\\<PhpParser\\\\Node\\\\Stmt\\>\\|null given\\.$#"
|
||||
count: 1
|
||||
path: rules/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php
|
||||
|
||||
-
|
||||
message: "#^Cognitive complexity for \"Rector\\\\PhpSpecToPHPUnit\\\\Rector\\\\MethodCall\\\\PhpSpecPromisesToPHPUnitAssertRector\\:\\:refactor\\(\\)\" is 13, keep it under 9$#"
|
||||
count: 1
|
||||
path: rules/php-spec-to-phpunit/src/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php
|
||||
|
||||
-
|
||||
message: "#^Class cognitive complexity for \"EregToPcreTransformer\" is (.*?), keep it under 50$#"
|
||||
path: rules/php70/src/EregToPcreTransformer.php
|
||||
|
||||
-
|
||||
message: "#Use explicit property fetch names over dynamic#"
|
||||
path: packages/doctrine-annotation-generated/src/PhpDocNode/ConstantReferenceIdentifierRestorer.php
|
||||
|
||||
- "#^Cognitive complexity for \"Rector\\\\Php70\\\\EregToPcreTransformer\\:\\:(.*?)\" is (.*?), keep it under 9$#"
|
||||
|
||||
- '#In method "Rector\\Utils\\ProjectValidator\\Process\\ParallelTaskRunner\:\:(.*?)", caught "Throwable" must be rethrown\. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception#'
|
||||
# weird
|
||||
|
||||
- '#Method (.*?) specified in iterable type Symfony\\Component\\Process\\Process#'
|
||||
- '#Cannot cast PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Identifier to string#'
|
||||
- '#Class cognitive complexity for "DumpNodesCommand" is \d+, keep it under 50#'
|
||||
- '#Cognitive complexity for "Rector\\Utils\\DocumentationGenerator\\Command\\DumpNodesCommand\:\:execute\(\)" is \d+, keep it under 9#'
|
||||
|
||||
- '#Parameter \#1 \$node of method Rector\\PostRector\\Collector\\NodesToAddCollector\:\:wrapToExpression\(\) expects PhpParser\\Node\\Expr\|PhpParser\\Node\\Stmt, PhpParser\\Node given#'
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$class#'
|
||||
- '#Method Rector\\BetterPhpDocParser\\Tests\\PhpDocParser\\AbstractPhpDocInfoTest\:\:parseFileAndGetFirstNodeOfType\(\) should return PhpParser\\Node but returns PhpParser\\Node\|null#'
|
||||
- '#Property PhpParser\\Node\\Stmt\\Namespace_\:\:\$stmts \(array<PhpParser\\Node\\Stmt\>\) does not accept array<PhpParser\\Node\>#'
|
||||
|
||||
- '#Cognitive complexity for "Rector\\TypeDeclaration\\PHPStan\\Type\\ObjectTypeSpecifier\:\:matchShortenedObjectType\(\)" is 10, keep it under 9#'
|
||||
- '#Parameter \#1 \$type of method PhpParser\\Builder\\FunctionLike\:\:setReturnType\(\) expects PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#'
|
||||
- '#Cognitive complexity for "Rector\\Core\\PhpParser\\Node\\Value\\ValueResolver\:\:getValue\(\)" is \d+, keep it under 9#'
|
||||
- '#Cognitive complexity for "Rector\\NetteKdyby\\ContributeEventClassResolver\:\:resolveGetterMethodByEventClassAndParam\(\)" is \d+, keep it under 9#'
|
||||
- '#Parameter \#1 \$type of class PhpParser\\Node\\NullableType constructor expects PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#'
|
||||
- '#Parameter \#1 \$object of function get_class expects object, PhpParser\\Node\|null given#'
|
||||
- '#Class "Rector\\FileSystemRector\\Rector\\Removing\\RemoveProjectFileRector" is missing @see annotation with test case class reference#'
|
||||
- '#Parameter \#1 \$type of method PhpParser\\Builder\\Param\:\:setType\(\) expects PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#'
|
||||
- '#Parameter \#1 \$node of method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:findFirstAncestorInstanceOf\(\) expects PhpParser\\Node, PhpParser\\Node\\Expr\\Variable\|null given#'
|
||||
- '#Parameter \#1 \$objectType of method Rector\\Naming\\Naming\\PropertyNaming\:\:fqnToVariableName\(\) expects PHPStan\\Type\\ObjectType\|string, PHPStan\\Type\\Type given#'
|
||||
- '#Method Rector\\Core\\PhpParser\\Node\\NodeFactory\:\:createConcat\(\) should return PhpParser\\Node\\Expr\\BinaryOp\\Concat\|null but returns PhpParser\\Node\\Expr#'
|
||||
- '#Method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:findFirstNonAnonymousClass\(\) should return PhpParser\\Node\\Stmt\\Class_\|null but returns PhpParser\\Node\|null#'
|
||||
# known value
|
||||
- '#Property PhpParser\\Node\\Stmt\\Foreach_\:\:\$valueVar \(PhpParser\\Node\\Expr\) does not accept PhpParser\\Node\\Expr\|null#'
|
||||
- '#Access to an undefined property PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode\:\:\$type#'
|
||||
|
||||
# local type
|
||||
-
|
||||
message: '#Method call "isObjectType\(\)" argument on position 1 cannot use "\:\:class" reference#'
|
||||
path: 'packages/dynamic-type-analysis/src/Rector/StaticCall/RemoveArgumentTypeProbeRector.php'
|
||||
|
||||
# only local use
|
||||
-
|
||||
message: '#Class "Rector\\RectorGenerator\\Rector\\Closure\\AddNewServiceToSymfonyPhpConfigRector" is missing @see annotation with test case class reference#'
|
||||
path: 'packages/rector-generator/src/Rector/Closure/AddNewServiceToSymfonyPhpConfigRector.php'
|
||||
|
||||
- '#Class Rector\\Renaming\\Tests\\Rector\\MethodCall\\RenameMethodRector\\Fixture\\SkipSelfMethodRename not found#'
|
||||
|
||||
# fixed in symplfiy dev
|
||||
-
|
||||
message: '#Separate function "Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ref\(\)" in method call to standalone row to improve readability#'
|
||||
path: 'packages/rector-generator/config/config.php'
|
||||
|
||||
- '#Method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:findPreviousAssignToExpr\(\) should return PhpParser\\Node\\Expr\\Assign\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Parameter \#1 \$shortControlString of method Rector\\NetteCodeQuality\\Rector\\Assign\\MakeGetComponentAssignAnnotatedRector\:\:resolveTypeFromShortControlNameAndVariable\(\) expects PhpParser\\Node\\Scalar\\String_, PhpParser\\Node\\Expr\|null given#'
|
||||
- '#Parameter \#1 \$variable of class Rector\\Php70\\ValueObject\\VariableAssignPair constructor expects PhpParser\\Node\\Expr\\ArrayDimFetch\|PhpParser\\Node\\Expr\\PropertyFetch\|PhpParser\\Node\\Expr\\StaticPropertyFetch\|PhpParser\\Node\\Expr\\Variable, PhpParser\\Node\\Expr given#'
|
||||
|
||||
# is nested expr
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$expr#'
|
||||
- '#Cognitive complexity for "Rector\\DeadCode\\NodeManipulator\\LivingCodeManipulator\:\:keepLivingCodeFromExpr\(\)" is \d+, keep it under 9#'
|
||||
- '#Parameter \#1 \$files of method Symplify\\SmartFileSystem\\Finder\\FinderSanitizer\:\:sanitize\(\) expects \(iterable<SplFileInfo\|string\>&Nette\\Utils\\Finder\)\|Symfony\\Component\\Finder\\Finder, array<string\> given#'
|
||||
- '#Static property Rector\\Core\\Testing\\PHPUnit\\AbstractGenericRectorTestCase\:\:\$allRectorContainer \(Rector\\Naming\\Tests\\Rector\\Class_\\RenamePropertyToMatchTypeRector\\Source\\ContainerInterface\|Symfony\\Component\\DependencyInjection\\Container\|null\) does not accept Psr\\Container\\ContainerInterface#'
|
||||
# stubs
|
||||
- '#Static property Symplify\\PackageBuilder\\Tests\\AbstractKernelTestCase\:\:\$container \(Psr\\Container\\ContainerInterface\) does not accept Rector\\Naming\\Tests\\Rector\\Class_\\RenamePropertyToMatchTypeRector\\Source\\ContainerInterface\|Symfony\\Component\\DependencyInjection\\Container#'
|
||||
|
||||
# wtf
|
||||
-
|
||||
message: '#Else branch is unreachable because ternary operator condition is always true#'
|
||||
path: 'rules/psr4/src/Composer/PSR4NamespaceMatcher.php'
|
||||
|
||||
# false positive
|
||||
- '#Parameter \#1 \$arrayItem of method Rector\\NetteKdyby\\NodeResolver\\ListeningMethodsCollector\:\:resolveCustomClassMethodAndEventClass\(\) expects PhpParser\\Node\\Expr\\ArrayItem, PhpParser\\Node given#'
|
||||
- '#Parameter \#1 \$type of method Rector\\NodeCollector\\NodeCollector\\ParsedNodeCollector<TNodeType of PhpParser\\Node\>\:\:getNodesByType\(\) expects class\-string<TNodeType of PhpParser\\Node\>, string given#'
|
||||
|
||||
- '#Class with base "(.*?)" name is already used in "_HumbugBox(.*?)"#'
|
||||
|
||||
-
|
||||
message: '#Class "Rector\\RectorGenerator\\ValueObject\\RectorRecipe" has invalid namespace category "ValueObject"\. Pick one of\: ""#'
|
||||
path: packages/rector-generator/src/ValueObject/RectorRecipe.php
|
||||
|
||||
- '#Parameter \#2 \$currentNode of method Rector\\CodingStyle\\Rector\\Assign\\ManualJsonStringToJsonEncodeArrayRector\:\:matchNextExprAssignConcatToSameVariable\(\) expects PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Expr\\AssignOp\\Concat, PhpParser\\Node given#'
|
||||
|
||||
-
|
||||
message: '#Array (with keys|destruct) is not allowed\. Use value object to pass data instead#'
|
||||
paths:
|
||||
# working with cvs file
|
||||
# 3rd party package
|
||||
- rules/php70/src/EregToPcreTransformer.php
|
||||
# output format
|
||||
- packages/changes-reporting/src/Output/JsonOutputFormatter.php
|
||||
# template variables
|
||||
- packages/rector-generator/src/TemplateVariablesFactory.php
|
||||
# output format to json
|
||||
- rules/doctrine/src/Collector/UuidMigrationDataCollector.php
|
||||
# should be replaced by symplify/composer-json-manipulator in the future
|
||||
- compiler/src/Composer/ComposerJsonManipulator.php
|
||||
# not sure how to improve
|
||||
- rules/symfony/src/ValueObject/Tag/EventListenerTag.php
|
||||
|
||||
-
|
||||
message: '#Use explicit return value over magic &reference#'
|
||||
paths:
|
||||
# 3rd party code
|
||||
- rules/php70/src/EregToPcreTransformer.php
|
||||
|
||||
- '#Cannot access property \$key on PhpParser\\Node\\Expr\\ArrayItem\|null#'
|
||||
- '#Class Nette\\DI\\CompilerExtension not found#'
|
||||
- '#Class Latte\\Macros\\MacroSet not found#'
|
||||
|
||||
# symfony/console
|
||||
-
|
||||
message: '#Cannot cast array<string\>\|string\|true to string#'
|
||||
path: 'src/Configuration/Configuration.php'
|
||||
|
||||
-
|
||||
message: '#Use explicit return value over magic &reference#'
|
||||
path: 'rules/dead-code/src/Rector/BinaryOp/RemoveDuplicatedInstanceOfRector.php'
|
||||
|
||||
-
|
||||
message: '#Class with base "NodeNameResolver" name is already used in "Symplify\\CodingStandard\\PhpParser\\NodeNameResolver", "Rector\\NodeNameResolver\\NodeNameResolver"\. Use unique name to make classes easy to recognize#'
|
||||
path: 'packages/node-name-resolver/src/NodeNameResolver.php'
|
||||
|
||||
-
|
||||
message: '#Use value object over return of values#'
|
||||
path: 'rules/phpunit/src/Composer/ComposerAutoloadedDirectoryProvider.php'
|
||||
|
||||
-
|
||||
message: '#Use value object over return of values#'
|
||||
path: 'rules/php70/src/EregToPcreTransformer.php'
|
||||
|
||||
# complex class
|
||||
- '#Class cognitive complexity for "NodeTypeResolver" is \d+, keep it under 50#'
|
16
rector.php
16
rector.php
|
@ -3,22 +3,12 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Generic\ValueObject\NamespacePrefixWithExcludedClasses;
|
||||
use Rector\SymfonyPhpConfig\Rector\ArrayItem\ReplaceArrayWithObjectRector;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->set(ReplaceArrayWithObjectRector::class)
|
||||
->call('configure', [[
|
||||
ReplaceArrayWithObjectRector::CONSTANT_NAMES_TO_VALUE_OBJECTS => [
|
||||
'Rector\Generic\Rector\Name\PseudoNamespaceToNamespaceRector::NAMESPACE_PREFIXES_WITH_EXCLUDED_CLASSES' => NamespacePrefixWithExcludedClasses::class,
|
||||
],
|
||||
]]);
|
||||
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
|
||||
$parameters->set(Option::SETS, [SetList::TYPE_DECLARATION]);
|
||||
|
||||
$parameters->set(Option::PATHS, [
|
||||
__DIR__ . '/src',
|
||||
|
@ -39,6 +29,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
'*.php.inc',
|
||||
]);
|
||||
|
||||
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
|
||||
|
||||
# so Rector code is still PHP 7.2 compatible
|
||||
$parameters->set(Option::PHP_VERSION_FEATURES, '7.2');
|
||||
};
|
||||
|
|
|
@ -12,5 +12,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->public();
|
||||
|
||||
$services->load('Rector\Architecture\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector/*']);
|
||||
->exclude([__DIR__ . '/../src/Rector']);
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@ final class DoctrineRepositoryAsServiceTest extends AbstractRectorTestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @return mixed[][]
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
|
|
|
@ -12,5 +12,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->public();
|
||||
|
||||
$services->load('Rector\Autodiscovery\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector/*', __DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/Rector', __DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -61,6 +61,9 @@ final class MoveServicesBySuffixToDirectoryRectorTest extends AbstractFileSystem
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
@ -74,7 +74,7 @@ final class MutualRenameTest extends AbstractFileSystemRectorTestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @return string[][][]
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
|
|
|
@ -48,7 +48,7 @@ final class MoveValueObjectsToValueObjectDirectoryRectorTest extends AbstractFil
|
|||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed[]>
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
|
|
|
@ -12,5 +12,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->public();
|
||||
|
||||
$services->load('Rector\CodeQuality\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector/*']);
|
||||
->exclude([__DIR__ . '/../src/Rector']);
|
||||
};
|
||||
|
|
|
@ -84,7 +84,7 @@ PHP
|
|||
&$countInCond,
|
||||
&$variableName,
|
||||
$forScope
|
||||
) {
|
||||
): ?Variable {
|
||||
if (! $node instanceof FuncCall) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ PHP
|
|||
|
||||
private function findPreviousNodeUsage(Node $node, Expr $expr): ?Node
|
||||
{
|
||||
return $this->scopeAwareNodeFinder->findParent($node, function (Node $node) use ($expr) {
|
||||
return $this->scopeAwareNodeFinder->findParent($node, function (Node $node) use ($expr): bool {
|
||||
if ($node === $expr) {
|
||||
return false;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ PHP
|
|||
|
||||
private function findPreviousNodeUsageInForeach(Node $node, Expr $expr): ?Node
|
||||
{
|
||||
return $this->betterNodeFinder->findFirstPrevious($node, function (Node $node) use ($expr) {
|
||||
return $this->betterNodeFinder->findFirstPrevious($node, function (Node $node) use ($expr): bool {
|
||||
if ($node === $expr) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ PHP
|
|||
|
||||
private function isVariableUsedInForeach(Variable $variable, Foreach_ $foreach): bool
|
||||
{
|
||||
return (bool) $this->betterNodeFinder->findFirst($foreach->stmts, function (Node $node) use ($variable) {
|
||||
return (bool) $this->betterNodeFinder->findFirst($foreach->stmts, function (Node $node) use ($variable): bool {
|
||||
return $this->areNodesEqual($node, $variable);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ PHP
|
|||
/** @var Assign|Node|null $previousAssignArraysKeysFuncCall */
|
||||
$previousAssignArraysKeysFuncCall = $this->betterNodeFinder->findFirstPrevious($node, function (Node $node) use (
|
||||
$arrayVariable
|
||||
) {
|
||||
): bool {
|
||||
// breaking out of scope
|
||||
if ($node instanceof FunctionLike) {
|
||||
return true;
|
||||
|
|
|
@ -10,6 +10,8 @@ use PhpParser\Node\Expr\AssignOp;
|
|||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PHPStan\Type\MixedType;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\Core\PhpParser\Node\AssignAndBinaryMap;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
|
@ -84,6 +86,10 @@ PHP
|
|||
}
|
||||
|
||||
if ($previousNode instanceof Assign) {
|
||||
if ($this->isReturnWithVarAnnotation($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$node->expr = $previousNode->expr;
|
||||
}
|
||||
|
||||
|
@ -127,6 +133,20 @@ PHP
|
|||
return $this->isPreviousExpressionVisuallySimilar($previousExpression, $previousNode);
|
||||
}
|
||||
|
||||
private function isReturnWithVarAnnotation(Node $node): bool
|
||||
{
|
||||
if (! $node instanceof Return_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
|
||||
if (! $phpDocInfo instanceof PhpDocInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! $phpDocInfo->getVarType() instanceof MixedType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AssignOp|Assign $previousNode
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\CodeQuality\Tests\Rector\Return_\SimplifyUselessVariableRector\Fixture;
|
||||
|
||||
class KeepVarDoc
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$name = $this->getValue();
|
||||
|
||||
/** @var string $name */
|
||||
return $name;
|
||||
}
|
||||
|
||||
private function getValue()
|
||||
{
|
||||
return 'name';
|
||||
}
|
||||
}
|
|
@ -12,5 +12,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->public();
|
||||
|
||||
$services->load('Rector\CodingStyle\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector/*', __DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/Rector', __DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ final class UseImportsAdder
|
|||
* @param Stmt[] $stmts
|
||||
* @param FullyQualifiedObjectType[] $useImportTypes
|
||||
* @param FullyQualifiedObjectType[] $functionUseImportTypes
|
||||
* @return Stmt[]
|
||||
* @return Stmt[] <int|string, \PhpParser\Node\Stmt>
|
||||
*/
|
||||
public function addImportsToStmts(array $stmts, array $useImportTypes, array $functionUseImportTypes): array
|
||||
{
|
||||
|
|
|
@ -59,6 +59,14 @@ final class ReturnArrayClassMethodToYieldRector extends AbstractRector implement
|
|||
public function __construct(NodeTransformer $nodeTransformer)
|
||||
{
|
||||
$this->nodeTransformer = $nodeTransformer;
|
||||
|
||||
// default values
|
||||
$this->methodsToYields = [
|
||||
new MethodToYield('PHPUnit\Framework\TestCase', 'provideData'),
|
||||
new MethodToYield('PHPUnit\Framework\TestCase', 'provideData*'),
|
||||
new MethodToYield('PHPUnit\Framework\TestCase', 'dataProvider'),
|
||||
new MethodToYield('PHPUnit\Framework\TestCase', 'dataProvider*'),
|
||||
];
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
|
|
|
@ -24,7 +24,7 @@ use Rector\Core\RectorDefinition\CodeSample;
|
|||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\CodingStyle\Tests\Rector\FuncCall\FunctionCallToConstantRector\FunctionCallToConstantRectorTest
|
||||
* @see \Rector\CodingStyle\Tests\Rector\FuncCall\VersionCompareFuncCallToConstantRector\VersionCompareFuncCallToConstantRectorTest
|
||||
*/
|
||||
final class VersionCompareFuncCallToConstantRector extends AbstractRector
|
||||
{
|
||||
|
|
|
@ -71,7 +71,7 @@ PHP
|
|||
// @see https://regex101.com/r/Vv41Qr/1/
|
||||
$matches = Strings::matchAll($string->value, '#([\\\\a-zA-Z0-9_\\x80-\\xff]*)::#', PREG_PATTERN_ORDER);
|
||||
|
||||
return array_filter($matches[1], function (string $className) {
|
||||
return array_filter($matches[1], function (string $className): bool {
|
||||
return class_exists($className);
|
||||
});
|
||||
}
|
||||
|
@ -81,14 +81,14 @@ PHP
|
|||
*/
|
||||
public function getParts(String_ $string, array $classNames): array
|
||||
{
|
||||
$classNames = array_map(function (string $className) {
|
||||
$classNames = array_map(function (string $className): string {
|
||||
return preg_quote($className);
|
||||
}, $classNames);
|
||||
|
||||
// @see https://regex101.com/r/8nGS0F/1
|
||||
$parts = Strings::split($string->value, '#(' . implode('|', $classNames) . ')#');
|
||||
|
||||
return array_filter($parts, function (string $className) {
|
||||
return array_filter($parts, function (string $className): bool {
|
||||
return $className !== '';
|
||||
});
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ PHP
|
|||
*/
|
||||
private function lowercaseArray(array $values): array
|
||||
{
|
||||
return array_map(function (string $value) {
|
||||
return array_map(function (string $value): string {
|
||||
return strtolower($value);
|
||||
}, $values);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@ final class ConcatStringAndPlaceholders
|
|||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getPlaceholderNodes(): array
|
||||
{
|
||||
return $this->placeholderNodes;
|
||||
|
|
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\CodingStyle\ValueObject;
|
||||
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
|
||||
final class ObjectMagicMethods
|
||||
{
|
||||
/**
|
||||
|
@ -13,9 +15,9 @@ final class ObjectMagicMethods
|
|||
'__call',
|
||||
'__callStatic',
|
||||
'__clone',
|
||||
'__construct',
|
||||
MethodName::CONSTRUCT,
|
||||
'__debugInfo',
|
||||
'__destruct',
|
||||
MethodName::DESCTRUCT,
|
||||
'__get',
|
||||
'__invoke',
|
||||
'__isset',
|
||||
|
|
|
@ -25,7 +25,7 @@ final class FunctionCallToConstantRectorTest extends AbstractRectorTestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @return string[][][]
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
|
|
|
@ -12,5 +12,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
->public();
|
||||
|
||||
$services->load('Rector\DeadCode\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector/*', __DIR__ . '/../src/ValueObject/*']);
|
||||
->exclude([__DIR__ . '/../src/Rector', __DIR__ . '/../src/ValueObject']);
|
||||
};
|
||||
|
|
|
@ -68,7 +68,7 @@ final class NextVariableUsageNodeFinder
|
|||
$this->callableNodeTraverser->traverseNodesWithCallable((array) $scopeNode->stmts, function (Node $currentNode) use (
|
||||
$expr,
|
||||
&$nextUsageOfVariable
|
||||
) {
|
||||
): ?int {
|
||||
// used above the assign
|
||||
if ($currentNode->getStartTokenPos() < $expr->getStartTokenPos()) {
|
||||
return null;
|
||||
|
|
|
@ -27,12 +27,12 @@ final class PreviousVariableAssignNodeFinder
|
|||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
|
||||
public function find(Assign $assign): ?Assign
|
||||
public function find(Assign $assign): ?Node
|
||||
{
|
||||
$currentAssign = $assign;
|
||||
$variableName = $this->nodeNameResolver->getName($assign->var);
|
||||
|
||||
return $this->betterNodeFinder->findFirstPrevious($assign, function (Node $node) use (
|
||||
$assign = $this->betterNodeFinder->findFirstPrevious($assign, function (Node $node) use (
|
||||
$variableName,
|
||||
$currentAssign
|
||||
): bool {
|
||||
|
@ -47,5 +47,8 @@ final class PreviousVariableAssignNodeFinder
|
|||
|
||||
return $this->nodeNameResolver->isName($node->var, $variableName);
|
||||
});
|
||||
|
||||
/** @var Assign|null $assign */
|
||||
return $assign;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Rector\DeadCode\NodeManipulator;
|
||||
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
||||
final class MagicMethodDetector
|
||||
|
@ -17,7 +18,7 @@ final class MagicMethodDetector
|
|||
'__callStatic',
|
||||
'__clone',
|
||||
'__debugInfo',
|
||||
'__destruct',
|
||||
MethodName::DESCTRUCT,
|
||||
'__get',
|
||||
'__invoke',
|
||||
'__isset',
|
||||
|
|
|
@ -40,7 +40,7 @@ final class VariadicFunctionLikeDetector
|
|||
|
||||
$this->callableNodeTraverser->traverseNodesWithCallable(
|
||||
(array) $functionLike->getStmts(),
|
||||
function (Node $node) use (&$isVariadic) {
|
||||
function (Node $node) use (&$isVariadic): ?int {
|
||||
if (! $node instanceof FuncCall) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -93,8 +93,11 @@ PHP
|
|||
*/
|
||||
private function filterItemsWithSameKey(array $arrayItemsByKeys): array
|
||||
{
|
||||
return array_filter($arrayItemsByKeys, function (array $arrayItems) {
|
||||
$arrayItemsByKeys = array_filter($arrayItemsByKeys, function (array $arrayItems): bool {
|
||||
return count($arrayItems) > 1;
|
||||
});
|
||||
|
||||
/** @var ArrayItem[][] $arrayItemsByKeys */
|
||||
return $arrayItemsByKeys;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,9 @@ PHP
|
|||
*/
|
||||
private function findVariableUsages(FunctionLike $functionLike, Assign $assign): array
|
||||
{
|
||||
return $this->betterNodeFinder->find((array) $functionLike->getStmts(), function (Node $node) use ($assign) {
|
||||
return $this->betterNodeFinder->find((array) $functionLike->getStmts(), function (Node $node) use (
|
||||
$assign
|
||||
): bool {
|
||||
if (! $node instanceof Variable) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ PHP
|
|||
$this->traverseNodesWithCallable($node, function (Node $node) use (
|
||||
$modifiedVariableNames,
|
||||
&$containsVariableNames
|
||||
) {
|
||||
): ?int {
|
||||
if (! $node instanceof Variable) {
|
||||
return null;
|
||||
}
|
||||
|
@ -170,12 +170,12 @@ PHP
|
|||
}
|
||||
|
||||
/**
|
||||
* @param If_[][] $ifWithOnlyReturnsByHash
|
||||
* @return If_[][]
|
||||
* @param array<string, If_[]> $ifWithOnlyReturnsByHash
|
||||
* @return array<string, If_[]>
|
||||
*/
|
||||
private function filterOutSingleItemStmts(array $ifWithOnlyReturnsByHash): array
|
||||
{
|
||||
return array_filter($ifWithOnlyReturnsByHash, function (array $stmts) {
|
||||
return array_filter($ifWithOnlyReturnsByHash, function (array $stmts): bool {
|
||||
return count($stmts) >= 2;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ PHP
|
|||
|
||||
/**
|
||||
* @param StaticCall|FuncCall|MethodCall $node
|
||||
* @return Expr[]|Node[]
|
||||
* @return Node[]
|
||||
*/
|
||||
private function resolveDefaultValuesFromCall(Node $node): array
|
||||
{
|
||||
|
|
|
@ -4,9 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\DeadCode\UnusedNodeResolver;
|
||||
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\NullableType;
|
||||
|
@ -92,24 +89,22 @@ final class UnusedClassResolver
|
|||
{
|
||||
$classNames = [];
|
||||
|
||||
/** @var Param[] $paramNodes */
|
||||
$paramNodes = $this->parsedNodeCollector->getNodesByType(Param::class);
|
||||
foreach ($paramNodes as $paramNode) {
|
||||
if ($paramNode->type === null) {
|
||||
foreach ($this->parsedNodeCollector->getParams() as $param) {
|
||||
if ($param->type === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($paramNode->type instanceof NullableType) {
|
||||
$paramNode = $paramNode->type;
|
||||
if ($param->type instanceof NullableType) {
|
||||
$param = $param->type;
|
||||
}
|
||||
|
||||
if ($paramNode->type instanceof Identifier) {
|
||||
if ($param->type instanceof Identifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($paramNode->type instanceof Name) {
|
||||
if ($param->type instanceof Name) {
|
||||
/** @var string $paramTypeName */
|
||||
$paramTypeName = $this->nodeNameResolver->getName($paramNode->type);
|
||||
$paramTypeName = $this->nodeNameResolver->getName($param->type);
|
||||
$classNames[] = $paramTypeName;
|
||||
} else {
|
||||
throw new NotImplementedException();
|
||||
|
@ -126,15 +121,13 @@ final class UnusedClassResolver
|
|||
{
|
||||
$classNames = [];
|
||||
|
||||
/** @var New_[] $newNodes */
|
||||
$newNodes = $this->parsedNodeCollector->getNodesByType(New_::class);
|
||||
foreach ($newNodes as $newNode) {
|
||||
$newNodeClassName = $this->nodeNameResolver->getName($newNode->class);
|
||||
if (! is_string($newNodeClassName)) {
|
||||
foreach ($this->parsedNodeCollector->getNews() as $newNode) {
|
||||
$newClassName = $this->nodeNameResolver->getName($newNode->class);
|
||||
if (! is_string($newClassName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$classNames[] = $newNodeClassName;
|
||||
$classNames[] = $newClassName;
|
||||
}
|
||||
|
||||
return $classNames;
|
||||
|
@ -147,9 +140,7 @@ final class UnusedClassResolver
|
|||
{
|
||||
$classNames = [];
|
||||
|
||||
/** @var StaticCall[] $staticCallNodes */
|
||||
$staticCallNodes = $this->parsedNodeCollector->getNodesByType(StaticCall::class);
|
||||
foreach ($staticCallNodes as $staticCallNode) {
|
||||
foreach ($this->parsedNodeCollector->getStaticCalls() as $staticCallNode) {
|
||||
$staticClassName = $this->nodeNameResolver->getName($staticCallNode->class);
|
||||
if (! is_string($staticClassName)) {
|
||||
continue;
|
||||
|
@ -165,8 +156,7 @@ final class UnusedClassResolver
|
|||
*/
|
||||
private function getClassConstantFetchNames(): array
|
||||
{
|
||||
/** @var ClassConstFetch[] $classConstFetches */
|
||||
$classConstFetches = $this->parsedNodeCollector->getNodesByType(ClassConstFetch::class);
|
||||
$classConstFetches = $this->parsedNodeCollector->getClassConstFetches();
|
||||
|
||||
$classNames = [];
|
||||
foreach ($classConstFetches as $classConstFetch) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user