Example #1
0
        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));
        }
 public MetadataOnlyReferenceSet(VersionStamp version, MetadataOnlyImage image)
 {
     _version = version;
     _image = image;
 }
Example #3
0
 public MetadataOnlyReferenceSet(VersionStamp version, MetadataOnlyImage image)
 {
     this.version = version;
     this.image   = image;
 }
Example #4
0
        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));
        }
Example #5
0
 public MetadataOnlyReferenceSet(VersionStamp version, MetadataOnlyImage image)
 {
     _version = version;
     _image   = image;
 }
Example #6
0
 public MetadataOnlyReferenceSet(VersionStamp version, MetadataOnlyImage image)
 {
     this.version = version;
     this.image = image;
 }