/
MetadataReferenceProperties.cs
188 lines (164 loc) · 7.63 KB
/
MetadataReferenceProperties.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// 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.
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
{
/// <summary>
/// Information about a metadata reference.
/// </summary>
public struct MetadataReferenceProperties : IEquatable<MetadataReferenceProperties>
{
private readonly MetadataImageKind _kind;
private readonly ImmutableArray<string> _aliases;
private readonly bool _embedInteropTypes;
/// <summary>
/// Default properties for a module reference.
/// </summary>
public static MetadataReferenceProperties Module => new MetadataReferenceProperties(MetadataImageKind.Module);
/// <summary>
/// Default properties for an assembly reference.
/// </summary>
public static MetadataReferenceProperties Assembly => new MetadataReferenceProperties(MetadataImageKind.Assembly);
/// <summary>
/// Initializes reference properties.
/// </summary>
/// <param name="kind">The image kind - assembly or module.</param>
/// <param name="aliases">Assembly aliases. Can't be set for a module.</param>
/// <param name="embedInteropTypes">True to embed interop types from the referenced assembly to the referencing compilation. Must be false for a module.</param>
public MetadataReferenceProperties(MetadataImageKind kind = MetadataImageKind.Assembly, ImmutableArray<string> aliases = default(ImmutableArray<string>), bool embedInteropTypes = false)
{
if (!kind.IsValid())
{
throw new ArgumentOutOfRangeException(nameof(kind));
}
if (kind == MetadataImageKind.Module)
{
if (embedInteropTypes)
{
throw new ArgumentException(CodeAnalysisResources.CannotEmbedInteropTypesFromModule, nameof(embedInteropTypes));
}
if (!aliases.IsDefaultOrEmpty)
{
throw new ArgumentException(CodeAnalysisResources.CannotAliasModule, nameof(aliases));
}
}
if (!aliases.IsDefaultOrEmpty)
{
foreach (var alias in aliases)
{
if (!alias.IsValidClrTypeName())
{
throw new ArgumentException(CodeAnalysisResources.InvalidAlias, nameof(aliases));
}
}
}
_kind = kind;
_aliases = aliases;
_embedInteropTypes = embedInteropTypes;
HasRecursiveAliases = false;
}
internal MetadataReferenceProperties(MetadataImageKind kind, ImmutableArray<string> aliases, bool embedInteropTypes, bool hasRecursiveAliases)
: this(kind, aliases, embedInteropTypes)
{
HasRecursiveAliases = hasRecursiveAliases;
}
/// <summary>
/// Returns <see cref="MetadataReferenceProperties"/> with specified aliases.
/// </summary>
/// <exception cref="ArgumentException">
/// <see cref="Kind"/> is <see cref="MetadataImageKind.Module"/>, as modules can't be aliased.
/// </exception>
public MetadataReferenceProperties WithAliases(IEnumerable<string> aliases)
{
return WithAliases(aliases.AsImmutableOrEmpty());
}
/// <summary>
/// Returns <see cref="MetadataReferenceProperties"/> with specified aliases.
/// </summary>
/// <exception cref="ArgumentException">
/// <see cref="Kind"/> is <see cref="MetadataImageKind.Module"/>, as modules can't be aliased.
/// </exception>
public MetadataReferenceProperties WithAliases(ImmutableArray<string> aliases)
{
return new MetadataReferenceProperties(_kind, aliases, _embedInteropTypes, HasRecursiveAliases);
}
/// <summary>
/// Returns <see cref="MetadataReferenceProperties"/> with <see cref="EmbedInteropTypes"/> set to specified value.
/// </summary>
/// <exception cref="ArgumentException"><see cref="Kind"/> is <see cref="MetadataImageKind.Module"/>, as interop types can't be embedded from modules.</exception>
public MetadataReferenceProperties WithEmbedInteropTypes(bool embedInteropTypes)
{
return new MetadataReferenceProperties(_kind, _aliases, embedInteropTypes, HasRecursiveAliases);
}
/// <summary>
/// Returns <see cref="MetadataReferenceProperties"/> with <see cref="HasRecursiveAliases"/> set to specified value.
/// </summary>
internal MetadataReferenceProperties WithRecursiveAliases(bool value)
{
return new MetadataReferenceProperties(_kind, _aliases, _embedInteropTypes, value);
}
/// <summary>
/// The image kind (assembly or module) the reference refers to.
/// </summary>
public MetadataImageKind Kind => _kind;
/// <summary>
/// Alias that represents a global declaration space.
/// </summary>
/// <remarks>
/// Namespaces in references whose <see cref="Aliases"/> contain <see cref="GlobalAlias"/> are available in global declaration space.
/// </remarks>
public static string GlobalAlias => "global";
/// <summary>
/// Aliases for the metadata reference. Empty if the reference has no aliases.
/// </summary>
/// <remarks>
/// In C# these aliases can be used in "extern alias" syntax to disambiguate type names.
/// </remarks>
public ImmutableArray<string> Aliases
{
get
{
// Simplify usage - we can't avoid the _aliases field being null but we can always return empty array here:
return _aliases.NullToEmpty();
}
}
/// <summary>
/// True if interop types defined in the referenced metadata should be embedded into the compilation referencing the metadata.
/// </summary>
public bool EmbedInteropTypes => _embedInteropTypes;
/// <summary>
/// True to apply <see cref="Aliases"/> recursively on the target assembly and on all its transitive dependencies.
/// False to apply <see cref="Aliases"/> only on the target assembly.
/// </summary>
internal bool HasRecursiveAliases { get; private set; }
public override bool Equals(object obj)
{
return obj is MetadataReferenceProperties && Equals((MetadataReferenceProperties)obj);
}
public bool Equals(MetadataReferenceProperties other)
{
return Aliases.SequenceEqual(other.Aliases)
&& _embedInteropTypes == other._embedInteropTypes
&& _kind == other._kind
&& HasRecursiveAliases == other.HasRecursiveAliases;
}
public override int GetHashCode()
{
return Hash.Combine(Hash.CombineValues(Aliases), Hash.Combine(_embedInteropTypes, Hash.Combine(HasRecursiveAliases, _kind.GetHashCode())));
}
public static bool operator ==(MetadataReferenceProperties left, MetadataReferenceProperties right)
{
return left.Equals(right);
}
public static bool operator !=(MetadataReferenceProperties left, MetadataReferenceProperties right)
{
return !left.Equals(right);
}
}
}