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;
}
}
}