private IEnumerable <IFileSystemInfo> FindCandidates( DirectoryPath path, MatchableNode node, GlobVisitorContext context, SearchScope option, bool includeFiles = true, bool includeDirectories = true) { var result = new List <IFileSystemInfo>(); var current = _fileSystem.GetDirectory(path); // Directories if (includeDirectories) { foreach (var directory in current.GetDirectories("*", option)) { var lastPath = directory.Path.Segments[directory.Path.Segments.Count - 1]; if (node.IsMatch(lastPath) && context.ShouldTraverse(directory)) { result.Add(directory); } } } // Files if (includeFiles) { foreach (var file in current.GetFiles("*", option)) { var lastPath = file.Path.Segments[file.Path.Segments.Count - 1]; if (node.IsMatch(lastPath) && context.ShouldInclude(file)) { result.Add(file); } } } return(result); }
public void VisitSegment(PathNode node, GlobVisitorContext context) { if (node.IsIdentifier) { // Get the (relative) path to the current node. var segment = node.GetPath(); // Get a directory that matches this segment. // This might be a file but we can't be sure so we need to check. var directoryPath = context.Path.Combine(segment); var directory = _fileSystem.GetDirectory(directoryPath); // Should we not traverse this directory? if (directory.Exists && !context.ShouldTraverse(directory)) { return; } if (node.Next == null) { if (directory.Exists) { // Directory context.AddResult(directory); } else { // Then it must be a file (if it exist). var filePath = context.Path.CombineWithFilePath(new FilePath(segment)); var file = _fileSystem.File.Retrieve(filePath); if (file.Exists && context.ShouldInclude(file)) { // File context.AddResult(file); } } } else { // Push the current node to the context. context.Push(node.GetPath()); node.Next.Accept(this, context); context.Pop(); } } else { if (node.Segments.Count > 1) { var path = _fileSystem.GetDirectory(context.Path); if (path.Exists) { foreach (var candidate in FindCandidates(path.Path, node, context, SearchScope.Current)) { if (node.Next != null) { context.Push(candidate.Path.FullPath.Substring(path.Path.FullPath.Length + (path.Path.FullPath.Length > 1 ? 1 : 0))); node.Next.Accept(this, context); context.Pop(); } else { context.AddResult(candidate); } } } } } }