SolutionInfo.cs 6.5 KB
Newer Older
J
Jonathon Marolf 已提交
1 2 3
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
P
Pilchie 已提交
4

5 6
#nullable enable

7
using System;
P
Pilchie 已提交
8
using System.Collections.Generic;
9 10
using System.Collections.Immutable;
using System.Linq;
11
using Microsoft.CodeAnalysis.Diagnostics;
12
using Microsoft.CodeAnalysis.Serialization;
13
using Microsoft.CodeAnalysis.Shared.Extensions;
P
Pilchie 已提交
14 15 16 17 18 19 20 21 22
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis
{
    /// <summary>
    /// A class that represents all the arguments necessary to create a new solution instance.
    /// </summary>
    public sealed class SolutionInfo
    {
23 24
        internal SolutionAttributes Attributes { get; }

P
Pilchie 已提交
25 26 27
        /// <summary>
        /// The unique Id of the solution.
        /// </summary>
28
        public SolutionId Id => Attributes.Id;
P
Pilchie 已提交
29 30 31 32

        /// <summary>
        /// The version of the solution.
        /// </summary>
33
        public VersionStamp Version => Attributes.Version;
P
Pilchie 已提交
34 35 36 37

        /// <summary>
        /// The path to the solution file, or null if there is no solution file.
        /// </summary>
38
        public string? FilePath => Attributes.FilePath;
P
Pilchie 已提交
39 40 41 42

        /// <summary>
        /// A list of projects initially associated with the solution.
        /// </summary>
43
        public IReadOnlyList<ProjectInfo> Projects { get; }
P
Pilchie 已提交
44

45 46 47 48 49 50
        /// <summary>
        /// The analyzers initially associated with this solution.
        /// </summary>
        public IReadOnlyList<AnalyzerReference> AnalyzerReferences { get; }

        private SolutionInfo(SolutionAttributes attributes, IReadOnlyList<ProjectInfo> projects, IReadOnlyList<AnalyzerReference> analyzerReferences)
P
Pilchie 已提交
51
        {
52
            Attributes = attributes;
53
            Projects = projects;
54 55 56 57 58 59 60 61 62 63 64 65 66 67
            AnalyzerReferences = analyzerReferences;
        }

        // 3.5.0 BACKCOMPAT OVERLOAD -- DO NOT TOUCH
        /// <summary>
        /// Create a new instance of a SolutionInfo.
        /// </summary>
        public static SolutionInfo Create(
            SolutionId id,
            VersionStamp version,
            string? filePath,
            IEnumerable<ProjectInfo>? projects)
        {
            return Create(id, version, filePath, projects, analyzerReferences: null);
P
Pilchie 已提交
68 69 70 71 72 73 74 75
        }

        /// <summary>
        /// Create a new instance of a SolutionInfo.
        /// </summary>
        public static SolutionInfo Create(
            SolutionId id,
            VersionStamp version,
76
            string? filePath = null,
77 78
            IEnumerable<ProjectInfo>? projects = null,
            IEnumerable<AnalyzerReference>? analyzerReferences = null)
P
Pilchie 已提交
79
        {
80 81 82 83
            return new SolutionInfo(
                new SolutionAttributes(
                    id ?? throw new ArgumentNullException(nameof(id)),
                    version,
84 85
                    filePath,
                    telemetryId: default),
86 87
                PublicContract.ToBoxedImmutableArrayWithDistinctNonNullItems(projects, nameof(projects)),
                PublicContract.ToBoxedImmutableArrayWithDistinctNonNullItems(analyzerReferences, nameof(analyzerReferences)));
88 89
        }

90 91 92
        internal ImmutableHashSet<string> GetProjectLanguages()
            => Projects.Select(p => p.Language).ToImmutableHashSet();

93 94 95
        internal SolutionInfo WithTelemetryId(Guid telemetryId)
            => new SolutionInfo(Attributes.With(telemetryId: telemetryId), Projects, AnalyzerReferences);

96 97 98 99
        /// <summary>
        /// type that contains information regarding this solution itself but
        /// no tree information such as project info
        /// </summary>
100
        internal sealed class SolutionAttributes : IChecksummedObject, IObjectWritable
101
        {
102 103
            private Checksum? _lazyChecksum;

104 105 106 107 108 109 110 111 112 113 114 115 116
            /// <summary>
            /// The unique Id of the solution.
            /// </summary>
            public SolutionId Id { get; }

            /// <summary>
            /// The version of the solution.
            /// </summary>
            public VersionStamp Version { get; }

            /// <summary>
            /// The path to the solution file, or null if there is no solution file.
            /// </summary>
117
            public string? FilePath { get; }
118

119
            /// <summary>
J
Joey Robichaud 已提交
120
            /// The id report during telemetry events.
121 122 123 124
            /// </summary>
            public Guid TelemetryId { get; }

            public SolutionAttributes(SolutionId id, VersionStamp version, string? filePath, Guid telemetryId)
125
            {
126
                Id = id;
127 128
                Version = version;
                FilePath = filePath;
129
                TelemetryId = telemetryId;
130 131
            }

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
            public SolutionAttributes With(
                VersionStamp? version = null,
                Optional<string?> filePath = default,
                Optional<Guid> telemetryId = default)
            {
                var newVersion = version ?? Version;
                var newFilePath = filePath.HasValue ? filePath.Value : FilePath;
                var newTelemetryId = telemetryId.HasValue ? telemetryId.Value : TelemetryId;

                if (newVersion == Version &&
                    newFilePath == FilePath &&
                    newTelemetryId == TelemetryId)
                {
                    return this;
                }

                return new SolutionAttributes(Id, newVersion, newFilePath, newTelemetryId);
            }
150

V
vsadov 已提交
151
            bool IObjectWritable.ShouldReuseInSerialization => true;
152

153 154 155 156 157 158 159 160 161
            public void WriteTo(ObjectWriter writer)
            {
                Id.WriteTo(writer);

                // TODO: figure out a way to send version info over as well.
                //       right now, version get updated automatically, so 2 can't be exactly match
                // info.Version.WriteTo(writer);

                writer.WriteString(FilePath);
162
                writer.WriteGuid(TelemetryId);
163 164 165 166 167 168 169
            }

            public static SolutionAttributes ReadFrom(ObjectReader reader)
            {
                var solutionId = SolutionId.ReadFrom(reader);
                // var version = VersionStamp.ReadFrom(reader);
                var filePath = reader.ReadString();
170
                var telemetryId = reader.ReadGuid();
171

172
                return new SolutionAttributes(solutionId, VersionStamp.Create(), filePath, telemetryId);
173 174 175
            }

            Checksum IChecksummedObject.Checksum
176
                => _lazyChecksum ??= Checksum.Create(WellKnownSynchronizationKind.SolutionAttributes, this);
P
Pilchie 已提交
177 178
        }
    }
179
}