diff --git a/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs b/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs index 5e5c625..63db9a5 100644 --- a/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs @@ -70,13 +70,7 @@ internal partial class InliningResolver nullablePolicy); var nullBranch = CastExpression( - ParseTypeName(convertedType.IsReferenceType && - convertedType.NullableAnnotation != NullableAnnotation.Annotated - ? TypeDisplay.ForSymbol( - convertedType, - NullableAnnotation.NotAnnotated, - nullablePolicy) - : castTypeName), + ParseTypeName(castTypeName), LiteralExpression(SyntaxKind.NullLiteralExpression)); return ParenthesizedExpression( diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index 3dcc056..b18802c 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -196,6 +196,54 @@ diagnostic.Location.SourceTree is { } tree && generatedTrees.Contains(tree))).IsNotEmpty(); } + [Test] + public async Task RewritePreservesNullableReferenceNullBranches() + { + const string source = """ + #nullable enable + using AlephMapper; + + namespace NullableRewriteFixture; + + public static partial class Mapper + { + [Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] + public static AddressDto Map(Person person) => + person.Address?.ToDto() ?? new AddressDto(); + } + + public static class AddressExtensions + { + public static AddressDto ToDto(this Address address) => new AddressDto(); + } + + public sealed class Person { public Address? Address { get; set; } } + public sealed class Address { } + public sealed class AddressDto { } + """; + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var compilation = CSharpCompilation.Create( + "NullableRewriteNullBranch", + [CSharpSyntaxTree.ParseText(source, _parseOptions)], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) + .WithNullableContextOptions(NullableContextOptions.Enable)); + + var driver = _driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out _); + var generatedTrees = outputCompilation.SyntaxTrees + .Where(tree => !compilation.SyntaxTrees.Contains(tree)) + .ToHashSet(); + var mapperSource = driver.GetRunResult().Results.Single().GeneratedSources + .Single(generated => generated.HintName.EndsWith("Mapper_GeneratedMappings.g.cs", StringComparison.Ordinal)) + .SourceText.ToString(); + + await Assert.That(mapperSource).Contains("(global::NullableRewriteFixture.AddressDto?)null"); + await Assert.That(outputCompilation.GetDiagnostics().Where(diagnostic => + diagnostic.Id == "CS8600" && + diagnostic.Location.SourceTree is { } tree && + generatedTrees.Contains(tree))).IsEmpty(); + } + [Test] public async Task MapperHelpersRemainCandidatesForInlining() {