Completed
Push — master ( ba40ee...261a9c )
by Tobias
02:47
created

BaseVisitor::addError()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 13
cts 13
cp 1
rs 9.2728
c 0
b 0
f 0
cc 5
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 32
    public function init(SourceCollection $collection, SplFileInfo $file)
46
    {
47 32
        $this->collection = $collection;
48 32
        $this->file = $file;
49 32
    }
50
51 29
    protected function getAbsoluteFilePath()
52
    {
53 29
        return $this->file->getRealPath();
54
    }
55
56
    /**
57
     * @param Node   $node
58
     * @param string $errorMessage
59
     */
60 8
    protected function addError(Node $node, $errorMessage)
61
    {
62 8
        $docComment = $node->getDocComment();
63 8
        $file = $this->getAbsoluteFilePath();
64
65 8
        if (property_exists($node, 'value')) {
66 6
            $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 8
        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 8
        $this->collection->addError(new Error($errorMessage, $file, $line));
80 8
    }
81
82
    /**
83
     * @param string    $text
84
     * @param int       $line
85
     * @param Node|null $node
86
     * @param array     $context
87
     */
88 9
    protected function addLocation($text, $line, Node $node = null, array $context = [])
89
    {
90 9
        if (null === $location = $this->getLocation($text, $line, $node, $context)) {
91
            return;
92
        }
93
94 9
        $this->collection->addLocation($location);
95 9
    }
96
97
    /**
98
     * @param string    $text
99
     * @param int       $line
100
     * @param Node|null $node
101
     * @param array     $context
102
     *
103
     * @return SourceLocation|null
104
     */
105 15
    protected function getLocation($text, $line, Node $node = null, array $context = [])
106
    {
107 15
        $file = $this->getAbsoluteFilePath();
108 15
        if (null !== $node && null !== $docComment = $node->getDocComment()) {
109 3
            $parserContext = 'file '.$file.' near line '.$line;
110 3
            foreach ($this->getDocParser()->parse($docComment->getText(), $parserContext) as $annotation) {
111 3
                if ($annotation instanceof Ignore) {
112 2
                    return null;
113 2
                } elseif ($annotation instanceof Desc) {
114 2
                    $context['desc'] = $annotation->text;
115
                }
116
            }
117
        }
118
119 15
        return new SourceLocation($text, $file, $line, $context);
120
    }
121
122
    /**
123
     * @return DocParser
124
     */
125 5
    private function getDocParser()
126
    {
127 5
        if (null === $this->docParser) {
128 5
            $this->docParser = new DocParser();
129
130 5
            $this->docParser->setImports([
131 5
                'ignore' => Ignore::class,
132
                'desc' => Desc::class,
133
            ]);
134 5
            $this->docParser->setIgnoreNotImportedAnnotations(true);
135
        }
136
137 5
        return $this->docParser;
138
    }
139
140
    /**
141
     * @param DocParser $docParser
142
     */
143
    public function setDocParser(DocParser $docParser)
144
    {
145
        $this->docParser = $docParser;
146
    }
147
}
148