diff --git a/src/Discovery/Cache/SnapshotClassFinderComputedCache.php b/src/Discovery/Cache/SnapshotClassFinderComputedCache.php index 46a80b48d0..df94c06545 100644 --- a/src/Discovery/Cache/SnapshotClassFinderComputedCache.php +++ b/src/Discovery/Cache/SnapshotClassFinderComputedCache.php @@ -10,6 +10,7 @@ use TheCodingMachine\GraphQLite\Discovery\ClassFinder; use function sprintf; +use function str_replace; /** * Provides cache for a {@see ClassFinder} based on a {@see filemtime()}. @@ -79,8 +80,11 @@ private function entries( $changed = false; $classFinder = $classFinder->withPathFilter(static function (string $filename) use (&$entries, &$result, &$changed, $previousEntries) { + // Normalize filename to avoid issues on Windows. + $normalizedFilename = str_replace('\\', '/', $filename); + /** @var array{ data: TEntry, dependencies: FilesSnapshot, matching: bool } $entry */ - $entry = $previousEntries[$filename] ?? null; + $entry = $previousEntries[$normalizedFilename] ?? null; // If there's no entry in cache for this filename (new file or previously uncached), // or if it the file has been modified since caching, we'll try to autoload @@ -90,7 +94,7 @@ private function entries( // it will not be emitted in the iterator and won't reach the `foreach()` below. // So to avoid iterating over these files again, we'll mark them as non-matching. // If they are matching, it'll be overwritten in the `foreach` loop below. - $entries[$filename] = [ + $entries[$normalizedFilename] = [ 'dependencies' => FilesSnapshot::for([$filename]), 'matching' => false, ]; @@ -101,10 +105,10 @@ private function entries( } if ($entry['matching']) { - $result[$filename] = $entry['data']; + $result[$normalizedFilename] = $entry['data']; } - $entries[$filename] = $entry; + $entries[$normalizedFilename] = $entry; return false; }); @@ -112,10 +116,18 @@ private function entries( foreach ($classFinder as $classReflection) { $filename = $classReflection->getFileName(); - $result[$filename] = $map($classReflection); - $entries[$filename] = [ + // Skip internal classes or classes without a file + if ($filename === false) { + continue; + } + + // Normalize filename to avoid issues on Windows. + $normalizedFilename = str_replace('\\', '/', $filename); + + $result[$normalizedFilename] = $map($classReflection); + $entries[$normalizedFilename] = [ 'dependencies' => FilesSnapshot::forClass($classReflection, true), - 'data' => $result[$filename], + 'data' => $result[$normalizedFilename], 'matching' => true, ];