Skip to content

Commit ae01f71

Browse files
committed
refactor(MessageRector): enhance method visibility and simplify logic
- Add missing exception documentation for updateMethodsOfListTypeOption. - Adjust visibility modifier for add method to improve clarity. - Simplify the logic for determining method visibility based on class type.
1 parent 76f5c94 commit ae01f71

2 files changed

Lines changed: 98 additions & 20 deletions

File tree

src/Foundation/Caches/FileCache.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ protected function emptyPayload(): mixed
141141

142142
private function filePathFromKey(string $key): string
143143
{
144-
return $this->directory.\DIRECTORY_SEPARATOR.'cache-'.hash('md5', $key); // @pest-mutate-ignore
144+
return $this->directory.\DIRECTORY_SEPARATOR.'cache-'.hash('xxh3', $key); // @pest-mutate-ignore
145145
}
146146

147147
private function expiration(null|\DateInterval|int $seconds): int

src/Foundation/Rectors/MessageRector.php

Lines changed: 97 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,25 +79,15 @@ private function updateDocCommentOfClass(Class_ $classNode): void
7979
$allowedTypes = (new \ReflectionClass($class))->getDefaultProperties()['allowedTypes'] ?? [];
8080
$phpDocInfo = $this->phpDocInfoFactory->createEmpty($classNode);
8181

82-
$this->definedFor($class)
82+
collect(Utils::definedFor($class))
83+
->filter(static fn (string $option): bool => !str($option)->is(['*@*']))
84+
->sort()
8385
->each(fn (string $option) => $phpDocInfo->addPhpDocTagNode(
8486
$this->createPhpDocTagNodeOfMethod($option, $allowedTypes)
8587
))
8688
->whenNotEmpty(fn () => $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($classNode));
8789
}
8890

