in ReSharper.FSharp/src/FSharp/FSharp.Psi/src/Impl/Cache2/Parts/FSharpTypeParametersOwnerPart.cs [173:220]
private static TypeParameterConstraintFlags GetTypeConstraintFlags(string paramName, ITypeConstraint constraint)
{
bool IsSimpleNamedTypeUsage(ITypeUsage typeUsage, string name) =>
typeUsage.IgnoreInnerParens() is INamedTypeUsage {ReferenceName: {Qualifier: null} returnName} &&
returnName.ShortName == name;
var flags = TypeParameterConstraintFlags.None;
switch (constraint)
{
case IValueTypeConstraint _:
flags |= TypeParameterConstraintFlags.ValueType;
break;
case INullConstraint _:
case IReferenceTypeConstraint _:
flags |= TypeParameterConstraintFlags.ReferenceType;
break;
case IUnmanagedTypeConstraint _:
flags |= TypeParameterConstraintFlags.Unmanaged;
break;
case IMemberConstraint memberConstraint:
if (!(memberConstraint.MemberSignature is IConstructorSignature ctorSig))
break;
if (!(ctorSig.ReturnTypeInfo?.ReturnType.IgnoreParameterSignature() is IFunctionTypeUsage typeUsage))
break;
if (IsSimpleNamedTypeUsage(typeUsage.ReturnTypeUsage, paramName) &&
IsSimpleNamedTypeUsage(typeUsage.ArgumentTypeUsage, "unit"))
flags |= TypeParameterConstraintFlags.Constructor;
break;
case ISubtypeConstraint _:
case IDefaultsToConstraint _:
case IComparableConstraint _:
case IEquatableConstraint _:
case IDelegateConstraint _:
case IEnumConstraint _:
break;
default:
throw new ArgumentOutOfRangeException(nameof(constraint));
}
return flags;
}