void Initialize(IProgressMonitor progressMonitor, List <FileName> filesToParse)
        {
            IReadOnlyCollection <ProjectItem> projectItems = project.Items.CreateSnapshot();

            lock (lockObj) {
                if (disposed)
                {
                    return;
                }
            }

            double scalingFactor = 1.0 / (projectItems.Count + LoadingReferencesWorkAmount);

            using (IProgressMonitor initReferencesProgressMonitor = progressMonitor.CreateSubTask(LoadingReferencesWorkAmount * scalingFactor),
                   parseProgressMonitor = progressMonitor.CreateSubTask(projectItems.Count * scalingFactor))
            {
                var resolveReferencesTask = Task.Run(
                    delegate {
                    DoResolveReferences(initReferencesProgressMonitor);
                }, initReferencesProgressMonitor.CancellationToken);

                ParseFiles(filesToParse, parseProgressMonitor);

                resolveReferencesTask.Wait();
            }
        }
 public TaskToObserverSubscription(Func <IProgressMonitor, Action <T>, Task> func, IProgressMonitor progressMonitor, IObserver <T> observer)
 {
     this.observer             = observer;
     this.progressMonitor      = progressMonitor;
     this.childProgressMonitor = progressMonitor.CreateSubTask(1, cts.Token);
     func(childProgressMonitor, Callback).ContinueWith(TaskCompleted).FireAndForget();
 }
 void RunThread()
 {
     while (true)
     {
         JobTask task;
         // copy fields from this class into local variables to ensure thread-safety
         // with concurrent Clear() calls
         double           totalWork, workDone;
         IProgressMonitor progressMonitor;
         lock (lockObj) {
             // enqueued null: quit thread and restart (used for cancellation)
             if (actions.Count == 0 || this.actions.Peek() == null)
             {
                 this.threadIsRunning = false;
                 this.progressMonitor.Dispose();
                 this.progressMonitor = null;
                 // restart if necessary:
                 if (actions.Count > 0)
                 {
                     actions.Dequeue();                                 // dequeue the null
                     if (actions.Count > 0)
                     {
                         SD.MainThread.InvokeAsyncAndForget(StartRunningIfRequired);
                     }
                     else
                     {
                         loadSolutionProjects.RaiseThreadEnded();
                     }
                 }
                 else
                 {
                     loadSolutionProjects.RaiseThreadEnded();
                 }
                 return;
             }
             task            = this.actions.Dequeue();
             totalWork       = this.totalWork;
             workDone        = this.workDone;
             progressMonitor = this.progressMonitor;
         }
         progressMonitor.Progress = workDone / totalWork;
         progressMonitor.TaskName = task.name;
         try {
             using (IProgressMonitor subTask = progressMonitor.CreateSubTask(task.cost / totalWork)) {
                 subTask.CancellationToken.ThrowIfCancellationRequested();
                 task.Run(subTask);
             }
             lock (lockObj) {
                 this.workDone += task.cost;
             }
         } catch (OperationCanceledException) {
             // ignore cancellation
         } catch (Exception ex) {
             MessageService.ShowException(ex, "Error on LoadSolutionProjects thread");
         }
     }
 }
