internal static MetadataReference GetOrBuildReference( Solution solution, ProjectReference projectReference, Compilation finalCompilation, VersionStamp version, CancellationToken cancellationToken) { MetadataReference reference; if (TryGetReference(solution, projectReference, finalCompilation, version, out reference)) { return(reference); } // okay, we don't have one. so create one now. // first, prepare image // * NOTE * image is cancellable, do not create it inside of canditional weak table. var service = solution.Workspace.Services.GetService <ITemporaryStorageService>(); var image = MetadataOnlyImage.Create(service, finalCompilation, cancellationToken); if (image.IsEmpty) { // unfortunately, we couldn't create one. do best effort if (TryGetReference(solution, projectReference, finalCompilation, VersionStamp.Default, out reference)) { // we have one from previous compilation!!, it might be out-of-date big time, but better than nothing. // re-use it return(reference); } } // okay, proceed with whatever image we have // now, remove existing set var mapFromBranch = cache.GetValue(solution.BranchId, createReferenceSetMap); mapFromBranch.Remove(projectReference.ProjectId); // create new one var newReferenceSet = new MetadataOnlyReferenceSet(version, image); var referenceSet = snapshotCache.GetValue(finalCompilation, _ => newReferenceSet); if (newReferenceSet != referenceSet) { // someone else has beaten us. // let image go eagarly. otherwise, finalizer in temporary storage will take care of it image.Cleanup(); // return new reference return(referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes)); } // record it to version based cache as well. snapshot cache always has a higher priority. we don't need to check returned set here // since snapshot based cache will take care of same compilation for us. mapFromBranch.GetValue(projectReference.ProjectId, _ => referenceSet); // return new reference return(referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes)); }
internal static MetadataReference GetOrBuildReference( Solution solution, ProjectReference projectReference, Compilation finalCompilation, VersionStamp version, CancellationToken cancellationToken) { MetadataReference reference; if (TryGetReference(solution, projectReference, finalCompilation, version, out reference)) { return reference; } // okay, we don't have one. so create one now. // first, prepare image // * NOTE * image is cancellable, do not create it inside of conditional weak table. var service = solution.Workspace.Services.GetService<ITemporaryStorageService>(); var image = MetadataOnlyImage.Create(service, finalCompilation, cancellationToken); if (image.IsEmpty) { // unfortunately, we couldn't create one. do best effort if (TryGetReference(solution, projectReference, finalCompilation, VersionStamp.Default, out reference)) { // we have one from previous compilation!!, it might be out-of-date big time, but better than nothing. // re-use it return reference; } } // okay, proceed with whatever image we have // now, remove existing set var mapFromBranch = s_cache.GetValue(solution.BranchId, s_createReferenceSetMap); mapFromBranch.Remove(projectReference.ProjectId); // create new one var newReferenceSet = new MetadataOnlyReferenceSet(version, image); var referenceSet = s_snapshotCache.GetValue(finalCompilation, _ => newReferenceSet); if (newReferenceSet != referenceSet) { // someone else has beaten us. // let image go eagerly. otherwise, finalizer in temporary storage will take care of it image.Cleanup(); // return new reference return referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes); } // record it to version based cache as well. snapshot cache always has a higher priority. we don't need to check returned set here // since snapshot based cache will take care of same compilation for us. mapFromBranch.GetValue(projectReference.ProjectId, _ => referenceSet); // return new reference return referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes); }
internal static MetadataReference GetOrBuildReference( SolutionState solution, ProjectReference projectReference, Compilation finalCompilation, VersionStamp version, CancellationToken cancellationToken) { solution.Workspace.LogTestMessage($"Looking to see if we already have a skeleton assembly for {projectReference.ProjectId} before we build one..."); if (TryGetReference(solution, projectReference, finalCompilation, version, out var reference)) { solution.Workspace.LogTestMessage($"A reference was found {projectReference.ProjectId} so we're skipping the build."); return(reference); } // okay, we don't have one. so create one now. // first, prepare image // * NOTE * image is cancellable, do not create it inside of conditional weak table. var service = solution.Workspace.Services.GetService <ITemporaryStorageService>(); var image = MetadataOnlyImage.Create(solution.Workspace, service, finalCompilation, cancellationToken); if (image.IsEmpty) { // unfortunately, we couldn't create one. do best effort if (TryGetReference(solution, projectReference, finalCompilation, VersionStamp.Default, out reference)) { solution.Workspace.LogTestMessage($"We failed to create metadata so we're using the one we just found from an earlier version."); // we have one from previous compilation!!, it might be out-of-date big time, but better than nothing. // re-use it return(reference); } } // okay, proceed with whatever image we have // now, remove existing set var mapFromBranch = s_cache.GetValue(solution.BranchId, s_createReferenceSetMap); mapFromBranch.Remove(projectReference.ProjectId); // create new one var newReferenceSet = new MetadataOnlyReferenceSet(version, image); var referenceSet = s_snapshotCache.GetValue(finalCompilation, _ => newReferenceSet); if (newReferenceSet != referenceSet) { // someone else has beaten us. // let image go eagerly. otherwise, finalizer in temporary storage will take care of it image.Cleanup(); // return new reference return(referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes)); } else { solution.Workspace.LogTestMessage($"Successfully stored the metadata generated for {projectReference.ProjectId}"); } // record it to version based cache as well. snapshot cache always has a higher priority. we don't need to check returned set here // since snapshot based cache will take care of same compilation for us. mapFromBranch.GetValue(projectReference.ProjectId, _ => referenceSet); // return new reference return(referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes)); }