From aa791f233b0a998879a110069edcb39d5e0fd6be Mon Sep 17 00:00:00 2001 From: MarkW Date: Mon, 14 Apr 2025 12:25:25 +0200 Subject: [PATCH 1/4] De-duplicate repeating sections in generated class names --- src/Frame.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Frame.php b/src/Frame.php index 6576c768cb..b06ef24bb6 100644 --- a/src/Frame.php +++ b/src/Frame.php @@ -60,11 +60,24 @@ public function getClassName(): ?string if (!$name) { return null; } - + + $segments = array_filter(explode('.', str_replace('_', '.', $prefix . '.' . $name))); + + $deduped = []; + foreach ($segments as $segment) { + foreach ($deduped as $existing) { + if (str_starts_with($segment, $existing)) { + $segment = substr($segment, strlen($existing)); + $segment = ltrim($segment, '._'); + } + } + $deduped[] = $segment; + } + return str_replace( ['$', ' ', '-', '.'], ['', '_', '_', '_'], - $prefix === '' ? $name : $prefix . '_' . $name, + implode('.', array_filter($deduped)) ); } From e5995838059e43d491fda99cba2d4fcba7dd2b0f Mon Sep 17 00:00:00 2001 From: Mark W Date: Wed, 16 Apr 2025 12:07:24 +0200 Subject: [PATCH 2/4] Some adjustments to test --- src/Frame.php | 33 +++++++++++---------------------- src/Registry.php | 8 ++++---- src/XmlFileParser.php | 2 +- 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/Frame.php b/src/Frame.php index b06ef24bb6..1b54ddfc5c 100644 --- a/src/Frame.php +++ b/src/Frame.php @@ -36,15 +36,17 @@ public function getRootNode(): self return $node; } - public function getName(): string + public function getName(bool $emptyParent = false): string { if ($this->parent && str_contains($this->name, '$parent')) { $parent = $this; $parentName = ''; - while ($parent = $parent->getParent()) { - $parentName = $parent->getName(); - if ($parentName) { - break; + if (!$emptyParent) { + while ($parent = $parent->getParent()) { + $parentName = $parent->getName(); + if ($parentName) { + break; + } } } return str_replace('$parent', $parentName, $this->name); @@ -56,28 +58,15 @@ public function getName(): string public function getClassName(): ?string { $prefix = $this->parent?->getClassName() ?? ''; - $name = $this->getName() ?: $this->getParentKey(); - if (!$name) { + $name = $this->getName(true) ?: $this->getParentKey(); + if (!$name || ($this->parent && !$prefix)) { return null; } - - $segments = array_filter(explode('.', str_replace('_', '.', $prefix . '.' . $name))); - - $deduped = []; - foreach ($segments as $segment) { - foreach ($deduped as $existing) { - if (str_starts_with($segment, $existing)) { - $segment = substr($segment, strlen($existing)); - $segment = ltrim($segment, '._'); - } - } - $deduped[] = $segment; - } - + return str_replace( ['$', ' ', '-', '.'], ['', '_', '_', '_'], - implode('.', array_filter($deduped)) + $prefix === '' ? $name : $prefix . '_' . $name, ); } diff --git a/src/Registry.php b/src/Registry.php index c9080391f5..e014e55f39 100644 --- a/src/Registry.php +++ b/src/Registry.php @@ -11,12 +11,12 @@ class Registry { /** - * @var T[] + * @var array */ private array $items = []; /** - * @param T $template + * @param T&Frame $template */ public function register(?string $name, Frame $template): void { @@ -27,7 +27,7 @@ public function register(?string $name, Frame $template): void } /** - * @return T|null + * @return (T&Frame)|null */ public function get(string $name): ?Frame { @@ -35,7 +35,7 @@ public function get(string $name): ?Frame } /** - * @return T[] + * @return array */ public function all(): array { diff --git a/src/XmlFileParser.php b/src/XmlFileParser.php index 1890affc49..86863f1539 100644 --- a/src/XmlFileParser.php +++ b/src/XmlFileParser.php @@ -103,7 +103,7 @@ private function parseNode(SimpleXMLElement $node, Registry $fileRegistry, ?Fram $this->frameRegistry->register($frame->getClassName(), $frame); } if (!empty($name)) { - $fileRegistry->register($name, $frame); + $fileRegistry->register($frame->getClassName(), $frame); } $parent?->addChild($frame); From b179961422a35ad963b9cf60e287c2d4c08840e0 Mon Sep 17 00:00:00 2001 From: Mark W Date: Wed, 16 Apr 2025 12:32:08 +0200 Subject: [PATCH 3/4] Default to the global name for generated class names if any --- src/Frame.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Frame.php b/src/Frame.php index 1b54ddfc5c..fc81751ad3 100644 --- a/src/Frame.php +++ b/src/Frame.php @@ -57,17 +57,16 @@ public function getName(bool $emptyParent = false): string public function getClassName(): ?string { + if ($this->getName()) { + return $this->sanitizeClassName($this->getName()); + } $prefix = $this->parent?->getClassName() ?? ''; $name = $this->getName(true) ?: $this->getParentKey(); if (!$name || ($this->parent && !$prefix)) { return null; } - return str_replace( - ['$', ' ', '-', '.'], - ['', '_', '_', '_'], - $prefix === '' ? $name : $prefix . '_' . $name, - ); + return $this->sanitizeClassName($prefix === '' ? $name : ($prefix . '_' . $name)); } public function getParent(): ?self @@ -142,7 +141,9 @@ public function getInherits(): array $inherits = (string) $this->xmlElement->attributes()['inherits'] ?? ''; $inherits = str_replace(' ', '', $inherits); - return $inherits === '' ? [] : explode(',', $inherits); + return $inherits === '' + ? [] + : array_map($this->sanitizeClassName(...), explode(',', $inherits)); } /** @@ -191,4 +192,13 @@ public function getLineNumber(): int return $node->getLineNo(); } + + private function sanitizeClassName(string $name): string + { + return str_replace( + ['$', ' ', '-', '.', '!'], + ['', '_', '_', '_', '_'], + $name, + ); + } } From 8827ba4e52be62e4b7644553e183e16f31364fc5 Mon Sep 17 00:00:00 2001 From: Mark W Date: Wed, 16 Apr 2025 12:34:56 +0200 Subject: [PATCH 4/4] Don't use global names for template children --- src/Frame.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Frame.php b/src/Frame.php index fc81751ad3..cbbe10e93e 100644 --- a/src/Frame.php +++ b/src/Frame.php @@ -57,7 +57,7 @@ public function getName(bool $emptyParent = false): string public function getClassName(): ?string { - if ($this->getName()) { + if ($this->getName() && $this->getRootNode()::class === Frame::class) { return $this->sanitizeClassName($this->getName()); } $prefix = $this->parent?->getClassName() ?? '';