File: CallAnalysis\CallAnalyzer.Handlers.cs
Web Access
Project: src\src\Analyzers\Microsoft.Analyzers.Local\Microsoft.Analyzers.Local.csproj (Microsoft.Analyzers.Local)
// 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.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
 
namespace Microsoft.Extensions.LocalAnalyzers.CallAnalysis;
 
public partial class CallAnalyzer
{
    private sealed class Handlers
    {
        private readonly State _state;
 
        public Handlers(State state)
        {
            _state = state;
        }
 
        public void HandleInvocation(OperationAnalysisContext context)
        {
            var op = (IInvocationOperation)context.Operation;
            var target = op.TargetMethod;
 
            if (target != null)
            {
                if (_state.Methods.TryGetValue(target.OriginalDefinition, out var handlers))
                {
                    if (op.Arguments.Length == target.Parameters.Length)
                    {
                        foreach (var handler in handlers)
                        {
                            handler(context, op);
                        }
                    }
                }
 
                if (_state.InterfaceMethodNames.Contains(target.Name))
                {
                    var type = target.ContainingType;
                    if (type.TypeKind == TypeKind.Interface)
                    {
                        if (_state.Interfaces.TryGetValue(type, out var l))
                        {
                            foreach (var h in l)
                            {
                                if (SymbolEqualityComparer.Default.Equals(target, h.Method))
                                {
                                    foreach (var action in h.Actions)
                                    {
                                        action(context, op);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        foreach (var iface in type.AllInterfaces)
                        {
                            if (_state.Interfaces.TryGetValue(iface, out var l))
                            {
                                foreach (var h in l)
                                {
                                    var impl = type.FindImplementationForInterfaceMember(h.Method);
                                    if (SymbolEqualityComparer.Default.Equals(target, impl))
                                    {
                                        foreach (var action in h.Actions)
                                        {
                                            action(context, op);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
 
        public void HandleObjectCreation(OperationAnalysisContext context)
        {
            var op = (IObjectCreationOperation)context.Operation;
            if (op.Constructor != null)
            {
                if (_state.Ctors.TryGetValue(op.Constructor.OriginalDefinition, out var handlers))
                {
                    if (op.Arguments.Length == op.Constructor.Parameters.Length)
                    {
                        foreach (var handler in handlers)
                        {
                            handler(context, op);
                        }
                    }
                }
            }
        }
 
        public void HandlePropertyReference(OperationAnalysisContext context)
        {
            var op = (IPropertyReferenceOperation)context.Operation;
            if (_state.Props.TryGetValue(op.Property, out var handlers))
            {
                foreach (var handler in handlers)
                {
                    handler(context, op);
                }
            }
        }
 
        public void HandleThrow(OperationAnalysisContext context)
        {
            var op = (IThrowOperation)context.Operation;
 
            if (op.Exception is IConversionOperation convOp)
            {
                if (convOp.Operand is IObjectCreationOperation creationOp)
                {
                    if (creationOp.Type != null)
                    {
                        if (_state.ExceptionTypes.TryGetValue(creationOp.Type, out var handlers))
                        {
                            foreach (var handler in handlers)
                            {
                                handler(context, op);
                            }
                        }
                    }
                }
            }
        }
    }
}