Exemplo n.º 4
0
        void StartBuildProjects()
        {
            lock (this) {
                while (workersToStart > 0)
                {
                    if (buildIsCancelled || projectsReadyForBuildStart.Count == 0)
                    {
                        if (runningWorkers == 0)
                        {
                            BuildDone();
                        }
                        return;
                    }

                    workersToStart--;

                    int projectToStartIndex = 0;
                    for (int i = 1; i < projectsReadyForBuildStart.Count; i++)
                    {
                        if (CompareBuildOrder(projectsReadyForBuildStart[i],
                                              projectsReadyForBuildStart[projectToStartIndex]) < 0)
                        {
                            projectToStartIndex = i;
                        }
                    }
                    BuildNode node = projectsReadyForBuildStart[projectToStartIndex];
                    projectsReadyForBuildStart.RemoveAt(projectToStartIndex);
                    node.perNodeProgressMonitor = progressMonitor.CreateSubTask(1.0 / nodeDict.Count);
                    node.buildStarted           = true;

                    bool hasDependencyErrors = false;
                    foreach (BuildNode n in node.dependencies)
                    {
                        if (!n.buildFinished)
                        {
                            throw new Exception("Trying to build project with unfinished dependencies");
                        }
                        hasDependencyErrors |= n.hasErrors;
                    }

                    ICSharpCode.Core.LoggingService.Info("Start building " + node.project.Name);
                    runningWorkers++;
                    projectsCurrentlyBuilding.Add(node);
                    if (hasDependencyErrors)
                    {
                        ICSharpCode.Core.LoggingService.Debug("Skipped building " + node.project.Name + " (errors in dependencies)");
                        node.hasErrors = true;
                        node.Done(false);
                    }
                    else
                    {
                        // do not run "DoStartBuild" inside lock - run it async on the thread pool
                        System.Threading.ThreadPool.QueueUserWorkItem(node.DoStartBuild);
                    }
                }
            }
        }
        public static async Task RenameSymbolAsync(ISymbol symbol, string newName, IProgressMonitor progressMonitor, Action <Error> errorCallback)
        {
            if (symbol == null)
            {
                throw new ArgumentNullException("symbol");
            }
            if (progressMonitor == null)
            {
                throw new ArgumentNullException("progressMonitor");
            }
            SD.MainThread.VerifyAccess();
            if (SD.ParserService.LoadSolutionProjectsThread.IsRunning)
            {
                progressMonitor.ShowingDialog = true;
                MessageService.ShowMessage("${res:SharpDevelop.Refactoring.LoadSolutionProjectsThreadRunning}");
                progressMonitor.ShowingDialog = false;
                return;
            }
            double totalWorkAmount;
            List <ISymbolSearch> symbolSearches = PrepareSymbolSearch(symbol, progressMonitor.CancellationToken, out totalWorkAmount);
            double workDone = 0;
            ParseableFileContentFinder parseableFileContentFinder = new ParseableFileContentFinder();
            var errors  = new List <Error>();
            var changes = new List <PatchedFile>();

            foreach (ISymbolSearch s in symbolSearches)
            {
                progressMonitor.CancellationToken.ThrowIfCancellationRequested();
                using (var childProgressMonitor = progressMonitor.CreateSubTask(s.WorkAmount / totalWorkAmount)) {
                    var args = new SymbolRenameArgs(newName, childProgressMonitor, parseableFileContentFinder);
                    args.ProvideHighlightedLine = false;
                    await s.RenameAsync(args, file => changes.Add(file), error => errors.Add(error));
                }

                workDone += s.WorkAmount;
                progressMonitor.Progress = workDone / totalWorkAmount;
            }
            if (errors.Count == 0)
            {
                foreach (var file in changes)
                {
                    ApplyChanges(file);
                }
            }
            else
            {
                foreach (var error in errors)
                {
                    errorCallback(error);
                }
            }
        }
        public async Task RunTestsAsync(IEnumerable <ITest> selectedTests, TestExecutionOptions options, CancellationToken cancellationToken)
        {
            this.cancellationToken = cancellationToken;
            GroupTestsByProject(selectedTests);

            ClearTasks();
            ShowUnitTestsPad();
            ShowOutputPad();

            ResetTestResults();
            saveAllFilesCommand.SaveAllFiles();

            // Run the build, if necessary:
            var projectsToBuild = testsByProject.Keys.Where(p => p.IsBuildNeededBeforeTestRun).Select(p => p.Project).ToList();

            if (projectsToBuild.Count > 0)
            {
                using (cancellationToken.Register(buildService.CancelBuild)) {
                    var buildOptions = new BuildOptions(BuildTarget.Build);
                    buildOptions.BuildDetection = BuildOptions.BuildOnExecute;
                    var buildResults = await buildService.BuildAsync(projectsToBuild, buildOptions);

                    if (buildResults.Result != BuildResultCode.Success)
                    {
                        return;
                    }
                }
            }

            cancellationToken.ThrowIfCancellationRequested();
            using (IProgressMonitor progressMonitor = statusBarService.CreateProgressMonitor(cancellationToken)) {
                int projectsLeftToRun = testsByProject.Count;
                foreach (IGrouping <ITestProject, ITest> g in testsByProject.OrderBy(g => g.Key.DisplayName))
                {
                    currentProjectBeingTested = g.Key;
                    progressMonitor.TaskName  = GetProgressMonitorLabel(currentProjectBeingTested);
                    progressMonitor.Progress  = GetProgress(projectsLeftToRun);
                    using (testProgressMonitor = progressMonitor.CreateSubTask(1.0 / testsByProject.Count)) {
                        using (ITestRunner testRunner = currentProjectBeingTested.CreateTestRunner(options)) {
                            testRunner.TestFinished += testRunner_TestFinished;
                            var writer = new MessageViewCategoryTextWriter(testService.UnitTestMessageView);
                            await testRunner.RunAsync(g, testProgressMonitor, writer, testProgressMonitor.CancellationToken);
                        }
                    }
                    projectsLeftToRun--;
                    progressMonitor.CancellationToken.ThrowIfCancellationRequested();
                }
            }

            ShowErrorList();
        }
        /// <summary>
        /// Finds all references to the specified entity.
        /// The results are reported using the callback.
        /// FindReferences may internally use parallelism, and may invoke the callback on multiple
        /// threads in parallel.
        /// </summary>
        public static async Task FindReferencesAsync(IEntity entity, IProgressMonitor progressMonitor, Action <SearchedFile> callback)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            if (progressMonitor == null)
            {
                throw new ArgumentNullException("progressMonitor");
            }
            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }
            SD.MainThread.VerifyAccess();
            if (SD.ParserService.LoadSolutionProjectsThread.IsRunning)
            {
                progressMonitor.ShowingDialog = true;
                MessageService.ShowMessage("${res:SharpDevelop.Refactoring.LoadSolutionProjectsThreadRunning}");
                progressMonitor.ShowingDialog = false;
                return;
            }
            double totalWorkAmount;
            List <ISymbolSearch> symbolSearches = PrepareSymbolSearch(entity, progressMonitor.CancellationToken, out totalWorkAmount);
            double workDone = 0;
            ParseableFileContentFinder parseableFileContentFinder = new ParseableFileContentFinder();

            foreach (ISymbolSearch s in symbolSearches)
            {
                progressMonitor.CancellationToken.ThrowIfCancellationRequested();
                using (var childProgressMonitor = progressMonitor.CreateSubTask(s.WorkAmount / totalWorkAmount)) {
                    await s.FindReferencesAsync(new SymbolSearchArgs(childProgressMonitor, parseableFileContentFinder), callback);
                }

                workDone += s.WorkAmount;
                progressMonitor.Progress = workDone / totalWorkAmount;
            }
        }
