Skip to content

Commit

Permalink
Merge pull request #7 from tasuku43/refactor-parser
Browse files Browse the repository at this point in the history
refactor parser
  • Loading branch information
tasuku43 committed Apr 20, 2024
2 parents b1e348e + ce909ba commit 7a6c658
Show file tree
Hide file tree
Showing 15 changed files with 254 additions and 158 deletions.
2 changes: 1 addition & 1 deletion src/ClassDiagramRenderer/ClassDiagram.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Tasuku43\MermaidClassDiagram\ClassDiagramRenderer;

use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Node;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Relationship\Relationship;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Relationship;

class ClassDiagram
{
Expand Down
2 changes: 1 addition & 1 deletion src/ClassDiagramRenderer/ClassDiagramBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function build(string $path): ClassDiagram
{
$classDigagram = new ClassDiagram();

foreach ($this->nodeParser->parse($path) as $node) {
foreach ($this->nodeParser->parse($path)->getAllNodes() as $node) {
$classDigagram->addNode($node)->addRelationships(...$node->relationships());
}

Expand Down
63 changes: 63 additions & 0 deletions src/ClassDiagramRenderer/Node/Connector/CompositionConnector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);

namespace Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Connector;

use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PhpParser\NodeFinder;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Class_;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Node as ClassDiagramNode;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Nodes;

class CompositionConnector extends Connector
{
public function connect(Nodes $nodes): void
{
$node = $nodes->findByName($this->nodeName);

foreach ($this->toConnectNodeNames as $toConnectNodeName) {
$node->composition($nodes->findByName($toConnectNodeName) ?? new Class_($toConnectNodeName));
}
}

public static function parse(
NodeFinder $nodeFinder,
Node\Stmt\Interface_|Node\Stmt\Class_ $classLike,
ClassDiagramNode $classDiagramNode,
): self
{
$propertieNodeNames = [];

// from constructor
$construct = $nodeFinder->findFirst($classLike, function (Node $node) {
return $node instanceof ClassMethod && (string)$node->name === '__construct';
});
if ($construct !== null) {
assert($construct instanceof ClassMethod);
foreach (array_filter($construct->getParams(), fn(Node\Param $param) => $param->type instanceof Name) as $param) {
assert($param instanceof Node\Param);

// If `visibirity` is not specified, flags is 0
if ($param->flags !== 0) {
$propertieNodeNames = array_merge(
$propertieNodeNames,
[$param->type->getLast()]
);
}
}
}

// from properties
$propertieNodeNames = array_merge(array_map(function (Property $property) {
return $property->type->getLast();
}, array_filter($classLike->getProperties(),
fn(Property $property) => $property->type instanceof FullyQualified)
), $propertieNodeNames);

return new CompositionConnector($classDiagramNode->nodeName(), $propertieNodeNames);
}
}
19 changes: 19 additions & 0 deletions src/ClassDiagramRenderer/Node/Connector/Connector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);

namespace Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Connector;

use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Nodes;

abstract class Connector
{
/**
* @param string $nodeName
* @param string[] $toConnectNodeNames
*/
public function __construct(protected string $nodeName, protected array $toConnectNodeNames)
{
}

abstract public function connect(Nodes $nodes): void;
}
50 changes: 50 additions & 0 deletions src/ClassDiagramRenderer/Node/Connector/InheritanceConnector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);

namespace Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Connector;

use PhpParser\Node;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Class_;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Interface_;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Node as ClassDiagramNode;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Nodes;

class InheritanceConnector extends Connector
{
public function connect(Nodes $nodes): void
{
$node = $nodes->findByName($this->nodeName);

foreach ($this->toConnectNodeNames as $toConnectNodeName) {
$node->extends(
$nodes->findByName($toConnectNodeName) ?? $this->createDefaultExtendsNode($node, $toConnectNodeName)
);
}
}

private function createDefaultExtendsNode(ClassDiagramNode $extended, string $extendsNodeName): ClassDiagramNode
{
return match (true) {
$extended instanceof Interface_ => new Interface_($extendsNodeName),
default => new Class_($extendsNodeName),
};
}

public static function parse(
Node\Stmt\Interface_|Node\Stmt\Class_ $classLike,
ClassDiagramNode $classDiagramNode,
): self
{
$extendsNodeNames = [];

if ($classLike->extends !== null) {
$extendsNodeNames = is_array($classLike->extends)
? array_map(function (Node\Name $name) {
return (string)$name->getLast();
}, $classLike->extends)
: [(string)$classLike->extends->getLast()];
}

return new InheritanceConnector($classDiagramNode->nodeName(), $extendsNodeNames);
}
}
39 changes: 39 additions & 0 deletions src/ClassDiagramRenderer/Node/Connector/RealizationConnector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);

namespace Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Connector;

use PhpParser\Node;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Interface_;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Node as ClassDiagramNode;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Nodes;

class RealizationConnector extends Connector
{
public function connect(Nodes $nodes): void
{
$node = $nodes->findByName($this->nodeName);

foreach ($this->toConnectNodeNames as $toConnectNodeName) {
$node->implements(
$nodes->findByName($toConnectNodeName) ?? new Interface_($toConnectNodeName)
);
}
}

public static function parse(
Node\Stmt\Interface_|Node\Stmt\Class_ $classLike,
ClassDiagramNode $classDiagramNode,
): self
{
$implementsNodeNames = [];

if (property_exists($classLike, 'implements') && $classLike->implements !== []) {
$implementsNodeNames = array_map(function (Node\Name $name) {
return (string)$name->getLast();
}, $classLike->implements);
}

return new RealizationConnector($classDiagramNode->nodeName(), $implementsNodeNames);
}
}
8 changes: 4 additions & 4 deletions src/ClassDiagramRenderer/Node/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

namespace Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node;

use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Relationship\Composition;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Relationship\Inheritance;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Relationship\Realization;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Relationship\Relationship;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Composition;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Inheritance;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Realization;
use Tasuku43\MermaidClassDiagram\ClassDiagramRenderer\Node\Relationship\Relationship;

abstract class Node
{
Expand Down

0 comments on commit 7a6c658

Please sign in to comment.