Completed
Push — master ( 04f40e...f278b5 )
by Tobias
05:43
created

BaseVisitor::addError()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 21
c 0
b 0
f 0
ccs 13
cts 13
cp 1
rs 8.7624
cc 5
eloc 13
nc 6
nop 2
crap 5
1
<?php
2
3
/*
4
 * This file is part of the PHP Translation package.
5
 *
6
 * (c) PHP Translation team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Translation\Extractor\Visitor;
13
14
use Doctrine\Common\Annotations\DocParser;
15
use PhpParser\Node;
16
use Symfony\Component\Finder\SplFileInfo;
17
use Translation\Extractor\Annotation\Desc;
18
use Translation\Extractor\Annotation\Ignore;
19
use Translation\Extractor\Model\Error;
20
use Translation\Extractor\Model\SourceCollection;
21
use Translation\Extractor\Model\SourceLocation;
22
23
/**
24
 * Base class for any visitor.
25
 *
26
 * @author Tobias Nyholm <[email protected]>
27
 */
28
abstract class BaseVisitor implements Visitor
29
{
30
    /**
31
     * @var SourceCollection
32
     */
33
    protected $collection;
34
35
    /**
36
     * @var SplFileInfo
37
     */
38
    protected $file;
39
40
    /**
41
     * @var DocParser
42
     */
43
    private $docParser;
44
45 26
    public function init(SourceCollection $collection, SplFileInfo $file)
46
    {
47 26
        $this->collection = $collection;
48 26
        $this->file = $file;
49 26
    }
50
51 24
    protected function getAbsoluteFilePath()
52
    {
53 24
        return $this->file->getRealPath();
54
    }
55
56
    /**
57
     * @param Node   $node
58
     * @param string $errorMessage
59
     */
60 7
    protected function addError(Node $node, $errorMessage)
61
    {
62 7
        $docComment = $node->getDocComment();
63 7
        $file = $this->getAbsoluteFilePath();
64
65 7
        if (property_exists($node, 'value')) {
66 5
            $line = $node->value->getAttribute('startLine');
0 ignored issues
show
Bug introduced by
Accessing value on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
67
        } else {
68 2
            $line = $node->getAttribute('startLine');
69
        }
70 7
        if (null !== $docComment) {
71 3
            $context = 'file '.$file.' near line '.$line;
72 3
            foreach ($this->getDocParser()->parse($docComment->getText(), $context) as $annotation) {
73 3
                if ($annotation instanceof Ignore) {
74 3
                    return;
75
                }
76
            }
77
        }
78
79 7
        $this->collection->addError(new Error($errorMessage, $file, $line));
80 7
    }
81
82
    /**
83
     * @param string    $text
84
     * @param int       $line
85
     * @param Node|null $node
86
     * @param array     $context
87
     */
88 12
    protected function addLocation($text, $line, Node $node = null, array $context = [])
89
    {
90 12
        $file = $this->getAbsoluteFilePath();
91 12
        if (null !== $node && null !== $docComment = $node->getDocComment()) {
92 2
            $parserContext = 'file '.$file.' near line '.$line;
93 2
            foreach ($this->getDocParser()->parse($docComment->getText(), $parserContext) as $annotation) {
94 2
                if ($annotation instanceof Ignore) {
95 1
                    return;
96 2
                } elseif ($annotation instanceof Desc) {
97 2
                    $context['desc'] = $annotation->text;
98
                }
99
            }
100
        }
101
102 12
        $source = new SourceLocation($text, $file, $line, $context);
103 12
        $this->collection->addLocation($source);
104 12
    }
105
106
    /**
107
     * @return DocParser
108
     */
109 4
    private function getDocParser()
110
    {
111 4
        if (null === $this->docParser) {
112 4
            $this->docParser = new DocParser();
113
114 4
            $this->docParser->setImports([
115 4
                'ignore' => Ignore::class,
116
                'desc' => Desc::class,
117
            ]);
118 4
            $this->docParser->setIgnoreNotImportedAnnotations(true);
119
        }
120
121 4
        return $this->docParser;
122
    }
123
124
    /**
125
     * @param DocParser $docParser
126
     */
127
    public function setDocParser(DocParser $docParser)
128
    {
129
        $this->docParser = $docParser;
130
    }
131
}
132