89-
/**
90-
* @param class-string<\Guanguans\Notify\Foundation\Message> $class
91-
*
92-
* @throws \ReflectionException
93-
*/
94-
private function definedFor(string $class): Collection
95-
{
96-
return collect(Utils::definedFor($class))
97-
->filter(static fn (string $option): bool => !str($option)->is(['*@*']))
98-
->sort();
99-
}
100-
10191
/**
10292
* @see \Symfony\Component\OptionsResolver\OptionsResolver::VALIDATION_FUNCTIONS
10393
*
@@ -129,22 +119,99 @@ private function createPhpDocTagNodeOfMethod(string $option, array $allowedTypes
129119
return new PhpDocTagNode('@method', new GenericTagValueNode("self $camelCasedOption($parameter)"));
130120
}
131121

122+
/**
123+
* @throws \ReflectionException
124+
*/
132125
private function updateAllowedTypesProperty(Class_ $classNode): void
133126
{
134-
collect($classNode->getMethods())
127+
// $defined = Utils::definedFor($this->getName($classNode));
128+
$allowedTypes = collect($classNode->getMethods())
135129
->filter(
136130
fn (ClassMethod $classMethodNode): bool => 1 === \count($classMethodNode->params)
137131
&& str_starts_with($this->getName($classMethodNode), 'add')
138132
)
139133
->mapWithKeys(function (ClassMethod $classMethodNode): array {
140-
$option = str($this->getName($classMethodNode))->after('add')->snake()->plural()->toString();
134+
// $rawOption = str($this->getName($classMethodNode))->after('add');
135+
// $caster = collect([
136+
// static fn (string $name): string => $name,
137+
// static fn (string $name): string => Str::snake($name),
138+
// Str::camel(...),
139+
// Str::pascal(...),
140+
// Str::kebab(...),
141+
// ])
142+
// ->flatMap(static fn (\Closure $caster): array => [
143+
// $caster,
144+
// static fn (string $name): string => $caster(\Illuminate\Support\Str::plural($name)),
145+
// ])
146+
// ->firstOrFail(fn (\Closure $caster) => $rawOption->pipe($caster)->is($defined));
147+
// $option = $rawOption->pipe($caster)->toString();
148+
$option = $this->valueResolver->getValue($classMethodNode->stmts[0]->expr->var->var->dim);
141149

142-
return [$option => $classMethodNode->params[0]->type->toString()];
143-
})
144-
->dump();
150+
return [$option => $this->getName($classMethodNode->params[0]->type).'[]'];
151+
});
152+
153+
if ($allowedTypes->isEmpty()) {
154+
return;
155+
}
156+
157+
$allowedTypesPropertyNode = collect($classNode->stmts)->first(
158+
fn (Stmt $stmtNode): bool => $stmtNode instanceof Property && $this->isName($stmtNode, 'allowedTypes')
159+
);
160+
161+
if (
162+
!$allowedTypesPropertyNode instanceof Property
163+
|| !($defaultNode = $allowedTypesPropertyNode->props[0]->default) instanceof Array_
164+
) {
165+
array_splice($classNode->stmts, 1, 0, [
166+
(new PropertyBuilder('allowedTypes'))
167+
->makeProtected()
168+
->setDocComment('/** @var array<string, list<string>|string> */')
169+
->setType('array')
170+
->setDefault($allowedTypes->all())
171+
->getNode(),
172+
]);
173+
174+
return;
175+
}
176+
177+
$value = $this->valueResolver->getValue($defaultNode);
178+
$allowedTypes->diffAssoc($value)->each(
179+
function (string $allowedType, string $option) use ($defaultNode): void {
180+
$arrayItemNode = collect($defaultNode->items)->first(
181+
fn (ArrayItem $arrayItemNode) => (string) $this->valueResolver->getValue($arrayItemNode->key) === $option,
182+
);
183+
184+
if ($arrayItemNode) {
185+
$arrayItemNode->value->value = $allowedType;
186+
187+
return;
188+
}
189+
190+
$defaultNode->items[] = new ArrayItem(new String_($allowedType), new String_($option));
191+
}
192+
);
193+
194+
// $newValue = [...$value, ...$allowedTypes->all()];
195+
//
196+
// if ($value !== $newValue) {
197+
// $allowedTypesPropertyNode->props[0]->default = $this->nodeFactory->createArray($newValue);
198+
// }
199+
200+
// collect($defaultNode->items)
201+
// ->each(function (ArrayItem $arrayItemNode): void {
202+
// $key = (string) $this->valueResolver->getValue($arrayItemNode->key);
203+
//
204+
// if (!isset($allowedTypes[$key])) {
205+
// return;
206+
// }
207+
//
208+
// $arrayItemNode->value->value = $allowedTypes[$key];
209+
// });
145210
}
146211

147212
/**
213+
* @throws \ReflectionException
214+
*
148215
* @noinspection PhpPossiblePolymorphicInvocationInspection
149216
*/
150217
private function updateMethodsOfListTypeOption(Class_ $classNode): void
@@ -175,6 +242,7 @@ private function updateMethodsOfListTypeOption(Class_ $classNode): void
175242
if (!$optionsPropertyNode instanceof Property) {
176243
$classNode->stmts[] = (new PropertyBuilder('options'))
177244
->makeProtected()
245+
->setDocComment('/** @var array<string, mixed> */')
178246
->setType('array')
179247
->setDefault($allowedTypes->map(static fn (): array => [])->all())
180248
->getNode();
@@ -218,16 +286,26 @@ class Message
218286
/**
219287
* @api
220288
*/
221-
final public function add%s(%s $%s): self
289+
%spublic function add%s(%s $%s): self
222290
{
223291
$this->options['%s'][] = $%s;
224292
225293
return $this;
226294
}
227295
}
228296
PHP,
297+
(new \ReflectionClass($this->getName($classNode)))->isAbstract() ? 'final ' : ' ',
229298
str($option)->singular()->studly(),
230299
str($allowedType)->beforeLast('[]'),
300+
// match ($type = str($allowedType)->beforeLast('[]')) {
301+
// 'array' => <<<'DOCBLOCK'
302+
// /**
303+
// * @param array<array-key, mixed> $array
304+
// */
305+
// DOCBLOCK
306+
// ,
307+
// default => $type,
308+
// },
231309
$camelSingularOption = str($option)->singular()->camel(),
232310
$option,
233311
$camelSingularOption,

0 commit comments

Comments
 (0)