public override bool TryApplyChanges(Microsoft.CodeAnalysis.Solution newSolution)
        {
            // first make sure we can edit the document we will be updating (check them out from source control, etc)
            var changedDocs = newSolution.GetChanges(this.CurrentSolution).GetProjectChanges().SelectMany(pd => pd.GetChangedDocuments()).ToList();

            if (changedDocs.Count > 0)
            {
                this.EnsureEditableDocuments(changedDocs);
            }

            return(base.TryApplyChanges(newSolution));
        }
Beispiel #2
0
        internal override bool TryApplyChanges(
            Microsoft.CodeAnalysis.Solution newSolution,
            IProgressTracker progressTracker)
        {
            if (_foregroundObject.IsValueCreated && !_foregroundObject.Value.IsForeground())
            {
                throw new InvalidOperationException(ServicesVSResources.VisualStudioWorkspace_TryApplyChanges_cannot_be_called_from_a_background_thread);
            }

            var projectChanges = newSolution.GetChanges(this.CurrentSolution).GetProjectChanges().ToList();
            var projectsToLoad = new HashSet <Guid>();

            foreach (var pc in projectChanges)
            {
                if (pc.GetAddedAdditionalDocuments().Any() ||
                    pc.GetAddedAnalyzerReferences().Any() ||
                    pc.GetAddedDocuments().Any() ||
                    pc.GetAddedMetadataReferences().Any() ||
                    pc.GetAddedProjectReferences().Any() ||
                    pc.GetRemovedAdditionalDocuments().Any() ||
                    pc.GetRemovedAnalyzerReferences().Any() ||
                    pc.GetRemovedDocuments().Any() ||
                    pc.GetRemovedMetadataReferences().Any() ||
                    pc.GetRemovedProjectReferences().Any())
                {
                    projectsToLoad.Add(GetHostProject(pc.ProjectId).Guid);
                }
            }

            if (projectsToLoad.Any())
            {
                var vsSolution4 = (IVsSolution4)DeferredState.ServiceProvider.GetService(typeof(SVsSolution));
                vsSolution4.EnsureProjectsAreLoaded(
                    (uint)projectsToLoad.Count,
                    projectsToLoad.ToArray(),
                    (uint)__VSBSLFLAGS.VSBSLFLAGS_None);
            }

            // first make sure we can edit the document we will be updating (check them out from source control, etc)
            var changedDocs = projectChanges.SelectMany(pd => pd.GetChangedDocuments()).ToList();

            if (changedDocs.Count > 0)
            {
                this.EnsureEditableDocuments(changedDocs);
            }

            return(base.TryApplyChanges(newSolution, progressTracker));
        }
			static IEnumerable<DocumentId> GetChangedDocuments (Solution newSolution, Solution oldSolution)
			{
				if (newSolution != null) {
					var solutionChanges = newSolution.GetChanges (oldSolution);
					foreach (var projectChanges in solutionChanges.GetProjectChanges ()) {
						foreach (var documentId in projectChanges.GetChangedDocuments ()) {
							yield return documentId;
						}
					}
				}
			}
            private async Task<Solution> CleanSolutionAsync(Solution newSolution, Solution oldSolution, CancellationToken cancellationToken)
            {
                var solution = newSolution;

                foreach (var projectChange in newSolution.GetChanges(oldSolution).GetProjectChanges())
                {
                    foreach (var documentId in projectChange.GetChangedDocuments())
                    {
                        solution = await CleanSolutionDocument(solution, documentId, cancellationToken);
                    }
                }

                return solution;
            }
        public static async Task<IEnumerable<ModifiedFileResponse>> GetFileChangesAsync(Solution newSolution, Solution oldSolution, string newFileDirectory, bool wantTextChanges)
        {
            var changes = new Dictionary<string, ModifiedFileResponse>();
            var solutionChanges = newSolution.GetChanges(oldSolution);
            foreach (var projectChange in solutionChanges.GetProjectChanges())
            {
                foreach (var changedDocumentId in projectChange.GetAddedDocuments())
                {
                    var document = newSolution.GetDocument(changedDocumentId);
                    var source = await document.GetTextAsync();
                    var modifiedFileResponse = new ModifiedFileResponse(document.Name);
                    var change = new LinePositionSpanTextChange();
                    change.NewText = source.ToString();
                    var newPath = Path.Combine(newFileDirectory, document.Name);
                    modifiedFileResponse.FileName = newPath;
                    modifiedFileResponse.Changes = new[] { change };
                    changes[newPath] = modifiedFileResponse;

                    // This is a little weird. The added document doesn't have a filepath
                    // and we need one so that future operations on this document work
                    var id = DocumentId.CreateNewId(document.Project.Id);
                    var version = VersionStamp.Create();
                    var documentInfo = DocumentInfo.Create(id, document.Name, filePath: newPath, loader: TextLoader.From(TextAndVersion.Create(source, version)));

                    var workspace = newSolution.Workspace as OmnisharpWorkspace;
                    workspace.RemoveDocument(changedDocumentId);
                    workspace.AddDocument(documentInfo);
                }

                foreach (var changedDocumentId in projectChange.GetChangedDocuments())
                {
                    var changedDocument = newSolution.GetDocument(changedDocumentId);
                    ModifiedFileResponse modifiedFileResponse;
                    var filePath = changedDocument.FilePath;

                    if (!changes.TryGetValue(filePath, out modifiedFileResponse))
                    {
                        modifiedFileResponse = new ModifiedFileResponse(filePath);
                        changes[filePath] = modifiedFileResponse;
                    }

                    if (!wantTextChanges)
                    {
                        var changedText = await changedDocument.GetTextAsync();
                        modifiedFileResponse.Buffer = changedText.ToString();
                    }
                    else
                    {
                        var originalDocument = oldSolution.GetDocument(changedDocumentId);
                        IEnumerable<TextChange> textChanges;
                        textChanges = await changedDocument.GetTextChangesAsync(originalDocument);
                        var linePositionSpanTextChanges = await LinePositionSpanTextChange.Convert(originalDocument, textChanges);

                        modifiedFileResponse.Changes = modifiedFileResponse.Changes != null
                            ? modifiedFileResponse.Changes.Union(linePositionSpanTextChanges)
                            : linePositionSpanTextChanges;
                    }
                }
            }
            return changes.Values;
        }