Exemplo n.º 8
0
			void RunThread()
			{
				while (true) {
					JobTask task;
					// copy fields from this class into local variables to ensure thread-safety
					// with concurrent Clear() calls
					double totalWork, workDone;
					IProgressMonitor progressMonitor;
					lock (lockObj) {
						// enqueued null: quit thread and restart (used for cancellation)
						if (actions.Count == 0 || this.actions.Peek() == null) {
							this.threadIsRunning = false;
							this.progressMonitor.Dispose();
							this.progressMonitor = null;
							// restart if necessary:
							if (actions.Count > 0) {
								actions.Dequeue(); // dequeue the null
								WorkbenchSingleton.SafeThreadAsyncCall(StartRunningIfRequired);
							}
							return;
						}
						task = this.actions.Dequeue();
						totalWork = this.totalWork;
						workDone = this.workDone;
						progressMonitor = this.progressMonitor;
					}
					progressMonitor.Progress = workDone / totalWork;
					progressMonitor.TaskName = task.name;
					try {
						using (IProgressMonitor subTask = progressMonitor.CreateSubTask(task.cost / totalWork)) {
							task.Run(subTask);
						}
						lock (lockObj) {
							this.workDone += task.cost;
						}
					} catch (OperationCanceledException) {
						// ignore cancellation
					} catch (Exception ex) {
						MessageService.ShowException(ex, "Error on LoadSolutionProjects thread");
					}
				}
			}
		/// <summary>
		/// Finds all references to the specified entity.
		/// The results are reported using the callback.
		/// FindReferences may internally use parallelism, and may invoke the callback on multiple
		/// threads in parallel.
		/// </summary>
		public static async Task FindReferencesAsync(IEntity entity, IProgressMonitor progressMonitor, Action<SearchedFile> callback)
		{
			if (entity == null)
				throw new ArgumentNullException("entity");
			if (progressMonitor == null)
				throw new ArgumentNullException("progressMonitor");
			if (callback == null)
				throw new ArgumentNullException("callback");
			SD.MainThread.VerifyAccess();
			if (SD.ParserService.LoadSolutionProjectsThread.IsRunning) {
				progressMonitor.ShowingDialog = true;
				MessageService.ShowMessage("${res:SharpDevelop.Refactoring.LoadSolutionProjectsThreadRunning}");
				progressMonitor.ShowingDialog = false;
				return;
			}
			double totalWorkAmount;
			List<ISymbolSearch> symbolSearches = PrepareSymbolSearch(entity, progressMonitor.CancellationToken, out totalWorkAmount);
			double workDone = 0;
			ParseableFileContentFinder parseableFileContentFinder = new ParseableFileContentFinder();
			foreach (ISymbolSearch s in symbolSearches) {
				progressMonitor.CancellationToken.ThrowIfCancellationRequested();
				using (var childProgressMonitor = progressMonitor.CreateSubTask(s.WorkAmount / totalWorkAmount)) {
					await s.FindReferencesAsync(new SymbolSearchArgs(childProgressMonitor, parseableFileContentFinder), callback);
				}
				
				workDone += s.WorkAmount;
				progressMonitor.Progress = workDone / totalWorkAmount;
			}
		}
