File: Experimental\TypeReferenceVisitor.cs
Web Access
Project: src\src\Microsoft.Cci.Extensions\Microsoft.Cci.Extensions.csproj (Microsoft.Cci.Extensions)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using Microsoft.Cci;
 
namespace Microsoft.Cci.Extensions
{
#pragma warning disable 612,618
    public class TypeReferenceVisitor : BaseMetadataTraverser
#pragma warning restore 612,618
    {
        private readonly ICollection<ITypeReference> _typeReferences;
        private readonly ICollection<IAssemblyReference> _assemblyReferences;
 
        public TypeReferenceVisitor()
        {
            _typeReferences = new HashSet<ITypeReference>();
            _assemblyReferences = new HashSet<IAssemblyReference>(new AssemblyReferenceComparer());
        }
 
        public ICollection<ITypeReference> TypeReferences { get { return _typeReferences; } }
 
        public ICollection<IAssemblyReference> AssemblyReferences { get { return _assemblyReferences; } }
 
        public override void Visit(INamespaceTypeReference type)
        {
            AddTypeReference(type);
            base.Visit(type);
        }
 
        public override void Visit(INestedTypeReference type)
        {
            AddTypeReference(type);
            base.Visit(type);
        }
 
        public override void Visit(ICustomAttribute attribute)
        {
            Visit(attribute.Type); // For some reason the base visitor doesn't visit the attribute type
            base.Visit(attribute);
        }
 
        public override void Visit(IMethodDefinition method)
        {
            base.Visit(method);
            Visit(method.Body);
        }
 
        public override void Visit(IMethodReference method)
        {
            base.Visit(method);
            Visit(method.ContainingType);
        }
 
        private void AddTypeReference(ITypeReference type)
        {
            Contract.Assert(type == type.UnWrap());
 
            _typeReferences.Add(type);
            IAssemblyReference asmRef = type.GetAssemblyReference();
 
            if (asmRef != null)
                _assemblyReferences.Add(asmRef);
        }
 
        private class AssemblyReferenceComparer : IEqualityComparer<IAssemblyReference>
        {
            public bool Equals(IAssemblyReference x, IAssemblyReference y)
            {
                return x.AssemblyIdentity.Equals(y.AssemblyIdentity);
            }
 
            public int GetHashCode(IAssemblyReference obj)
            {
                return obj.AssemblyIdentity.GetHashCode();
            }
        }
    }
}