| File: MetadataReference\MetadataReferenceProperties.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// 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 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, 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, ((int)_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); } } }