/// <summary>
        /// Return the |FileName| instance corresponding to the full path |path|. Returns |null| if |path|
        /// is invalid or not part of a project.
        /// </summary>
        public static Tuple <IProject, FileName> GetProjectFileName(IFileSystemNameFactory fileSystemNameFactory, IProjectDiscovery projectDiscovery, FullPathName path)
        {
            var project = projectDiscovery.GetProject(path);

            if (project == null)
            {
                return(null);
            }

            var rootPath   = project.RootPath;
            var rootLength = rootPath.FullName.Length + 1;

            if (rootPath.FullName.Last() == Path.DirectorySeparatorChar)
            {
                rootLength--;
            }

            var directoryName = fileSystemNameFactory.CreateAbsoluteDirectoryName(rootPath);
            var relativePath  = path.FullName.Substring(rootLength);
            var items         = relativePath.Split(new char[] {
                Path.DirectorySeparatorChar
            });

            foreach (var item in items)
            {
                if (item == items.Last())
                {
                    return(Tuple.Create(project, fileSystemNameFactory.CreateFileName(directoryName, item)));
                }

                directoryName = fileSystemNameFactory.CreateDirectoryName(directoryName, item);
            }
            return(null);
        }
        /// <summary>
        /// Return the |FileName| instance corresponding to the full path |path|.
        /// Returns |null| if |path| is invalid or not part of a project.
        /// </summary>
        public static ProjectFileName GetProjectFileName(IFileSystemNameFactory fileSystemNameFactory, IProjectDiscovery projectDiscovery, FullPath path)
        {
            var project = projectDiscovery.GetProject(path);

            if (project == null)
            {
                return(default(ProjectFileName));
            }

            var split        = PathHelpers.SplitPrefix(path.Value, project.RootPath.Value);
            var relativePath = split.Suffix;

            var directoryName = fileSystemNameFactory.CreateAbsoluteDirectoryName(project.RootPath);
            var names         = relativePath.Split(Path.DirectorySeparatorChar);

            foreach (var name in names)
            {
                if (name == names.Last())
                {
                    return(new ProjectFileName(project, fileSystemNameFactory.CreateFileName(directoryName, name)));
                }

                directoryName = fileSystemNameFactory.CreateDirectoryName(directoryName, name);
            }
            return(default(ProjectFileName));
        }
Example #3
0
        /// <summary>
        /// Return the <see cref="ProjectFileName"/> instance of the project file <paramref name="relativePath"/>.
        /// Returns the default value if <paramref name="relativePath"/> is invalid or not part of a project.
        /// </summary>
        public static ProjectFileName CreateProjectFileNameFromRelativePath(
            this IFileSystemNameFactory fileSystemNameFactory, IProject project, string relativePath)
        {
            if (project == null)
            {
                throw new ArgumentNullException();
            }
            if (string.IsNullOrEmpty(relativePath))
            {
                return(default(ProjectFileName));
            }

            var directoryName = fileSystemNameFactory.CreateAbsoluteDirectoryName(project.RootPath);
            var names         = PathHelpers.SplitPath(relativePath).ToList();

            foreach (var name in names)
            {
                if (name == names.Last())
                {
                    return(new ProjectFileName(project, fileSystemNameFactory.CreateFileName(directoryName, name)));
                }

                directoryName = fileSystemNameFactory.CreateDirectoryName(directoryName, name);
            }

            Debug.Assert(false, "Unreachable code");
            throw new InvalidOperationException();
        }
Example #4
0
        public DirectoryName CreateAbsoluteDirectoryName(FullPathName rootPath)
        {
            var rootdirectory = FindRootDirectory(rootPath);

            if (rootdirectory != null)
            {
                return(rootdirectory.DirectoryName);
            }

            return(_previous.CreateAbsoluteDirectoryName(rootPath));
        }
        private DirectorySnapshot ProcessProject(IFileSystemNameFactory fileNameFactory, IProject project, IProgressTracker progress)
        {
            var projectPath = fileNameFactory.CreateAbsoluteDirectoryName(project.RootPath);

            var ssw = new ScopedStopWatch();
            // Create list of pairs (DirectoryName, List[FileNames])
            var directoriesWithFiles = TraverseFileSystem(fileNameFactory, project, projectPath)
                                       .AsParallel()
                                       .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                                       .Select(traversedDirectoryEntry => {
                var directoryName = traversedDirectoryEntry.DirectoryName;
                if (progress.Step())
                {
                    progress.DisplayProgress((i, n) => string.Format("Traversing directory: {0}\\{1}", project.RootPath.FullName, directoryName.RelativePathName.RelativeName));
                }
                var entries = traversedDirectoryEntry.ChildrenNames
                              .Where(childFilename => project.FileFilter.Include(childFilename.RelativePathName.RelativeName))
                              .OrderBy(x => x.RelativePathName)
                              .ToReadOnlyCollection();

                return(KeyValuePair.Create(directoryName, entries));
            })
                                       .ToList();

            ssw.Step(sw => Logger.Log("Done traversing file system in {0:n0} msec.", sw.ElapsedMilliseconds));

            // We sort entries by directory name *descending* to make sure we process
            // directories bottom up, so that we know
            // 1) it is safe to skip DirectoryEntry instances where "Entries.Count" == 0,
            // 2) we create instances of child directories before their parent.
            directoriesWithFiles.Sort((x, y) => - x.Key.RelativePathName.CompareTo(y.Key.RelativePathName));
            ssw.Step(sw => Logger.Log("Done sorting list of directories in {0:n0} msec.", sw.ElapsedMilliseconds));

            // Build map from parent directory -> list of child directories
            var directoriesToChildDirectories = new Dictionary <DirectoryName, List <DirectoryName> >();

            directoriesWithFiles.ForAll(x => {
                var directoryName = x.Key;

                // Ignore root project directory name
                if (directoryName.IsAbsoluteName)
                {
                    return;
                }

                GetOrCreateList(directoriesToChildDirectories, directoryName.Parent).Add(directoryName);
            });
            ssw.Step(sw => Logger.Log("Done creating children directories in {0:n0} msec.", sw.ElapsedMilliseconds));

            // Build directory snapshots for each directory entry, using an
            // intermediate map to enable connecting snapshots to their parent.
            var directoriesToSnapshot = new Dictionary <DirectoryName, DirectorySnapshot>();
            var directorySnapshots    = directoriesWithFiles.Select(entry => {
                var directoryName  = entry.Key;
                var childFilenames = entry.Value;

                var childDirectories = GetOrEmptyList(directoriesToChildDirectories, directoryName)
                                       .Select(x => directoriesToSnapshot[x])
                                       .OrderBy(x => x.DirectoryName.RelativePathName)
                                       .ToReadOnlyCollection();

                // TODO(rpaquay): Not clear the lines below are a perf win, even though
                // they do not hurt correctness.
                // Remove children since we processed them
                //GetOrEmptyList(directoriesToChildDirectories, directoryName)
                //  .ForAll(x => directoriesToSnapshot.Remove(x));

                var result = new DirectorySnapshot(directoryName, childDirectories, childFilenames);
                directoriesToSnapshot.Add(directoryName, result);
                return(result);
            })
                                        .ToList();

            ssw.Step(sw => Logger.Log("Done creating directory snapshots in {0:n0} msec.", sw.ElapsedMilliseconds));

            // Since we sort directories by name descending, the last entry is always the
            // entry correcsponding to the project root.
            Debug.Assert(directorySnapshots.Count >= 1);
            Debug.Assert(directorySnapshots.Last().DirectoryName.Equals(projectPath));
            return(directorySnapshots.Last());
        }