internal static void ProjectStateEqual(IRemotableDataService service, ProjectStateChecksums projectObjects1, ProjectStateChecksums projectObjects2) { ChecksumWithChildrenEqual(projectObjects1, projectObjects2); ChecksumWithChildrenEqual(projectObjects1.Documents.ToDocumentObjects(service), projectObjects2.Documents.ToDocumentObjects(service)); ChecksumWithChildrenEqual(projectObjects1.AdditionalDocuments.ToDocumentObjects(service), projectObjects2.AdditionalDocuments.ToDocumentObjects(service)); }
private async Task <Solution> UpdateProjectAsync(Project project, ProjectStateChecksums oldProjectChecksums, ProjectStateChecksums newProjectChecksums) { // changed info if (oldProjectChecksums.Info != newProjectChecksums.Info) { project = await UpdateProjectInfoAsync(project, newProjectChecksums.Info).ConfigureAwait(false); } // changed compilation options if (oldProjectChecksums.CompilationOptions != newProjectChecksums.CompilationOptions) { project = project.WithCompilationOptions( FixUpCompilationOptions( project.State.ProjectInfo.Attributes, await _assetService.GetAssetAsync <CompilationOptions>( newProjectChecksums.CompilationOptions, _cancellationToken).ConfigureAwait(false))); } // changed parse options if (oldProjectChecksums.ParseOptions != newProjectChecksums.ParseOptions) { project = project.WithParseOptions(await _assetService.GetAssetAsync <ParseOptions>(newProjectChecksums.ParseOptions, _cancellationToken).ConfigureAwait(false)); } // changed project references if (oldProjectChecksums.ProjectReferences.Checksum != newProjectChecksums.ProjectReferences.Checksum) { project = project.WithProjectReferences(await CreateCollectionAsync <ProjectReference>(newProjectChecksums.ProjectReferences).ConfigureAwait(false)); } // changed metadata references if (oldProjectChecksums.MetadataReferences.Checksum != newProjectChecksums.MetadataReferences.Checksum) { project = project.WithMetadataReferences(await CreateCollectionAsync <MetadataReference>(newProjectChecksums.MetadataReferences).ConfigureAwait(false)); } // changed analyzer references if (oldProjectChecksums.AnalyzerReferences.Checksum != newProjectChecksums.AnalyzerReferences.Checksum) { project = project.WithAnalyzerReferences(await CreateCollectionAsync <AnalyzerReference>(newProjectChecksums.AnalyzerReferences).ConfigureAwait(false)); } // changed analyzer references if (oldProjectChecksums.Documents.Checksum != newProjectChecksums.Documents.Checksum) { project = await UpdateDocumentsAsync(project, oldProjectChecksums.Documents, newProjectChecksums.Documents, additionalText : false).ConfigureAwait(false); } // changed analyzer references if (oldProjectChecksums.AdditionalDocuments.Checksum != newProjectChecksums.AdditionalDocuments.Checksum) { project = await UpdateDocumentsAsync(project, oldProjectChecksums.AdditionalDocuments, newProjectChecksums.AdditionalDocuments, additionalText : true).ConfigureAwait(false); } return(project.Solution); }
internal static async Task VerifyAssetAsync(IRemotableDataService service, ProjectStateChecksums projectObject) { var info = await VerifyAssetSerializationAsync <ProjectInfo.ProjectAttributes>( service, projectObject.Info, WellKnownSynchronizationKind.ProjectAttributes, (v, k, s) => new SolutionAsset(s.CreateChecksum(v, CancellationToken.None), v, s)).ConfigureAwait(false); await VerifyAssetSerializationAsync <CompilationOptions>( service, projectObject.CompilationOptions, WellKnownSynchronizationKind.CompilationOptions, (v, k, s) => new SolutionAsset(s.CreateChecksum(v, CancellationToken.None), v, s)); await VerifyAssetSerializationAsync <ParseOptions>( service, projectObject.ParseOptions, WellKnownSynchronizationKind.ParseOptions, (v, k, s) => new SolutionAsset(s.CreateChecksum(v, CancellationToken.None), v, s)); foreach (var checksum in projectObject.Documents) { var documentObject = await service.GetValueAsync <DocumentStateChecksums>(checksum).ConfigureAwait(false); await VerifyAssetAsync(service, documentObject).ConfigureAwait(false); } foreach (var checksum in projectObject.ProjectReferences) { await VerifyAssetSerializationAsync <ProjectReference>( service, checksum, WellKnownSynchronizationKind.ProjectReference, (v, k, s) => new SolutionAsset(s.CreateChecksum(v, CancellationToken.None), v, s)); } foreach (var checksum in projectObject.MetadataReferences) { await VerifyAssetSerializationAsync <MetadataReference>( service, checksum, WellKnownSynchronizationKind.MetadataReference, (v, k, s) => new SolutionAsset(s.CreateChecksum(v, CancellationToken.None), v, s)); } foreach (var checksum in projectObject.AnalyzerReferences) { await VerifyAssetSerializationAsync <AnalyzerReference>( service, checksum, WellKnownSynchronizationKind.AnalyzerReference, (v, k, s) => new SolutionAsset(s.CreateChecksum(v, CancellationToken.None), v, s)); } foreach (var checksum in projectObject.AdditionalDocuments) { var documentObject = await service.GetValueAsync <DocumentStateChecksums>(checksum).ConfigureAwait(false); await VerifyAssetAsync(service, documentObject).ConfigureAwait(false); } foreach (var checksum in projectObject.AnalyzerConfigDocuments) { var documentObject = await service.GetValueAsync <DocumentStateChecksums>(checksum).ConfigureAwait(false); await VerifyAssetAsync(service, documentObject).ConfigureAwait(false); } }
internal static void VerifySnapshotInService( IRemotableDataService snapshotService, ProjectStateChecksums projectObject, int expectedDocumentCount, int expectedProjectReferenceCount, int expectedMetadataReferenceCount, int expectedAnalyzerReferenceCount, int expectedAdditionalDocumentCount) { VerifyChecksumInService(snapshotService, projectObject.Checksum, projectObject.GetWellKnownSynchronizationKind()); VerifyChecksumInService(snapshotService, projectObject.Info, WellKnownSynchronizationKind.ProjectAttributes); VerifyChecksumInService(snapshotService, projectObject.CompilationOptions, WellKnownSynchronizationKind.CompilationOptions); VerifyChecksumInService(snapshotService, projectObject.ParseOptions, WellKnownSynchronizationKind.ParseOptions); VerifyCollectionInService(snapshotService, projectObject.Documents.ToDocumentObjects(snapshotService), expectedDocumentCount); VerifyCollectionInService(snapshotService, projectObject.ProjectReferences, expectedProjectReferenceCount, WellKnownSynchronizationKind.ProjectReference); VerifyCollectionInService(snapshotService, projectObject.MetadataReferences, expectedMetadataReferenceCount, WellKnownSynchronizationKind.MetadataReference); VerifyCollectionInService(snapshotService, projectObject.AnalyzerReferences, expectedAnalyzerReferenceCount, WellKnownSynchronizationKind.AnalyzerReference); VerifyCollectionInService(snapshotService, projectObject.AdditionalDocuments.ToDocumentObjects(snapshotService), expectedAdditionalDocumentCount); }
private async Task <Solution> UpdateProjectAsync(Project project, ProjectStateChecksums oldProjectChecksums, ProjectStateChecksums newProjectChecksums) { // changed info if (oldProjectChecksums.Info != newProjectChecksums.Info) { project = await UpdateProjectInfoAsync(project, newProjectChecksums.Info).ConfigureAwait(false); } // changed compilation options if (oldProjectChecksums.CompilationOptions != newProjectChecksums.CompilationOptions) { project = project.WithCompilationOptions( project.State.ProjectInfo.Attributes.FixUpCompilationOptions( await _assetProvider.GetAssetAsync <CompilationOptions>( newProjectChecksums.CompilationOptions, _cancellationToken).ConfigureAwait(false))); } // changed parse options if (oldProjectChecksums.ParseOptions != newProjectChecksums.ParseOptions) { project = project.WithParseOptions(await _assetProvider.GetAssetAsync <ParseOptions>(newProjectChecksums.ParseOptions, _cancellationToken).ConfigureAwait(false)); } // changed project references if (oldProjectChecksums.ProjectReferences.Checksum != newProjectChecksums.ProjectReferences.Checksum) { project = project.WithProjectReferences(await _assetProvider.CreateCollectionAsync <ProjectReference>( newProjectChecksums.ProjectReferences, _cancellationToken).ConfigureAwait(false)); } // changed metadata references if (oldProjectChecksums.MetadataReferences.Checksum != newProjectChecksums.MetadataReferences.Checksum) { project = project.WithMetadataReferences(await _assetProvider.CreateCollectionAsync <MetadataReference>( newProjectChecksums.MetadataReferences, _cancellationToken).ConfigureAwait(false)); } // changed analyzer references if (oldProjectChecksums.AnalyzerReferences.Checksum != newProjectChecksums.AnalyzerReferences.Checksum) { project = project.WithAnalyzerReferences(await _assetProvider.CreateCollectionAsync <AnalyzerReference>( newProjectChecksums.AnalyzerReferences, _cancellationToken).ConfigureAwait(false)); } // changed analyzer references if (oldProjectChecksums.Documents.Checksum != newProjectChecksums.Documents.Checksum) { project = await UpdateDocumentsAsync( project, project.State.DocumentStates.States.Values, oldProjectChecksums.Documents, newProjectChecksums.Documents, (solution, documents) => solution.AddDocuments(documents), (solution, documentId) => solution.RemoveDocument(documentId)).ConfigureAwait(false); } // changed additional documents if (oldProjectChecksums.AdditionalDocuments.Checksum != newProjectChecksums.AdditionalDocuments.Checksum) { project = await UpdateDocumentsAsync( project, project.State.AdditionalDocumentStates.States.Values, oldProjectChecksums.AdditionalDocuments, newProjectChecksums.AdditionalDocuments, (solution, documents) => solution.AddAdditionalDocuments(documents), (solution, documentId) => solution.RemoveAdditionalDocument(documentId)).ConfigureAwait(false); } // changed analyzer config documents if (oldProjectChecksums.AnalyzerConfigDocuments.Checksum != newProjectChecksums.AnalyzerConfigDocuments.Checksum) { project = await UpdateDocumentsAsync( project, project.State.AnalyzerConfigDocumentStates.States.Values, oldProjectChecksums.AnalyzerConfigDocuments, newProjectChecksums.AnalyzerConfigDocuments, (solution, documents) => solution.AddAnalyzerConfigDocuments(documents), (solution, documentId) => solution.RemoveAnalyzerConfigDocument(documentId)).ConfigureAwait(false); } return(project.Solution); }
public bool TryGetStateChecksums(out ProjectStateChecksums stateChecksums) { return(_lazyChecksums.TryGetValue(out stateChecksums)); }
public bool TryGetStateChecksums(out ProjectStateChecksums stateChecksums) => _lazyChecksums.TryGetValue(out stateChecksums);
private async Task <Project> UpdateDocumentsAsync( Project project, ProjectStateChecksums projectChecksums, IEnumerable <TextDocumentState> existingTextDocumentStates, ChecksumCollection oldChecksums, ChecksumCollection newChecksums, Func <Solution, ImmutableArray <DocumentInfo>, Solution> addDocuments, Func <Solution, ImmutableArray <DocumentId>, Solution> removeDocuments, CancellationToken cancellationToken) { using var olds = SharedPools.Default <HashSet <Checksum> >().GetPooledObject(); using var news = SharedPools.Default <HashSet <Checksum> >().GetPooledObject(); olds.Object.UnionWith(oldChecksums); news.Object.UnionWith(newChecksums); // remove documents that exist in both side olds.Object.ExceptWith(newChecksums); news.Object.ExceptWith(oldChecksums); var oldMap = await GetDocumentMapAsync(existingTextDocumentStates, olds.Object, cancellationToken).ConfigureAwait(false); var newMap = await GetDocumentMapAsync(_assetProvider, news.Object, cancellationToken).ConfigureAwait(false); // If more than two documents changed during a single update, perform a bulk synchronization on the // project to avoid large numbers of small synchronization calls during document updates. // 🔗 https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1365014 if (newMap.Count > 2) { await _assetProvider.SynchronizeProjectAssetsAsync(new[] { projectChecksums.Checksum }, cancellationToken).ConfigureAwait(false); } // added document ImmutableArray <DocumentInfo> .Builder?lazyDocumentsToAdd = null; foreach (var(documentId, newDocumentChecksums) in newMap) { if (!oldMap.ContainsKey(documentId)) { lazyDocumentsToAdd ??= ImmutableArray.CreateBuilder <DocumentInfo>(); // we have new document added var documentInfo = await _assetProvider.CreateDocumentInfoAsync(newDocumentChecksums.Checksum, cancellationToken).ConfigureAwait(false); lazyDocumentsToAdd.Add(documentInfo); } } if (lazyDocumentsToAdd != null) { project = addDocuments(project.Solution, lazyDocumentsToAdd.ToImmutable()).GetProject(project.Id) !; } // changed document foreach (var(documentId, newDocumentChecksums) in newMap) { if (!oldMap.TryGetValue(documentId, out var oldDocumentChecksums)) { continue; } Contract.ThrowIfTrue(oldDocumentChecksums.Checksum == newDocumentChecksums.Checksum); var document = project.GetDocument(documentId) ?? project.GetAdditionalDocument(documentId) ?? project.GetAnalyzerConfigDocument(documentId); Contract.ThrowIfNull(document); project = await UpdateDocumentAsync(document, oldDocumentChecksums, newDocumentChecksums, cancellationToken).ConfigureAwait(false); } // removed document ImmutableArray <DocumentId> .Builder?lazyDocumentsToRemove = null; foreach (var(documentId, _) in oldMap) { if (!newMap.ContainsKey(documentId)) { // we have a document removed lazyDocumentsToRemove ??= ImmutableArray.CreateBuilder <DocumentId>(); lazyDocumentsToRemove.Add(documentId); } } if (lazyDocumentsToRemove is not null) { project = removeDocuments(project.Solution, lazyDocumentsToRemove.ToImmutable()).GetProject(project.Id) !; } return(project); }
public bool TryGetStateChecksums(out ProjectStateChecksums stateChecksums) { return _lazyChecksums.TryGetValue(out stateChecksums); }
internal static void ProjectStateEqual(ISolutionSynchronizationService service, ProjectStateChecksums projectObjects1, ProjectStateChecksums projectObjects2) { ChecksumWithChildrenEqual(projectObjects1, projectObjects2); ChecksumWithChildrenEqual(projectObjects1.Documents.ToDocumentObjects(service), projectObjects2.Documents.ToDocumentObjects(service)); ChecksumWithChildrenEqual(projectObjects1.AdditionalDocuments.ToDocumentObjects(service), projectObjects2.AdditionalDocuments.ToDocumentObjects(service)); }