|
3 | 3 | namespace Lkrms\LkUtil\Command\Generate\Concept; |
4 | 4 |
|
5 | 5 | use Lkrms\Cli\Catalog\CliOptionType; |
| 6 | +use Lkrms\Cli\Exception\CliInvalidArgumentsException; |
6 | 7 | use Lkrms\Cli\CliOption; |
7 | 8 | use Lkrms\Cli\CliOptionBuilder; |
8 | | -use Lkrms\Cli\Exception\CliInvalidArgumentsException; |
9 | 9 | use Lkrms\Facade\Composer; |
10 | 10 | use Lkrms\Facade\Console; |
11 | 11 | use Lkrms\Facade\File; |
12 | 12 | use Lkrms\Facade\Reflect; |
13 | 13 | use Lkrms\LkUtil\Command\Concept\Command; |
14 | 14 | use Lkrms\Support\Catalog\RegularExpression as Regex; |
15 | | -use Lkrms\Support\IntrospectionClass; |
16 | | -use Lkrms\Support\Introspector; |
17 | 15 | use Lkrms\Support\PhpDoc\PhpDoc; |
18 | 16 | use Lkrms\Support\PhpDoc\PhpDocTag; |
19 | 17 | use Lkrms\Support\PhpDoc\PhpDocTemplateTag; |
| 18 | +use Lkrms\Support\IntrospectionClass; |
| 19 | +use Lkrms\Support\Introspector; |
20 | 20 | use Lkrms\Support\TokenExtractor; |
21 | 21 | use Lkrms\Utility\Convert; |
22 | 22 | use Lkrms\Utility\Test; |
@@ -445,16 +445,26 @@ protected function generate( |
445 | 445 | */ |
446 | 446 | protected function generateImports(): array |
447 | 447 | { |
448 | | - $imports = []; |
| 448 | + $map = []; |
449 | 449 | foreach ($this->ImportMap as $alias) { |
450 | 450 | $import = $this->AliasMap[strtolower($alias)]; |
451 | 451 | if (!strcasecmp($alias, Convert::classToBasename($import))) { |
452 | | - $imports[] = sprintf('use %s;', $import); |
| 452 | + $map[$import] = null; |
453 | 453 | continue; |
454 | 454 | } |
455 | | - $imports[] = sprintf('use %s as %s;', $import, $alias); |
| 455 | + $map[$import] = $alias; |
| 456 | + } |
| 457 | + |
| 458 | + // Sort by FQCN, depth-first |
| 459 | + uksort($map, fn($a, $b) => $this->getSortableFqcn($a) <=> $this->getSortableFqcn($b)); |
| 460 | + |
| 461 | + $imports = []; |
| 462 | + foreach ($map as $import => $alias) { |
| 463 | + $imports[] = |
| 464 | + $alias === null |
| 465 | + ? sprintf('use %s;', $import) |
| 466 | + : sprintf('use %s as %s;', $import, $alias); |
456 | 467 | } |
457 | | - sort($imports); |
458 | 468 |
|
459 | 469 | return $imports; |
460 | 470 | } |
@@ -596,4 +606,39 @@ private function generatePhpDocBlock($phpDoc): array |
596 | 606 | ' */' |
597 | 607 | ]; |
598 | 608 | } |
| 609 | + |
| 610 | + /** |
| 611 | + * Normalise a FQCN for depth-first sorting |
| 612 | + * |
| 613 | + * Before: |
| 614 | + * |
| 615 | + * ``` |
| 616 | + * A |
| 617 | + * A\B\C |
| 618 | + * A\B |
| 619 | + * ``` |
| 620 | + * |
| 621 | + * After: |
| 622 | + * |
| 623 | + * ``` |
| 624 | + * 1A |
| 625 | + * 0A \ 0B \ 1C |
| 626 | + * 0A \ 1B |
| 627 | + * ``` |
| 628 | + */ |
| 629 | + private function getSortableFqcn(string $import): string |
| 630 | + { |
| 631 | + $names = explode('\\', $import); |
| 632 | + $import = ''; |
| 633 | + $prefix = 0; |
| 634 | + do { |
| 635 | + $name = array_shift($names); |
| 636 | + if (!$names) { |
| 637 | + $prefix = 1; |
| 638 | + } |
| 639 | + $import .= ($import === '' ? '' : ' \ ') . "$prefix$name"; |
| 640 | + } while (!$prefix); |
| 641 | + |
| 642 | + return $import; |
| 643 | + } |
599 | 644 | } |
0 commit comments