Skip to content

Commit 6cfbafb

Browse files
committed
package diagram hierarchy. wip
1 parent 06ded8a commit 6cfbafb

File tree

5 files changed

+159
-18
lines changed

5 files changed

+159
-18
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php declare(strict_types=1);
2+
namespace Smeghead\PhpClassDiagram\DiagramElement\ExternalPackage;
3+
4+
class PackageHierarchy {
5+
/**
6+
* @var string[] external packages.
7+
*/
8+
private array $externalPackages;
9+
10+
private PackageNode $root;
11+
12+
/**
13+
* @param string[] $externalPackages external package list
14+
*/
15+
public function __construct(array $externalPackages) {
16+
$this->externalPackages = $externalPackages;
17+
$this->root = new PackageNode('root');
18+
foreach ($externalPackages as $p) {
19+
$this->root->register(explode('.', $p));
20+
}
21+
}
22+
23+
public function dump(): string {
24+
$elements = [];
25+
foreach ($this->root->getChildren() as $c) {
26+
$elements[] = $c->dump(1);
27+
}
28+
return implode("\n", $elements);
29+
}
30+
}
31+
32+
class PackageNode {
33+
private string $name;
34+
/** @var PackageNode[] children */
35+
private array $children = [];
36+
37+
public function __construct(string $name) {
38+
$this->name = $name;
39+
}
40+
41+
/**
42+
* @return PackageNode[]
43+
*/
44+
public function getChildren(): array {
45+
return $this->children;
46+
}
47+
48+
/**
49+
* @param string[] $packages
50+
*/
51+
public function register(array $packages): void {
52+
if (count($packages) === 0) {
53+
return;
54+
}
55+
$next = array_shift($packages);
56+
foreach ($this->children as $c) {
57+
if ($c->name === $next) {
58+
$c->register($packages);
59+
return;
60+
}
61+
}
62+
$new = new PackageNode($next);
63+
$new->register($packages);
64+
$this->children[] = $new;
65+
}
66+
67+
public function dump(int $indent): string {
68+
$lines = [];
69+
$lines[] = sprintf('%spackage %s as %s {', str_repeat(' ', $indent), $this->name, $this->name);
70+
foreach ($this->children as $c) {
71+
$lines[] = $c->dump($indent + 1);
72+
}
73+
$lines[] = sprintf('%s}', str_repeat(' ', $indent));
74+
return implode("\n", $lines);
75+
}
76+
}

