Repository: PowerShell/PowerShell
File: src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs (C#)

Code before:
                    methodName = "op_Modulus";
                    break;

                case TokenKind.Shl:
                    methodName = "op_LeftShift";
                    break;

                case TokenKind.Shr:
                    methodName = "op_RightShift";
                    break;

                default:
                    return lhsTypes;
            }

            List<PSTypeName> rhsTypes = InferTypes(binaryExpressionAst.Right).ToList();
            var addedReturnTypes = new HashSet<string>();
            var result = new List<PSTypeName>();
            foreach (var lType in lhsTypes)
            {
                if (lType.Type is null)
                {
                    continue;
                }

                foreach (MethodInfo method in lType.Type.GetMethods(BindingFlags.Public | BindingFlags.Static))
                {
                    if (!method.Name.Equals(methodName, StringComparison.Ordinal))
                    {
                        continue;
                    }

                    if (rhsTypes.Count == 0)
                    {
                        if (addedReturnTypes.Add(method.ReturnType.FullName))
                        {
                            result.Add(new PSTypeName(method.ReturnType));
                        }

                        continue;
                    }

                    ParameterInfo[] methodParams = method.GetParameters();
                    if (methodParams.Length != 2)
                    {
                        continue;
                    }

                    bool addType = false;
                    foreach (PSTypeName rType in rhsTypes)
                    {

Review comment (performance):
Can we use one of  `GetMethod(string name, ...)` overloads? I guess it could be more efficient for filtering by name and parameters.

Code after:
                    methodName = "op_Modulus";
                    break;

                case TokenKind.Shl:
                    methodName = "op_LeftShift";
                    break;

                case TokenKind.Shr:
                    methodName = "op_RightShift";
                    break;

                default:
                    return lhsTypes;
            }

            List<PSTypeName> rhsTypes = InferTypes(binaryExpressionAst.Right).ToList();
            HashSet<string> addedReturnTypes = new HashSet<string>();
            List<PSTypeName> result = new List<PSTypeName>();
            foreach (PSTypeName lType in lhsTypes)
            {
                if (lType.Type is null)
                {
                    continue;
                }

                foreach (MethodInfo method in lType.Type.GetMethods(BindingFlags.Public | BindingFlags.Static))
                {
                    if (!method.Name.Equals(methodName, StringComparison.Ordinal))
                    {
                        continue;
                    }

                    if (rhsTypes.Count == 0)
                    {
                        if (addedReturnTypes.Add(method.ReturnType.FullName))
                        {
                            result.Add(new PSTypeName(method.ReturnType));
                        }

                        continue;
                    }

                    ParameterInfo[] methodParams = method.GetParameters();
                    if (methodParams.Length != 2)
                    {
                        continue;
                    }

                    foreach (PSTypeName rType in rhsTypes)
                    {
                        if (rType.Type is not null && rType.Type.IsAssignableTo(methodParams[1].ParameterType))