Skip to content

Commit

Permalink
Use NullabilityInfoContext to determine if member is nullable
Browse files Browse the repository at this point in the history
Add-on to domaindrivendev#3043
(should be no conflict)

Very similar to my previous PR: domaindrivendev#3041

In his PR, @VladimirTyrin surgically fixes a specific problem for all platforms. I suggest we use the new and fancy NET6+ toys when available, to avoid nullable logic completely in the future. I tested it with the same added test as in @VladimirTyrin's original PR.
  • Loading branch information
patrikwlund committed Aug 26, 2024
1 parent 16e2a94 commit 9fb2765
Showing 1 changed file with 26 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ namespace Swashbuckle.AspNetCore.SwaggerGen
{
public static class MemberInfoExtensions
{
#if !NET6_0_OR_GREATER
private const string NullableAttributeFullTypeName = "System.Runtime.CompilerServices.NullableAttribute";
private const string NullableFlagsFieldName = "NullableFlags";
private const string NullableContextAttributeFullTypeName = "System.Runtime.CompilerServices.NullableContextAttribute";
private const string FlagFieldName = "Flag";
private const int NotAnnotated = 1; // See https://github.com/dotnet/roslyn/blob/af7b0ebe2b0ed5c335a928626c25620566372dd1/docs/features/nullable-metadata.md?plain=1#L40
#endif

public static IEnumerable<object> GetInlineAndMetadataAttributes(this MemberInfo memberInfo)
{
Expand All @@ -34,8 +36,27 @@ public static IEnumerable<object> GetInlineAndMetadataAttributes(this MemberInfo
return attributes;
}

#if NET6_0_OR_GREATER
private static NullabilityInfo GetNullabilityInfo(this MemberInfo memberInfo)
{
var context = new NullabilityInfoContext();

return memberInfo switch
{
FieldInfo fieldInfo => context.Create(fieldInfo),
PropertyInfo propertyInfo => context.Create(propertyInfo),
EventInfo eventInfo => context.Create(eventInfo),
_ => throw new InvalidOperationException($"MemberInfo type {memberInfo.MemberType} is not supported.")
};
}
#endif

public static bool IsNonNullableReferenceType(this MemberInfo memberInfo)
{
#if NET6_0_OR_GREATER
var nullableInfo = GetNullabilityInfo(memberInfo);
return nullableInfo.ReadState == NullabilityState.NotNull;
#else
var memberType = memberInfo.MemberType == MemberTypes.Field
? ((FieldInfo)memberInfo).FieldType
: ((PropertyInfo)memberInfo).PropertyType;
Expand All @@ -57,16 +78,13 @@ public static bool IsNonNullableReferenceType(this MemberInfo memberInfo)
}

return false;
#endif
}

public static bool IsDictionaryValueNonNullable(this MemberInfo memberInfo)
{
#if NET6_0_OR_GREATER
var context = new NullabilityInfoContext();
var nullableInfo = memberInfo.MemberType == MemberTypes.Field
? context.Create((FieldInfo)memberInfo)
: context.Create((PropertyInfo)memberInfo);

var nullableInfo = GetNullabilityInfo(memberInfo);
if (nullableInfo.GenericTypeArguments.Length != 2)
{
var length = nullableInfo.GenericTypeArguments.Length;
Expand Down Expand Up @@ -124,6 +142,8 @@ public static bool IsDictionaryValueNonNullable(this MemberInfo memberInfo)
#endif
}


#if !NET6_0_OR_GREATER
private static object GetNullableAttribute(this MemberInfo memberInfo)
{
var nullableAttribute = memberInfo
Expand Down Expand Up @@ -162,5 +182,6 @@ private static bool GetNullableFallbackValue(this MemberInfo memberInfo)

return false;
}
#endif
}
}

0 comments on commit 9fb2765

Please sign in to comment.