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