Chris@0
|
1 <?php
|
Chris@0
|
2 namespace Consolidation\AnnotatedCommand\Parser\Internal;
|
Chris@0
|
3
|
Chris@0
|
4 class FullyQualifiedClassCache
|
Chris@0
|
5 {
|
Chris@0
|
6 protected $classCache = [];
|
Chris@0
|
7 protected $namespaceCache = [];
|
Chris@0
|
8
|
Chris@0
|
9 public function qualify($filename, $className)
|
Chris@0
|
10 {
|
Chris@0
|
11 $this->primeCache($filename, $className);
|
Chris@0
|
12 return $this->cached($filename, $className);
|
Chris@0
|
13 }
|
Chris@0
|
14
|
Chris@0
|
15 protected function cached($filename, $className)
|
Chris@0
|
16 {
|
Chris@0
|
17 return isset($this->classCache[$filename][$className]) ? $this->classCache[$filename][$className] : $className;
|
Chris@0
|
18 }
|
Chris@0
|
19
|
Chris@0
|
20 protected function primeCache($filename, $className)
|
Chris@0
|
21 {
|
Chris@0
|
22 // If the cache has already been primed, do no further work
|
Chris@0
|
23 if (isset($this->namespaceCache[$filename])) {
|
Chris@0
|
24 return false;
|
Chris@0
|
25 }
|
Chris@0
|
26
|
Chris@0
|
27 $handle = fopen($filename, "r");
|
Chris@0
|
28 if (!$handle) {
|
Chris@0
|
29 return false;
|
Chris@0
|
30 }
|
Chris@0
|
31
|
Chris@0
|
32 $namespaceName = $this->primeNamespaceCache($filename, $handle);
|
Chris@0
|
33 $this->primeUseCache($filename, $handle);
|
Chris@0
|
34
|
Chris@0
|
35 // If there is no 'use' statement for the className, then
|
Chris@0
|
36 // generate an effective classname from the namespace
|
Chris@0
|
37 if (!isset($this->classCache[$filename][$className])) {
|
Chris@0
|
38 $this->classCache[$filename][$className] = $namespaceName . '\\' . $className;
|
Chris@0
|
39 }
|
Chris@0
|
40
|
Chris@0
|
41 fclose($handle);
|
Chris@0
|
42 }
|
Chris@0
|
43
|
Chris@0
|
44 protected function primeNamespaceCache($filename, $handle)
|
Chris@0
|
45 {
|
Chris@0
|
46 $namespaceName = $this->readNamespace($handle);
|
Chris@0
|
47 if (!$namespaceName) {
|
Chris@0
|
48 return false;
|
Chris@0
|
49 }
|
Chris@0
|
50 $this->namespaceCache[$filename] = $namespaceName;
|
Chris@0
|
51 return $namespaceName;
|
Chris@0
|
52 }
|
Chris@0
|
53
|
Chris@0
|
54 protected function primeUseCache($filename, $handle)
|
Chris@0
|
55 {
|
Chris@0
|
56 $usedClasses = $this->readUseStatements($handle);
|
Chris@0
|
57 if (empty($usedClasses)) {
|
Chris@0
|
58 return false;
|
Chris@0
|
59 }
|
Chris@0
|
60 $this->classCache[$filename] = $usedClasses;
|
Chris@0
|
61 }
|
Chris@0
|
62
|
Chris@0
|
63 protected function readNamespace($handle)
|
Chris@0
|
64 {
|
Chris@0
|
65 $namespaceRegex = '#^\s*namespace\s+#';
|
Chris@0
|
66 $line = $this->readNextRelevantLine($handle);
|
Chris@0
|
67 if (!$line || !preg_match($namespaceRegex, $line)) {
|
Chris@0
|
68 return false;
|
Chris@0
|
69 }
|
Chris@0
|
70
|
Chris@0
|
71 $namespaceName = preg_replace($namespaceRegex, '', $line);
|
Chris@0
|
72 $namespaceName = rtrim($namespaceName, ';');
|
Chris@0
|
73 return $namespaceName;
|
Chris@0
|
74 }
|
Chris@0
|
75
|
Chris@0
|
76 protected function readUseStatements($handle)
|
Chris@0
|
77 {
|
Chris@0
|
78 $useRegex = '#^\s*use\s+#';
|
Chris@0
|
79 $result = [];
|
Chris@0
|
80 while (true) {
|
Chris@0
|
81 $line = $this->readNextRelevantLine($handle);
|
Chris@0
|
82 if (!$line || !preg_match($useRegex, $line)) {
|
Chris@0
|
83 return $result;
|
Chris@0
|
84 }
|
Chris@0
|
85 $usedClass = preg_replace($useRegex, '', $line);
|
Chris@0
|
86 $usedClass = rtrim($usedClass, ';');
|
Chris@0
|
87 $unqualifiedClass = preg_replace('#.*\\\\#', '', $usedClass);
|
Chris@0
|
88 // If this is an aliased class, 'use \Foo\Bar as Baz', then adjust
|
Chris@0
|
89 if (strpos($usedClass, ' as ')) {
|
Chris@0
|
90 $unqualifiedClass = preg_replace('#.*\sas\s+#', '', $usedClass);
|
Chris@17
|
91 $usedClass = preg_replace('#[a-zA-Z0-9]+\s+as\s+#', '', $usedClass);
|
Chris@0
|
92 }
|
Chris@0
|
93 $result[$unqualifiedClass] = $usedClass;
|
Chris@0
|
94 }
|
Chris@0
|
95 }
|
Chris@0
|
96
|
Chris@0
|
97 protected function readNextRelevantLine($handle)
|
Chris@0
|
98 {
|
Chris@0
|
99 while (($line = fgets($handle)) !== false) {
|
Chris@0
|
100 if (preg_match('#^\s*\w#', $line)) {
|
Chris@0
|
101 return trim($line);
|
Chris@0
|
102 }
|
Chris@0
|
103 }
|
Chris@0
|
104 return false;
|
Chris@0
|
105 }
|
Chris@0
|
106 }
|