diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs index 43d2b65fc218e..57727d1b0dc3e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs @@ -325,7 +325,14 @@ private static NotAnnotatedStatus PopulateAnnotationInfo(IList customAttributes) diff --git a/src/libraries/System.Runtime/tests/System/Reflection/NullabilityInfoContextTests.cs b/src/libraries/System.Runtime/tests/System/Reflection/NullabilityInfoContextTests.cs index deb55e01d9b67..6146d32190cee 100644 --- a/src/libraries/System.Runtime/tests/System/Reflection/NullabilityInfoContextTests.cs +++ b/src/libraries/System.Runtime/tests/System/Reflection/NullabilityInfoContextTests.cs @@ -1089,6 +1089,67 @@ public void TestNestedGenericInheritanceWithMultipleParameters() Assert.Equal(NullabilityState.NotNull, item3Info.ElementType!.ReadState); Assert.Equal(NullabilityState.NotNull, item3Info.ElementType.WriteState); } + + [Fact] + [SkipOnMono("Nullability attributes trimmed on Mono")] + public void TestNullabilityInfoCreationOnPropertiesWithNestedGenericTypeArguments() + { + Type type = typeof(TypeWithPropertiesNestingItsGenericTypeArgument); + + NullabilityInfo shallow1Info = nullabilityContext.Create(type.GetProperty("Shallow1")!); + NullabilityInfo deep1Info = nullabilityContext.Create(type.GetProperty("Deep1")!); + NullabilityInfo deep2Info = nullabilityContext.Create(type.GetProperty("Deep2")!); + NullabilityInfo deep3Info = nullabilityContext.Create(type.GetProperty("Deep3")!); + NullabilityInfo deep4Info = nullabilityContext.Create(type.GetProperty("Deep4")!); + NullabilityInfo deep5Info = nullabilityContext.Create(type.GetProperty("Deep5")!); + + //public Tuple? Shallow1 { get; set; } + NullabilityInfo info = shallow1Info; + Assert.Equal(1, info.GenericTypeArguments.Length); + Assert.Equal(NullabilityState.Nullable, info.GenericTypeArguments[0].ReadState); + + //public Tuple>? Deep1 { get; set; } + info = deep1Info; + Assert.Equal(1, info.GenericTypeArguments.Length); + Assert.Equal(1, info.GenericTypeArguments[0].GenericTypeArguments.Length); + Assert.Equal(NullabilityState.NotNull, info.GenericTypeArguments[0].ReadState); + Assert.Equal(NullabilityState.Nullable, info.GenericTypeArguments[0].GenericTypeArguments[0].ReadState); + + //public Tuple, int>? Deep2 { get; set; } + info = deep2Info; + Assert.Equal(2, info.GenericTypeArguments.Length); + Assert.Equal(1, info.GenericTypeArguments[0].GenericTypeArguments.Length); + Assert.Equal(NullabilityState.NotNull, info.GenericTypeArguments[0].ReadState); + Assert.Equal(NullabilityState.NotNull, info.GenericTypeArguments[1].ReadState); + Assert.Equal(NullabilityState.Nullable, info.GenericTypeArguments[0].GenericTypeArguments[0].ReadState); + + //public Tuple>? Deep3 { get; set; } + info = deep3Info; + Assert.Equal(2, info.GenericTypeArguments.Length); + Assert.Equal(1, info.GenericTypeArguments[1].GenericTypeArguments.Length); + Assert.Equal(NullabilityState.Nullable, info.GenericTypeArguments[0].ReadState); + Assert.Equal(NullabilityState.NotNull, info.GenericTypeArguments[1].ReadState); + Assert.Equal(NullabilityState.Nullable, info.GenericTypeArguments[1].GenericTypeArguments[0].ReadState); + + //public Tuple>? Deep4 { get; set; } + info = deep4Info; + Assert.Equal(3, info.GenericTypeArguments.Length); + Assert.Equal(1, info.GenericTypeArguments[2].GenericTypeArguments.Length); + Assert.Equal(NullabilityState.NotNull, info.GenericTypeArguments[0].ReadState); + Assert.Equal(NullabilityState.Nullable, info.GenericTypeArguments[1].ReadState); + Assert.Equal(NullabilityState.NotNull, info.GenericTypeArguments[2].ReadState); + Assert.Equal(NullabilityState.Nullable, info.GenericTypeArguments[2].GenericTypeArguments[0].ReadState); + + //public Tuple?>? Deep5 { get; set; } + info = deep5Info; + Assert.Equal(3, info.GenericTypeArguments.Length); + Assert.Equal(2, info.GenericTypeArguments[2].GenericTypeArguments.Length); + Assert.Equal(NullabilityState.NotNull, info.GenericTypeArguments[0].ReadState); + Assert.Equal(NullabilityState.NotNull, info.GenericTypeArguments[1].ReadState); + Assert.Equal(NullabilityState.Nullable, info.GenericTypeArguments[2].ReadState); + Assert.Equal(NullabilityState.Nullable, info.GenericTypeArguments[2].GenericTypeArguments[0].ReadState); + Assert.Equal(NullabilityState.NotNull, info.GenericTypeArguments[2].GenericTypeArguments[1].ReadState); + } } #pragma warning disable CS0649, CS0067, CS0414 @@ -1348,4 +1409,14 @@ public DerivesFromTupleOfNestedGenerics(List item1, Dictionary + { + public Tuple? Shallow1 { get; set; } + public Tuple>? Deep1 { get; set; } + public Tuple, int>? Deep2 { get; set; } + public Tuple>? Deep3 { get; set; } + public Tuple>? Deep4 { get; set; } + public Tuple?>? Deep5 { get; set; } + } }