/// <summary>
        /// Checks if a given method implements IEqualityComparer.Equals or IEquatable.Equals.
        /// </summary>
        private static bool IsEqualsInterfaceImplementation(IMethodSymbol method, Compilation compilation)
        {
            if (method.Name != WellKnownMemberNames.ObjectEquals)
            {
                return(false);
            }

            int paramCount = method.Parameters.Length;

            if (method.ReturnType.SpecialType == SpecialType.System_Boolean &&
                (paramCount == 1 || paramCount == 2))
            {
                // Substitute the type of the first parameter of Equals in the generic interface and then check if that
                // interface method is implemented by the given method.
                INamedTypeSymbol?iEqualityComparer = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsGenericIEqualityComparer1);
                if (method.IsImplementationOfInterfaceMethod(method.Parameters.First().Type, iEqualityComparer, WellKnownMemberNames.ObjectEquals))
                {
                    return(true);
                }

                // Substitute the type of the first parameter of Equals in the generic interface and then check if that
                // interface method is implemented by the given method.
                INamedTypeSymbol?iEquatable = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIEquatable1);
                if (method.IsImplementationOfInterfaceMethod(method.Parameters.First().Type, iEquatable, WellKnownMemberNames.ObjectEquals))
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// Checks if a given method implements IEqualityComparer.GetHashCode or IHashCodeProvider.GetHashCode.
        /// </summary>
        /// <param name="method"></param>
        /// <param name="compilation"></param>
        /// <returns></returns>
        private static bool IsGetHashCodeInterfaceImplementation(IMethodSymbol method, Compilation compilation)
        {
            if (method.Name != WellKnownMemberNames.ObjectGetHashCode)
            {
                return(false);
            }

            if (method.ReturnType.SpecialType == SpecialType.System_Int32 && method.Parameters.Length == 1)
            {
                // Substitute the type of the first parameter of Equals in the generic interface and then check if that
                // interface method is implemented by the given method.
                INamedTypeSymbol?iEqualityComparer = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsGenericIEqualityComparer1);
                if (method.IsImplementationOfInterfaceMethod(method.Parameters.First().Type, iEqualityComparer, WellKnownMemberNames.ObjectGetHashCode))
                {
                    return(true);
                }

                INamedTypeSymbol?iHashCodeProvider = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsIHashCodeProvider);
                if (method.IsImplementationOfInterfaceMethod(null, iHashCodeProvider, WellKnownMemberNames.ObjectGetHashCode))
                {
                    return(true);
                }
            }

            return(false);
        }
Example #3
0
        /// <summary>
        /// Checks if the given method implements IDisposable.Dispose()
        /// </summary>
        public static bool IsDisposeImplementation(this IMethodSymbol method, INamedTypeSymbol iDisposable)
        {
            if (method.ReturnType.SpecialType == SpecialType.System_Void && method.Parameters.Length == 0)
            {
                // Identify the implementor of IDisposable.Dispose in the given method's containing type and check
                // if it is the given method.
                if (method.IsImplementationOfInterfaceMethod(null, iDisposable, "Dispose"))
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// Checks if the given method implements <see cref="IDisposable.Dispose"/> or overrides an implementation of <see cref="IDisposable.Dispose"/>.
        /// </summary>
        public static bool IsDisposeImplementation(this IMethodSymbol method, INamedTypeSymbol iDisposable)
        {
            if (method == null)
            {
                return(false);
            }

            if (method.IsOverride)
            {
                return(method.OverriddenMethod.IsDisposeImplementation(iDisposable));
            }

            // Identify the implementor of IDisposable.Dispose in the given method's containing type and check
            // if it is the given method.
            return(method.ReturnsVoid &&
                   method.Parameters.Length == 0 &&
                   method.IsImplementationOfInterfaceMethod(null, iDisposable, "Dispose"));
        }
        /// <summary>
        /// Checks if the given method implements 'System.Runtime.Serialization.IDeserializationCallback.OnDeserialization' or overrides an implementation of 'System.Runtime.Serialization.IDeserializationCallback.OnDeserialization'/>.
        /// </summary>
        public static bool IsOnDeserializationImplementation(this IMethodSymbol method, INamedTypeSymbol iDeserializationCallback)
        {
            if (method == null)
            {
                return(false);
            }

            if (method.IsOverride)
            {
                return(method.OverriddenMethod.IsOnDeserializationImplementation(iDeserializationCallback));
            }

            // Identify the implementor of IDisposable.Dispose in the given method's containing type and check
            // if it is the given method.
            return(method.ReturnsVoid &&
                   method.Parameters.Length == 1 &&
                   method.Parameters[0].Type.SpecialType == SpecialType.System_Object &&
                   method.IsImplementationOfInterfaceMethod(null, iDeserializationCallback, "OnDeserialization"));
        }
        /// <summary>
        /// Checks if a given method implements IEqualityComparer.GetHashCode or IHashCodeProvider.GetHashCode.
        /// </summary>
        /// <param name="method"></param>
        /// <param name="compilation"></param>
        /// <returns></returns>
        private static bool IsGetHashCodeInterfaceImplementation(IMethodSymbol method, Compilation compilation)
        {
            if (method.Name != WellKnownMemberNames.ObjectGetHashCode)
            {
                return false;
            }

            if (method.ReturnType.SpecialType == SpecialType.System_Int32 && method.Parameters.Length == 1)
            {
                // Substitute the type of the first parameter of Equals in the generic interface and then check if that
                // interface method is implemented by the given method.
                INamedTypeSymbol iEqualityComparer = WellKnownTypes.GenericIEqualityComparer(compilation);
                if (method.IsImplementationOfInterfaceMethod(method.Parameters.First().Type, iEqualityComparer, WellKnownMemberNames.ObjectGetHashCode))
                {
                    return true;
                }


                INamedTypeSymbol iHashCodeProvider = WellKnownTypes.IHashCodeProvider(compilation);
                if (method.IsImplementationOfInterfaceMethod(null, iHashCodeProvider, WellKnownMemberNames.ObjectGetHashCode))
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// Checks if a given method implements IEqualityComparer.Equals or IEquatable.Equals.
        /// </summary>
        private static bool IsEqualsInterfaceImplementation(IMethodSymbol method, Compilation compilation)
        {
            if (method.Name != WellKnownMemberNames.ObjectEquals)
            {
                return false;
            }

            int paramCount = method.Parameters.Length;
            if (method.ReturnType.SpecialType == SpecialType.System_Boolean &&
                (paramCount == 1 || paramCount == 2))
            {
                // Substitute the type of the first parameter of Equals in the generic interface and then check if that
                // interface method is implemented by the given method.
                INamedTypeSymbol iEqualityComparer = WellKnownTypes.GenericIEqualityComparer(compilation);
                if (method.IsImplementationOfInterfaceMethod(method.Parameters.First().Type, iEqualityComparer, WellKnownMemberNames.ObjectEquals))
                {
                    return true;
                }

                // Substitute the type of the first parameter of Equals in the generic interface and then check if that
                // interface method is implemented by the given method.
                INamedTypeSymbol iEquatable = WellKnownTypes.GenericIEquatable(compilation);
                if (method.IsImplementationOfInterfaceMethod(method.Parameters.First().Type, iEquatable, WellKnownMemberNames.ObjectEquals))
                {
                    return true;
                }
            }

            return false;
        }