diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/CompleteDynamicPropertiesRectorTest.php b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/CompleteDynamicPropertiesRectorTest.php deleted file mode 100644 index 451b011fc12..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/CompleteDynamicPropertiesRectorTest.php +++ /dev/null @@ -1,28 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/pre_union_types.php'; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/class_string_case_insensitive.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/class_string_case_insensitive.php.inc deleted file mode 100644 index 619c2861e7c..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/class_string_case_insensitive.php.inc +++ /dev/null @@ -1,29 +0,0 @@ -value = 'classStringCaseInSensitive'; - } -} - -?> ------ -value = 'classStringCaseInSensitive'; - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/class_string_case_sensitive.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/class_string_case_sensitive.php.inc deleted file mode 100644 index 29ba6a5af3b..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/class_string_case_sensitive.php.inc +++ /dev/null @@ -1,29 +0,0 @@ -value = 'ClassStringCaseSensitive'; - } -} - -?> ------ - - */ - public $value; - public function set() - { - $this->value = 'ClassStringCaseSensitive'; - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/constructor_private.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/constructor_private.php.inc deleted file mode 100644 index d55b5e114a2..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/constructor_private.php.inc +++ /dev/null @@ -1,28 +0,0 @@ -value = 'constructorPrivate'; - } -} - -?> ------ -value = 'constructorPrivate'; - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/fixture.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/fixture.php.inc deleted file mode 100644 index 71bcd344f6b..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/fixture.php.inc +++ /dev/null @@ -1,31 +0,0 @@ -value = 5; - } -} - -?> ------ -value = 5; - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/multiple_props.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/multiple_props.php.inc deleted file mode 100644 index ca3e3ababef..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/multiple_props.php.inc +++ /dev/null @@ -1,35 +0,0 @@ -c = 5; - } -} - -?> ------ -c = 5; - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/multiple_types.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/multiple_types.php.inc deleted file mode 100644 index d1970dd9eed..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/multiple_types.php.inc +++ /dev/null @@ -1,35 +0,0 @@ -value = 5; - - $this->value = 'hey'; - } -} - -?> ------ -value = 5; - - $this->value = 'hey'; - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/setup_private.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/setup_private.php.inc deleted file mode 100644 index 35f463e49d6..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/setup_private.php.inc +++ /dev/null @@ -1,28 +0,0 @@ -initialValue = 123; - } -} - -?> ------ -initialValue = 123; - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_abstract_class.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_abstract_class.php.inc deleted file mode 100644 index db0d695efea..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_abstract_class.php.inc +++ /dev/null @@ -1,11 +0,0 @@ -value = 5; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_allow_dynamic_attribute.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_allow_dynamic_attribute.php.inc deleted file mode 100644 index 36f2ac581e9..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_allow_dynamic_attribute.php.inc +++ /dev/null @@ -1,14 +0,0 @@ -value = 5; - - $this->value = 'hey'; - } -} \ No newline at end of file diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_anonymous_class.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_anonymous_class.php.inc deleted file mode 100644 index 76bab72d64a..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_anonymous_class.php.inc +++ /dev/null @@ -1,49 +0,0 @@ -addVisitor($this->createNodeVisitor($callable)); - $nodeTraverser->traverse($nodes); - } - - private function createNodeVisitor(callable $callable): NodeVisitor - { - return new class($callable) extends NodeVisitorAbstract { - /** - * @var callable - */ - private $callable; - - public function __construct(callable $callable) - { - $this->callable = $callable; - } - - /** - * @return int|Node|null - */ - public function enterNode(Node $node) - { - $callable = $this->callable; - return $callable($node); - } - }; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_closure_bind_to.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_closure_bind_to.php.inc deleted file mode 100644 index 307bbae9b88..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_closure_bind_to.php.inc +++ /dev/null @@ -1,18 +0,0 @@ -uuidV4Generator; - })->bindTo($randomGenerator); - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_closure_call.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_closure_call.php.inc deleted file mode 100644 index a8d1ddb028c..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_closure_call.php.inc +++ /dev/null @@ -1,17 +0,0 @@ -uuidV4Generator; - })->call($randomGenerator); - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_closure_property.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_closure_property.php.inc deleted file mode 100644 index 863573138e1..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_closure_property.php.inc +++ /dev/null @@ -1,18 +0,0 @@ -uuidV4Generator; - }, $randomGenerator, $randomGenerator)(); - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_defined.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_defined.php.inc deleted file mode 100644 index cc30d4dac89..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_defined.php.inc +++ /dev/null @@ -1,12 +0,0 @@ -value = 5; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_dynamic_properties.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_dynamic_properties.php.inc deleted file mode 100644 index 53e797c5bdf..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_dynamic_properties.php.inc +++ /dev/null @@ -1,14 +0,0 @@ - $v) { - $this->$k = $v; - } - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_inner_class.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_inner_class.php.inc deleted file mode 100644 index 3db4284261d..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_inner_class.php.inc +++ /dev/null @@ -1,20 +0,0 @@ -logged = $value; - } - }; - - echo $box->logged; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_laravel_closure_binding.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_laravel_closure_binding.php.inc deleted file mode 100644 index d419d760779..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_laravel_closure_binding.php.inc +++ /dev/null @@ -1,23 +0,0 @@ -items; - ksort($list); - - return new static($list); - }); - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_late_static_binding.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_late_static_binding.php.inc deleted file mode 100644 index a30ca6cba33..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_late_static_binding.php.inc +++ /dev/null @@ -1,13 +0,0 @@ -{static::PRIMARY_KEY} = 1; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_magic.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_magic.php.inc deleted file mode 100644 index 8f838912db5..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_magic.php.inc +++ /dev/null @@ -1,15 +0,0 @@ -value = 5; - } - - public function __set($key, $value) - { - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_magic_parent.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_magic_parent.php.inc deleted file mode 100644 index d830e0f1c8b..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_magic_parent.php.inc +++ /dev/null @@ -1,13 +0,0 @@ -value = 5; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_parent_property.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_parent_property.php.inc deleted file mode 100644 index 4387353a0a5..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_parent_property.php.inc +++ /dev/null @@ -1,16 +0,0 @@ -value = 5; - } -} - -class SomeParentClassWithProperty -{ - public $value; -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_property_from_not_autoloaded_grandparent.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_property_from_not_autoloaded_grandparent.php.inc deleted file mode 100644 index 8bffac21901..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_property_from_not_autoloaded_grandparent.php.inc +++ /dev/null @@ -1,15 +0,0 @@ -configFactory->get(''); - } -} - -class CancelableHandler extends \NotAutoloaded\EmailHandler -{ -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_pull_from_different_class.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_pull_from_different_class.php.inc deleted file mode 100644 index ed12ee3ecc8..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_pull_from_different_class.php.inc +++ /dev/null @@ -1,14 +0,0 @@ -property; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_static_return_object.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_static_return_object.php.inc deleted file mode 100644 index 8c446642c74..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_static_return_object.php.inc +++ /dev/null @@ -1,13 +0,0 @@ -timestamp; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_trait_used.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_trait_used.php.inc deleted file mode 100644 index b9d9521546d..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_trait_used.php.inc +++ /dev/null @@ -1,18 +0,0 @@ -value = 5; - } -} - -trait PropertyInjection -{ - private $value; -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_undefined_parent_class.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_undefined_parent_class.php.inc deleted file mode 100644 index 22e4b0dd072..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/skip_undefined_parent_class.php.inc +++ /dev/null @@ -1,11 +0,0 @@ -value = 5; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/with_array_type.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/with_array_type.php.inc deleted file mode 100644 index ceb7537d426..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Fixture/with_array_type.php.inc +++ /dev/null @@ -1,31 +0,0 @@ -someProperty[$name] = true; - } -} - -?> ------ - - */ - public $someProperty; - public function addSome(string $name) - { - $this->someProperty[$name] = true; - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/FixtureUnionTypes/multiple_types.php.inc b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/FixtureUnionTypes/multiple_types.php.inc deleted file mode 100644 index 78c0bc77575..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/FixtureUnionTypes/multiple_types.php.inc +++ /dev/null @@ -1,39 +0,0 @@ -value = 5; - - $this->value = 'hey'; - - $this->value = false; - } -} - -?> ------ -value = 5; - - $this->value = 'hey'; - - $this->value = false; - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Source/DifferentClass.php b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Source/DifferentClass.php deleted file mode 100644 index 7499b5e76ac..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/Source/DifferentClass.php +++ /dev/null @@ -1,10 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/FixtureUnionTypes'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/config/configured_rule.php deleted file mode 100644 index 5b19208ea16..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/config/configured_rule.php +++ /dev/null @@ -1,9 +0,0 @@ -withRules([CompleteDynamicPropertiesRector::class]); diff --git a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/config/pre_union_types.php b/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/config/pre_union_types.php deleted file mode 100644 index 1cadc358a63..00000000000 --- a/rules-tests/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector/config/pre_union_types.php +++ /dev/null @@ -1,12 +0,0 @@ -phpVersion(PhpVersionFeature::UNION_TYPES - 1); - $rectorConfig->rule(CompleteDynamicPropertiesRector::class); -}; diff --git a/rules/CodeQuality/NodeAnalyzer/ClassLikeAnalyzer.php b/rules/CodeQuality/NodeAnalyzer/ClassLikeAnalyzer.php deleted file mode 100644 index 99aff2f6b50..00000000000 --- a/rules/CodeQuality/NodeAnalyzer/ClassLikeAnalyzer.php +++ /dev/null @@ -1,26 +0,0 @@ -getProperties() as $property) { - foreach ($property->props as $prop) { - $propertyNames[] = $prop->name->toString(); - } - } - - return $propertyNames; - } -} diff --git a/rules/CodeQuality/NodeAnalyzer/LocalPropertyAnalyzer.php b/rules/CodeQuality/NodeAnalyzer/LocalPropertyAnalyzer.php deleted file mode 100644 index 07332188075..00000000000 --- a/rules/CodeQuality/NodeAnalyzer/LocalPropertyAnalyzer.php +++ /dev/null @@ -1,208 +0,0 @@ -getMethods() as $classMethod) { - $methodName = $this->nodeNameResolver->getName($classMethod); - - $this->simpleCallableNodeTraverser->traverseNodesWithCallable( - $classMethod->getStmts(), - function (Node $node) use (&$definedPropertiesWithTypes, $methodName): ?int { - if ($this->shouldSkip($node)) { - return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN; - } - - if ($node instanceof Assign && ($node->var instanceof PropertyFetch || $node->var instanceof ArrayDimFetch)) { - $propertyFetch = $node->var; - - $propertyName = $this->resolvePropertyName( - $propertyFetch instanceof ArrayDimFetch ? $propertyFetch->var : $propertyFetch - ); - - if ($propertyName === null) { - return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN; - } - - if ($propertyFetch instanceof ArrayDimFetch) { - $propertyType = $this->arrayDimFetchTypeResolver->resolve($propertyFetch, $node); - - $definedPropertiesWithTypes[] = new DefinedPropertyWithType( - $propertyName, - $propertyType, - $methodName - ); - - return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN; - } - - $propertyType = $this->nodeTypeResolver->getType($node->expr); - - $definedPropertiesWithTypes[] = new DefinedPropertyWithType( - $propertyName, - $propertyType, - $methodName - ); - - return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN; - } - - $propertyName = $this->resolvePropertyName($node); - if ($propertyName === null) { - return null; - } - - $definedPropertiesWithTypes[] = new DefinedPropertyWithType( - $propertyName, - new MixedType(), - $methodName - ); - - return null; - } - ); - } - - return $this->normalizeToSingleType($definedPropertiesWithTypes); - } - - private function shouldSkip(Node $node): bool - { - // skip anonymous classes and inner function - if ($node instanceof Class_ || $node instanceof Function_) { - return true; - } - - // skip closure call - if ($node instanceof MethodCall && $node->var instanceof Closure) { - return true; - } - - if ($node instanceof StaticCall) { - return $this->nodeNameResolver->isName($node->class, self::LARAVEL_COLLECTION_CLASS); - } - - return false; - } - - private function resolvePropertyName(Node $node): string|null - { - if (! $node instanceof PropertyFetch) { - return null; - } - - if (! $this->propertyFetchAnalyzer->isLocalPropertyFetch($node)) { - return null; - } - - if ($this->shouldSkipPropertyFetch($node)) { - return null; - } - - return $this->nodeNameResolver->getName($node->name); - } - - private function shouldSkipPropertyFetch(PropertyFetch $propertyFetch): bool - { - if ($this->isPartOfClosureBind($propertyFetch)) { - return true; - } - - return ! $propertyFetch->name instanceof Identifier; - } - - /** - * @param DefinedPropertyWithType[] $definedPropertiesWithTypes - * @return DefinedPropertyWithType[] - */ - private function normalizeToSingleType(array $definedPropertiesWithTypes): array - { - $definedPropertiesWithTypesByPropertyName = []; - foreach ($definedPropertiesWithTypes as $definedPropertyWithType) { - $definedPropertiesWithTypesByPropertyName[$definedPropertyWithType->getName()][] = $definedPropertyWithType; - } - - $normalizedDefinedPropertiesWithTypes = []; - - foreach ($definedPropertiesWithTypesByPropertyName as $propertyName => $definedPropertiesWithTypes) { - if (count($definedPropertiesWithTypes) === 1) { - $normalizedDefinedPropertiesWithTypes[] = $definedPropertiesWithTypes[0]; - continue; - } - - $propertyTypes = []; - foreach ($definedPropertiesWithTypes as $definedPropertyWithType) { - /** @var DefinedPropertyWithType $definedPropertyWithType */ - $propertyTypes[] = $definedPropertyWithType->getType(); - } - - $normalizePropertyType = $this->typeFactory->createMixedPassedOrUnionType($propertyTypes); - $normalizedDefinedPropertiesWithTypes[] = new DefinedPropertyWithType( - $propertyName, - $normalizePropertyType, - // skip as multiple places can define the same property - null - ); - } - - return $normalizedDefinedPropertiesWithTypes; - } - - /** - * Local property is actually not local one, but belongs to passed object - * See https://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/ - */ - private function isPartOfClosureBind(PropertyFetch $propertyFetch): bool - { - $scope = $propertyFetch->getAttribute(AttributeKey::SCOPE); - if (! $scope instanceof Scope) { - return false; - } - - return $scope->isInClosureBind(); - } -} diff --git a/rules/CodeQuality/NodeAnalyzer/MissingPropertiesResolver.php b/rules/CodeQuality/NodeAnalyzer/MissingPropertiesResolver.php deleted file mode 100644 index 65c9b1aacab..00000000000 --- a/rules/CodeQuality/NodeAnalyzer/MissingPropertiesResolver.php +++ /dev/null @@ -1,57 +0,0 @@ -classLikeAnalyzer->resolvePropertyNames($class); - - $missingPropertiesWithTypes = []; - - foreach ($definedPropertiesWithTypes as $definedPropertyWithType) { - // 1. property already exists, skip it - if (in_array($definedPropertyWithType->getName(), $existingPropertyNames, true)) { - continue; - } - - // 2. is part of class docblock or another magic, skip it - if ($classReflection->hasInstanceProperty($definedPropertyWithType->getName())) { - continue; - } - - // 3. is fetched by parent class on non-private property etc., skip it - $hasClassContextProperty = $this->propertyPresenceChecker->hasClassContextProperty( - $class, - $definedPropertyWithType - ); - - if ($hasClassContextProperty) { - continue; - } - - // it's most likely missing! - $missingPropertiesWithTypes[] = $definedPropertyWithType; - } - - return $missingPropertiesWithTypes; - } -} diff --git a/rules/CodeQuality/NodeFactory/MissingPropertiesFactory.php b/rules/CodeQuality/NodeFactory/MissingPropertiesFactory.php deleted file mode 100644 index 8b534032c7d..00000000000 --- a/rules/CodeQuality/NodeFactory/MissingPropertiesFactory.php +++ /dev/null @@ -1,75 +0,0 @@ -isFromAlwaysDefinedMethod($definedPropertyWithType) - ? Modifiers::PRIVATE - : Modifiers::PUBLIC; - - $property = new Property($visibilityModifier, [ - new PropertyItem($definedPropertyWithType->getName()), - ]); - - if ($this->isFromAlwaysDefinedMethod( - $definedPropertyWithType - ) && $this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::TYPED_PROPERTIES)) { - $propertyType = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode( - $definedPropertyWithType->getType(), - TypeKind::PROPERTY - ); - if ($propertyType instanceof Node) { - $property->type = $propertyType; - $newProperties[] = $property; - - continue; - } - } - - // fallback to docblock - $this->propertyTypeDecorator->decorateProperty($property, $definedPropertyWithType->getType()); - - $newProperties[] = $property; - } - - return $newProperties; - } - - private function isFromAlwaysDefinedMethod(DefinedPropertyWithType $definedPropertyWithType): bool - { - return in_array( - $definedPropertyWithType->getDefinedInMethodName(), - [MethodName::CONSTRUCT, MethodName::SET_UP], - true - ); - } -} diff --git a/rules/CodeQuality/NodeFactory/PropertyTypeDecorator.php b/rules/CodeQuality/NodeFactory/PropertyTypeDecorator.php deleted file mode 100644 index bd0b22941d0..00000000000 --- a/rules/CodeQuality/NodeFactory/PropertyTypeDecorator.php +++ /dev/null @@ -1,32 +0,0 @@ -typeNormalizer->generalizeConstantTypes($propertyType); - - $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property); - $phpDocInfo->makeMultiLined(); - - $this->phpDocTypeChanger->changeVarType($property, $phpDocInfo, $propertyType); - } -} diff --git a/rules/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector.php b/rules/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector.php index 88d1014643c..0af73f8ef58 100644 --- a/rules/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector.php +++ b/rules/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector.php @@ -6,34 +6,17 @@ use PhpParser\Node; use PhpParser\Node\Stmt\Class_; -use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\ReflectionProvider; -use Rector\CodeQuality\NodeAnalyzer\LocalPropertyAnalyzer; -use Rector\CodeQuality\NodeAnalyzer\MissingPropertiesResolver; -use Rector\CodeQuality\NodeFactory\MissingPropertiesFactory; -use Rector\NodeAnalyzer\ClassAnalyzer; -use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer; +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; +use Rector\Exception\ShouldNotHappenException; use Rector\Rector\AbstractRector; -use Rector\Reflection\ClassReflectionAnalyzer; use Rector\RuleDoc\CodeSample\CodeSample; use Rector\RuleDoc\RuleDefinition; /** - * @see \Rector\Tests\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector\CompleteDynamicPropertiesRectorTest + * @deprecated This rule is deprecated, as it can create invalid properties on classes with partial type information. Add missing properties by hand with proper types instead. */ -final class CompleteDynamicPropertiesRector extends AbstractRector +final class CompleteDynamicPropertiesRector extends AbstractRector implements DeprecatedInterface { - public function __construct( - private readonly MissingPropertiesFactory $missingPropertiesFactory, - private readonly LocalPropertyAnalyzer $localPropertyAnalyzer, - private readonly ReflectionProvider $reflectionProvider, - private readonly ClassAnalyzer $classAnalyzer, - private readonly PhpAttributeAnalyzer $phpAttributeAnalyzer, - private readonly MissingPropertiesResolver $missingPropertiesResolver, - private readonly ClassReflectionAnalyzer $classReflectionAnalyzer, - ) { - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Add missing dynamic properties', [ @@ -79,100 +62,9 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - if ($this->shouldSkipClass($node)) { - return null; - } - - $classReflection = $this->matchClassReflection($node); - if (! $classReflection instanceof ClassReflection) { - return null; - } - - // special case for Laravel Collection macro magic - $definedLocalPropertiesWithTypes = $this->localPropertyAnalyzer->resolveFetchedPropertiesToTypesFromClass( - $node - ); - - $propertiesToComplete = $this->missingPropertiesResolver->resolve( - $node, - $classReflection, - $definedLocalPropertiesWithTypes - ); - - $newProperties = $this->missingPropertiesFactory->create($propertiesToComplete); - if ($newProperties === []) { - return null; - } - - $node->stmts = array_merge($newProperties, $node->stmts); - - return $node; - } - - private function shouldSkipClass(Class_ $class): bool - { - if ($this->classAnalyzer->isAnonymousClass($class)) { - return true; - } - - // abstract class property might be accessed from child class - if ($class->isAbstract()) { - return true; - } - - $className = (string) $this->getName($class); - if (! $this->reflectionProvider->hasClass($className)) { - return true; - } - - // dynamic property on purpose - if ($this->phpAttributeAnalyzer->hasPhpAttribute($class, 'AllowDynamicProperties')) { - return true; - } - - $classReflection = $this->reflectionProvider->getClass($className); - - // properties are accessed via magic, nothing we can do - if ($classReflection->hasMethod('__set')) { - return true; - } - - if ($classReflection->hasMethod('__get')) { - return true; - } - - // any not autoloaded ancestor may already declare the property, so we cannot safely add it - return $this->hasNotAutoloadedAncestor($classReflection); - } - - private function hasNotAutoloadedAncestor(ClassReflection $classReflection): bool - { - $currentClassReflection = $classReflection; - - while ($currentClassReflection instanceof ClassReflection) { - $parentClassName = $this->classReflectionAnalyzer->resolveParentClassName($currentClassReflection); - - if ($parentClassName !== null && ! $this->reflectionProvider->hasClass($parentClassName)) { - return true; - } - - $currentClassReflection = $currentClassReflection->getParentClass(); - } - - return false; - } - - private function matchClassReflection(Class_ $class): ?ClassReflection - { - $className = $this->getName($class); - if ($className === null) { - return null; - } - - if (! $this->reflectionProvider->hasClass($className)) { - return null; - } - - return $this->reflectionProvider->getClass($className); + throw new ShouldNotHappenException(sprintf( + '"%s" rule is deprecated, as it can create invalid properties on classes with partial type information', + self::class + )); } } diff --git a/rules/CodeQuality/TypeResolver/ArrayDimFetchTypeResolver.php b/rules/CodeQuality/TypeResolver/ArrayDimFetchTypeResolver.php deleted file mode 100644 index 8f5938d6c02..00000000000 --- a/rules/CodeQuality/TypeResolver/ArrayDimFetchTypeResolver.php +++ /dev/null @@ -1,38 +0,0 @@ -resolveDimType($arrayDimFetch); - $valueStaticType = $this->nodeTypeResolver->getType($assign->expr); - - return new ArrayType($keyStaticType, $valueStaticType); - } - - private function resolveDimType(ArrayDimFetch $arrayDimFetch): Type - { - if ($arrayDimFetch->dim instanceof Expr) { - return $this->nodeTypeResolver->getType($arrayDimFetch->dim); - } - - return new MixedType(); - } -} diff --git a/rules/CodeQuality/ValueObject/DefinedPropertyWithType.php b/rules/CodeQuality/ValueObject/DefinedPropertyWithType.php deleted file mode 100644 index 7105d8089d9..00000000000 --- a/rules/CodeQuality/ValueObject/DefinedPropertyWithType.php +++ /dev/null @@ -1,32 +0,0 @@ -propertyName; - } - - public function getType(): Type - { - return $this->type; - } - - public function getDefinedInMethodName(): ?string - { - return $this->definedInMethodName; - } -} diff --git a/src/Config/Level/CodeQualityLevel.php b/src/Config/Level/CodeQualityLevel.php index 2e491f9774c..56f7b7c01a0 100644 --- a/src/Config/Level/CodeQualityLevel.php +++ b/src/Config/Level/CodeQualityLevel.php @@ -15,7 +15,6 @@ use Rector\CodeQuality\Rector\BooleanNot\SimplifyDeMorganBinaryRector; use Rector\CodeQuality\Rector\BooleanOr\RepeatedOrEqualToInArrayRector; use Rector\CodeQuality\Rector\Catch_\ThrowWithPreviousExceptionRector; -use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector; use Rector\CodeQuality\Rector\Class_\ConvertStaticToSelfRector; use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector; use Rector\CodeQuality\Rector\ClassConstFetch\VariableConstFetchToClassConstFetchRector; @@ -125,7 +124,6 @@ final class CodeQualityLevel BooleanNotIdenticalToNotIdenticalRector::class, AndAssignsToSeparateLinesRector::class, CompactToVariablesRector::class, - CompleteDynamicPropertiesRector::class, IsAWithStringWithThirdArgumentRector::class, StrlenZeroToIdenticalEmptyStringRector::class, ArrayExplicitBoolCompareRector::class, diff --git a/src/NodeAnalyzer/PropertyPresenceChecker.php b/src/NodeAnalyzer/PropertyPresenceChecker.php index 96412ed75f3..fbcb9340c09 100644 --- a/src/NodeAnalyzer/PropertyPresenceChecker.php +++ b/src/NodeAnalyzer/PropertyPresenceChecker.php @@ -7,7 +7,6 @@ use PhpParser\Node\Param; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\Property; -use Rector\CodeQuality\ValueObject\DefinedPropertyWithType; use Rector\NodeNameResolver\NodeNameResolver; use Rector\Php80\NodeAnalyzer\PromotedPropertyResolver; use Rector\PostRector\ValueObject\PropertyMetadata; @@ -26,15 +25,9 @@ public function __construct( /** * Includes parent classes and traits */ - public function hasClassContextProperty(Class_ $class, DefinedPropertyWithType $definedPropertyWithType): bool - { - $propertyOrParam = $this->getClassContextProperty($class, $definedPropertyWithType); - return $propertyOrParam !== null; - } - public function getClassContextProperty( Class_ $class, - DefinedPropertyWithType|PropertyMetadata $definedPropertyWithType + PropertyMetadata $definedPropertyWithType ): Property|Param|null { $className = $this->nodeNameResolver->getName($class); if ($className === null) {