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

CommandDocBlockParser2   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 153
Duplicated Lines 35.29 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 21
c 1
b 0
f 0
lcom 1
cbo 5
dl 54
loc 153
rs 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A parse() 7 18 3
A processGenericTag() 0 4 1
A processCommandTag() 0 7 1
A processAlternateDescriptionTag() 0 4 1
A processArgumentTag() 0 4 1
A processParamTag() 13 13 3
A processReturnTag() 0 7 2
A processOptionTag() 0 4 1
A addOptionOrArgumentTag() 10 10 2
A processDefaultTag() 16 16 4
A processAliases() 0 4 1
A processUsageTag() 8 8 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace Consolidation\AnnotatedCommand\Parser\Internal;
3
4
use phpDocumentor\Reflection\DocBlock;
5
use phpDocumentor\Reflection\DocBlock\Tag\ParamTag;
6
use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
7
use Consolidation\AnnotatedCommand\Parser\CommandInfo;
8
use Consolidation\AnnotatedCommand\Parser\DefaultsWithDescriptions;
9
10
/**
11
 * Given a class and method name, parse the annotations in the
12
 * DocBlock comment, and provide accessor methods for all of
13
 * the elements that are needed to create an annotated Command.
14
 */
15
class CommandDocBlockParser2 extends AbstractCommandDocBlockParser
16
{
17
    /**
18
     * Parse the docBlock comment for this command, and set the
19
     * fields of this class with the data thereby obtained.
20
     */
21
    public function parse()
22
    {
23
        $docblockComment = $this->reflection->getDocComment();
24
        $phpdoc = new DocBlock($docblockComment);
25
26
        // First set the description (synopsis) and help.
27
        $this->commandInfo->setDescription((string)$phpdoc->getShortDescription());
0 ignored issues
show
Bug introduced by
The method getShortDescription() does not seem to exist on object<phpDocumentor\Reflection\DocBlock>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
28
        $this->commandInfo->setHelp((string)$phpdoc->getLongDescription());
0 ignored issues
show
Bug introduced by
The method getLongDescription() does not seem to exist on object<phpDocumentor\Reflection\DocBlock>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
29
30
        // Iterate over all of the tags, and process them as necessary.
31 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...
32
            $processFn = [$this, 'processGenericTag'];
33
            if (array_key_exists($tag->getName(), $this->tagProcessors)) {
34
                $processFn = [$this, $this->tagProcessors[$tag->getName()]];
35
            }
36
            $processFn($tag);
37
        }
38
    }
39
40
    /**
41
     * Save any tag that we do not explicitly recognize in the
42
     * 'otherAnnotations' map.
43
     */
44
    protected function processGenericTag($tag)
45
    {
46
        $this->commandInfo->addOtherAnnotation($tag->getName(), $tag->getContent());
47
    }
48
49
    /**
50
     * Set the name of the command from a @command or @name annotation.
51
     */
52
    protected function processCommandTag($tag)
53
    {
54
        $this->commandInfo->setName($tag->getContent());
55
        // We also store the name in the 'other annotations' so that is is
56
        // possible to determine if the method had a @command annotation.
57
        $this->processGenericTag($tag);
58
    }
59
60
    /**
61
     * The @description and @desc annotations may be used in
62
     * place of the synopsis (which we call 'description').
63
     * This is discouraged.
64
     *
65
     * @deprecated
66
     */
67
    protected function processAlternateDescriptionTag($tag)
68
    {
69
        $this->commandInfo->setDescription($tag->getContent());
70
    }
71
72
    /**
73
     * Store the data from a @arg annotation in our argument descriptions.
74
     */
75
    protected function processArgumentTag($tag)
76
    {
77
        $this->addOptionOrArgumentTag($tag, $this->commandInfo->arguments());
78
    }
79
80
    /**
81
     * Store the data from a @param annotation in our argument descriptions.
82
     */
83 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...
84
    {
85
        if (!$tag instanceof ParamTag) {
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\DocBlock\Tag\ParamTag does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
86
            return;
87
        }
88
        $variableName = $tag->getVariableName();
89
        $variableName = str_replace('$', '', $variableName);
90
        $description = static::removeLineBreaks($tag->getDescription());
91
        if ($variableName == $this->commandInfo->optionParamName()) {
92
            return;
93
        }
94
        $this->commandInfo->arguments()->add($variableName, $description);
95
    }
96
97
    /**
98
     * Store the data from a @return annotation in our argument descriptions.
99
     */
100
    protected function processReturnTag($tag)
101
    {
102
        if (!$tag instanceof ReturnTag) {
0 ignored issues
show
Bug introduced by
The class phpDocumentor\Reflection\DocBlock\Tag\ReturnTag does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
103
            return;
104
        }
105
        $this->commandInfo->setReturnType($tag->getType());
106
    }
107
108
    /**
109
     * Store the data from an @option annotation in our option descriptions.
110
     */
111
    protected function processOptionTag($tag)
112
    {
113
        $this->addOptionOrArgumentTag($tag, $this->commandInfo->options());
114
    }
115
116 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...
117
    {
118
        if (!$this->pregMatchNameAndDescription($tag->getDescription(), $match)) {
119
            return;
120
        }
121
        $variableName = $this->commandInfo->findMatchingOption($match['name']);
122
        $desc = $match['description'];
123
        $description = static::removeLineBreaks($desc);
124
        $set->add($variableName, $description);
125
    }
126
127
    /**
128
     * Store the data from a @default annotation in our argument or option store,
129
     * as appropriate.
130
     */
131 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...
132
    {
133
        if (!$this->pregMatchNameAndDescription($tag->getDescription(), $match)) {
134
            return;
135
        }
136
        $variableName = $match['name'];
137
        $defaultValue = $this->interpretDefaultValue($match['description']);
138
        if ($this->commandInfo->arguments()->exists($variableName)) {
139
            $this->commandInfo->arguments()->setDefaultValue($variableName, $defaultValue);
140
            return;
141
        }
142
        $variableName = $this->commandInfo->findMatchingOption($variableName);
143
        if ($this->commandInfo->options()->exists($variableName)) {
144
            $this->commandInfo->options()->setDefaultValue($variableName, $defaultValue);
145
        }
146
    }
147
148
    /**
149
     * Process the comma-separated list of aliases
150
     */
151
    protected function processAliases($tag)
152
    {
153
        $this->commandInfo->setAliases($tag->getDescription());
154
    }
155
156
    /**
157
     * Store the data from a @usage annotation in our example usage list.
158
     */
159 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...
160
    {
161
        $lines = explode("\n", $tag->getContent());
162
        $usage = array_shift($lines);
163
        $description = static::removeLineBreaks(implode("\n", $lines));
164
165
        $this->commandInfo->setExampleUsage($usage, $description);
166
    }
167
}
168