internal static void SnapshotEqual(ISolutionChecksumService service, SolutionChecksumObject solutionId1, SolutionChecksumObject solutionId2)
        {
            ChecksumObjectEqual(solutionId1, solutionId2);
            Assert.Equal(solutionId1.Info, solutionId2.Info);

            CollectionEqual(service, solutionId1.Projects.ToProjectObjects(service), solutionId2.Projects.ToProjectObjects(service));
        }
        internal static async Task <T> VerifyAssetSerializationAsync <T>(
            ISolutionChecksumService service,
            Checksum checksum,
            string kind,
            Func <T, string, Serializer, Asset> assetGetter)
        {
            var snapshotService        = (SolutionChecksumServiceFactory.Service)service;
            var originalChecksumObject = service.GetChecksumObject(checksum, CancellationToken.None);

            using (var stream = SerializableBytes.CreateWritableStream())
                using (var writer = new ObjectWriter(stream))
                {
                    // serialize asset to bits
                    await originalChecksumObject.WriteObjectToAsync(writer, CancellationToken.None).ConfigureAwait(false);

                    stream.Position = 0;
                    using (var reader = new ObjectReader(stream))
                    {
                        // deserialize bits to object
                        var serializer     = snapshotService.Serializer_TestOnly;
                        var recoveredValue = serializer.Deserialize <T>(kind, reader, CancellationToken.None);

                        // re-create asset from object
                        var recreatedChecksumObject = assetGetter(recoveredValue, kind, serializer);

                        // make sure original checksum object and re-created checksum object are same.
                        ChecksumObjectEqual(originalChecksumObject, recreatedChecksumObject);

                        return(recoveredValue);
                    }
                }
        }
        internal static void VerifyChecksumInService(ISolutionChecksumService snapshotService, Checksum checksum, string kind)
        {
            Assert.NotNull(checksum);
            var otherObject = snapshotService.GetChecksumObject(checksum, CancellationToken.None);

            ChecksumEqual(checksum, kind, otherObject.Checksum, otherObject.Kind);
        }
        internal static void VerifyCollectionInService(ISolutionChecksumService snapshotService, ChecksumCollection checksums, int expectedCount, string expectedItemKind)
        {
            VerifyChecksumObjectInService(snapshotService, checksums);
            Assert.Equal(checksums.Count, expectedCount);

            foreach (var checksum in checksums)
            {
                VerifyChecksumInService(snapshotService, checksum, expectedItemKind);
            }
        }
        internal static void CollectionEqual(ISolutionChecksumService service, ChecksumObjectCollection <ProjectChecksumObject> projectIds1, ChecksumObjectCollection <ProjectChecksumObject> projectIds2)
        {
            ChecksumObjectEqual(projectIds1, projectIds2);
            Assert.Equal(projectIds1.Count, projectIds2.Count);

            for (var i = 0; i < projectIds1.Count; i++)
            {
                SnapshotEqual(service, projectIds1[i], projectIds2[i]);
            }
        }
        internal static void VerifyCollectionInService(ISolutionChecksumService snapshotService, ChecksumObjectCollection <DocumentChecksumObject> documents, int expectedCount)
        {
            VerifyChecksumObjectInService(snapshotService, documents);
            Assert.Equal(documents.Count, expectedCount);

            foreach (var documentId in documents)
            {
                VerifySnapshotInService(snapshotService, documentId);
            }
        }
        private async Task UpdateLastSolutionSnapshotAsync(ISolutionChecksumService snapshotService, Solution solution)
        {
            // TODO: actual incremental build of solution snapshot should be its own service
            // this is needed to make sure we incrementally update solution checksums. otherwise, we will always create from
            // scratch which can be quite expansive for big solution
            var lastSnapshot = _lastSnapshot;

            _lastSnapshot = await snapshotService.CreateChecksumAsync(solution, CancellationToken.None).ConfigureAwait(false);

            lastSnapshot?.Dispose();
        }
        internal static async Task VerifyAssetAsync(ISolutionChecksumService service, Solution solution, SolutionChecksumObject solutionId)
        {
            await VerifyAssetSerializationAsync <SolutionChecksumObjectInfo>(
                service, solutionId.Info, WellKnownChecksumObjects.SolutionChecksumObjectInfo,
                (v, k, s) => new Asset <SolutionChecksumObjectInfo>(v, k, s.SerializeSolutionSnapshotInfo)).ConfigureAwait(false);

            foreach (var checksum in solutionId.Projects)
            {
                var projectId = (ProjectChecksumObject)service.GetChecksumObject(checksum, CancellationToken.None);
                await VerifyAssetAsync(service, solution, projectId).ConfigureAwait(false);
            }
        }
        internal static async Task VerifyAssetAsync(
            ISolutionChecksumService service,
            Solution solution,
            ProjectChecksumObject projectId)
        {
            var info = await VerifyAssetSerializationAsync <ProjectChecksumObjectInfo>(
                service, projectId.Info, WellKnownChecksumObjects.ProjectChecksumObjectInfo,
                (v, k, s) => new Asset <ProjectChecksumObjectInfo>(v, k, s.SerializeProjectSnapshotInfo)).ConfigureAwait(false);

            var project = solution.GetProject(info.Id);

            await VerifyAssetSerializationAsync <CompilationOptions>(
                service, projectId.CompilationOptions, WellKnownChecksumObjects.CompilationOptions,
                (v, k, s) => new LanguageSpecificAsset <CompilationOptions>(project.Language, v, k, s.SerializeCompilationOptions));

            await VerifyAssetSerializationAsync <ParseOptions>(
                service, projectId.ParseOptions, WellKnownChecksumObjects.ParseOptions,
                (v, k, s) => new LanguageSpecificAsset <ParseOptions>(project.Language, v, k, s.SerializeParseOptions));

            foreach (var checksum in projectId.Documents)
            {
                var documentId = (DocumentChecksumObject)service.GetChecksumObject(checksum, CancellationToken.None);
                await VerifyAssetAsync(service, solution, documentId).ConfigureAwait(false);
            }

            foreach (var projectReference in projectId.ProjectReferences)
            {
                await VerifyAssetSerializationAsync <ProjectReference>(
                    service, projectReference, WellKnownChecksumObjects.ProjectReference,
                    (v, k, s) => new Asset <ProjectReference>(v, k, s.SerializeProjectReference));
            }

            foreach (var metadataReference in projectId.MetadataReferences)
            {
                await VerifyAssetSerializationAsync <MetadataReference>(
                    service, metadataReference, WellKnownChecksumObjects.MetadataReference,
                    (v, k, s) => new MetadataReferenceAsset(s, v, s.HostSerializationService.CreateChecksum(v, CancellationToken.None), k));
            }

            foreach (var analyzerReference in projectId.AnalyzerReferences)
            {
                await VerifyAssetSerializationAsync <AnalyzerReference>(
                    service, analyzerReference, WellKnownChecksumObjects.AnalyzerReference,
                    (v, k, s) => new AnalyzerReferenceAsset(s, v, s.HostSerializationService.CreateChecksum(v, CancellationToken.None), k));
            }

            foreach (var checksum in projectId.AdditionalDocuments)
            {
                var documentId = (DocumentChecksumObject)service.GetChecksumObject(checksum, CancellationToken.None);
                await VerifyAssetAsync(service, solution, documentId).ConfigureAwait(false);
            }
        }
        internal static async Task VerifyAssetAsync(
            ISolutionChecksumService service,
            Solution solution,
            DocumentChecksumObject documentId)
        {
            var info = await VerifyAssetSerializationAsync <DocumentChecksumObjectInfo>(
                service, documentId.Info, WellKnownChecksumObjects.DocumentChecksumObjectInfo,
                (v, k, s) => new Asset <DocumentChecksumObjectInfo>(v, k, s.SerializeDocumentSnapshotInfo)).ConfigureAwait(false);

            await VerifyAssetSerializationAsync <SourceText>(
                service, documentId.Text, WellKnownChecksumObjects.SourceText,
                (v, k, s) => new SourceTextAsset(s, CreateTextState(solution, v), new Checksum(v.GetChecksum()), k));
        }
        private ImmutableArray <byte[]> GetHostAnalyzerReferences(ISolutionChecksumService snapshotService, IEnumerable <AnalyzerReference> references, CancellationToken cancellationToken)
        {
            // TODO: cache this to somewhere
            var builder = ImmutableArray.CreateBuilder <byte[]>();

            foreach (var reference in references)
            {
                var asset = snapshotService.GetGlobalAsset(reference, cancellationToken);
                builder.Add(asset.Checksum.ToArray());
            }

            return(builder.ToImmutable());
        }
        internal static void SnapshotEqual(ISolutionChecksumService service, ProjectChecksumObject projectId1, ProjectChecksumObject projectId2)
        {
            ChecksumObjectEqual(projectId1, projectId2);

            Assert.Equal(projectId1.Info, projectId2.Info);
            Assert.Equal(projectId1.CompilationOptions, projectId2.CompilationOptions);
            Assert.Equal(projectId1.ParseOptions, projectId2.ParseOptions);

            CollectionEqual(projectId1.Documents.ToDocumentObjects(service), projectId2.Documents.ToDocumentObjects(service));

            CollectionEqual(projectId1.ProjectReferences, projectId2.ProjectReferences);
            CollectionEqual(projectId1.MetadataReferences, projectId2.MetadataReferences);
            CollectionEqual(projectId1.AnalyzerReferences, projectId2.AnalyzerReferences);

            CollectionEqual(projectId1.AdditionalDocuments.ToDocumentObjects(service), projectId2.AdditionalDocuments.ToDocumentObjects(service));
        }
        internal static async Task VerifySnapshotSerializationAsync(ISolutionChecksumService service, Solution solution, SolutionChecksumObject solutionId)
        {
            using (var stream = SerializableBytes.CreateWritableStream())
                using (var writer = new ObjectWriter(stream))
                {
                    await solutionId.WriteToAsync(writer, CancellationToken.None).ConfigureAwait(false);

                    stream.Position = 0;
                    using (var reader = new ObjectReader(stream))
                    {
                        var serializer = new Serializer(solution.Workspace.Services);
                        var recovered  = serializer.Deserialize <SolutionChecksumObject>(SolutionChecksumObject.Name, reader, CancellationToken.None);

                        SnapshotEqual(service, solutionId, recovered);
                    }
                }
        }
