private static TypeParameterConstraintFlags GetTypeConstraintFlags()

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