Exemplo n.º 10
0
		public static async Task RenameSymbolAsync(ISymbol symbol, string newName, IProgressMonitor progressMonitor, Action<Error> errorCallback)
		{
			if (symbol == null)
				throw new ArgumentNullException("symbol");
			if (progressMonitor == null)
				throw new ArgumentNullException("progressMonitor");
			SD.MainThread.VerifyAccess();
			if (SD.ParserService.LoadSolutionProjectsThread.IsRunning) {
				progressMonitor.ShowingDialog = true;
				MessageService.ShowMessage("${res:SharpDevelop.Refactoring.LoadSolutionProjectsThreadRunning}");
				progressMonitor.ShowingDialog = false;
				return;
			}
			double totalWorkAmount;
			List<ISymbolSearch> symbolSearches = PrepareSymbolSearch(symbol, progressMonitor.CancellationToken, out totalWorkAmount);
			double workDone = 0;
			ParseableFileContentFinder parseableFileContentFinder = new ParseableFileContentFinder();
			var errors = new List<Error>();
			var changes = new List<PatchedFile>();
			foreach (ISymbolSearch s in symbolSearches) {
				progressMonitor.CancellationToken.ThrowIfCancellationRequested();
				using (var childProgressMonitor = progressMonitor.CreateSubTask(s.WorkAmount / totalWorkAmount)) {
					var args = new SymbolRenameArgs(newName, childProgressMonitor, parseableFileContentFinder);
					args.ProvideHighlightedLine = false;
					await s.RenameAsync(args, file => changes.Add(file), error => errors.Add(error));
				}
				
				workDone += s.WorkAmount;
				progressMonitor.Progress = workDone / totalWorkAmount;
			}
			if (errors.Count == 0) {
				foreach (var file in changes) {
					ApplyChanges(file);
				}
			} else {
				foreach (var error in errors) {
					errorCallback(error);
				}
			}
		}
