File: Emit\EditAndContinue\DeletedSourceDefinition.cs
Web Access
Project: src\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.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.Symbols;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.Emit.EditAndContinue
{
    internal abstract class DeletedSourceDefinition<T> : IDefinition
        where T : IDefinition
    {
        public readonly T OldDefinition;
 
        private readonly Dictionary<ITypeDefinition, DeletedSourceTypeDefinition> _typesUsedByDeletedMembers;
 
        /// <summary>
        /// Constructs a deleted definition
        /// </summary>
        /// <param name="oldDefinition">The old definition of the member</param>
        /// <param name="typesUsedByDeletedMembers">
        /// Cache of type definitions used in signatures of deleted members. Used so that if a method 'C M(C c)' is deleted
        /// we use the same <see cref="DeletedSourceTypeDefinition"/> instance for the method return type, and the parameter type.
        /// </param>
        protected DeletedSourceDefinition(T oldDefinition, Dictionary<ITypeDefinition, DeletedSourceTypeDefinition> typesUsedByDeletedMembers)
        {
            OldDefinition = oldDefinition;
 
            _typesUsedByDeletedMembers = typesUsedByDeletedMembers;
        }
 
        public bool IsEncDeleted
            => true;
 
        public IEnumerable<ICustomAttribute> GetAttributes(EmitContext context)
            // attributes shouldn't be emitted for deleted definitions
            => throw ExceptionUtilities.Unreachable();
 
        public ISymbolInternal? GetInternalSymbol()
            => OldDefinition.GetInternalSymbol();
 
        public abstract void Dispatch(MetadataVisitor visitor);
 
        public IDefinition? AsDefinition(EmitContext context)
            => this;
 
        protected ImmutableArray<DeletedSourceParameterDefinition> WrapParameters(ImmutableArray<IParameterDefinition> parameters)
        {
            return parameters.SelectAsArray(p => new DeletedSourceParameterDefinition(p, _typesUsedByDeletedMembers));
        }
 
        [return: NotNullIfNotNull(nameof(typeReference))]
        protected ITypeReference? WrapType(ITypeReference? typeReference)
        {
            if (typeReference is ITypeDefinition typeDef)
            {
                if (!_typesUsedByDeletedMembers.TryGetValue(typeDef, out var deletedType))
                {
                    deletedType = new DeletedSourceTypeDefinition(typeDef, _typesUsedByDeletedMembers);
                    _typesUsedByDeletedMembers.Add(typeDef, deletedType);
                }
 
                return deletedType;
            }
 
            return typeReference;
        }
    }
}