Example #14
0
            public SolutionChecksumUpdater(RemoteHostClientService service, CancellationToken shutdownToken) :
                base(AggregateAsynchronousOperationListener.CreateEmptyListener(),
                     service.Workspace.Services.GetService <IGlobalOperationNotificationService>(),
                     service.Workspace.Options.GetOption(RemoteHostOptions.SolutionChecksumMonitorBackOffTimeSpanInMS), shutdownToken)
            {
                _service         = service;
                _checksumService = service.Workspace.Services.GetService <ISolutionChecksumService>();

                _gate  = new SemaphoreSlim(initialCount: 1);
                _event = new SemaphoreSlim(initialCount: 0);

                // start listening workspace change event
                _service.Workspace.WorkspaceChanged += OnWorkspaceChanged;

                // create its own cancellation token source
                _globalOperationCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(shutdownToken);

                Start();
            }
            public SolutionChecksumUpdater(RemoteHostClientService service, CancellationToken shutdownToken) :
                base(AggregateAsynchronousOperationListener.CreateEmptyListener(),
                     service.Workspace.Services.GetService<IGlobalOperationNotificationService>(),
                     service.Workspace.Options.GetOption(RemoteHostOptions.SolutionChecksumMonitorBackOffTimeSpanInMS), shutdownToken)
            {
                _service = service;
                _checksumService = service.Workspace.Services.GetService<ISolutionChecksumService>();

                _gate = new SemaphoreSlim(initialCount: 1);
                _event = new SemaphoreSlim(initialCount: 0);

                // start listening workspace change event
                _service.Workspace.WorkspaceChanged += OnWorkspaceChanged;

                // create its own cancellation token source
                _globalOperationCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(shutdownToken);

                Start();
            }
        internal static async Task <T> GetValueAsync <T>(ISolutionChecksumService service, Checksum checksum, string kind)
        {
            var snapshotService = (SolutionChecksumServiceFactory.Service)service;
            var checksumObject  = service.GetChecksumObject(checksum, CancellationToken.None);

            using (var stream = SerializableBytes.CreateWritableStream())
                using (var writer = new ObjectWriter(stream))
                {
                    // serialize asset to bits
                    await checksumObject.WriteToAsync(writer, CancellationToken.None).ConfigureAwait(false);

                    stream.Position = 0;
                    using (var reader = new ObjectReader(stream))
                    {
                        // deserialize bits to object
                        var serializer = snapshotService.Serializer_TestOnly;
                        return(serializer.Deserialize <T>(kind, reader, CancellationToken.None));
                    }
                }
        }
        internal static void VerifySnapshotInService(
            ISolutionChecksumService snapshotService,
            ProjectChecksumObject projectId,
            int expectedDocumentCount,
            int expectedProjectReferenceCount,
            int expectedMetadataReferenceCount,
            int expectedAnalyzerReferenceCount,
            int expectedAdditionalDocumentCount)
        {
            VerifyChecksumObjectInService(snapshotService, projectId);
            VerifyChecksumInService(snapshotService, projectId.Info, WellKnownChecksumObjects.ProjectChecksumObjectInfo);
            VerifyChecksumInService(snapshotService, projectId.CompilationOptions, WellKnownChecksumObjects.CompilationOptions);
            VerifyChecksumInService(snapshotService, projectId.ParseOptions, WellKnownChecksumObjects.ParseOptions);

            VerifyCollectionInService(snapshotService, projectId.Documents.ToDocumentObjects(snapshotService), expectedDocumentCount);

            VerifyCollectionInService(snapshotService, projectId.ProjectReferences, expectedProjectReferenceCount, WellKnownChecksumObjects.ProjectReference);
            VerifyCollectionInService(snapshotService, projectId.MetadataReferences, expectedMetadataReferenceCount, WellKnownChecksumObjects.MetadataReference);
            VerifyCollectionInService(snapshotService, projectId.AnalyzerReferences, expectedAnalyzerReferenceCount, WellKnownChecksumObjects.AnalyzerReference);

            VerifyCollectionInService(snapshotService, projectId.AdditionalDocuments.ToDocumentObjects(snapshotService), expectedAdditionalDocumentCount);
        }
 internal static void VerifyChecksumObjectInService <T>(ISolutionChecksumService snapshotService, T checksumObject) where T : ChecksumObject
 {
     VerifyChecksumInService(snapshotService, checksumObject.Checksum, checksumObject.Kind);
 }
        private ImmutableArray<byte[]> GetHostAnalyzerReferences(ISolutionChecksumService snapshotService, IEnumerable<AnalyzerReference> references, CancellationToken cancellationToken)
        {
            // TODO: cache this to somewhere
            var builder = ImmutableArray.CreateBuilder<byte[]>();
            foreach (var reference in references)
            {
                var asset = snapshotService.GetGlobalAsset(reference, cancellationToken);
                builder.Add(asset.Checksum.ToArray());
            }

            return builder.ToImmutable();
        }
