private async Task UpdateReferenceAsync( Project project, Compilation compilation, PortableExecutableReference reference, CancellationToken cancellationToken) { var key = GetReferenceKey(reference); if (key == null) { return; } DateTime lastWriteTime; if (!TryGetLastWriteTime(key, out lastWriteTime)) { // Couldn't get the write time. Just ignore this reference. return; } MetadataInfo metadataInfo; if (!_metadataPathToInfo.TryGetValue(key, out metadataInfo) || metadataInfo.TimeStamp == lastWriteTime) { var assembly = compilation.GetAssemblyOrModuleSymbol(reference) as IAssemblySymbol; var info = assembly == null ? null : await SymbolTreeInfo.TryGetInfoForMetadataAssemblyAsync(project.Solution, assembly, reference, loadOnly : false, cancellationToken : cancellationToken).ConfigureAwait(false); metadataInfo = new MetadataInfo(lastWriteTime, info, metadataInfo.ReferencingProjects ?? new HashSet <ProjectId>()); _metadataPathToInfo.AddOrUpdate(key, metadataInfo, (_1, _2) => metadataInfo); } // Keep track that this dll is referenced by this project. metadataInfo.ReferencingProjects.Add(project.Id); }
public async Task <SymbolTreeInfo> TryGetSymbolTreeInfoAsync( Solution solution, IAssemblySymbol assembly, PortableExecutableReference reference, CancellationToken cancellationToken) { var key = GetReferenceKey(reference); if (key != null) { MetadataInfo metadataInfo; if (_metadataPathToInfo.TryGetValue(key, out metadataInfo)) { DateTime writeTime; if (TryGetLastWriteTime(key, out writeTime) && writeTime == metadataInfo.TimeStamp) { return(metadataInfo.SymbolTreeInfo); } } } // If we didn't have it in our cache, see if we can load it from disk. // Note: pass 'loadOnly' so we only attempt to load from disk, not to actually // try to create the metadata. var info = await SymbolTreeInfo.TryGetInfoForMetadataAssemblyAsync( solution, assembly, reference, loadOnly : true, cancellationToken : cancellationToken).ConfigureAwait(false); return(info); }