| File: Mapping\NamespaceMapper.cs | Web Access |
| Project: src\sdk\src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompatibility\Microsoft.DotNet.ApiCompatibility.csproj (Microsoft.DotNet.ApiCompatibility) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.CodeAnalysis; using Microsoft.DotNet.ApiCompatibility.Rules; namespace Microsoft.DotNet.ApiCompatibility.Mapping { /// <summary> /// Object that represents a mapping between two <see cref="INamespaceSymbol"/> objects. /// This also holds a list of <see cref="ITypeMapper"/> to represent the mapping of types in between /// <see cref="IElementMapper{T}.Left"/> and <see cref="IElementMapper{T}.Right"/>. /// </summary> public class NamespaceMapper : ElementMapper<INamespaceSymbol>, INamespaceMapper { private readonly Dictionary<ITypeSymbol, ITypeMapper> _types; private bool _expandedTree = false; private readonly bool _typeForwardsOnly; /// <inheritdoc /> public IAssemblyMapper ContainingAssembly { get; } /// <summary> /// Instantiates a namespace mapper. /// </summary> /// <param name="ruleRunner">The <see cref="IRuleRunner"/> that compares the namespace mapper elements.</param> /// <param name="settings">The <see cref="IMapperSettings"/> used to compare the namespace mapper elements.</param> /// <param name="rightSetSize">The number of elements in the right set to compare.</param> /// <param name="containingAssembly">The containing <see cref="IAssemblyMapper"/>.</param> /// <param name="typeForwardsOnly">Indicates if <see cref="GetTypes"/> should return forwarded types only.</param> public NamespaceMapper(IRuleRunner ruleRunner, IMapperSettings settings, int rightSetSize, IAssemblyMapper containingAssembly, bool typeForwardsOnly = false) : base(ruleRunner, settings, rightSetSize) { ContainingAssembly = containingAssembly; _types = new Dictionary<ITypeSymbol, ITypeMapper>(Settings.SymbolEqualityComparer); _typeForwardsOnly = typeForwardsOnly; } /// <inheritdoc /> public IEnumerable<ITypeMapper> GetTypes() { if (!_expandedTree) { // if the _typeForwardsOnly flag is specified it means this namespace is already // populated with the resolved type forwards by the assembly mapper and that we // didn't find this namespace in the initial assembly. So we avoid getting the types // as that would return the types defined in the assembly where the type forwards // were resolved from. if (!_typeForwardsOnly) { AddOrCreateMappers(Left, ElementSide.Left); for (int i = 0; i < Right.Length; i++) { AddOrCreateMappers(Right[i], ElementSide.Right, i); } } _expandedTree = true; } return _types.Values; } /// <inheritdoc /> public void AddForwardedTypes(IEnumerable<INamedTypeSymbol>? forwardedTypes, ElementSide side, int setIndex) { AddOrCreateMappers(forwardedTypes, side, setIndex); } private void AddOrCreateMappers(INamespaceSymbol? symbol, ElementSide side, int setIndex = 0) { if (symbol == null) { return; } AddOrCreateMappers(symbol.GetTypeMembers(), side, setIndex); } private void AddOrCreateMappers(IEnumerable<ITypeSymbol>? types, ElementSide side, int setIndex) { // Silently return if the element hasn't been added yet. if (types == null) return; foreach (ITypeSymbol type in types) { if (Settings.SymbolFilter.Include(type)) { if (!_types.TryGetValue(type, out ITypeMapper? mapper)) { mapper = new TypeMapper(RuleRunner, Settings, Right.Length, this, null); _types.Add(type, mapper); } mapper.AddElement(type, side, setIndex); } } } } }