Example #20
0
        private async Task <Solution> GetSolutionAsync(ISolutionChecksumService service, ChecksumScope snapshot)
        {
            var workspace = new AdhocWorkspace();

            var solutionInfo = await GetValueAsync <SolutionChecksumObjectInfo>(service, snapshot.SolutionChecksum.Info, WellKnownChecksumObjects.SolutionChecksumObjectInfo).ConfigureAwait(false);

            var projects = new List <ProjectInfo>();

            foreach (var projectSnapshot in snapshot.SolutionChecksum.Projects.ToProjectObjects(service))
            {
                var documents = new List <DocumentInfo>();
                foreach (var documentSnapshot in projectSnapshot.Documents.ToDocumentObjects(service))
                {
                    var documentInfo = await GetValueAsync <DocumentChecksumObjectInfo>(service, documentSnapshot.Info, WellKnownChecksumObjects.DocumentChecksumObjectInfo).ConfigureAwait(false);

                    var text = await GetValueAsync <SourceText>(service, documentSnapshot.Text, WellKnownChecksumObjects.SourceText).ConfigureAwait(false);

                    // TODO: do we need version?
                    documents.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create())),
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var p2p = new List <ProjectReference>();
                foreach (var checksum in projectSnapshot.ProjectReferences)
                {
                    var reference = await GetValueAsync <ProjectReference>(service, checksum, WellKnownChecksumObjects.ProjectReference).ConfigureAwait(false);

                    p2p.Add(reference);
                }
                var metadata = new List <MetadataReference>();
                foreach (var checksum in projectSnapshot.MetadataReferences)
                {
                    var reference = await GetValueAsync <MetadataReference>(service, checksum, WellKnownChecksumObjects.MetadataReference).ConfigureAwait(false);

                    metadata.Add(reference);
                }

                var analyzers = new List <AnalyzerReference>();
                foreach (var checksum in projectSnapshot.AnalyzerReferences)
                {
                    var reference = await GetValueAsync <AnalyzerReference>(service, checksum, WellKnownChecksumObjects.AnalyzerReference).ConfigureAwait(false);

                    analyzers.Add(reference);
                }

                var additionals = new List <DocumentInfo>();
                foreach (var documentSnapshot in projectSnapshot.AdditionalDocuments.ToDocumentObjects(service))
                {
                    var documentInfo = await GetValueAsync <DocumentChecksumObjectInfo>(service, documentSnapshot.Info, WellKnownChecksumObjects.DocumentChecksumObjectInfo).ConfigureAwait(false);

                    var text = await GetValueAsync <SourceText>(service, documentSnapshot.Text, WellKnownChecksumObjects.SourceText).ConfigureAwait(false);

                    // TODO: do we need version?
                    additionals.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create())),
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var projectInfo = await GetValueAsync <ProjectChecksumObjectInfo>(service, projectSnapshot.Info, WellKnownChecksumObjects.ProjectChecksumObjectInfo).ConfigureAwait(false);

                var compilationOptions = await GetValueAsync <CompilationOptions>(service, projectSnapshot.CompilationOptions, WellKnownChecksumObjects.CompilationOptions).ConfigureAwait(false);

                var parseOptions = await GetValueAsync <ParseOptions>(service, projectSnapshot.ParseOptions, WellKnownChecksumObjects.ParseOptions).ConfigureAwait(false);

                projects.Add(
                    ProjectInfo.Create(
                        projectInfo.Id, projectInfo.Version, projectInfo.Name, projectInfo.AssemblyName,
                        projectInfo.Language, projectInfo.FilePath, projectInfo.OutputFilePath,
                        compilationOptions, parseOptions,
                        documents, p2p, metadata, analyzers, additionals));
            }

            return(workspace.AddSolution(SolutionInfo.Create(solutionInfo.Id, solutionInfo.Version, solutionInfo.FilePath, projects)));
        }
        private async Task<Solution> GetSolutionAsync(ISolutionChecksumService service, ChecksumScope snapshot)
        {
            var workspace = new AdhocWorkspace();

            var solutionInfo = await GetValueAsync<SolutionChecksumObjectInfo>(service, snapshot.SolutionChecksum.Info, WellKnownChecksumObjects.SolutionChecksumObjectInfo).ConfigureAwait(false);

            var projects = new List<ProjectInfo>();
            foreach (var projectSnapshot in snapshot.SolutionChecksum.Projects.ToProjectObjects(service))
            {
                var documents = new List<DocumentInfo>();
                foreach (var documentSnapshot in projectSnapshot.Documents.ToDocumentObjects(service))
                {
                    var documentInfo = await GetValueAsync<DocumentChecksumObjectInfo>(service, documentSnapshot.Info, WellKnownChecksumObjects.DocumentChecksumObjectInfo).ConfigureAwait(false);
                    var text = await GetValueAsync<SourceText>(service, documentSnapshot.Text, WellKnownChecksumObjects.SourceText).ConfigureAwait(false);

                    // TODO: do we need version?
                    documents.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create())),
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var p2p = new List<ProjectReference>();
                foreach (var checksum in projectSnapshot.ProjectReferences)
                {
                    var reference = await GetValueAsync<ProjectReference>(service, checksum, WellKnownChecksumObjects.ProjectReference).ConfigureAwait(false);
                    p2p.Add(reference);
                }
                var metadata = new List<MetadataReference>();
                foreach (var checksum in projectSnapshot.MetadataReferences)
                {
                    var reference = await GetValueAsync<MetadataReference>(service, checksum, WellKnownChecksumObjects.MetadataReference).ConfigureAwait(false);
                    metadata.Add(reference);
                }

                var analyzers = new List<AnalyzerReference>();
                foreach (var checksum in projectSnapshot.AnalyzerReferences)
                {
                    var reference = await GetValueAsync<AnalyzerReference>(service, checksum, WellKnownChecksumObjects.AnalyzerReference).ConfigureAwait(false);
                    analyzers.Add(reference);
                }

                var additionals = new List<DocumentInfo>();
                foreach (var documentSnapshot in projectSnapshot.AdditionalDocuments.ToDocumentObjects(service))
                {
                    var documentInfo = await GetValueAsync<DocumentChecksumObjectInfo>(service, documentSnapshot.Info, WellKnownChecksumObjects.DocumentChecksumObjectInfo).ConfigureAwait(false);
                    var text = await GetValueAsync<SourceText>(service, documentSnapshot.Text, WellKnownChecksumObjects.SourceText).ConfigureAwait(false);

                    // TODO: do we need version?
                    additionals.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create())),
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var projectInfo = await GetValueAsync<ProjectChecksumObjectInfo>(service, projectSnapshot.Info, WellKnownChecksumObjects.ProjectChecksumObjectInfo).ConfigureAwait(false);
                var compilationOptions = await GetValueAsync<CompilationOptions>(service, projectSnapshot.CompilationOptions, WellKnownChecksumObjects.CompilationOptions).ConfigureAwait(false);
                var parseOptions = await GetValueAsync<ParseOptions>(service, projectSnapshot.ParseOptions, WellKnownChecksumObjects.ParseOptions).ConfigureAwait(false);

                projects.Add(
                    ProjectInfo.Create(
                        projectInfo.Id, projectInfo.Version, projectInfo.Name, projectInfo.AssemblyName,
                        projectInfo.Language, projectInfo.FilePath, projectInfo.OutputFilePath,
                        compilationOptions, parseOptions,
                        documents, p2p, metadata, analyzers, additionals));
            }

            return workspace.AddSolution(SolutionInfo.Create(solutionInfo.Id, solutionInfo.Version, solutionInfo.FilePath, projects));
        }
