BaseVisitor   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 90.91%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 8
dl 0
loc 92
c 0
b 0
f 0
ccs 40
cts 44
cp 0.9091
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 5 1
A getAbsoluteFilePath() 0 4 1
A addError() 0 21 5
A addLocation() 0 8 2
A getLocation() 0 16 6
A getDocParser() 0 14 2
A setDocParser() 0 4 1
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
    protected $collection;
31
    protected $file;
32
33
    /**
34
     * @var DocParser
35
     */
36
    private $docParser;
37
38
    /**
39
     * {@inheritdoc}
40
     */
41 37
    public function init(SourceCollection $collection, SplFileInfo $file): void
42
    {
43 37
        $this->collection = $collection;
44 37
        $this->file = $file;
45 37
    }
46
47 34
    protected function getAbsoluteFilePath(): string
48
    {
49 34
        return $this->file->getRealPath();
50
    }
51
52 9
    protected function addError(Node $node, string $errorMessage): void
53
    {
54 9
        $docComment = $node->getDocComment();
55 9
        $file = $this->getAbsoluteFilePath();
56
57 9
        if (property_exists($node, 'value')) {
58 7
            $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...
59
        } else {
60 2
            $line = $node->getAttribute('startLine');
61
        }
62 9
        if (null !== $docComment) {
63 3
            $context = 'file '.$file.' near line '.$line;
64 3
            foreach ($this->getDocParser()->parse($docComment->getText(), $context) as $annotation) {
65 3
                if ($annotation instanceof Ignore) {
66 3
                    return;
67
                }
68
            }
69
        }
70
71 9
        $this->collection->addError(new Error($errorMessage, $file, $line));
72 9
    }
73
74 11
    protected function addLocation(string $text, int $line, Node $node = null, array $context = []): void
75
    {
76 11
        if (null === $location = $this->getLocation($text, $line, $node, $context)) {
77
            return;
78
        }
79
80 11
        $this->collection->addLocation($location);
81 11
    }
82
83 20
    protected function getLocation(string $text, int $line, Node $node = null, array $context = []): ?SourceLocation
84
    {
85 20
        $file = $this->getAbsoluteFilePath();
86 20
        if (null !== $node && null !== $docComment = $node->getDocComment()) {
87 4
            $parserContext = 'file '.$file.' near line '.$line;
88 4
            foreach ($this->getDocParser()->parse($docComment->getText(), $parserContext) as $annotation) {
89 3
                if ($annotation instanceof Ignore) {
90 2
                    return null;
91 2
                } elseif ($annotation instanceof Desc) {
92 2
                    $context['desc'] = $annotation->text;
93
                }
94
            }
95
        }
96
97 20
        return new SourceLocation($text, $file, $line, $context);
98
    }
99
100 6
    private function getDocParser(): DocParser
101
    {
102 6
        if (null === $this->docParser) {
103 6
            $this->docParser = new DocParser();
104
105 6
            $this->docParser->setImports([
106 6
                'ignore' => Ignore::class,
107
                'desc' => Desc::class,
108
            ]);
109 6
            $this->docParser->setIgnoreNotImportedAnnotations(true);
110
        }
111
112 6
        return $this->docParser;
113
    }
114
115
    public function setDocParser(DocParser $docParser): void
116
    {
117
        $this->docParser = $docParser;
118
    }
119
}
120