src/DiagramElement/Package.php

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,26 @@ public function dump($level = 0): array {
8585
public function dumpPackages($level = 1): array {
8686
$indent = str_repeat(' ', $level);
8787
$lines = [];
88-
$lines[] = sprintf(
89-
'%spackage %s as %s {',
90-
$indent,
91-
$this->name === 'ROOT' ? (empty($this->package) ? 'ROOT': $this->package) : $this->name,
92-
$this->getLogicalName()
93-
);
88+
// if ($level == 1) {
89+
// $lines[] = sprintf(
90+
// '%spackage %s as %s {',
91+
// $indent,
92+
// $this->name === 'ROOT' ? (empty($this->package) ? 'ROOT': $this->package) : $this->name,
93+
// $this->getLogicalName()
94+
// );
95+
// } else {
96+
$lines[] = sprintf(
97+
'%spackage %s {',
98+
$indent,
99+
$this->package
100+
);
101+
// }
102+
// $lines[] = sprintf(
103+
// '%spackage %s as %s {',
104+
// $indent,
105+
// $this->name === 'ROOT' ? (empty($this->package) ? 'ROOT': $this->package) : $this->name,
106+
// $this->getLogicalName()
107+
// );
94108
foreach ($this->children as $n) {
95109
$lines = array_merge($lines, $n->dumpPackages($level + 1));
96110
}

src/DiagramElement/PackageRelations.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,41 @@
11
<?php declare(strict_types=1);
22
namespace Smeghead\PhpClassDiagram\DiagramElement;
33

4+
use Smeghead\PhpClassDiagram\DiagramElement\ExternalPackage\PackageHierarchy;
5+
use Smeghead\PhpClassDiagram\Php\PhpType;
6+
47
class PackageRelations {
5-
/** @var \Smeghead\PhpClassDiagram\Php\PhpType[] */
8+
/** @var array<string, \Smeghead\PhpClassDiagram\Php\PhpType[]> */
69
private array $uses;
710
/** @var \Smeghead\PhpClassDiagram\Php\PhpType[] */
811
private array $targetPackages;
912

13+
/**
14+
* @param array<string, \Smeghead\PhpClassDiagram\Php\PhpType[]> $uses
15+
*/
1016
public function __construct(array $uses, array $targetPackages) {
1117
$this->uses = $uses;
1218
$this->targetPackages = $targetPackages;
1319
}
1420

1521
private function displayPackage($package) {
16-
if (in_array($package, array_keys($this->targetPackages))) {
17-
return $this->targetPackages[$package]; // 解析対象のpackageはディレクトリ名で表示
18-
} else {
19-
return $package; //外部のpackageはpackage表示
22+
if (empty($package)) {
23+
return $this->targetPackages[$package];
2024
}
25+
return $package;
26+
// if (in_array($package, array_keys($this->targetPackages))) {
27+
// return $this->targetPackages[$package]; // 解析対象のpackageはディレクトリ名で表示
28+
// } else {
29+
// return $package; //外部のpackageはpackage表示
30+
// }
2131
}
2232

2333
public function getArrows(): array {
2434
$lines = [];
2535
$all = [];
2636
$packageRelations = [];
2737
foreach ($this->uses as $namespace => $us) {
28-
$packages = array_unique(array_map(function($x){
38+
$packages = array_unique(array_map(function(PhpType $x){
2939
return implode('.', $x->getNamespace());
3040
}, $us));
3141
// 対象となっているpackage以外のpackageは、即席で定義する必要がある。
@@ -34,8 +44,10 @@ public function getArrows(): array {
3444
return $this->displayPackage($x, $this->targetPackages);
3545
}, $packages);
3646
}
37-
foreach (array_diff($all, array_keys($this->targetPackages)) as $external) {
38-
$lines[] = sprintf(' package %s', $external);
47+
$externals = array_diff($all, array_keys($this->targetPackages));
48+
if (count($externals) > 0) {
49+
$externalPackage = new PackageHierarchy($externals);
50+
$lines[] = $externalPackage->dump();
3951
}
4052
$arrows = [];
4153
foreach ($packageRelations as $package => $dependencies) {

test/PackageHierarchyTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php declare(strict_types=1);
2+
3+
use PhpParser\ParserFactory;
4+
use PHPUnit\Framework\TestCase;
5+
use Smeghead\PhpClassDiagram\DiagramElement\ExternalPackage\PackageHierarchy;
6+
7+
final class PackageHierarchyTest extends TestCase {
8+
public function setUp(): void {
9+
}
10+
11+
public function testEmptyExternalPackages(): void {
12+
$externals = [];
13+
14+
$sut = new PackageHierarchy($externals);
15+
16+
$this->assertSame('', $sut->dump(), 'empty string');
17+
18+
}
19+
20+
public function testOnlyExternalPackage(): void {
21+
$externals = [
22+
'External.One',
23+
];
24+
25+
$sut = new PackageHierarchy($externals);
26+
27+
$expected = <<<EOC
28+
package External as External {
29+
package One as One {
30+
}
31+
}
32+
EOC;
33+
$this->assertSame($expected, $sut->dump(), 'empty string');
34+
35+
}
36+
37+
38+
}

test/PackageTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,10 +471,11 @@ public function testDumpPackage1(): void {
471471
$expected =<<<EOS
472472
@startuml package-related-diagram
473473
package ROOT as ROOT {
474-
package product as product {
474+
package product {
475475
}
476476
}
477-
package PhpParse
477+
package PhpParse as PhpParse {
478+
}
478479
product --> PhpParse
479480
@enduml
480481
EOS;
@@ -493,8 +494,8 @@ public function testDumpPackage_bothSideArrows(): void {
493494
$expected =<<<EOS
494495
@startuml package-related-diagram
495496
package hoge.fuga as ROOT {
496-
package product as product {
497-
package utility as product.utility {
497+
package product {
498+
package utility {
498499
}
499500
}
500501
}

0 commit comments

Comments
 (0)