private static ISet <ProjectLinkObject> GetRawLibrariesReferences(ProjectDetailRepository projectRepository, ProjectFile projectFile)
        {
            var projectReferenceObjects = new HashSet <ProjectLinkObject>();

            {
                var libReferences = projectFile.SelectNodes(@"/msb:Project/msb:ItemDefinitionGroup/msb:Link/msb:AdditionalDependencies");
                var libsToIgnore  = new HashSet <string> {
                    "%(AdditionalDependencies)"
                };

                projectReferenceObjects.UnionWith(GetRawLibrariesReferencesInNode(libReferences, libsToIgnore));
            }

            {
                var libReferences = projectFile.SelectNodes(@"/msb:Project/msb:ItemDefinitionGroup/msb:Link/msb:DelayLoadDLLs");
                var libsToIgnore  = new HashSet <string> {
                    "%(DelayLoadDLLs)"
                };

                projectReferenceObjects.UnionWith(GetRawLibrariesReferencesInNode(libReferences, libsToIgnore));
            }

            OptimizeCollection(projectRepository, projectReferenceObjects);

            return(projectReferenceObjects);
        }
        private static ISet <ProjectDetail> ReplaceChildProjectPlaceholders(ProjectDetailRepository other, ISet <ProjectLinkObject> childProjects)
        {
            var projectsToRemove          = new HashSet <ProjectLinkObject>();
            var projectLinksToAdd         = new HashSet <ProjectLinkObject>();
            var projectsToAddToRepository = new HashSet <ProjectDetail>();

            foreach (var childProject in childProjects)
            {
                if (childProject.IsOutOfSolution)
                {
                    string name = Path.GetFileNameWithoutExtension(childProject.FullPath);

                    var possibleProjects = other.GetByName(name);

                    if (possibleProjects.Count == 0)
                    {
                    }
                    else if (possibleProjects.Count == 1)
                    {
                        _ = projectsToRemove.Add(childProject);
                        _ = projectsToAddToRepository.Add(possibleProjects.First());
                        _ = projectLinksToAdd.Add(new ProjectLinkObject(possibleProjects.First()));
                    }
                    else
                    {
                        throw new ArgumentException(string.Format("There is more than one possible project '{0}'", name));
                    }
                }
            }

            childProjects.ExceptWith(projectsToRemove);
            childProjects.UnionWith(projectLinksToAdd);

            return(projectsToAddToRepository);
        }
        private static void OptimizeCollection(ProjectDetailRepository projectRepository, ISet <ProjectLinkObject> references)
        {
            var projectsToRemove = new HashSet <ProjectLinkObject>();
            var projectsToAdd    = new HashSet <ProjectLinkObject>();

            foreach (var reference in references)
            {
                if (reference.IsOutOfSolution)
                {
                    string name = Path.GetFileNameWithoutExtension(reference.FullPath);

                    var projects = projectRepository.GetByName(name);

                    if (projects.Count == 0)
                    {
                        // Just leave it as is
                    }
                    else if (projects.Count == 1)
                    {
                        var projectLinkObject = new ProjectLinkObject(projects.First());

                        _ = projectsToRemove.Add(reference);
                        _ = projectsToAdd.Add(projectLinkObject);
                    }
                    else
                    {
                        throw new ArgumentException(string.Format("More than one project has the same name '{0}'", name));
                    }
                }
            }

            references.ExceptWith(projectsToRemove);
            references.UnionWith(projectsToAdd);
        }
        private ISet <ProjectLinkObject> GetDependencies(ProjectDetailRepository projectRepository, string projectPath, ProjectFile projectFile)
        {
            var references = GetProjectReferences(projectPath, projectFile);

            MergeReferencesWith(references, GetRawLibrariesReferences(projectRepository, projectFile));

            return(references);
        }
        private void AddChildrenToRepository(ProjectDetailRepository other, ISet <ProjectLinkObject> childProjects)
        {
            foreach (var childProject in childProjects)
            {
                var project = other.GetById(childProject.Id);
                if (null != project)
                {
                    _ = _projectDetails.Add(project);

                    AddChildrenToRepository(other, project.ChildProjects);
                }
            }
        }
        public void Merge(ProjectDetailRepository other)
        {
            var projectsToAddToRepository = new HashSet <ProjectDetail>();
            var projectsWithPlaceholders  = _projectDetails.Where(x => HasAnyPlaceholder(x));

            foreach (var projectWithPlaceholders in projectsWithPlaceholders)
            {
                projectsToAddToRepository.UnionWith(ReplaceChildProjectPlaceholders(other, projectWithPlaceholders.ChildProjects));
            }

            foreach (var projectToAdd in projectsToAddToRepository)
            {
                _ = _projectDetails.Add(projectToAdd);

                AddChildrenToRepository(other, projectToAdd.ChildProjects);
            }
        }
        public ProjectDetail(ProjectDetailRepository projectRepository, string fullFilePath, Guid projectGuidInSolution, ProjectFile projectFile, bool includeExternalReferences)
        {
            FullPath       = fullFilePath;
            ParentProjects = new HashSet <ProjectLinkObject>();
            Type           = GetProjectType(fullFilePath);

            FillUpExtraInformation(Type, projectGuidInSolution, projectFile);

            if (string.IsNullOrWhiteSpace(Name))
            {
                Name = Path.GetFileNameWithoutExtension(fullFilePath);
            }

            ChildProjects = GetDependencies(projectRepository, FullPath, projectFile);

            if (includeExternalReferences)
            {
                References = GetExternalReferences(fullFilePath, projectFile);
            }
            else
            {
                References = new HashSet <DllReference>();
            }
        }
 public void OptimizeReferences(ProjectDetailRepository projectRepository)
 {
     OptimizeCollection(projectRepository, ChildProjects);
     OptimizeCollection(projectRepository, ParentProjects);
 }
 public RootNode()
 {
     ChildProjects = new ProjectDetailRepository();
 }