Example #22
0
 public ChecksumObjectCollection(ISolutionChecksumService service, ChecksumCollection collection) : base(collection.Checksum, collection.Kind)
 {
     Children = ImmutableArray.CreateRange(collection.Select(c => (T)service.GetChecksumObject(c, CancellationToken.None)));
 }
Example #23
0
 public static ChecksumObjectCollection <DocumentChecksumObject> ToDocumentObjects(this ChecksumCollection collection, ISolutionChecksumService service)
 {
     Contract.ThrowIfFalse(collection.Kind == WellKnownChecksumObjects.Documents || collection.Kind == WellKnownChecksumObjects.TextDocuments);
     return(new ChecksumObjectCollection <DocumentChecksumObject>(service, collection));
 }
 private async Task UpdateLastSolutionSnapshotAsync(ISolutionChecksumService snapshotService, Solution solution)
 {
     // TODO: actual incremental build of solution snapshot should be its own service
     // this is needed to make sure we incrementally update solution checksums. otherwise, we will always create from
     // scratch which can be quite expansive for big solution
     var lastSnapshot = _lastSnapshot;
     _lastSnapshot = await snapshotService.CreateChecksumAsync(solution, CancellationToken.None).ConfigureAwait(false);
     lastSnapshot?.Dispose();
 }
 internal static void VerifySnapshotInService(ISolutionChecksumService snapshotService, DocumentChecksumObject documentId)
 {
     VerifyChecksumObjectInService(snapshotService, documentId);
     VerifyChecksumInService(snapshotService, documentId.Info, WellKnownChecksumObjects.DocumentChecksumObjectInfo);
     VerifyChecksumInService(snapshotService, documentId.Text, WellKnownChecksumObjects.SourceText);
 }