diff --git a/InterfaceGenerator.Tests/MethodGenerationTests.cs b/InterfaceGenerator.Tests/MethodGenerationTests.cs index fb9a748..83fe29d 100644 --- a/InterfaceGenerator.Tests/MethodGenerationTests.cs +++ b/InterfaceGenerator.Tests/MethodGenerationTests.cs @@ -202,6 +202,34 @@ public void GenericVoidMethodWithConstraints_IsImplemented() _sut.GenericVoidMethodWithConstraints(); } + [Fact] + public void GenericVoidMethodWithValueTypeConstraints_IsImplemented() + { + var method = typeof(IMethodsTestService) + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithValueTypeConstraints)); + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var genericArgs = method.GetGenericArguments(); + genericArgs.Should().HaveCount(2); + + genericArgs[0].IsValueType.Should().BeTrue(); + genericArgs[0] + .GenericParameterAttributes.Should() + .HaveFlag(GenericParameterAttributes.DefaultConstructorConstraint) + .And.HaveFlag(GenericParameterAttributes.NotNullableValueTypeConstraint); + + genericArgs[1].IsValueType.Should().BeTrue(); + genericArgs[1] + .GenericParameterAttributes.Should() + .HaveFlag(GenericParameterAttributes.DefaultConstructorConstraint) + .And.HaveFlag(GenericParameterAttributes.NotNullableValueTypeConstraint); + + _sut.GenericVoidMethodWithValueTypeConstraints, long>(); + } + [Fact] public void VoidMethodWithOptionalParams_IsImplemented() { @@ -315,6 +343,12 @@ public void GenericVoidMethodWithConstraints() { } + public void GenericVoidMethodWithValueTypeConstraints() + where TX : struct + where TY : unmanaged + { + } + public void VoidMethodWithOptionalParams( string stringLiteral = "cGFyYW0=", string stringConstant = StringConstant, diff --git a/InterfaceGenerator/TypeParameterSymbolExtensions.cs b/InterfaceGenerator/TypeParameterSymbolExtensions.cs index bfaa883..53cf1b3 100644 --- a/InterfaceGenerator/TypeParameterSymbolExtensions.cs +++ b/InterfaceGenerator/TypeParameterSymbolExtensions.cs @@ -7,23 +7,21 @@ internal static class TypeParameterSymbolExtensions { public static IEnumerable EnumGenericConstraints(this ITypeParameterSymbol symbol) { - // the class/struct/unmanaged/notnull constraint has to be the last + // the class/struct/unmanaged/notnull constraint has to be the first + // and cannot be combined with one another if (symbol.HasNotNullConstraint) { yield return "notnull"; } - - if (symbol.HasValueTypeConstraint) + else if (symbol.HasUnmanagedTypeConstraint) { - yield return "struct"; + yield return "unmanaged"; } - - if (symbol.HasUnmanagedTypeConstraint) + else if (symbol.HasValueTypeConstraint) { - yield return "unmanaged"; + yield return "struct"; } - - if (symbol.HasReferenceTypeConstraint) + else if (symbol.HasReferenceTypeConstraint) { yield return symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated ? "class?"