in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Util/FSharpPatternUtil.cs [170:221]
public static void SetParameterFcsType(this IList<IFSharpPattern> parameterPatternGroups,
[NotNull] IFSharpParameterOwnerDeclaration paramOwnerDecl, FSharpParameterIndex index, FSharpType fcsType)
{
var typeAnnotationUtil = paramOwnerDecl.GetFSharpTypeAnnotationUtil();
if (parameterPatternGroups.GetParameterDeclaration(index) is IReferencePat refPat)
{
var declPat = refPat.TryGetContainingParameterDeclarationPattern();
typeAnnotationUtil.SetPatternFcsType(declPat, fcsType);
return;
}
if (parameterPatternGroups.ElementAtOrDefault(index.GroupIndex) is not { } groupPattern)
return;
if (index.ParameterIndex is { } parameterIndex)
{
if (groupPattern.IgnoreInnerParens() is ITypedPat { TypeUsage: ITupleTypeUsage tupleTypeUsage })
{
if (tupleTypeUsage.Items.ElementAtOrDefault(parameterIndex) is { } paramTypeUsage)
typeAnnotationUtil.ReplaceWithFcsType(paramTypeUsage, fcsType);
}
else
{
// todo: union case
if (paramOwnerDecl.GetFcsSymbol() is not FSharpMemberOrFunctionOrValue mfv)
return;
var fcsParamGroup = mfv.CurriedParameterGroups.ElementAtOrDefault(index.GroupIndex);
if (fcsParamGroup == null)
return;
var fcsGroupParameterCount = GetFcsGroupParameterCount(fcsParamGroup);
if (fcsGroupParameterCount == 1)
{
typeAnnotationUtil.SetPatternFcsType(groupPattern, fcsType);
return;
}
var factory = paramOwnerDecl.CreateElementFactory();
var tupleTypeString = Enumerable.Repeat("_", fcsGroupParameterCount).Join(" * ");
var newTypeUsage = factory.CreateTypeUsage(tupleTypeString, TypeUsageContext.TopLevel);
var typeUsage = (ITupleTypeUsage)typeAnnotationUtil.SetPatternTypeUsage(groupPattern, newTypeUsage).TypeUsage;
if (typeUsage.Items.ElementAtOrDefault(parameterIndex) is { } paramTypeUsage)
typeAnnotationUtil.ReplaceWithFcsType(paramTypeUsage, fcsType);
}
}
else
{
typeAnnotationUtil.SetPatternFcsType(groupPattern, fcsType);
}
}