|
14 | 14 | using Microsoft.CodeAnalysis.Diagnostics; |
15 | 15 | using Microsoft.CodeAnalysis.Test.Utilities; |
16 | 16 | using Roslyn.Test.Utilities; |
| 17 | +using Roslyn.Utilities; |
17 | 18 | using Xunit; |
18 | 19 | using PublicNullableAnnotation = Microsoft.CodeAnalysis.NullableAnnotation; |
19 | 20 | using PublicNullableFlowState = Microsoft.CodeAnalysis.NullableFlowState; |
@@ -5235,5 +5236,156 @@ void test(SemanticModelOptions options) |
5235 | 5236 | Assert.Equal(PublicNullableAnnotation.None, typeInfo.Type.NullableAnnotation); |
5236 | 5237 | } |
5237 | 5238 | } |
| 5239 | + |
| 5240 | + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71522")] |
| 5241 | + public void CollectionExpression_NestedNullability_01() |
| 5242 | + { |
| 5243 | + var source = """ |
| 5244 | + #nullable enable |
| 5245 | +
|
| 5246 | + var b = false; |
| 5247 | + var arr = b ? ["1"] : new[] { "2" }; |
| 5248 | + """; |
| 5249 | + |
| 5250 | + var comp = CreateCompilation(source); |
| 5251 | + var tree = comp.SyntaxTrees[0]; |
| 5252 | + var model = comp.GetSemanticModel(tree); |
| 5253 | + |
| 5254 | + var root = tree.GetRoot(); |
| 5255 | + var collectionExpr = root.DescendantNodes().OfType<CollectionExpressionSyntax>().Single(); |
| 5256 | + var typeInfo = model.GetTypeInfo(collectionExpr); |
| 5257 | + var type = (IArrayTypeSymbol)typeInfo.ConvertedType; |
| 5258 | + Assert.Equal("System.String[]", type.ToTestDisplayString()); |
| 5259 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.NullableAnnotation); |
| 5260 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.ElementNullableAnnotation); |
| 5261 | + } |
| 5262 | + |
| 5263 | + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71522")] |
| 5264 | + public void CollectionExpression_NestedNullability_02() |
| 5265 | + { |
| 5266 | + var source = """ |
| 5267 | + #nullable enable |
| 5268 | +
|
| 5269 | + using System; |
| 5270 | + using System.Collections.Generic; |
| 5271 | + using System.Linq.Expressions; |
| 5272 | +
|
| 5273 | + class C |
| 5274 | + { |
| 5275 | + void M() |
| 5276 | + { |
| 5277 | + string[] x = ["1"]; |
| 5278 | + } |
| 5279 | + } |
| 5280 | + """; |
| 5281 | + |
| 5282 | + var comp = CreateCompilation(source); |
| 5283 | + var tree = comp.SyntaxTrees[0]; |
| 5284 | + var model = comp.GetSemanticModel(tree); |
| 5285 | + |
| 5286 | + var root = tree.GetRoot(); |
| 5287 | + var collectionExpr = root.DescendantNodes().OfType<CollectionExpressionSyntax>().Single(); |
| 5288 | + var typeInfo = model.GetTypeInfo(collectionExpr); |
| 5289 | + var type = (IArrayTypeSymbol)typeInfo.ConvertedType; |
| 5290 | + Assert.Equal("System.String[]", type.ToTestDisplayString()); |
| 5291 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.NullableAnnotation); |
| 5292 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.ElementNullableAnnotation); |
| 5293 | + } |
| 5294 | + |
| 5295 | + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71522")] |
| 5296 | + public void CollectionExpression_NestedNullability_03() |
| 5297 | + { |
| 5298 | + var source = """ |
| 5299 | + #nullable enable |
| 5300 | +
|
| 5301 | + var b = false; |
| 5302 | + var arr = b switch { true => ["1"], false => new[] { "2" } }; |
| 5303 | + """; |
| 5304 | + |
| 5305 | + var comp = CreateCompilation(source); |
| 5306 | + var tree = comp.SyntaxTrees[0]; |
| 5307 | + var model = comp.GetSemanticModel(tree); |
| 5308 | + |
| 5309 | + var root = tree.GetRoot(); |
| 5310 | + var collectionExpr = root.DescendantNodes().OfType<CollectionExpressionSyntax>().Single(); |
| 5311 | + var typeInfo = model.GetTypeInfo(collectionExpr); |
| 5312 | + var type = (IArrayTypeSymbol)typeInfo.ConvertedType; |
| 5313 | + Assert.Equal("System.String[]", type.ToTestDisplayString()); |
| 5314 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.NullableAnnotation); |
| 5315 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.ElementNullableAnnotation); |
| 5316 | + } |
| 5317 | + |
| 5318 | + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71522")] |
| 5319 | + public void CollectionExpression_NestedNullability_04() |
| 5320 | + { |
| 5321 | + var source = """ |
| 5322 | + #nullable enable |
| 5323 | +
|
| 5324 | + var arr = new[] { ["1"], new[] { "2" } }; |
| 5325 | + """; |
| 5326 | + |
| 5327 | + var comp = CreateCompilation(source); |
| 5328 | + var tree = comp.SyntaxTrees[0]; |
| 5329 | + var model = comp.GetSemanticModel(tree); |
| 5330 | + |
| 5331 | + var root = tree.GetRoot(); |
| 5332 | + var collectionExpr = root.DescendantNodes().OfType<CollectionExpressionSyntax>().Single(); |
| 5333 | + var typeInfo = model.GetTypeInfo(collectionExpr); |
| 5334 | + var type = (IArrayTypeSymbol)typeInfo.ConvertedType; |
| 5335 | + Assert.Equal("System.String[]", type.ToTestDisplayString()); |
| 5336 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.NullableAnnotation); |
| 5337 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.ElementNullableAnnotation); |
| 5338 | + } |
| 5339 | + |
| 5340 | + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71522")] |
| 5341 | + public void CollectionExpression_NestedNullability_05() |
| 5342 | + { |
| 5343 | + var source = """ |
| 5344 | + #nullable enable |
| 5345 | + public class C |
| 5346 | + { |
| 5347 | + public string[] M1(bool b) |
| 5348 | + { |
| 5349 | + var arr = b ? ["1"] : new[] { "2" }; |
| 5350 | + arr[0] = null; // 1 |
| 5351 | + return arr; |
| 5352 | + } |
| 5353 | +
|
| 5354 | + public string[] M2(bool b) |
| 5355 | + { |
| 5356 | + var arr = new[] { "2" }; |
| 5357 | + arr = b ? ["1"] : arr; |
| 5358 | + arr[0] = null; // 2 |
| 5359 | + return arr; |
| 5360 | + } |
| 5361 | + } |
| 5362 | + """; |
| 5363 | + |
| 5364 | + var comp = CreateCompilation(source); |
| 5365 | + comp.VerifyEmitDiagnostics( |
| 5366 | + // (7,18): warning CS8625: Cannot convert null literal to non-nullable reference type. |
| 5367 | + // arr[0] = null; // 1 |
| 5368 | + Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(7, 18), |
| 5369 | + // (15,18): warning CS8625: Cannot convert null literal to non-nullable reference type. |
| 5370 | + // arr[0] = null; // 2 |
| 5371 | + Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(15, 18)); |
| 5372 | + |
| 5373 | + var tree = comp.SyntaxTrees[0]; |
| 5374 | + var model = comp.GetSemanticModel(tree); |
| 5375 | + |
| 5376 | + var root = tree.GetRoot(); |
| 5377 | + var collectionExprs = root.DescendantNodes().OfType<CollectionExpressionSyntax>().ToArray(); |
| 5378 | + Assert.Equal(2, collectionExprs.Length); |
| 5379 | + foreach (var collectionExpr in collectionExprs) |
| 5380 | + { |
| 5381 | + var typeInfo = model.GetTypeInfo(collectionExpr); |
| 5382 | + var type = (IArrayTypeSymbol)typeInfo.ConvertedType; |
| 5383 | + Assert.Equal("System.String[]", type.ToTestDisplayString()); |
| 5384 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.NullableAnnotation); |
| 5385 | + Assert.Equal(PublicNullableAnnotation.NotAnnotated, type.ElementNullableAnnotation); |
| 5386 | + } |
| 5387 | + } |
| 5388 | + |
| 5389 | + // TODO2: test collection-exprs in lambda returns to exercise all BestTypeInferrer usages in NullableWalker |
5238 | 5390 | } |
5239 | 5391 | } |
0 commit comments