-
-
Notifications
You must be signed in to change notification settings - Fork 117
/
AbstractClassLikeIndexer.php
91 lines (77 loc) · 3.25 KB
/
AbstractClassLikeIndexer.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php
namespace Phpactor\Indexer\Adapter\Tolerant\Indexer;
use Microsoft\PhpParser\NamespacedNameInterface;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Node\QualifiedName;
use Microsoft\PhpParser\Node\DelimitedList\QualifiedNameList;
use Microsoft\PhpParser\Node\Statement\ClassDeclaration;
use Microsoft\PhpParser\Node\Statement\EnumDeclaration;
use Microsoft\PhpParser\Node\Statement\InterfaceDeclaration;
use Microsoft\PhpParser\Node\Statement\TraitDeclaration;
use Phpactor\Indexer\Adapter\Tolerant\TolerantIndexer;
use Phpactor\Indexer\Model\Exception\CannotIndexNode;
use Phpactor\Indexer\Model\Name\FullyQualifiedName;
use Phpactor\Indexer\Model\Record\ClassRecord;
use Phpactor\TextDocument\ByteOffset;
use Phpactor\Indexer\Model\Index;
use Phpactor\TextDocument\TextDocument;
abstract class AbstractClassLikeIndexer implements TolerantIndexer
{
public function beforeParse(Index $index, TextDocument $document): void
{
}
protected function removeImplementations(Index $index, ClassRecord $record): void
{
foreach ($record->implements() as $implementedClass) {
$implementedRecord = $index->get(ClassRecord::fromName($implementedClass));
if (false === $implementedRecord->removeImplementation($record->fqn())) {
continue;
}
$index->write($implementedRecord);
}
}
protected function indexInterfaceList(QualifiedNameList $interfaceList, ClassRecord $record, Index $index): void
{
foreach ($interfaceList->children as $interfaceName) {
if (!$interfaceName instanceof QualifiedName) {
continue;
}
$interfaceName = (string) $interfaceName->getResolvedName();
$interfaceRecord = $index->get(ClassRecord::fromName($interfaceName));
$record->addImplements(
FullyQualifiedName::fromString($interfaceName)
);
assert($interfaceRecord instanceof ClassRecord);
$interfaceRecord->addImplementation($record->fqn());
$index->write($interfaceRecord);
}
}
/**
* @param ClassRecord::TYPE_* $type
*/
protected function getClassLikeRecord(string $type, Node $node, Index $index, TextDocument $document): ClassRecord
{
assert($node instanceof NamespacedNameInterface);
$name = $node->getNamespacedName()->getFullyQualifiedNameText();
if (empty($name)) {
throw new CannotIndexNode(sprintf(
'Name is empty for file "%s"',
$document->uri()?->__toString() ?? 'unknown',
));
}
if (!$document->uri()) {
throw new CannotIndexNode(sprintf(
'Document has no URI for class "%s"',
$name
));
}
$record = $index->get(ClassRecord::fromName($name));
assert($record instanceof ClassRecord);
/** @var ClassDeclaration|InterfaceDeclaration|EnumDeclaration|TraitDeclaration $node */
$record->setStart(ByteOffset::fromInt($node->name->getStartPosition()));
$record->setEnd(ByteOffset::fromInt($node->name->getEndPosition()));
$record->setFilePath($document->uriOrThrow());
$record->setType($type);
return $record;
}
}