Exemplo n.º 11
0
		static ProjectSection SetupSolutionLoadSolutionProjects(Solution newSolution, StreamReader sr, IProgressMonitor progressMonitor)
		{
			if (progressMonitor == null)
				throw new ArgumentNullException("progressMonitor");
			
			string solutionDirectory = Path.GetDirectoryName(newSolution.FileName);
			
			ProjectSection nestedProjectsSection = null;
			IList<ProjectLoadInformation> projectsToLoad = new List<ProjectLoadInformation>();
			IList<IList<ProjectSection>> readProjectSections = new List<IList<ProjectSection>>();
			
			// process the solution file contents
			while (true) {
				string line = sr.ReadLine();
				
				if (line == null) {
					break;
				}
				Match match = projectLinePattern.Match(line);
				if (match.Success) {
					string projectGuid  = match.Result("${ProjectGuid}");
					string title        = match.Result("${Title}");
					string location     = match.Result("${Location}");
					string guid         = match.Result("${Guid}");
					
					if (!FileUtility.IsUrl(location)) {
						location = FileUtility.NormalizePath(Path.Combine(solutionDirectory, location));
					}
					
					if (projectGuid == FolderGuid) {
						SolutionFolder newFolder = SolutionFolder.ReadFolder(sr, title, location, guid);
						newSolution.AddFolder(newFolder);
					} else {
						ProjectLoadInformation loadInfo = new ProjectLoadInformation(newSolution, location, title);
						loadInfo.TypeGuid = projectGuid;
						loadInfo.Guid = guid;
						projectsToLoad.Add(loadInfo);
						IList<ProjectSection> currentProjectSections = new List<ProjectSection>();
						ReadProjectSections(sr, currentProjectSections);
						readProjectSections.Add(currentProjectSections);
					}
					match = match.NextMatch();
				} else {
					match = globalSectionPattern.Match(line);
					if (match.Success) {
						ProjectSection newSection = ProjectSection.ReadGlobalSection(sr, match.Result("${Name}"), match.Result("${Type}"));
						// Don't put the NestedProjects section into the global sections list
						// because it's transformed to a tree representation and the tree representation
						// is transformed back to the NestedProjects section during save.
						if (newSection.Name == "NestedProjects") {
							nestedProjectsSection = newSection;
						} else {
							newSolution.Sections.Add(newSection);
						}
					}
				}
			}
			// load projects
			for(int i=0; i<projectsToLoad.Count; i++) {
				ProjectLoadInformation loadInfo = projectsToLoad[i];
				IList<ProjectSection> projectSections = readProjectSections[i];
				loadInfo.ProjectSections = projectSections;
				
				// set the target platform
				SolutionItem projectConfig = newSolution.GetProjectConfiguration(loadInfo.Guid);
				loadInfo.Platform = AbstractProject.GetPlatformNameFromKey(projectConfig.Location);
				
				loadInfo.ProgressMonitor = progressMonitor;
				progressMonitor.Progress = (double)i / projectsToLoad.Count;
				progressMonitor.TaskName = "Loading " + loadInfo.ProjectName;
				
				using (IProgressMonitor nestedProgressMonitor = progressMonitor.CreateSubTask(1.0 / projectsToLoad.Count)) {
					loadInfo.ProgressMonitor = nestedProgressMonitor;
					IProject newProject = ProjectBindingService.LoadProject(loadInfo);
					newProject.IdGuid = loadInfo.Guid;
					newProject.ProjectSections.AddRange(projectSections);
					newSolution.AddFolder(newProject);
				}
			}
			return nestedProjectsSection;
		}
Exemplo n.º 12
0
		void Initialize(IProgressMonitor progressMonitor, List<FileName> filesToParse)
		{
			IReadOnlyCollection<ProjectItem> projectItems = project.Items.CreateSnapshot();
			lock (lockObj) {
				if (disposed) {
					return;
				}
			}

			double scalingFactor = 1.0 / (projectItems.Count + LoadingReferencesWorkAmount);
			using (IProgressMonitor initReferencesProgressMonitor = progressMonitor.CreateSubTask(LoadingReferencesWorkAmount * scalingFactor),
			       parseProgressMonitor = progressMonitor.CreateSubTask(projectItems.Count * scalingFactor))
			{
				var resolveReferencesTask = Task.Run(
					delegate {
						DoResolveReferences(initReferencesProgressMonitor);
					}, initReferencesProgressMonitor.CancellationToken);
				
				ParseFiles(filesToParse, parseProgressMonitor);
				
				resolveReferencesTask.Wait();
			}
		}
