Completed
Push — master ( 46a28a...d0144c )
by Greg
03:47
created

CommandDocBlockParser3::parse()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 11

Duplication

Lines 7
Ratio 33.33 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 7
loc 21
rs 9.0534
cc 4
eloc 11
nc 4
nop 0
1
<?php
2
namespace Consolidation\AnnotatedCommand\Parser\Internal;
3
4
use phpDocumentor\Reflection\DocBlock\Tags\Param;
5
use phpDocumentor\Reflection\DocBlock\Tags\Return_;
6
use Consolidation\AnnotatedCommand\Parser\CommandInfo;
7
use Consolidation\AnnotatedCommand\Parser\DefaultsWithDescriptions;
8
9
/**
10
 * Given a class and method name, parse the annotations in the
11
 * DocBlock comment, and provide accessor methods for all of
12
 * the elements that are needed to create an annotated Command.
13
 */
14
class CommandDocBlockParser3 extends AbstractCommandDocBlockParser
15
{
16
    /**
17
     * Parse the docBlock comment for this command, and set the
18
     * fields of this class with the data thereby obtained.
19
     */
20
    public function parse()
21
    {
22
        // DocBlockFactory::create fails if the comment is empty.
23
        if (empty($this->reflection->getDocComment())) {
24
            return;
25
        }
26
        $phpdoc = $this->createDocBlock();
27
28
        // First set the description (synopsis) and help.
29
        $this->commandInfo->setDescription((string)$phpdoc->getSummary());
30
        $this->commandInfo->setHelp((string)$phpdoc->getDescription());
31
32
        // Iterate over all of the tags, and process them as necessary.
33 View Code Duplication
        foreach ($phpdoc->getTags() as $tag) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
34
            $processFn = [$this, 'processGenericTag'];
35
            if (array_key_exists($tag->getName(), $this->tagProcessors)) {
36
                $processFn = [$this, $this->tagProcessors[$tag->getName()]];
37
            }
38
            $processFn($tag);
39
        }
40
    }
41
42
    public function createDocBlock()
43
    {
44
        $docBlockFactory = \phpDocumentor\Reflection\DocBlockFactory::createInstance();
45
        $contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory();
46
47
        return $docBlockFactory->create(
48
            $this->reflection,
49
            $contextFactory->createFromReflector($this->reflection)
50
        );
51
    }
52
53
    /**
54
     * Save any tag that we do not explicitly recognize in the
55
     * 'otherAnnotations' map.
56
     */
57
    protected function processGenericTag($tag)
58
    {
59
        $this->commandInfo->addOtherAnnotation($tag->getName(), (string)$tag);
60
    }
61
62
    /**
63
     * Set the name of the command from a @command or @name annotation.
64
     */
65
    protected function processCommandTag($tag)
66
    {
67
        $this->commandInfo->setName((string)$tag);
68
        // We also store the name in the 'other annotations' so that is is
69
        // possible to determine if the method had a @command annotation.
70
        $this->processGenericTag($tag);
71
    }
72
73
    /**
74
     * The @description and @desc annotations may be used in
75
     * place of the synopsis (which we call 'description').
76
     * This is discouraged.
77
     *
78
     * @deprecated
79
     */
80
    protected function processAlternateDescriptionTag($tag)
81
    {
82
        $this->commandInfo->setDescription((string)$tag);
83
    }
84
85
    /**
86
     * Store the data from a @arg annotation in our argument descriptions.
87
     */
88
    protected function processArgumentTag($tag)
89
    {
90
        $this->addOptionOrArgumentTag($tag, $this->commandInfo->arguments());
91
    }
92
93
    /**
94
     * Store the data from a @param annotation in our argument descriptions.
95
     */
96 View Code Duplication
    protected function processParamTag($tag)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
    {
98
        if (!$tag instanceof Param) {
99
            return;
100
        }
101
        $variableName = $tag->getVariableName();
102
        $variableName = str_replace('$', '', $variableName);
103
        $description = static::removeLineBreaks((string)$tag->getDescription());
104
        if ($variableName == $this->commandInfo->optionParamName()) {
105
            return;
106
        }
107
        $this->commandInfo->arguments()->add($variableName, $description);
108
    }
109
110
    /**
111
     * Store the data from a @return annotation in our argument descriptions.
112
     */
113
    protected function processReturnTag($tag)
114
    {
115
        if (!$tag instanceof Return_) {
116
            return;
117
        }
118
        // If there is a spurrious trailing space on the return type, remove it.
119
        $this->commandInfo->setReturnType(trim((string)$tag));
120
    }
121
122
    /**
123
     * Store the data from an @option annotation in our option descriptions.
124
     */
125
    protected function processOptionTag($tag)
126
    {
127
        $this->addOptionOrArgumentTag($tag, $this->commandInfo->options());
128
    }
129
130 View Code Duplication
    protected function addOptionOrArgumentTag($tag, DefaultsWithDescriptions $set)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
    {
132
        if (!$this->pregMatchNameAndDescription((string)$tag->getDescription(), $match)) {
133
            return;
134
        }
135
        $variableName = $this->commandInfo->findMatchingOption($match['name']);
136
        $desc = $match['description'];
137
        $description = static::removeLineBreaks($desc);
138
        $set->add($variableName, $description);
139
    }
140
141
    /**
142
     * Store the data from a @default annotation in our argument or option store,
143
     * as appropriate.
144
     */
145 View Code Duplication
    protected function processDefaultTag($tag)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
146
    {
147
        if (!$this->pregMatchNameAndDescription((string)$tag->getDescription(), $match)) {
148
            return;
149
        }
150
        $variableName = $match['name'];
151
        $defaultValue = $this->interpretDefaultValue($match['description']);
152
        if ($this->commandInfo->arguments()->exists($variableName)) {
153
            $this->commandInfo->arguments()->setDefaultValue($variableName, $defaultValue);
154
            return;
155
        }
156
        $variableName = $this->commandInfo->findMatchingOption($variableName);
157
        if ($this->commandInfo->options()->exists($variableName)) {
158
            $this->commandInfo->options()->setDefaultValue($variableName, $defaultValue);
159
        }
160
    }
161
162
    /**
163
     * Process the comma-separated list of aliases
164
     */
165
    protected function processAliases($tag)
166
    {
167
        $this->commandInfo->setAliases((string)$tag->getDescription());
168
    }
169
170
    /**
171
     * Store the data from a @usage annotation in our example usage list.
172
     */
173 View Code Duplication
    protected function processUsageTag($tag)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
174
    {
175
        $lines = explode("\n", (string)$tag);
176
        $usage = array_shift($lines);
177
        $description = static::removeLineBreaks(implode("\n", $lines));
178
179
        $this->commandInfo->setExampleUsage($usage, $description);
180
    }
181
}
182