Ejemplo n.º 1
0
        /// <summary>
        /// Returns solution projects.
        /// </summary>
        /// <param name="flags">Processor flags.</param>
        /// <param name="filter">Code model filter.</param>
        /// <returns>Projects.</returns>
        public SolutionModel GetProjects(ProcessorFlags flags, CodeModelFilterFlags filter = CodeModelFilterFlags.All)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            var model = new SolutionModel();

            GetProjectsInternal(model, flags, filter);
            return(model);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns solution projects.
        /// </summary>
        private void GetProjectsInternal(SolutionModel model, ProcessorFlags flags, CodeModelFilterFlags filter)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            var dte = _shellProjectService.GetDTE() as DTE;

            _log.LogMessage("Collecting solution projects");

            var projects = dte.Solution.Projects;

            for (int index = 1; index <= projects.Count; index++)
            {
                Project project = projects.Item(index);

                if (_shellProjectService.IsProjectLoadDeferred(project, out bool loaded))
                {
                    continue;
                }

                // Reacquire project reference if it's been reloaded
                if (loaded)
                {
                    project = projects.Item(index);
                }

                if (ProcessProject(project, model.Projects, flags, filter))
                {
                    ProcessProjectRecursively(project, model.Projects, flags, filter);
                }
            }

            model.Files = model.Projects.SelectMany(p => p.Files).ToList();

            if (flags.HasFlag(ProcessorFlags.GroupLinkedFiles))
            {
                // Get all grouped, ie duplicate, files, keep the first code file and remove the rest
                var groupedFiles = model.Files.GroupBy(f => f.FileNameWithPath).Where(g => g.Count() > 1).Select(g => g);
                foreach (var group in groupedFiles)
                {
                    var file = group.FirstOrDefault(f => f.Project.Language.SupportsCompileBuildAction && _shellProjectService.CompileBuildAction(f.ProjectItem));
                    if (file != null)
                    {
                        group.ForEach(f =>
                        {
                            if (f != file)
                            {
                                model.Files.Remove(f);
                                f.Project.Files.Remove(f);
                                AddProjectName(file, f.ProjectName);
                            }
                        });
                    }
                }
            }

            _log.LogMessage($"Collected {model.Projects.Count} solution projects");
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns solution projects.
        /// </summary>
        private void GetProjectsInternal(SolutionModel model, ProcessorFlags flags, CodeModelFilterFlags filter)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            _log.LogMessage("Collecting solution projects", LOG_CATEGORY);

            var dte             = _shellProjectService.GetDTE() as DTE;
            var serviceProvider = new Microsoft.VisualStudio.Shell.ServiceProvider(dte as Microsoft.VisualStudio.OLE.Interop.IServiceProvider);
            var solutionService = serviceProvider.GetService <IVsSolution, SVsSolution>(false);

            Guid guid = Guid.Empty;

            if (solutionService.GetProjectEnum((uint)__VSENUMPROJFLAGS.EPF_LOADEDINSOLUTION, ref guid, out IEnumHierarchies enumHierarchies) != VSConstants.S_OK)
            {
                return;
            }

            IVsHierarchy[] hierarchy = new IVsHierarchy[1];
            List <Project> projects  = new List <Project>();

            while ((enumHierarchies.Next((uint)hierarchy.Length, hierarchy, out uint fetched) == VSConstants.S_OK) && (fetched == hierarchy.Length))
            {
                if ((hierarchy.Length > 0) && (hierarchy[0] != null))
                {
                    IVsHierarchy projectHierarchy = hierarchy[0];

                    if ((projectHierarchy.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_ExtObject, out object project) == VSConstants.S_OK) &&
                        (project is Project dteProject) &&
                        _shellProjectService.IsProject(project))
                    {
                        projects.Add(dteProject);
                    }
                }
            }

            _log.LogMessage("Resolving solution name", LOG_CATEGORY);

            var solution = dte.Solution?.FileName;

            if (!string.IsNullOrEmpty(solution))
            {
                solution = Path.GetFileNameWithoutExtension(solution);
            }
            model.SolutionName = solution;

            _log.LogMessage($"Processing {projects.Count} collected solution projects", LOG_CATEGORY);

            foreach (Project project in projects)
            {
                if (_shellProjectService.IsProjectLoadDeferred(project, out _))
                {
                    continue;
                }

                if (ProcessProject(project, model.Projects, flags, filter))
                {
                    ProcessProjectRecursively(project, model.Projects, flags, filter);
                }
            }

            model.Files = model.Projects.SelectMany(p => p.Files).ToList();

            if (flags.HasFlag(ProcessorFlags.GroupLinkedFiles))
            {
                // Get all grouped, ie duplicate, files, keep the first code file and remove the rest
                var groupedFiles = model.Files.GroupBy(f => f.FileNameWithPath).Where(g => g.Count() > 1).Select(g => g);
                foreach (var group in groupedFiles)
                {
                    var file = group.FirstOrDefault(f => f.Project.Language.SupportsCompileBuildAction && _shellProjectService.CompileBuildAction(f.ProjectItem));
                    if (file != null)
                    {
                        group.ForEach(f =>
                        {
                            if (f != file)
                            {
                                model.Files.Remove(f);
                                f.Project.Files.Remove(f);
                                AddProjectName(file, f.ProjectName);
                            }
                        });
                    }
                }
            }

            _log.LogMessage($"Processed {model.Projects.Count} qualified solution projects", LOG_CATEGORY);
        }