Exemplo n.º 13
0
		public void ReadSolution(Solution solution, IProgressMonitor progress)
		{
			ReadFormatHeader();
			ReadVersionProperties(solution);
			
			// Read solution folder and project entries:
			var solutionEntries = new List<ProjectLoadInformation>();
			var projectInfoDict = new Dictionary<Guid, ProjectLoadInformation>();
			var solutionFolderDict = new Dictionary<Guid, SolutionFolder>();
			int projectCount = 0;
			bool fixedGuidConflicts = false;
			
			ProjectLoadInformation information;
			while ((information = ReadProjectEntry(solution)) != null) {
				solutionEntries.Add(information);
				if (projectInfoDict.ContainsKey(information.IdGuid)) {
					// resolve GUID conflicts
					SD.Log.WarnFormatted("Detected duplicate GUID in .sln file: {0} is used for {1} and {2}", information.IdGuid, information.ProjectName, projectInfoDict[information.IdGuid].ProjectName);
					information.IdGuid = Guid.NewGuid();
					fixedGuidConflicts = true;
				}
				projectInfoDict.Add(information.IdGuid, information);
				
				if (information.TypeGuid == ProjectTypeGuids.SolutionFolder) {
					solutionFolderDict.Add(information.IdGuid, CreateSolutionFolder(solution, information));
				} else {
					projectCount++;
				}
			}
			
			progress.CancellationToken.ThrowIfCancellationRequested();
			
			// Read global sections:
			if (currentLine != "Global") {
				if (currentLine == null)
					throw Error("Unexpected end of file");
				else
					throw Error("Unknown line: " + currentLine);
			}
			NextLine();
			
			Dictionary<Guid, SolutionFolder> guidToParentFolderDict = null;
			
			SolutionSection section;
			while ((section = ReadSection(isGlobal: true)) != null) {
				switch (section.SectionName) {
					case "SolutionConfigurationPlatforms":
						var configurations = LoadSolutionConfigurations(section);
						foreach (var config in configurations.Select(c => c.Configuration).Distinct(ConfigurationAndPlatform.ConfigurationNameComparer))
							solution.ConfigurationNames.Add(config, null);
						foreach (var platform in configurations.Select(c => c.Platform).Distinct(ConfigurationAndPlatform.ConfigurationNameComparer))
							solution.PlatformNames.Add(platform, null);
						break;
					case "ProjectConfigurationPlatforms":
						LoadProjectConfigurations(section, projectInfoDict);
						break;
					case "NestedProjects":
						guidToParentFolderDict = LoadNesting(section, solutionFolderDict);
						break;
					default:
						solution.GlobalSections.Add(section);
						break;
				}
			}
			if (currentLine != "EndGlobal")
				throw Error("Expected 'EndGlobal'");
			NextLine();
			if (currentLine != null)
				throw Error("Expected end of file");
			
			solution.LoadPreferences();
			
			// Now that the project configurations have been set, we can actually load the projects:
			int projectsLoaded = 0;
			foreach (var projectInfo in solutionEntries) {
				// Make copy of IdGuid just in case the project binding writes to projectInfo.IdGuid
				Guid idGuid = projectInfo.IdGuid;
				ISolutionItem solutionItem;
				if (projectInfo.TypeGuid == ProjectTypeGuids.SolutionFolder) {
					solutionItem = solutionFolderDict[idGuid];
				} else {
					// Load project:
					projectInfo.ActiveProjectConfiguration = projectInfo.ConfigurationMapping.GetProjectConfiguration(solution.ActiveConfiguration);
					progress.TaskName = "Loading " + projectInfo.ProjectName;
					using (projectInfo.ProgressMonitor = progress.CreateSubTask(1.0 / projectCount)) {
						solutionItem = LoadProjectWithErrorHandling(projectInfo);
					}
					if (solutionItem.IdGuid != idGuid) {
						Guid projectFileGuid = solutionItem.IdGuid;
						if (!projectInfoDict.ContainsKey(projectFileGuid)) {
							// We'll use the GUID from the project file.
							// Register that GUID in the dictionary to avoid its use by multiple projects.
							projectInfoDict.Add(projectFileGuid, projectInfo);
						} else {
							// Cannot use GUID from project file due to conflict.
							// To fix the problem without potentially introducing new conflicts in other .sln files that contain the project,
							// we generate a brand new GUID:
							solutionItem.IdGuid = Guid.NewGuid();
						}
						SD.Log.WarnFormatted("<ProjectGuid> in project '{0}' is '{1}' and does not match the GUID stored in the solution ({2}). "
						                     + "The conflict was resolved using the GUID {3}",
						                     projectInfo.ProjectName, projectFileGuid, idGuid, solutionItem.IdGuid);
						fixedGuidConflicts = true;
					}
					projectsLoaded++;
					progress.Progress = (double)projectsLoaded / projectCount;
				}
				// Add solutionItem to solution:
				SolutionFolder folder;
				if (guidToParentFolderDict != null && guidToParentFolderDict.TryGetValue(idGuid, out folder)) {
					folder.Items.Add(solutionItem);
				} else {
					solution.Items.Add(solutionItem);
				}
			}
			
			solution.IsDirty = fixedGuidConflicts; // reset IsDirty=false unless we've fixed GUID conflicts
		}
