/// <summary> /// this is for a metadata reference in a solution /// </summary> private static async Task <SymbolTreeInfo> LoadOrCreateAsync(Solution solution, IAssemblySymbol assembly, string filePath, CancellationToken cancellationToken) { // if assembly is not from a file, just create one on the fly if (filePath == null || !File.Exists(filePath) || !FilePathUtilities.PartOfFrameworkOrReferencePaths(filePath)) { return(Create(VersionStamp.Default, assembly, cancellationToken)); } // if solution is not from a disk, just create one. if (solution.FilePath == null || !File.Exists(solution.FilePath)) { return(Create(VersionStamp.Default, assembly, cancellationToken)); } // okay, see whether we can get one from persistence service. var relativePath = FilePathUtilities.GetRelativePath(solution.FilePath, filePath); var version = VersionStamp.Create(File.GetLastWriteTimeUtc(filePath)); var persistentStorageService = solution.Workspace.Services.GetService <IPersistentStorageService>(); // attempt to load from persisted state. metadata reference is solution wise information SymbolTreeInfo info; using (var storage = persistentStorageService.GetStorage(solution)) { var key = PrefixMetadataSymbolTreeInfo + relativePath; using (var stream = await storage.ReadStreamAsync(key, cancellationToken).ConfigureAwait(false)) { if (stream != null) { using (var reader = new ObjectReader(stream)) { info = ReadFrom(reader); if (info != null && VersionStamp.CanReusePersistedVersion(version, info.version)) { return(info); } } } } cancellationToken.ThrowIfCancellationRequested(); // compute it if we couldn't load it from cache info = Create(version, assembly, cancellationToken); if (info != null) { using (var stream = SerializableBytes.CreateWritableStream()) using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken)) { info.WriteTo(writer); stream.Position = 0; await storage.WriteStreamAsync(key, stream, cancellationToken).ConfigureAwait(false); } } } return(info); }