mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-21 16:02:23 +02:00
Updated Rector to commit b007a8bd11ea0451b50dbafbacd5450b295f6266
b007a8bd11
[Php83] Add implements interface support on AddOverrideAttributeToOverriddenMethodsRector (#5429)
This commit is contained in:
parent
5457aea4e0
commit
41a86add1d
@ -8,6 +8,7 @@ use PhpParser\Node\Attribute;
|
||||
use PhpParser\Node\AttributeGroup;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\NodeAnalyzer\ClassAnalyzer;
|
||||
use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer;
|
||||
@ -37,6 +38,10 @@ final class AddOverrideAttributeToOverriddenMethodsRector extends AbstractRector
|
||||
* @var \Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer
|
||||
*/
|
||||
private $phpAttributeAnalyzer;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hasChanged = \false;
|
||||
public function __construct(ReflectionProvider $reflectionProvider, ClassAnalyzer $classAnalyzer, PhpAttributeAnalyzer $phpAttributeAnalyzer)
|
||||
{
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
@ -90,33 +95,18 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node) : ?Node
|
||||
{
|
||||
// Detect if class extends a parent class
|
||||
if ($this->shouldSkipClass($node)) {
|
||||
$this->hasChanged = \false;
|
||||
if ($this->classAnalyzer->isAnonymousClass($node)) {
|
||||
return null;
|
||||
}
|
||||
// Fetch the parent class reflection
|
||||
$parentClassReflection = $this->reflectionProvider->getClass((string) $node->extends);
|
||||
$hasChanged = \false;
|
||||
foreach ($node->getMethods() as $classMethod) {
|
||||
if ($classMethod->name->toString() === '__construct') {
|
||||
continue;
|
||||
}
|
||||
// Private methods should be ignored
|
||||
if ($parentClassReflection->hasNativeMethod($classMethod->name->toString())) {
|
||||
// ignore if it is a private method on the parent
|
||||
$parentMethod = $parentClassReflection->getNativeMethod($classMethod->name->toString());
|
||||
if ($parentMethod->isPrivate()) {
|
||||
continue;
|
||||
}
|
||||
// ignore if it already uses the attribute
|
||||
if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, 'Override')) {
|
||||
continue;
|
||||
}
|
||||
$classMethod->attrGroups[] = new AttributeGroup([new Attribute(new FullyQualified('Override'))]);
|
||||
$hasChanged = \true;
|
||||
}
|
||||
$className = (string) $this->getName($node);
|
||||
if (!$this->reflectionProvider->hasClass($className)) {
|
||||
return null;
|
||||
}
|
||||
if (!$hasChanged) {
|
||||
$classReflection = $this->reflectionProvider->getClass($className);
|
||||
$parentClassReflections = \array_merge($classReflection->getParents(), $classReflection->getInterfaces());
|
||||
$this->processAddOverrideAttribute($node, $parentClassReflections);
|
||||
if (!$this->hasChanged) {
|
||||
return null;
|
||||
}
|
||||
return $node;
|
||||
@ -125,14 +115,36 @@ CODE_SAMPLE
|
||||
{
|
||||
return PhpVersionFeature::OVERRIDE_ATTRIBUTE;
|
||||
}
|
||||
private function shouldSkipClass(Class_ $class) : bool
|
||||
/**
|
||||
* @param ClassReflection[] $parentClassReflections
|
||||
*/
|
||||
private function processAddOverrideAttribute(Class_ $class, array $parentClassReflections) : void
|
||||
{
|
||||
if ($this->classAnalyzer->isAnonymousClass($class)) {
|
||||
return \true;
|
||||
if ($parentClassReflections === []) {
|
||||
return;
|
||||
}
|
||||
if (!$class->extends instanceof FullyQualified) {
|
||||
return \true;
|
||||
foreach ($class->getMethods() as $classMethod) {
|
||||
if ($classMethod->name->toString() === '__construct') {
|
||||
continue;
|
||||
}
|
||||
// ignore if it already uses the attribute
|
||||
if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, 'Override')) {
|
||||
continue;
|
||||
}
|
||||
// Private methods should be ignored
|
||||
foreach ($parentClassReflections as $parentClassReflection) {
|
||||
if (!$parentClassReflection->hasNativeMethod($classMethod->name->toString())) {
|
||||
continue;
|
||||
}
|
||||
// ignore if it is a private method on the parent
|
||||
$parentMethod = $parentClassReflection->getNativeMethod($classMethod->name->toString());
|
||||
if ($parentMethod->isPrivate()) {
|
||||
continue;
|
||||
}
|
||||
$classMethod->attrGroups[] = new AttributeGroup([new Attribute(new FullyQualified('Override'))]);
|
||||
$this->hasChanged = \true;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
return !$this->reflectionProvider->hasClass($class->extends->toString());
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ final class VersionResolver
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = '1f9829d2a3820f39fe0601b996c5cba71ffb42b0';
|
||||
public const PACKAGE_VERSION = 'b007a8bd11ea0451b50dbafbacd5450b295f6266';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2024-01-04 22:47:15';
|
||||
public const RELEASE_DATE = '2024-01-04 20:12:00';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
2
vendor/composer/autoload_classmap.php
vendored
2
vendor/composer/autoload_classmap.php
vendored
@ -50,6 +50,8 @@ return array(
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTextNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTextNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PropertyTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\RequireExtendsTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireExtendsTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\RequireImplementsTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireImplementsTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\ReturnTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\SelfOutTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/SelfOutTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\TemplateTagValueNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/TemplateTagValueNode.php',
|
||||
|
2
vendor/composer/autoload_static.php
vendored
2
vendor/composer/autoload_static.php
vendored
@ -264,6 +264,8 @@ class ComposerStaticInit8c7215074e107c54fa988078cf9a09f8
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTextNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTextNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PropertyTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\RequireExtendsTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireExtendsTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\RequireImplementsTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireImplementsTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\ReturnTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\SelfOutTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/SelfOutTagValueNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\PhpDoc\\TemplateTagValueNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/PhpDoc/TemplateTagValueNode.php',
|
||||
|
14
vendor/composer/installed.json
vendored
14
vendor/composer/installed.json
vendored
@ -858,17 +858,17 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan\/phpdoc-parser",
|
||||
"version": "1.24.5",
|
||||
"version_normalized": "1.24.5.0",
|
||||
"version": "1.25.0",
|
||||
"version_normalized": "1.25.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/phpstan\/phpdoc-parser.git",
|
||||
"reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc"
|
||||
"reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/phpstan\/phpdoc-parser\/zipball\/fedf211ff14ec8381c9bf5714e33a7a552dd1acc",
|
||||
"reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc",
|
||||
"url": "https:\/\/api.github.com\/repos\/phpstan\/phpdoc-parser\/zipball\/bd84b629c8de41aa2ae82c067c955e06f1b00240",
|
||||
"reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -885,7 +885,7 @@
|
||||
"phpunit\/phpunit": "^9.5",
|
||||
"symfony\/process": "^5.2"
|
||||
},
|
||||
"time": "2023-12-16T09:33:33+00:00",
|
||||
"time": "2024-01-04T17:06:16+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -902,7 +902,7 @@
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"support": {
|
||||
"issues": "https:\/\/github.com\/phpstan\/phpdoc-parser\/issues",
|
||||
"source": "https:\/\/github.com\/phpstan\/phpdoc-parser\/tree\/1.24.5"
|
||||
"source": "https:\/\/github.com\/phpstan\/phpdoc-parser\/tree\/1.25.0"
|
||||
},
|
||||
"install-path": "..\/phpstan\/phpdoc-parser"
|
||||
},
|
||||
|
2
vendor/composer/installed.php
vendored
2
vendor/composer/installed.php
vendored
File diff suppressed because one or more lines are too long
@ -129,6 +129,24 @@ class PhpDocNode implements Node
|
||||
return $value instanceof \PHPStan\PhpDocParser\Ast\PhpDoc\MixinTagValueNode;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @return RequireExtendsTagValueNode[]
|
||||
*/
|
||||
public function getRequireExtendsTagValues(string $tagName = '@phpstan-require-extends') : array
|
||||
{
|
||||
return array_filter(array_column($this->getTagsByName($tagName), 'value'), static function (\PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode $value) : bool {
|
||||
return $value instanceof \PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @return RequireImplementsTagValueNode[]
|
||||
*/
|
||||
public function getRequireImplementsTagValues(string $tagName = '@phpstan-require-implements') : array
|
||||
{
|
||||
return array_filter(array_column($this->getTagsByName($tagName), 'value'), static function (\PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode $value) : bool {
|
||||
return $value instanceof \PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @return DeprecatedTagValueNode[]
|
||||
*/
|
||||
|
25
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireExtendsTagValueNode.php
vendored
Normal file
25
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireExtendsTagValueNode.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
class RequireExtendsTagValueNode implements \PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode
|
||||
{
|
||||
use NodeAttributes;
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
public function __construct(TypeNode $type, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return trim("{$this->type} {$this->description}");
|
||||
}
|
||||
}
|
25
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireImplementsTagValueNode.php
vendored
Normal file
25
vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/RequireImplementsTagValueNode.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\NodeAttributes;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use function trim;
|
||||
class RequireImplementsTagValueNode implements \PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode
|
||||
{
|
||||
use NodeAttributes;
|
||||
/** @var TypeNode */
|
||||
public $type;
|
||||
/** @var string (may be empty) */
|
||||
public $description;
|
||||
public function __construct(TypeNode $type, string $description)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
}
|
||||
public function __toString() : string
|
||||
{
|
||||
return trim("{$this->type} {$this->description}");
|
||||
}
|
||||
}
|
@ -301,6 +301,14 @@ class PhpDocParser
|
||||
case '@mixin':
|
||||
$tagValue = $this->parseMixinTagValue($tokens);
|
||||
break;
|
||||
case '@psalm-require-extends':
|
||||
case '@phpstan-require-extends':
|
||||
$tagValue = $this->parseRequireExtendsTagValue($tokens);
|
||||
break;
|
||||
case '@psalm-require-implements':
|
||||
case '@phpstan-require-implements':
|
||||
$tagValue = $this->parseRequireImplementsTagValue($tokens);
|
||||
break;
|
||||
case '@deprecated':
|
||||
$tagValue = $this->parseDeprecatedTagValue($tokens);
|
||||
break;
|
||||
@ -604,6 +612,18 @@ class PhpDocParser
|
||||
$description = $this->parseOptionalDescription($tokens, \true);
|
||||
return new Ast\PhpDoc\MixinTagValueNode($type, $description);
|
||||
}
|
||||
private function parseRequireExtendsTagValue(\PHPStan\PhpDocParser\Parser\TokenIterator $tokens) : Ast\PhpDoc\RequireExtendsTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens, \true);
|
||||
return new Ast\PhpDoc\RequireExtendsTagValueNode($type, $description);
|
||||
}
|
||||
private function parseRequireImplementsTagValue(\PHPStan\PhpDocParser\Parser\TokenIterator $tokens) : Ast\PhpDoc\RequireImplementsTagValueNode
|
||||
{
|
||||
$type = $this->typeParser->parse($tokens);
|
||||
$description = $this->parseOptionalDescription($tokens, \true);
|
||||
return new Ast\PhpDoc\RequireImplementsTagValueNode($type, $description);
|
||||
}
|
||||
private function parseDeprecatedTagValue(\PHPStan\PhpDocParser\Parser\TokenIterator $tokens) : Ast\PhpDoc\DeprecatedTagValueNode
|
||||
{
|
||||
$description = $this->parseOptionalDescription($tokens);
|
||||
|
@ -29,6 +29,8 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireExtendsTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\RequireImplementsTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\SelfOutTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
|
||||
@ -210,6 +212,14 @@ final class Printer
|
||||
$type = $this->printType($node->type);
|
||||
return trim("{$type} {$node->description}");
|
||||
}
|
||||
if ($node instanceof RequireExtendsTagValueNode) {
|
||||
$type = $this->printType($node->type);
|
||||
return trim("{$type} {$node->description}");
|
||||
}
|
||||
if ($node instanceof RequireImplementsTagValueNode) {
|
||||
$type = $this->printType($node->type);
|
||||
return trim("{$type} {$node->description}");
|
||||
}
|
||||
if ($node instanceof ParamOutTagValueNode) {
|
||||
$type = $this->printType($node->type);
|
||||
return trim("{$type} {$node->parameterName} {$node->description}");
|
||||
|
Loading…
x
Reference in New Issue
Block a user