valueResolver = $valueResolver; } public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('Replace key value on specific attribute to class constant', [new ConfiguredCodeSample(<<<'CODE_SAMPLE' use Doctrine\ORM\Mapping\Column; class SomeClass { #[Column(type: "string")] public $name; } CODE_SAMPLE , <<<'CODE_SAMPLE' use Doctrine\ORM\Mapping\Column; use Doctrine\DBAL\Types\Types; class SomeClass { #[Column(type: Types::STRING)] public $name; } CODE_SAMPLE , [new AttributeKeyToClassConstFetch('Doctrine\\ORM\\Mapping\\Column', 'type', 'Doctrine\\DBAL\\Types\\Types', ['string' => 'STRING'])])]); } /** * @return array> */ public function getNodeTypes() : array { return [Class_::class, Property::class, Param::class, ClassMethod::class, Function_::class, Closure::class, ArrowFunction::class, Interface_::class]; } /** * @param Class_|Property|Param|ClassMethod|Function_|Closure|ArrowFunction|Interface_ $node */ public function refactor(Node $node) : ?Node { if ($node->attrGroups === []) { return null; } $hasChanged = \false; foreach ($this->attributeKeysToClassConstFetches as $attributeKeyToClassConstFetch) { foreach ($node->attrGroups as $attrGroup) { if ($this->processToClassConstFetch($attrGroup, $attributeKeyToClassConstFetch)) { $hasChanged = \true; } } } if ($hasChanged) { return $node; } return null; } /** * @param mixed[] $configuration */ public function configure(array $configuration) : void { Assert::allIsAOf($configuration, AttributeKeyToClassConstFetch::class); $this->attributeKeysToClassConstFetches = $configuration; } private function processToClassConstFetch(AttributeGroup $attributeGroup, AttributeKeyToClassConstFetch $attributeKeyToClassConstFetch) : bool { $hasChanged = \false; foreach ($attributeGroup->attrs as $attribute) { if (!$this->isName($attribute->name, $attributeKeyToClassConstFetch->getAttributeClass())) { continue; } foreach ($attribute->args as $arg) { $argName = $arg->name; if (!$argName instanceof Identifier) { continue; } if (!$this->isName($argName, $attributeKeyToClassConstFetch->getAttributeKey())) { continue; } if ($this->processArg($arg, $attributeKeyToClassConstFetch)) { $hasChanged = \true; } } } return $hasChanged; } private function processArg(Arg $arg, AttributeKeyToClassConstFetch $attributeKeyToClassConstFetch) : bool { $value = $this->valueResolver->getValue($arg->value); $constName = $attributeKeyToClassConstFetch->getValuesToConstantsMap()[$value] ?? null; if ($constName === null) { return \false; } $newValue = $this->nodeFactory->createClassConstFetch($attributeKeyToClassConstFetch->getConstantClass(), $constName); if ($arg->value instanceof ClassConstFetch && $this->getName($arg->value) === $this->getName($newValue)) { return \false; } $arg->value = $newValue; return \true; } }