Ejemplo n.º 1
0
        /// <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);
        }