-
-
Notifications
You must be signed in to change notification settings - Fork 39
/
NamespaceMap.php
85 lines (75 loc) · 2.3 KB
/
NamespaceMap.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
<?php declare(strict_types=1);
namespace Hyva\Admin\Model\TypeReflection;
use function array_merge as merge;
class NamespaceMap
{
/**
* @var string[]
*/
private $namespaceMap;
/**
* @var string
*/
private $file;
private function __construct(string $file, array $namespaceMap)
{
$this->file = $file;
$this->namespaceMap = $namespaceMap;
}
/**
* Simplified namespace resolution
*
* Only supports single line imports and aliases.
*/
public static function forFile(string $fileName): NamespaceMap
{
$f = fopen($fileName, 'r');
try {
$map = self::readUntilCassDefiniton($f);
} finally {
fclose($f);
}
return new self($fileName, $map ?? []);
}
private static function readUntilCassDefiniton($f): array
{
$map = [];
while (!feof($f)) {
if (!is_string($line = fgets($f, 4096))) {
break;
}
if (!isset($map['@default']) && preg_match('/namespace +([^;[:space:]]+)/', $line, $m)) {
$map['@default'] = $m[1];
} elseif (preg_match('/use +(?<import>[^;[:space:]]+)(?:\s+as\s+(?<alias>[^;[:space:]]+))?/', $line, $m)) {
$fullyQualifiedClass = ltrim($m['import'], '\\');
$import = $m['alias'] ?? self::lastPart($fullyQualifiedClass);
$map[$import] = $fullyQualifiedClass;
} elseif (preg_match('/^(?:class|interface) /', trim($line))) {
break;
}
}
return $map;
}
private static function lastPart(string $fqcn): string
{
$parts = explode('\\', $fqcn);
return end($parts);
}
public function qualify(string $class): string
{
if (substr($class, 0, 1) === '\\') {
return $class;
}
if (isset($this->namespaceMap[$class])) {
return $this->namespaceMap[$class];
}
[$base, $rest] = merge(explode('\\', $class, 2), [null]);
return $base === $class
? ($this->namespaceMap['@default'] ?? '') . '\\' . $class
: $this->qualify($base) . '\\' . $rest;
}
public function getFile(): string
{
return $this->file;
}
}