Exemplo n.º 14
0
        public void ReadSolution(Solution solution, IProgressMonitor progress)
        {
            ReadFormatHeader();
            ReadVersionProperties(solution);

            // Read solution folder and project entries:
            var  solutionEntries    = new List <ProjectLoadInformation>();
            var  projectInfoDict    = new Dictionary <Guid, ProjectLoadInformation>();
            var  solutionFolderDict = new Dictionary <Guid, SolutionFolder>();
            int  projectCount       = 0;
            bool fixedGuidConflicts = false;

            ProjectLoadInformation information;

            while ((information = ReadProjectEntry(solution)) != null)
            {
                solutionEntries.Add(information);
                if (projectInfoDict.ContainsKey(information.IdGuid))
                {
                    // resolve GUID conflicts
                    SD.Log.WarnFormatted("Detected duplicate GUID in .sln file: {0} is used for {1} and {2}", information.IdGuid, information.ProjectName, projectInfoDict[information.IdGuid].ProjectName);
                    information.IdGuid = Guid.NewGuid();
                    fixedGuidConflicts = true;
                }
                projectInfoDict.Add(information.IdGuid, information);

                if (information.TypeGuid == ProjectTypeGuids.SolutionFolder)
                {
                    solutionFolderDict.Add(information.IdGuid, CreateSolutionFolder(solution, information));
                }
                else
                {
                    projectCount++;
                }
            }

            progress.CancellationToken.ThrowIfCancellationRequested();

            // Read global sections:
            if (currentLine != "Global")
            {
                if (currentLine == null)
                {
                    throw Error("Unexpected end of file");
                }
                else
                {
                    throw Error("Unknown line: " + currentLine);
                }
            }
            NextLine();

            Dictionary <Guid, SolutionFolder> guidToParentFolderDict = null;

            SolutionSection section;

            while ((section = ReadSection(isGlobal: true)) != null)
            {
                switch (section.SectionName)
                {
                case "SolutionConfigurationPlatforms":
                    var configurations = LoadSolutionConfigurations(section);
                    foreach (var config in configurations.Select(c => c.Configuration).Distinct(ConfigurationAndPlatform.ConfigurationNameComparer))
                    {
                        solution.ConfigurationNames.Add(config, null);
                    }
                    foreach (var platform in configurations.Select(c => c.Platform).Distinct(ConfigurationAndPlatform.ConfigurationNameComparer))
                    {
                        solution.PlatformNames.Add(platform, null);
                    }
                    break;

                case "ProjectConfigurationPlatforms":
                    LoadProjectConfigurations(section, projectInfoDict);
                    break;

                case "NestedProjects":
                    guidToParentFolderDict = LoadNesting(section, solutionFolderDict);
                    break;

                default:
                    solution.GlobalSections.Add(section);
                    break;
                }
            }
            if (currentLine != "EndGlobal")
            {
                throw Error("Expected 'EndGlobal'");
            }
            NextLine();
            if (currentLine != null)
            {
                throw Error("Expected end of file");
            }

            solution.LoadPreferences();

            // Now that the project configurations have been set, we can actually load the projects:
            int projectsLoaded = 0;

            foreach (var projectInfo in solutionEntries)
            {
                // Make copy of IdGuid just in case the project binding writes to projectInfo.IdGuid
                Guid          idGuid = projectInfo.IdGuid;
                ISolutionItem solutionItem;
                if (projectInfo.TypeGuid == ProjectTypeGuids.SolutionFolder)
                {
                    solutionItem = solutionFolderDict[idGuid];
                }
                else
                {
                    // Load project:
                    projectInfo.ActiveProjectConfiguration = projectInfo.ConfigurationMapping.GetProjectConfiguration(solution.ActiveConfiguration);
                    progress.TaskName = "Loading " + projectInfo.ProjectName;
                    using (projectInfo.ProgressMonitor = progress.CreateSubTask(1.0 / projectCount)) {
                        solutionItem = LoadProjectWithErrorHandling(projectInfo);
                    }
                    if (solutionItem.IdGuid != idGuid)
                    {
                        Guid projectFileGuid = solutionItem.IdGuid;
                        if (!projectInfoDict.ContainsKey(projectFileGuid))
                        {
                            // We'll use the GUID from the project file.
                            // Register that GUID in the dictionary to avoid its use by multiple projects.
                            projectInfoDict.Add(projectFileGuid, projectInfo);
                        }
                        else
                        {
                            // Cannot use GUID from project file due to conflict.
                            // To fix the problem without potentially introducing new conflicts in other .sln files that contain the project,
                            // we generate a brand new GUID:
                            solutionItem.IdGuid = Guid.NewGuid();
                        }
                        SD.Log.WarnFormatted("<ProjectGuid> in project '{0}' is '{1}' and does not match the GUID stored in the solution ({2}). "
                                             + "The conflict was resolved using the GUID {3}",
                                             projectInfo.ProjectName, projectFileGuid, idGuid, solutionItem.IdGuid);
                        fixedGuidConflicts = true;
                    }
                    projectsLoaded++;
                    progress.Progress = (double)projectsLoaded / projectCount;
                }
                // Add solutionItem to solution:
                SolutionFolder folder;
                if (guidToParentFolderDict != null && guidToParentFolderDict.TryGetValue(idGuid, out folder))
                {
                    folder.Items.Add(solutionItem);
                }
                else
                {
                    solution.Items.Add(solutionItem);
                }
            }

            solution.IsDirty = fixedGuidConflicts;             // reset IsDirty=false unless we've fixed GUID conflicts
        }