Beispiel #6
0
        internal static ProjectDependencyGraph From(Solution newSolution, ProjectDependencyGraph oldGraph, CancellationToken cancellationToken)
        {
            var oldSolution = oldGraph.Solution;

            if (oldSolution == newSolution)
            {
                return(oldGraph);
            }

            // in case old and new are incompatible just build it the hard way
            if (oldSolution.Id != newSolution.Id)
            {
                return(From(newSolution, cancellationToken));
            }

            var map         = oldGraph.projectToProjectsItReferencesMap;
            var reverseMap  = oldGraph.projectToProjectsThatReferenceItMap;
            var differences = newSolution.GetChanges(oldSolution);

            // remove projects that no longer occur in new solution
            foreach (var project in differences.GetRemovedProjects())
            {
                cancellationToken.ThrowIfCancellationRequested();
                ImmutableHashSet <ProjectId> referencedProjectIds;
                if (oldGraph.projectToProjectsItReferencesMap.TryGetValue(project.Id, out referencedProjectIds))
                {
                    map        = map.Remove(project.Id);
                    reverseMap = reverseMap.RemoveAll(referencedProjectIds, project.Id);
                }
            }

            // add projects that don't occur in old solution
            foreach (var project in differences.GetAddedProjects())
            {
                cancellationToken.ThrowIfCancellationRequested();
                var referencedProjectIds = project.ProjectReferences.Select(p => p.ProjectId);
                map        = map.Add(project.Id, ImmutableHashSet.CreateRange <ProjectId>(referencedProjectIds));
                reverseMap = reverseMap.AddAll(referencedProjectIds, project.Id);
            }

            // update projects that are changed.
            foreach (var projectChanges in differences.GetProjectChanges().Where(pc => pc.OldProject.AllProjectReferences != pc.NewProject.AllProjectReferences))
            {
                var projectId = projectChanges.ProjectId;

                cancellationToken.ThrowIfCancellationRequested();
                ImmutableHashSet <ProjectId> oldReferencedProjectIds;
                if (oldGraph.projectToProjectsItReferencesMap.TryGetValue(projectId, out oldReferencedProjectIds))
                {
                    map        = map.Remove(projectId);
                    reverseMap = reverseMap.RemoveAll(oldReferencedProjectIds, projectId);
                }

                var newReferencedProjectIds = newSolution.GetProject(projectId).ProjectReferences.Select(p => p.ProjectId);
                map        = map.Add(projectId, ImmutableHashSet.CreateRange <ProjectId>(newReferencedProjectIds));
                reverseMap = reverseMap.AddAll(newReferencedProjectIds, projectId);
            }

            var version = newSolution.GetLatestProjectVersion();

            return(new ProjectDependencyGraph(newSolution, version, map, reverseMap));
        }