public static FSharpParameterIndex? TryGetFSharpParameterIndex()

in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/FSharpArgumentsOwnerUtil.cs [104:189]


    public static FSharpParameterIndex? TryGetFSharpParameterIndex([NotNull] IFSharpTypeOwnerNode node,
      out IFSharpArgumentsOwner argOwner)
    {
      argOwner = null;

      if (node is IFSharpExpression expr)
      {
        var argGroupExpr = GetArgGroupExpr(out var parameterIndex, out var namedArg);
        argOwner = FSharpArgumentOwnerNavigator.GetByArgumentExpression(argGroupExpr);
        if (argOwner == null)
          return null;

        if (argOwner is IAttribute or INewExpr)
          return new FSharpParameterIndex(0, parameterIndex, namedArg);

        var paramGroupIndex = 0;
        while (argOwner is IPrefixAppExpr prefixAppExpr)
        {
          if (prefixAppExpr.FunctionExpression is IPrefixAppExpr funPrefixAppExpr)
          {
            argOwner = funPrefixAppExpr;
            paramGroupIndex++;
          }
          else
            break;
        }

        return new FSharpParameterIndex(paramGroupIndex, parameterIndex, namedArg);
      }

      if (node is IFSharpPattern pat)
      {
        var argPat = GetArgGroupPat(out var parameterIndex, out var namedArg);
        if (ParametersOwnerPatNavigator.GetByParameter(argPat) is { } parametersOwnerPat)
        {
          argOwner = parametersOwnerPat;
          return new FSharpParameterIndex(0, parameterIndex, namedArg);
        }
      }

      return null;

      IFSharpPattern GetArgGroupPat(out int? parameterIndex, out string namedArg)
      {
        parameterIndex = null;
        namedArg = null;

        if (FieldPatNavigator.GetByPattern(pat) is { } fieldPat)
        {
          namedArg = fieldPat.ShortName;
          return NamedUnionCaseFieldsPatNavigator.GetByFieldPattern(fieldPat);
        }
        else
        {
          var tupleItemPat = pat.IgnoreParentParens();
          var tuplePat = TuplePatNavigator.GetByPattern(tupleItemPat);
          parameterIndex = tuplePat?.Patterns.IndexOf(tupleItemPat);

          return tuplePat.IgnoreParentParens() ?? tupleItemPat;
        }
      }

      IFSharpExpression GetArgGroupExpr(out int? parameterIndex, out string namedArg)
      {
        parameterIndex = null;
        namedArg = null;

        var binaryAppExpr = BinaryAppExprNavigator.GetByRightArgument(expr);
        if (binaryAppExpr is { Operator.ShortName: "=", LeftArgument: IReferenceExpr { IsSimpleName: true } refExpr })
        {
          namedArg = refExpr.ShortName;
          var tupleExpr = TupleExprNavigator.GetByExpression(binaryAppExpr);
          var parenExpr = ParenExprNavigator.GetByInnerExpression((IFSharpExpression)tupleExpr ?? binaryAppExpr);
          return parenExpr;
        }
        else
        {
          var tupleItemExpr = expr.IgnoreParentParens();
          var tupleExpr = TupleExprNavigator.GetByExpression(tupleItemExpr);
          parameterIndex = tupleExpr?.Expressions.IndexOf(tupleItemExpr);

          var argGroupExpr = tupleExpr.IgnoreParentParens() ?? tupleItemExpr;
          return argGroupExpr;
        }
      }
    }