ClassVisitor.php 3.53 KB
Newer Older
1
<?php declare(strict_types=1);
2
/*
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
3
4
 * Copyright (C) 2016-2017 IRSTEA
 * All rights reserved.
5
6
7
8
 */

namespace Irstea\PlantUmlBundle\Model;

9
use Irstea\PlantUmlBundle\Model\Decorator\NullDecorator;
10
use Irstea\PlantUmlBundle\Model\Filter\AcceptAllFilter;
11
use Irstea\PlantUmlBundle\Model\Namespace_\Php\RootNamespace;
12
13
14
use Irstea\PlantUmlBundle\Model\Node\Class_;
use Irstea\PlantUmlBundle\Model\Node\Interface_;
use Irstea\PlantUmlBundle\Model\Node\Trait_;
15
use Irstea\PlantUmlBundle\Writer\WriterInterface;
16
17
18
use ReflectionClass;

/**
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
19
 * Description of Visitor.
20
 */
21
class ClassVisitor implements ClassVisitorInterface
22
23
{
    /**
24
     * @var NamespaceInterface
25
     */
26
    protected $rootNamespace;
27

28
29
30
31
32
    /**
     * @var ClassFilterInterface
     */
    protected $filter;

33
34
35
36
37
    /**
     * @var DecoratorInterface
     */
    protected $decorator;

38
39
40
41
42
    public function __construct(
        DecoratorInterface $decorator = null,
        ClassFilterInterface $filter = null,
        NamespaceInterface $namespace = null
    ) {
43
        $this->filter = $filter ?: AcceptAllFilter::instance();
44
        $this->decorator = $decorator ?: NullDecorator::instance();
45
        $this->rootNamespace = $namespace ?: new RootNamespace();
46
47
48
    }

    /**
49
     * @param ClassFilterInterface $filter
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
50
     *
51
52
53
54
55
     * @return self
     */
    public function setClassFilter(ClassFilterInterface $filter)
    {
        $this->filter = $filter;
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
56

57
        return $this;
58
    }
Guillaume Perréal's avatar
Guillaume Perréal committed
59

60
61
    /**
     * @param DecoratorInterface $decorator
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
62
     *
63
64
65
66
67
     * @return self
     */
    public function setDecorator(DecoratorInterface $decorator)
    {
        $this->decorator = $decorator;
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
68

69
70
71
        return $this;
    }

72
    public function visitClass($classOrName)
73
    {
74
75
76
77
78
        if ($classOrName instanceof \ReflectionClass) {
            $class = $classOrName;
        } elseif (is_string($classOrName)) {
            $class = new \ReflectionClass($classOrName);
        } else {
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
79
            throw new \InvalidArgumentException('Invalid argument, expected ReflectionClass or string');
80
81
82
        }
        $className = $class->getName();

83
84
85
        if (isset($this->nodes[$className])) {
            return $this->nodes[$className];
        }
86
87

        if (!$this->filter->accept($class)) {
88
89
            return $this->nodes[$className] = false;
        }
90

91
92
93
94
95
96
97
        $namespace = $this->rootNamespace->getNamespace($class->getNamespaceName());
        $node = $this->nodes[$className] = $this->createNode($namespace, $class);
        $namespace->addNode($node);

        $this->decorator->decorate($class, $node, $this);

        return $node;
98
99
100
    }

    /**
101
     * @param NamespaceInterface $namespace
Guillaume Perréal's avatar
CS.    
Guillaume Perréal committed
102
103
     * @param ReflectionClass    $class
     *
104
     * @return NodeInterface
105
     */
106
    protected function createNode(NamespaceInterface $namespace, ReflectionClass $class)
107
    {
108
109
        $className = $class->getName();

110
        if ($class->isTrait()) {
111
            return new Trait_($namespace, $className);
112
        }
113

114
        if ($class->isInterface()) {
115
            return new Interface_($namespace, $className);
116
        }
117

118
        return new Class_($namespace, $className, $class->isAbstract(), $class->isFinal());
119
120
    }

121
    public function writeTo(WriterInterface $writer)
Guillaume Perréal's avatar
Guillaume Perréal committed
122
    {
123
        return $this->rootNamespace->writeTo($writer);
Guillaume Perréal's avatar
Guillaume Perréal committed
124
    }
125
126
127
128
129
130
131
132
133
134
135
136
137

    /**
     * @param array $conf
     */
    public function toConfig(array &$conf)
    {
        $conf['layout'] = [];
        $conf['decoration'] = [];

        $this->filter->toConfig($conf['layout']);
        $this->rootNamespace->toConfig($conf['layout']);
        $this->decorator->toConfig($conf['decoration']);
    }
138
}