private static async Task <Checksum> ComputeSourceSymbolsChecksumAsync(ProjectState projectState, CancellationToken cancellationToken) { // The SymbolTree for source is built from the source-symbols from the project's compilation's // assembly. Specifically, we only get the name, kind and parent/child relationship of all the // child symbols. So we want to be able to reuse the index as long as none of these have // changed. The only thing that can make those source-symbols change in that manner are if // the text of any document changes, or if options for the project change. So we build our // checksum out of that data. var serializer = projectState.LanguageServices.WorkspaceServices.GetService <ISerializerService>(); var projectStateChecksums = await projectState.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false); // Order the documents by FilePath. Default ordering in the RemoteWorkspace is // to be ordered by Guid (which is not consistent across VS sessions). var textChecksumsTasks = projectState.DocumentStates.OrderBy(d => d.Value.FilePath, StringComparer.Ordinal).Select(async d => { var documentStateChecksum = await d.Value.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false); return(documentStateChecksum.Text); }); var compilationOptionsChecksum = projectStateChecksums.CompilationOptions; var parseOptionsChecksum = projectStateChecksums.ParseOptions; var textChecksums = await Task.WhenAll(textChecksumsTasks).ConfigureAwait(false); var allChecksums = ArrayBuilder <Checksum> .GetInstance(); try { allChecksums.AddRange(textChecksums); allChecksums.Add(compilationOptionsChecksum); allChecksums.Add(parseOptionsChecksum); // Include serialization format version in our checksum. That way if the // version ever changes, all persisted data won't match the current checksum // we expect, and we'll recompute things. allChecksums.Add(SerializationFormatChecksum); var checksum = Checksum.Create(WellKnownSynchronizationKind.SymbolTreeInfo, allChecksums); return(checksum); } finally { allChecksums.Free(); } }