Skip to content

Commit f38d8b5

Browse files
committed
fix not to set nullability annotation to generic parameters which have no constraints
1 parent 7158bc0 commit f38d8b5

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating/CSharpTypeFormatter.FormatTypeNameWithNullabilityAnnotation.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ FormatTypeNameOptions options
104104
.Append(nullabilityAnnotationForByRefParameter);
105105
}
106106

107+
if (targetType.IsGenericParameter && targetType.HasGenericParameterNoConstraints())
108+
// generic parameter which has no constraints must not have nullability annotation
109+
return builder.Append(GetTypeName(targetType, options));
110+
107111
if (!targetType.IsGenericParameter) {
108112
if (targetType.IsNested && options.WithDeclaringTypeName)
109113
builder.Append(FormatTypeNameCore(targetType.GetDeclaringTypeOrThrow(), options)).Append('.');

src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection/TypeGenericParameterExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,16 @@ genericParameter.DeclaringMethod is not null &&
7777
continue;
7878
}
7979
}
80+
81+
public static bool HasGenericParameterNoConstraints(this Type genericParameter)
82+
{
83+
ValidateGenericParameterArgument(genericParameter, nameof(genericParameter));
84+
85+
var genericParameterConstraintAttrs = genericParameter.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
86+
87+
if (genericParameterConstraintAttrs != GenericParameterAttributes.None)
88+
return false;
89+
90+
return !HasGenericParameterNotNullConstraint(genericParameter);
91+
}
8092
}

tests/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating/Generator.MemberDeclaration.Parameters.NullabilityAnnotations.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,38 @@ public void RefType(string p) { }
141141
[MemberDeclarationTestCase($"public void {nameof(NullableRefType)}(string p) {{}}", MemberEnableNullabilityAnnotations = false)]
142142
[MemberDeclarationTestCase($"public void {nameof(NullableRefType)}(string? p) {{}}", MemberEnableNullabilityAnnotations = true)]
143143
public void NullableRefType(string? p) { }
144+
145+
[MemberDeclarationTestCase($"public void {nameof(GenericType)}<T>(T p) {{}}", MemberEnableNullabilityAnnotations = false)]
146+
[MemberDeclarationTestCase($"public void {nameof(GenericType)}<T>(T p) {{}}", MemberEnableNullabilityAnnotations = true)]
147+
public void GenericType<T>(T p) { }
148+
149+
[MemberDeclarationTestCase($"public void {nameof(NullableGenericType)}<T>(T p) {{}}", MemberEnableNullabilityAnnotations = false)]
150+
[MemberDeclarationTestCase($"public void {nameof(NullableGenericType)}<T>(T p) {{}}", MemberEnableNullabilityAnnotations = true)]
151+
public void NullableGenericType<T>(T? p) { }
152+
153+
[MemberDeclarationTestCase($"public void {nameof(GenericNotNullType)}<TNotNull>(TNotNull p) where TNotNull : notnull {{}}", MemberEnableNullabilityAnnotations = false)]
154+
[MemberDeclarationTestCase($"public void {nameof(GenericNotNullType)}<TNotNull>(TNotNull p) where TNotNull : notnull {{}}", MemberEnableNullabilityAnnotations = true)]
155+
public void GenericNotNullType<TNotNull>(TNotNull p) where TNotNull : notnull { }
156+
157+
[MemberDeclarationTestCase($"public void {nameof(NullableGenericNotNullType)}<TNotNull>(TNotNull p) where TNotNull : notnull {{}}", MemberEnableNullabilityAnnotations = false)]
158+
[MemberDeclarationTestCase($"public void {nameof(NullableGenericNotNullType)}<TNotNull>(TNotNull? p) where TNotNull : notnull {{}}", MemberEnableNullabilityAnnotations = true)]
159+
public void NullableGenericNotNullType<TNotNull>(TNotNull? p) where TNotNull : notnull { }
160+
161+
[MemberDeclarationTestCase($"public void {nameof(GenericValueType)}<TValue>(TValue p) where TValue : struct {{}}", MemberEnableNullabilityAnnotations = false)]
162+
[MemberDeclarationTestCase($"public void {nameof(GenericValueType)}<TValue>(TValue p) where TValue : struct {{}}", MemberEnableNullabilityAnnotations = true)]
163+
public void GenericValueType<TValue>(TValue p) where TValue : struct { }
164+
165+
[MemberDeclarationTestCase($"public void {nameof(NullableGenericValueType)}<TValue>(TValue? p) where TValue : struct {{}}", MemberEnableNullabilityAnnotations = false)]
166+
[MemberDeclarationTestCase($"public void {nameof(NullableGenericValueType)}<TValue>(TValue? p) where TValue : struct {{}}", MemberEnableNullabilityAnnotations = true)]
167+
public void NullableGenericValueType<TValue>(TValue? p) where TValue : struct { }
168+
169+
[MemberDeclarationTestCase($"public void {nameof(GenericRefType)}<TRef>(TRef p) where TRef : class {{}}", MemberEnableNullabilityAnnotations = false)]
170+
[MemberDeclarationTestCase($"public void {nameof(GenericRefType)}<TRef>(TRef p) where TRef : class {{}}", MemberEnableNullabilityAnnotations = true)]
171+
public void GenericRefType<TRef>(TRef p) where TRef : class { }
172+
173+
[MemberDeclarationTestCase($"public void {nameof(NullableGenericRefType)}<TRef>(TRef p) where TRef : class {{}}", MemberEnableNullabilityAnnotations = false)]
174+
[MemberDeclarationTestCase($"public void {nameof(NullableGenericRefType)}<TRef>(TRef? p) where TRef : class {{}}", MemberEnableNullabilityAnnotations = true)]
175+
public void NullableGenericRefType<TRef>(TRef? p) where TRef : class { }
144176
}
145177
}
146178
#endif

0 commit comments

Comments
 (0)