Exemplo n.º 15
0
		public void ReadSolution(Solution solution, IProgressMonitor progress)
		{
			ReadFormatHeader();
			ReadVersionProperties(solution);
			
			// Read solution folder and project entries:
			var solutionEntries = new List<ProjectLoadInformation>();
			var projectInfoDict = new Dictionary<Guid, ProjectLoadInformation>();
			var solutionFolderDict = new Dictionary<Guid, SolutionFolder>();
			int projectCount = 0;
			bool fixedGuidConflicts = false;
			
			ProjectLoadInformation information;
			while ((information = ReadProjectEntry(solution)) != null) {
				solutionEntries.Add(information);
				if (projectInfoDict.ContainsKey(information.IdGuid)) {
					// resolve GUID conflicts
					information.IdGuid = Guid.NewGuid();
					fixedGuidConflicts = true;
				}
				projectInfoDict.Add(information.IdGuid, information);
				
				if (information.TypeGuid == ProjectTypeGuids.SolutionFolder) {
					solutionFolderDict.Add(information.IdGuid, CreateSolutionFolder(solution, information));
				} else {
					projectCount++;
				}
			}
			
			progress.CancellationToken.ThrowIfCancellationRequested();
			
			// Read global sections:
			if (currentLine != "Global") {
				if (currentLine == null)
					throw Error("Unexpected end of file");
				else
					throw Error("Unknown line: " + currentLine);
			}
			NextLine();
			
			Dictionary<Guid, SolutionFolder> guidToParentFolderDict = null;
			
			SolutionSection section;
			while ((section = ReadSection(isGlobal: true)) != null) {
				switch (section.SectionName) {
					case "SolutionConfigurationPlatforms":
						var configurations = LoadSolutionConfigurations(section);
						foreach (var config in configurations.Select(c => c.Configuration).Distinct(ConfigurationAndPlatform.ConfigurationNameComparer))
							solution.ConfigurationNames.Add(config, null);
						foreach (var platform in configurations.Select(c => c.Platform).Distinct(ConfigurationAndPlatform.ConfigurationNameComparer))
							solution.PlatformNames.Add(platform, null);
						break;
					case "ProjectConfigurationPlatforms":
						LoadProjectConfigurations(section, projectInfoDict);
						break;
					case "NestedProjects":
						guidToParentFolderDict = LoadNesting(section, solutionFolderDict);
						break;
					default:
						solution.GlobalSections.Add(section);
						break;
				}
			}
			if (currentLine != "EndGlobal")
				throw Error("Expected 'EndGlobal'");
			NextLine();
			if (currentLine != null)
				throw Error("Expected end of file");
			
			solution.LoadPreferences();
			
			// Now that the project configurations have been set, we can actually load the projects:
			int projectsLoaded = 0;
			foreach (var projectInfo in solutionEntries) {
				ISolutionItem solutionItem;
				if (projectInfo.TypeGuid == ProjectTypeGuids.SolutionFolder) {
					solutionItem = solutionFolderDict[projectInfo.IdGuid];
				} else {
					// Load project:
					projectInfo.ActiveProjectConfiguration = projectInfo.ConfigurationMapping.GetProjectConfiguration(solution.ActiveConfiguration);
					progress.TaskName = "Loading " + projectInfo.ProjectName;
					using (projectInfo.ProgressMonitor = progress.CreateSubTask(1.0 / projectCount)) {
						solutionItem = ProjectBindingService.LoadProject(projectInfo);
					}
					projectsLoaded++;
					progress.Progress = (double)projectsLoaded / projectCount;
				}
				// Add solutionItem to solution:
				SolutionFolder folder;
				if (guidToParentFolderDict != null && guidToParentFolderDict.TryGetValue(projectInfo.IdGuid, out folder)) {
					folder.Items.Add(solutionItem);
				} else {
					solution.Items.Add(solutionItem);
				}
			}
			
			solution.IsDirty = fixedGuidConflicts; // reset IsDirty=false unless we've fixed GUID conflicts
		}