From cbe954af768379f60620230cf4840d37d6c0c957 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Mon, 31 Aug 2026 18:12:27 +0200 Subject: [PATCH 01/22] Optional detailed body: - Hide generated configuration types from consumer APIs - Mark generated sources explicitly - Filter unrelated syntax candidates - Remove compiler objects from cached models - Scope generation to individual mappers - Preserve existing mapping behavior and packaging --- source/Adaptation/AdaptationValidator.cs | 2 +- source/Attributes.cs | 12 +++--- source/Generation/AttributeSourceEmitter.cs | 3 +- .../Emitters/AdaptationMemberEmitter.cs | 2 +- source/Generation/MapperFileEmitter.cs | 3 ++ source/Generation/MappingMethodCandidate.cs | 26 ++++++++++++- source/Generation/MappingModelFactory.cs | 8 +++- source/Models/AdaptationModel.cs | 39 +++++++++++++++++-- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- .../Tests_PersonMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- .../Tests_PersonMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...s_AdaptUpdateMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...ests_CircularMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...cularPropertyMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...ts_CollectionMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...tionalPatternMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ..._EfCoreIgnoreMapper_GeneratedMappings.g.cs | 5 ++- ..._Tests_EfCoreMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- .../Tests_SampleMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...ionTestPersonMapper_GeneratedMappings.g.cs | 5 ++- ...onTestAddressMapper_GeneratedMappings.g.cs | 5 ++- ...ionTestPersonMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...Mapper_Tests_Mapper_GeneratedMappings.g.cs | 7 +++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ..._SimpleObjectMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...tyList_PersonMapper_GeneratedMappings.g.cs | 10 ++--- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...ProductMapperIgnore_GeneratedMappings.g.cs | 5 ++- ...roductMapperRewrite_GeneratedMappings.g.cs | 5 ++- ...ining_ProductMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...ramExpressiveMapper_GeneratedMappings.g.cs | 5 ++- ...ning_NamedArgMapper_GeneratedMappings.g.cs | 5 ++- ...tedMultiParamMapper_GeneratedMappings.g.cs | 5 ++- ...lining_PersonMapper_GeneratedMappings.g.cs | 5 ++- ...bleMultiParamMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...edExt_AddressMapper_GeneratedMappings.g.cs | 5 ++- ...PersonMapper_Ignore_GeneratedMappings.g.cs | 5 ++- ...ersonMapper_Rewrite_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...lueAssignmentMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ..._Tests_IgnoreMapper_GeneratedMappings.g.cs | 5 ++- ...er_Tests_NoneMapper_GeneratedMappings.g.cs | 5 ++- ...Tests_RewriteMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...lableDisabledMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...llableEnabledMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...chDebtAddressMapper_GeneratedMappings.g.cs | 5 ++- ...tPersonMapperIgnore_GeneratedMappings.g.cs | 5 ++- ...ebtPersonMapperNone_GeneratedMappings.g.cs | 5 ++- ...PersonMapperRewrite_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...ests_Address1Mapper_GeneratedMappings.g.cs | 5 ++- ...s_AddressLineMapper_GeneratedMappings.g.cs | 5 ++- ...ts_TestModel1Mapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- .../Tests_SampleMapper_GeneratedMappings.g.cs | 5 ++- .../Expected/AlephMapper.Attributes.g.cs | 17 ++++---- ...mplexPropertyMapper_GeneratedMappings.g.cs | 5 ++- ...plexValueTypeMapper_GeneratedMappings.g.cs | 5 ++- ...ests_EdgeCaseMapper_GeneratedMappings.g.cs | 5 ++- ...sts_MixedTypeMapper_GeneratedMappings.g.cs | 5 ++- ...ableValueTypeMapper_GeneratedMappings.g.cs | 5 ++- ...renceTypeOnlyMapper_GeneratedMappings.g.cs | 5 ++- ...ueToReferenceMapper_GeneratedMappings.g.cs | 5 ++- ...ueToReferenceMapper_GeneratedMappings.g.cs | 5 ++- ...sts_ValueTypeMapper_GeneratedMappings.g.cs | 5 ++- ...ValueTypeOnlyMapper_GeneratedMappings.g.cs | 5 ++- 84 files changed, 537 insertions(+), 245 deletions(-) diff --git a/source/Adaptation/AdaptationValidator.cs b/source/Adaptation/AdaptationValidator.cs index 82ff21d..9e4a4d0 100644 --- a/source/Adaptation/AdaptationValidator.cs +++ b/source/Adaptation/AdaptationValidator.cs @@ -22,7 +22,7 @@ public static bool Validate( AdaptationModel adaptation, ExpressionSyntax inlinedBody) { - var location = adaptation.Attribute.ApplicationSyntaxReference?.GetSyntax().GetLocation() + var location = adaptation.Location?.ToLocation() ?? mapping.MethodSymbol.Locations.FirstOrDefault(); var isValid = true; diff --git a/source/Attributes.cs b/source/Attributes.cs index 5e01a87..da5503f 100644 --- a/source/Attributes.cs +++ b/source/Attributes.cs @@ -5,7 +5,7 @@ namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +34,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +46,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +58,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +80,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +121,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/source/Generation/AttributeSourceEmitter.cs b/source/Generation/AttributeSourceEmitter.cs index c43bde8..a23686e 100644 --- a/source/Generation/AttributeSourceEmitter.cs +++ b/source/Generation/AttributeSourceEmitter.cs @@ -11,6 +11,7 @@ public static void AddAttributes(IncrementalGeneratorPostInitializationContext c { var assembly = typeof(AlephSourceGenerator).Assembly; using var reader = new StreamReader(assembly.GetManifestResourceStream("AlephMapper.Attributes.cs")!); - context.AddSource("AlephMapper.Attributes.g.cs", SourceText.From(reader.ReadToEnd(), Encoding.UTF8)); + var source = "// \n#nullable enable\n\n" + reader.ReadToEnd(); + context.AddSource("AlephMapper.Attributes.g.cs", SourceText.From(source, Encoding.UTF8)); } } diff --git a/source/Generation/Emitters/AdaptationMemberEmitter.cs b/source/Generation/Emitters/AdaptationMemberEmitter.cs index 15deceb..134accf 100644 --- a/source/Generation/Emitters/AdaptationMemberEmitter.cs +++ b/source/Generation/Emitters/AdaptationMemberEmitter.cs @@ -270,7 +270,7 @@ private static void EmitUpdateMember( private static Location? GetLocation(MappingModel mapping, AdaptationModel adaptation) { - return adaptation.Attribute.ApplicationSyntaxReference?.GetSyntax().GetLocation() ?? + return adaptation.Location?.ToLocation() ?? mapping.MethodSymbol.Locations.FirstOrDefault(); } } diff --git a/source/Generation/MapperFileEmitter.cs b/source/Generation/MapperFileEmitter.cs index 87e35dd..362755e 100644 --- a/source/Generation/MapperFileEmitter.cs +++ b/source/Generation/MapperFileEmitter.cs @@ -24,6 +24,9 @@ public static GeneratedMapperFile Render(MapperGenerationContext context) : ""; var output = new StringBuilder(); + output.AppendLine("// "); + output.AppendLine("#nullable enable"); + output.AppendLine(); foreach (var usingDirective in context.UsingDirectives.OrderBy(static directive => directive)) { if (usingDirective != containingNamespace && !string.IsNullOrEmpty(usingDirective)) diff --git a/source/Generation/MappingMethodCandidate.cs b/source/Generation/MappingMethodCandidate.cs index 870d1b4..144a2a6 100644 --- a/source/Generation/MappingMethodCandidate.cs +++ b/source/Generation/MappingMethodCandidate.cs @@ -1,5 +1,7 @@ using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Linq; using System.Threading; namespace AlephMapper.Generation; @@ -8,6 +10,28 @@ internal static class MappingMethodCandidate { public static bool IsCandidate(SyntaxNode node, CancellationToken _) { - return node is MethodDeclarationSyntax { Parent: ClassDeclarationSyntax }; + if (node is not MethodDeclarationSyntax + { + Parent: ClassDeclarationSyntax containingClass, + ExpressionBody: not null + } method) + { + return false; + } + + if (!containingClass.Modifiers.Any(static modifier => modifier.IsKind(SyntaxKind.StaticKeyword))) + { + return false; + } + + return method.AttributeLists.Count != 0 || + containingClass.AttributeLists.Count != 0 || + containingClass.Members.OfType().Any(static member => + member.AttributeLists.Count != 0) || + containingClass.Members.OfType().Any(static member => + member.ParameterList.Parameters.Any(static parameter => + parameter.Modifiers.Any(static modifier => modifier.IsKind(SyntaxKind.ThisKeyword)))) || + method.ParameterList.Parameters.Any(static parameter => + parameter.Modifiers.Any(static modifier => modifier.IsKind(SyntaxKind.ThisKeyword))); } } diff --git a/source/Generation/MappingModelFactory.cs b/source/Generation/MappingModelFactory.cs index d76659a..031cdca 100644 --- a/source/Generation/MappingModelFactory.cs +++ b/source/Generation/MappingModelFactory.cs @@ -91,7 +91,13 @@ attribute.ConstructorArguments[0].Value is not INamedTypeSymbol sourceType || } } - adaptations.Add(new AdaptationModel(sourceType, destinationType, name, generation, nullStrategy, attribute)); + adaptations.Add(new AdaptationModel( + sourceType, + destinationType, + name, + generation, + nullStrategy, + SourceLocationModel.FromSyntax(attribute.ApplicationSyntaxReference))); } return adaptations; diff --git a/source/Models/AdaptationModel.cs b/source/Models/AdaptationModel.cs index 49e8aba..267022c 100644 --- a/source/Models/AdaptationModel.cs +++ b/source/Models/AdaptationModel.cs @@ -1,6 +1,7 @@ #nullable enable using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; namespace AlephMapper.Models; @@ -12,14 +13,14 @@ public AdaptationModel( string? generatedName, AdaptGeneration generation, NullConditionalRewrite nullStrategy, - AttributeData attribute) + SourceLocationModel? location) { SourceType = sourceType; DestinationType = destinationType; GeneratedName = generatedName; Generation = generation; NullStrategy = nullStrategy; - Attribute = attribute; + Location = location; } public INamedTypeSymbol SourceType { get; } @@ -27,5 +28,37 @@ public AdaptationModel( public string? GeneratedName { get; } public AdaptGeneration Generation { get; } public NullConditionalRewrite NullStrategy { get; } - public AttributeData Attribute { get; } + public SourceLocationModel? Location { get; } +} + +internal sealed class SourceLocationModel +{ + private SourceLocationModel(string? filePath, int start, int length) + { + FilePath = filePath; + Start = start; + Length = length; + } + + public string? FilePath { get; } + public int Start { get; } + public int Length { get; } + + public static SourceLocationModel? FromSyntax(SyntaxReference? syntaxReference) + { + if (syntaxReference is null) + { + return null; + } + + var syntax = syntaxReference.GetSyntax(); + return new SourceLocationModel(syntax.SyntaxTree.FilePath, syntax.Span.Start, syntax.Span.Length); + } + + public Location ToLocation() + { + var span = new TextSpan(Start, Length); + var lineSpan = new LinePositionSpan(new LinePosition(0, Start), new LinePosition(0, Start + Length)); + return Microsoft.CodeAnalysis.Location.Create(FilePath ?? string.Empty, span, lineSpan); + } } diff --git a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index 846facc..f6e5258 100644 --- a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index e4c889c..576f3e3 100644 --- a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs index d99b1f0..d89967b 100644 --- a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs index 31670c3..390f70b 100644 --- a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs index 5b50265..f391633 100644 --- a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs index 7c543f1..3802ac7 100644 --- a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs index b847600..d89b644 100644 --- a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs index 0837d97..a34276c 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs index 794969d..2bb6acb 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index e0abbab..249b0e0 100644 --- a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs index 5d77c39..33d73b4 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs index 6a332ba..842d395 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs index 9805e9e..a7b797d 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs index cbcd7dd..8a2d50d 100644 --- a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; @@ -17,7 +20,7 @@ partial class Mapper /// /// public static Expression> BornInKyivAndOlder35Expression() => - source => source.BirthInfo.Address == "Kyiv" && source.BirthInfo.Age > 35 && source.BirthInfo.Age < 65; + source => source.BirthInfo.Address == "Kyiv" && Mapper1.Older35(source.BirthInfo) && source.BirthInfo.Age < 65; /// /// This is an auto-generated expression companion for . diff --git a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs index 7c279c3..dced7d9 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs index e320be5..555aaa3 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Collections.Generic; @@ -22,10 +25,7 @@ public static Expression> ToEntityExpression() => dto => new Person { ContactNumbers = dto.PhoneNumbers - .Select(dto => new PhoneNumber - { - Number = dto.Number - }) + .Select(PhoneMapper.ToEntity) .ToList() }; } diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs index e4e2936..c133454 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs index 33da943..9268fcb 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs index 7f3971c..baed6ec 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs index 39bd9f2..e2934e4 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs index 6d7a232..e15d052 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs index 025f784..87393ca 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs index d5b36e4..1be614a 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs index 32cf9d6..809849b 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs index 966394c..caab30d 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs index 14cbaca..23e8157 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs index a6a1f17..dda002a 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs index aa2cd08..c170be4 100644 --- a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using AlephMapper; using System; using System.CodeDom.Compiler; diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs index f3a3027..9b60a8c 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs index 70253a6..2dc4305 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs index 2a2a053..339bcd6 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs index df60f3f..886a907 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs index 44c8fe2..8888671 100644 --- a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs index 83c965d..0df4018 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs index 957a5e1..38ec812 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs index d0d7347..cf3d607 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs index f572d17..3bad366 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AgileObjects.ReadableExpressions; +// +#nullable enable + +using AgileObjects.ReadableExpressions; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs index b139120..4cffb42 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs index 6b214d0..a887d65 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs index 26062bb..1b43175 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index 37f6eff..ddb1c0d 100644 --- a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using AlephMapper; +// +#nullable enable + +using AlephMapper; using System; using System.CodeDom.Compiler; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs index 5e01a87..a62e671 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs @@ -1,11 +1,14 @@ -using System; +// +#nullable enable + +using System; namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// -public enum NullConditionalRewrite +internal enum NullConditionalRewrite { /// /// Don't rewrite null conditional operators (Default behavior). @@ -34,7 +37,7 @@ public enum NullConditionalRewrite /// Marks a class to generate expressive companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class ExpressiveAttribute : Attribute +internal sealed class ExpressiveAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -46,7 +49,7 @@ public sealed class ExpressiveAttribute : Attribute /// Marks a class to generate update companion methods. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -public sealed class UpdatableAttribute : Attribute +internal sealed class UpdatableAttribute : Attribute { /// /// Gets or sets the policy for handling collection updates during mapping operations @@ -58,7 +61,7 @@ public sealed class UpdatableAttribute : Attribute /// Defines which adapted companions are generated for an declaration. /// [Flags] -public enum AdaptGeneration +internal enum AdaptGeneration { /// /// Generate a regular mapping method. @@ -80,7 +83,7 @@ public enum AdaptGeneration /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] -public sealed class AdaptAttribute : Attribute +internal sealed class AdaptAttribute : Attribute { /// /// Initializes a new adaptation from the template method to the specified source and destination types. @@ -121,7 +124,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// -public enum CollectionPropertiesPolicy +internal enum CollectionPropertiesPolicy { /// /// Skip collection updates - collections will not be modified during mapping diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs index bd7c329..938eade 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs index 41f08e5..e2d3b5a 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs index 5936084..204cc15 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs index b09b69d..e341b64 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs index 6c3d02b..248ec4a 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs index dc23cc1..fa09a20 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs index 62966a3..f15f07c 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs index 4ca2235..eed0b2c 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs index 30a06e5..aaf12ff 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs index b7b9edf..c5ee4b9 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs @@ -1,4 +1,7 @@ -using System; +// +#nullable enable + +using System; using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; From c1956d4b747801054510558eee7192b8fed57d0d Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Mon, 31 Aug 2026 19:06:57 +0200 Subject: [PATCH 02/22] Refactor generator pipeline around mapper-scoped value candidates --- source/Adaptation/AdaptationValidator.cs | 6 +- source/AlephSourceGenerator.cs | 12 +- .../Emitters/AdaptationMemberEmitter.cs | 2 +- source/Generation/MapperCandidate.cs | 66 +++++++ source/Generation/MapperGenerationContext.cs | 4 +- source/Generation/MapperSourceOutput.cs | 166 +++++++++++++++--- ...elFactory.cs => MappingAnalysisFactory.cs} | 19 +- source/Generation/MappingCatalog.cs | 48 +++++ source/Generation/MappingMethodDetails.cs | 4 +- ...aptationModel.cs => AdaptationAnalysis.cs} | 7 +- .../{MappingModel.cs => MappingAnalysis.cs} | 24 +-- .../InliningResolver.InvocationRewriter.cs | 5 +- .../AlephMapper.Tests/SourceGeneratorTests.cs | 149 ++++++++++++++++ 13 files changed, 444 insertions(+), 68 deletions(-) create mode 100644 source/Generation/MapperCandidate.cs rename source/Generation/{MappingModelFactory.cs => MappingAnalysisFactory.cs} (90%) create mode 100644 source/Generation/MappingCatalog.cs rename source/Models/{AdaptationModel.cs => AdaptationAnalysis.cs} (90%) rename source/Models/{MappingModel.cs => MappingAnalysis.cs} (74%) diff --git a/source/Adaptation/AdaptationValidator.cs b/source/Adaptation/AdaptationValidator.cs index 9e4a4d0..ee7b0a0 100644 --- a/source/Adaptation/AdaptationValidator.cs +++ b/source/Adaptation/AdaptationValidator.cs @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable using AlephMapper.Diagnostics; using AlephMapper.Models; @@ -18,8 +18,8 @@ internal static class AdaptationValidator { public static bool Validate( SourceProductionContext context, - MappingModel mapping, - AdaptationModel adaptation, + MappingAnalysis mapping, + AdaptationAnalysis adaptation, ExpressionSyntax inlinedBody) { var location = adaptation.Location?.ToLocation() diff --git a/source/AlephSourceGenerator.cs b/source/AlephSourceGenerator.cs index 7dec66a..7029c0b 100644 --- a/source/AlephSourceGenerator.cs +++ b/source/AlephSourceGenerator.cs @@ -14,11 +14,13 @@ public void Initialize(IncrementalGeneratorInitializationContext context) { context.RegisterPostInitializationOutput(AttributeSourceEmitter.AddAttributes); - var mappings = context.SyntaxProvider - .CreateSyntaxProvider(MappingMethodCandidate.IsCandidate, MappingModelFactory.Create) - .Where(static mapping => mapping != null) - .Select(static (mapping, _) => mapping!); + var mapperCandidates = context.SyntaxProvider + .CreateSyntaxProvider( + MapperCandidate.IsCandidate, + static (syntaxContext, cancellationToken) => MapperCandidate.Create(syntaxContext.Node, cancellationToken)); - context.RegisterSourceOutput(mappings.Collect(), MapperSourceOutput.Generate); + context.RegisterSourceOutput( + mapperCandidates.Combine(context.CompilationProvider), + MapperSourceOutput.Generate); } } diff --git a/source/Generation/Emitters/AdaptationMemberEmitter.cs b/source/Generation/Emitters/AdaptationMemberEmitter.cs index 134accf..1cfe7e2 100644 --- a/source/Generation/Emitters/AdaptationMemberEmitter.cs +++ b/source/Generation/Emitters/AdaptationMemberEmitter.cs @@ -268,7 +268,7 @@ private static void EmitUpdateMember( }); } - private static Location? GetLocation(MappingModel mapping, AdaptationModel adaptation) + private static Location? GetLocation(MappingAnalysis mapping, AdaptationAnalysis adaptation) { return adaptation.Location?.ToLocation() ?? mapping.MethodSymbol.Locations.FirstOrDefault(); diff --git a/source/Generation/MapperCandidate.cs b/source/Generation/MapperCandidate.cs new file mode 100644 index 0000000..5e77042 --- /dev/null +++ b/source/Generation/MapperCandidate.cs @@ -0,0 +1,66 @@ +#nullable enable + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; +using System.Linq; +using System.Threading; + +namespace AlephMapper.Generation; + +/// +/// Value-only identity for a mapper declaration. One instance drives one +/// generated mapper file and therefore forms the incremental output unit. +/// +internal sealed class MapperCandidate : IEquatable +{ + private MapperCandidate(string filePath, int start, int length) + { + FilePath = filePath; + Start = start; + Length = length; + } + + public string FilePath { get; } + public int Start { get; } + public int Length { get; } + + public static bool IsCandidate(SyntaxNode node, CancellationToken _) + { + if (node is not ClassDeclarationSyntax containingClass || + !containingClass.Modifiers.Any(static modifier => modifier.IsKind(SyntaxKind.StaticKeyword))) + { + return false; + } + + return containingClass.AttributeLists.Count != 0 || + containingClass.Members.OfType().Any(static method => + method.AttributeLists.Count != 0); + } + + public static MapperCandidate Create(SyntaxNode node, CancellationToken _) + { + return new MapperCandidate(node.SyntaxTree.FilePath, node.SpanStart, node.Span.Length); + } + + public bool Equals(MapperCandidate? other) + { + return other is not null && + Start == other.Start && + Length == other.Length && + string.Equals(FilePath, other.FilePath, StringComparison.Ordinal); + } + + public override bool Equals(object? obj) => Equals(obj as MapperCandidate); + + public override int GetHashCode() + { + unchecked + { + var hash = StringComparer.Ordinal.GetHashCode(FilePath); + hash = (hash * 397) ^ Start; + return (hash * 397) ^ Length; + } + } +} diff --git a/source/Generation/MapperGenerationContext.cs b/source/Generation/MapperGenerationContext.cs index 6b4af1e..6bad2a2 100644 --- a/source/Generation/MapperGenerationContext.cs +++ b/source/Generation/MapperGenerationContext.cs @@ -17,7 +17,7 @@ internal sealed class MapperGenerationContext public MapperGenerationContext( INamedTypeSymbol mapperType, - IDictionary mappingsByMethod, + MappingCatalog mappingsByMethod, SourceProductionContext sourceProductionContext) { MapperType = mapperType; @@ -27,7 +27,7 @@ public MapperGenerationContext( } public INamedTypeSymbol MapperType { get; } - public IDictionary MappingsByMethod { get; } + public MappingCatalog MappingsByMethod { get; } public SourceProductionContext SourceProductionContext { get; } public AdaptationMemberPlanner AdaptationMembers { get; } public HashSet UsingDirectives { get; } = new(StringComparer.Ordinal); diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index b111899..7095749 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -1,45 +1,64 @@ +#nullable enable + +using AlephMapper.Diagnostics; using AlephMapper.Generation.Emitters; using AlephMapper.Helpers; using AlephMapper.Models; -using AlephMapper.Diagnostics; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Text; +using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.Linq; +using System.Threading; namespace AlephMapper.Generation; internal static class MapperSourceOutput { - public static void Generate(SourceProductionContext context, ImmutableArray mappings) + public static void Generate( + SourceProductionContext context, + (MapperCandidate Left, Compilation Right) input) { try { - if (mappings.Length == 0) + var mapperDeclaration = FindMapperDeclaration(input.Right, input.Left, context.CancellationToken); + if (mapperDeclaration is null) { return; } - var mappingsByMethod = new Dictionary(SymbolHelpers.MethodComparer.Instance); - var mappingsByClass = new Dictionary>(SymbolEqualityComparer.Default); - foreach (var mapping in mappings) + var mapperSemanticModel = input.Right.GetSemanticModel(mapperDeclaration.SyntaxTree); + var mapperType = mapperSemanticModel.GetDeclaredSymbol(mapperDeclaration, context.CancellationToken) as INamedTypeSymbol; + if (mapperType is null) { - mappingsByMethod[SymbolHelpers.Normalize(mapping.MethodSymbol)] = mapping; - if (!mappingsByClass.TryGetValue(mapping.ContainingType, out var classMappings)) - { - classMappings = []; - mappingsByClass.Add(mapping.ContainingType, classMappings); - } + return; + } - classMappings.Add(mapping); + if (!IsPrimaryMapperDeclaration(mapperType, mapperDeclaration, context.CancellationToken)) + { + return; + } + + var mappings = CreateMapperAnalyses(input.Right, mapperType, context.CancellationToken); + if (mappings.Count == 0 || !mappings.Any(static mapping => + (mapping.IsExpressive || mapping.IsUpdatable || mapping.Adaptations.Count > 0) && mapping.IsClassPartial)) + { + return; } - foreach (var pair in mappingsByClass) + var mappingsByMethod = new Dictionary(SymbolHelpers.MethodComparer.Instance); + foreach (var mapping in mappings) { - GenerateMapper(context, pair.Key, pair.Value, mappingsByMethod); + mappingsByMethod[SymbolHelpers.Normalize(mapping.MethodSymbol)] = mapping; } + + var catalog = new MappingCatalog( + mappingsByMethod, + method => CreateExternalAnalysis(input.Right, method, context.CancellationToken)); + GenerateMapper(context, mapperType, mappings, catalog); } - catch (System.Exception exception) + catch (Exception exception) { CrashDiagnosticsReporter.Report(context, exception); #if DEBUG @@ -48,19 +67,116 @@ public static void Generate(SourceProductionContext context, ImmutableArray CreateMapperAnalyses( + Compilation compilation, INamedTypeSymbol mapperType, - IReadOnlyList mappings, - IDictionary mappingsByMethod) + CancellationToken cancellationToken) { - if (!mappings.Any(static mapping => - (mapping.IsExpressive || mapping.IsUpdatable || mapping.Adaptations.Count > 0) && mapping.IsClassPartial)) + var mappings = new List(); + foreach (var declarationReference in mapperType.DeclaringSyntaxReferences + .OrderBy(static reference => reference.SyntaxTree.FilePath, StringComparer.Ordinal) + .ThenBy(static reference => reference.Span.Start)) { - return; + if (declarationReference.GetSyntax(cancellationToken) is not ClassDeclarationSyntax declaration) + { + continue; + } + + var semanticModel = compilation.GetSemanticModel(declaration.SyntaxTree); + foreach (var method in declaration.Members.OfType() + .Where(static method => method.ExpressionBody is not null) + .OrderBy(static method => method.SpanStart)) + { + var mapping = MappingAnalysisFactory.Create(semanticModel, method, cancellationToken); + if (mapping is not null) + { + mappings.Add(mapping); + } + } } - var context = new MapperGenerationContext(mapperType, mappingsByMethod, sourceProductionContext); + return mappings + .OrderBy(static mapping => mapping.MethodSymbol.Locations.FirstOrDefault()?.SourceSpan.Start ?? int.MaxValue) + .ThenBy(static mapping => mapping.Name, StringComparer.Ordinal) + .ToArray(); + } + + private static MappingAnalysis? CreateExternalAnalysis( + Compilation compilation, + IMethodSymbol method, + CancellationToken cancellationToken) + { + foreach (var declarationReference in method.DeclaringSyntaxReferences + .OrderBy(static reference => reference.SyntaxTree.FilePath, StringComparer.Ordinal) + .ThenBy(static reference => reference.Span.Start)) + { + if (declarationReference.GetSyntax(cancellationToken) is not MethodDeclarationSyntax declaration || + declaration.ExpressionBody is null || + !MappingMethodCandidate.IsCandidate(declaration, cancellationToken)) + { + continue; + } + + var semanticModel = compilation.GetSemanticModel(declaration.SyntaxTree); + return MappingAnalysisFactory.Create(semanticModel, declaration, cancellationToken); + } + + return null; + } + + private static bool IsPrimaryMapperDeclaration( + INamedTypeSymbol mapperType, + ClassDeclarationSyntax mapperDeclaration, + CancellationToken cancellationToken) + { + var primaryDeclaration = mapperType.DeclaringSyntaxReferences + .OrderBy(static reference => reference.SyntaxTree.FilePath, StringComparer.Ordinal) + .ThenBy(static reference => reference.Span.Start) + .Select(reference => reference.GetSyntax(cancellationToken) as ClassDeclarationSyntax) + .FirstOrDefault(static declaration => declaration is not null && + MapperCandidate.IsCandidate(declaration, CancellationToken.None)); + + return primaryDeclaration is not null && + primaryDeclaration.SyntaxTree == mapperDeclaration.SyntaxTree && + primaryDeclaration.Span == mapperDeclaration.Span; + } + + private static ClassDeclarationSyntax? FindMapperDeclaration( + Compilation compilation, + MapperCandidate candidate, + CancellationToken cancellationToken) + { + var span = new TextSpan(candidate.Start, candidate.Length); + foreach (var tree in compilation.SyntaxTrees) + { + if (!string.Equals(tree.FilePath, candidate.FilePath, StringComparison.Ordinal)) + { + continue; + } + + var root = tree.GetRoot(cancellationToken); + if (span.End > root.FullSpan.End) + { + continue; + } + + if (root.FindNode(span, getInnermostNodeForTie: true) is ClassDeclarationSyntax declaration && + declaration.Span == span) + { + return declaration; + } + } + + return null; + } + + private static void GenerateMapper( + SourceProductionContext sourceProductionContext, + INamedTypeSymbol mapperType, + IReadOnlyList mappings, + MappingCatalog catalog) + { + var context = new MapperGenerationContext(mapperType, catalog, sourceProductionContext); foreach (var mapping in mappings) { if (!mapping.IsExpressive && !mapping.IsUpdatable && mapping.Adaptations.Count == 0) diff --git a/source/Generation/MappingModelFactory.cs b/source/Generation/MappingAnalysisFactory.cs similarity index 90% rename from source/Generation/MappingModelFactory.cs rename to source/Generation/MappingAnalysisFactory.cs index 031cdca..3917b65 100644 --- a/source/Generation/MappingModelFactory.cs +++ b/source/Generation/MappingAnalysisFactory.cs @@ -11,18 +11,19 @@ namespace AlephMapper.Generation; -internal static class MappingModelFactory +internal static class MappingAnalysisFactory { - public static MappingModel? Create(GeneratorSyntaxContext context, CancellationToken cancellationToken) + public static MappingAnalysis? Create( + SemanticModel semanticModel, + MethodDeclarationSyntax methodDeclaration, + CancellationToken cancellationToken) { - if (context.Node is not MethodDeclarationSyntax methodDeclaration || - methodDeclaration.Parent is not ClassDeclarationSyntax classDeclaration || + if (methodDeclaration.Parent is not ClassDeclarationSyntax classDeclaration || !classDeclaration.Modifiers.Any(static modifier => modifier.IsKind(SyntaxKind.StaticKeyword))) { return null; } - var semanticModel = context.SemanticModel; var classSymbol = semanticModel.GetDeclaredSymbol(classDeclaration, cancellationToken); var methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); if (classSymbol == null || methodSymbol == null || methodSymbol.Parameters.Length == 0) @@ -36,7 +37,7 @@ methodDeclaration.Parent is not ClassDeclarationSyntax classDeclaration || return null; } - return new MappingModel( + return new MappingAnalysis( classSymbol, methodSymbol, methodSymbol.Name, @@ -59,9 +60,9 @@ private static bool HasAttribute(INamedTypeSymbol classSymbol, IMethodSymbol met SymbolHelpers.HasAttribute(methodSymbol, attributeName); } - private static IReadOnlyList GetAdaptations(IMethodSymbol methodSymbol) + private static IReadOnlyList GetAdaptations(IMethodSymbol methodSymbol) { - var adaptations = new List(); + var adaptations = new List(); foreach (var attribute in methodSymbol.GetAttributes()) { if (attribute.AttributeClass?.ToDisplayString() != typeof(AdaptAttribute).FullName || @@ -91,7 +92,7 @@ attribute.ConstructorArguments[0].Value is not INamedTypeSymbol sourceType || } } - adaptations.Add(new AdaptationModel( + adaptations.Add(new AdaptationAnalysis( sourceType, destinationType, name, diff --git a/source/Generation/MappingCatalog.cs b/source/Generation/MappingCatalog.cs new file mode 100644 index 0000000..7ca2991 --- /dev/null +++ b/source/Generation/MappingCatalog.cs @@ -0,0 +1,48 @@ +#nullable enable + +using AlephMapper.Helpers; +using AlephMapper.Models; +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; + +namespace AlephMapper.Generation; + +/// +/// Resolves local mappings eagerly and source-defined helper mappings lazily. +/// This keeps each mapper output independent while preserving cross-mapper +/// inlining support. +/// +internal sealed class MappingCatalog +{ + private readonly Dictionary _mappings; + private readonly Func _createExternalMapping; + + public MappingCatalog( + Dictionary mappings, + Func createExternalMapping) + { + _mappings = mappings; + _createExternalMapping = createExternalMapping; + } + + public bool TryGetValue(IMethodSymbol method, out MappingAnalysis mapping) + { + var normalizedMethod = SymbolHelpers.Normalize(method); + if (_mappings.TryGetValue(normalizedMethod, out mapping)) + { + return true; + } + + var externalMapping = _createExternalMapping(normalizedMethod); + if (externalMapping is null) + { + mapping = null!; + return false; + } + + _mappings[normalizedMethod] = externalMapping; + mapping = externalMapping; + return true; + } +} diff --git a/source/Generation/MappingMethodDetails.cs b/source/Generation/MappingMethodDetails.cs index 1e4fc48..f94082b 100644 --- a/source/Generation/MappingMethodDetails.cs +++ b/source/Generation/MappingMethodDetails.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Generation; /// internal sealed class MappingMethodDetails { - public MappingMethodDetails(MappingModel mapping) + public MappingMethodDetails(MappingAnalysis mapping) { Mapping = mapping; var nullableContextPosition = mapping.MethodSymbol.Locations.FirstOrDefault()?.SourceSpan.Start ?? 0; @@ -34,7 +34,7 @@ public MappingMethodDetails(MappingModel mapping) NullableContext = nullableContext; } - public MappingModel Mapping { get; } + public MappingAnalysis Mapping { get; } public string[] ParameterTypeNames { get; } public string DestinationTypeName { get; } public string SourceTypeName { get; } diff --git a/source/Models/AdaptationModel.cs b/source/Models/AdaptationAnalysis.cs similarity index 90% rename from source/Models/AdaptationModel.cs rename to source/Models/AdaptationAnalysis.cs index 267022c..8132732 100644 --- a/source/Models/AdaptationModel.cs +++ b/source/Models/AdaptationAnalysis.cs @@ -5,9 +5,12 @@ namespace AlephMapper.Models; -internal sealed class AdaptationModel +/// +/// Compiler-bound adaptation analysis state used only while rendering output. +/// +internal sealed class AdaptationAnalysis { - public AdaptationModel( + public AdaptationAnalysis( INamedTypeSymbol sourceType, INamedTypeSymbol destinationType, string? generatedName, diff --git a/source/Models/MappingModel.cs b/source/Models/MappingAnalysis.cs similarity index 74% rename from source/Models/MappingModel.cs rename to source/Models/MappingAnalysis.cs index 7262d88..17ab7e0 100644 --- a/source/Models/MappingModel.cs +++ b/source/Models/MappingAnalysis.cs @@ -4,7 +4,11 @@ namespace AlephMapper.Models; -internal sealed class MappingModel( +/// +/// Compiler-bound analysis state used only within a source-output callback. +/// It is intentionally not retained by the incremental pipeline. +/// +internal sealed class MappingAnalysis( INamedTypeSymbol containingType, IMethodSymbol methodSymbol, string name, @@ -18,7 +22,7 @@ internal sealed class MappingModel( NullConditionalRewrite nullStrategy, CollectionPropertiesPolicy collectionPolicy, IReadOnlyList usingDirectives, - IReadOnlyList adaptations) + IReadOnlyList adaptations) { public readonly INamedTypeSymbol ContainingType = containingType; public readonly IMethodSymbol MethodSymbol = methodSymbol; @@ -36,19 +40,5 @@ internal sealed class MappingModel( public readonly NullConditionalRewrite NullStrategy = nullStrategy; public readonly CollectionPropertiesPolicy CollectionPolicy = collectionPolicy; public readonly IReadOnlyList UsingDirectives = usingDirectives; - public readonly IReadOnlyList Adaptations = adaptations; - - public override bool Equals(object obj) - { - if (obj is MappingModel other) - { - return SymbolEqualityComparer.Default.Equals(MethodSymbol, other.MethodSymbol); - } - return false; - } - - public override int GetHashCode() - { - return SymbolEqualityComparer.Default.GetHashCode(MethodSymbol); - } + public readonly IReadOnlyList Adaptations = adaptations; } diff --git a/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs b/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs index 8aa2240..0729bb8 100644 --- a/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs @@ -1,4 +1,5 @@ using AlephMapper.Helpers; +using AlephMapper.Generation; using AlephMapper.Models; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -12,7 +13,7 @@ namespace AlephMapper.SyntaxRewriters; internal sealed partial class InliningResolver( SemanticModel model, - IDictionary catalog, + MappingCatalog catalog, bool forUpdateMethod, NullConditionalRewrite rewriteSupport, ITypeSymbol returnTypeToAnnotate = null) @@ -23,7 +24,7 @@ internal sealed partial class InliningResolver( private HashSet _callStack = new(SymbolEqualityComparer.Default); private List _circularReferences = []; - private Dictionary _inlinedMethods = new(SymbolEqualityComparer.Default); + private Dictionary _inlinedMethods = new(SymbolEqualityComparer.Default); private List _unsafeConditionalReceivers = []; private List _unsupportedNullConditionals = []; public IEnumerable UsingDirectives => _inlinedMethods.SelectMany(il => il.Value.UsingDirectives).Distinct(); diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index da2573f..b850613 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -1,7 +1,9 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Testing; using Microsoft.EntityFrameworkCore; +using AlephMapper.Generation; namespace AlephMapper.Tests; @@ -17,6 +19,153 @@ public SourceGeneratorTests() _driver = CSharpGeneratorDriver.Create(generators: [generator], parseOptions: _parseOptions); } + [Test] + public async Task UnrelatedMethodsAreRejectedBySyntaxCandidateFilter() + { + var tree = CSharpSyntaxTree.ParseText( + "public class Unrelated { public int Add(int left, int right) => left + right; }", + _parseOptions); + var method = tree.GetRoot().DescendantNodes().OfType().Single(); + + await Assert.That(MappingMethodCandidate.IsCandidate(method, CancellationToken.None)).IsFalse(); + } + + [Test] + public async Task MapperHelpersRemainCandidatesForInlining() + { + var tree = CSharpSyntaxTree.ParseText( + "using AlephMapper; public static partial class Mapper { [Expressive] public static int Map(int value) => Helper(value); public static int Helper(int value) => value; }", + _parseOptions); + var methods = tree.GetRoot().DescendantNodes().OfType().ToArray(); + + await Assert.That(methods).Count().IsEqualTo(2); + await Assert.That(MappingMethodCandidate.IsCandidate(methods.Single(method => method.Identifier.ValueText == "Helper"), CancellationToken.None)).IsTrue(); + } + + [Test] + public async Task ClassLevelConfigurationAcrossPartialDeclarationsGeneratesOnce() + { + const string configuration = """ + using AlephMapper; + namespace Fixture; + [Expressive] + public static partial class Mapper { } + """; + const string mapping = """ + namespace Fixture; + public static partial class Mapper + { + public static Target Map(Source source) => new() { Value = source.Value }; + } + public sealed class Source { public int Value { get; set; } } + public sealed class Target { public int Value { get; set; } } + """; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var compilation = CSharpCompilation.Create( + "PartialMapper", + [ + CSharpSyntaxTree.ParseText(configuration, _parseOptions, "Configuration.cs"), + CSharpSyntaxTree.ParseText(mapping, _parseOptions, "Mapping.cs") + ], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var driver = CSharpGeneratorDriver.Create( + generators: [new AlephSourceGenerator().AsSourceGenerator()], + parseOptions: _parseOptions); + var updatedDriver = driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics); + var generatorResult = updatedDriver.GetRunResult().Results.Single(); + + await Assert.That(diagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(outputCompilation.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(generatorResult.Exception).IsNull(); + await Assert.That(generatorResult.GeneratedSources + .Count(source => source.HintName.EndsWith("Mapper_GeneratedMappings.g.cs", StringComparison.Ordinal))).IsEqualTo(1); + } + + [Test] + public async Task GeneratedConfigurationTypesAreNotPublic() + { + var assembly = typeof(AlephSourceGenerator).Assembly; + var typeNames = new[] + { + "ExpressiveAttribute", + "UpdatableAttribute", + "AdaptAttribute", + "NullConditionalRewrite", + "CollectionPropertiesPolicy", + "AdaptGeneration" + }; + + foreach (var typeName in typeNames) + { + var type = assembly.GetType("AlephMapper." + typeName); + await Assert.That(type).IsNotNull(); + await Assert.That(type!.IsPublic).IsFalse(); + } + } + + [Test] + public async Task GeneratedConfigurationTypesDoNotConflictAcrossConsumerAssemblies() + { + const string projectASource = """ + using AlephMapper; + namespace ProjectA; + public static partial class Mapper + { + [Expressive] + public static Target Map(Source source) => new() { Value = source.Value }; + } + public sealed class Source { public int Value { get; set; } } + public sealed class Target { public int Value { get; set; } } + """; + const string projectBSource = """ + using AlephMapper; + using ProjectA; + namespace ProjectB; + public static partial class Mapper + { + [Expressive] + public static Target Map(Source source) => new() { Value = source.Value }; + } + """; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var projectA = CSharpCompilation.Create( + "ProjectA", + [CSharpSyntaxTree.ParseText(projectASource, _parseOptions, "ProjectA.cs")], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var projectADriver = CSharpGeneratorDriver.Create( + generators: [new AlephSourceGenerator().AsSourceGenerator()], + parseOptions: _parseOptions); + projectADriver.RunGeneratorsAndUpdateCompilation(projectA, out var projectAOutput, out var projectADiagnostics); + await Assert.That(projectADiagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(projectAOutput.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + + using var projectAImage = new MemoryStream(); + var emitResult = projectAOutput.Emit(projectAImage); + await Assert.That(emitResult.Success).IsTrue(); + + var projectB = CSharpCompilation.Create( + "ProjectB", + [CSharpSyntaxTree.ParseText(projectBSource, _parseOptions, "ProjectB.cs")], + references.Add(MetadataReference.CreateFromImage(projectAImage.ToArray())), + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var projectBDriver = CSharpGeneratorDriver.Create( + generators: [new AlephSourceGenerator().AsSourceGenerator()], + parseOptions: _parseOptions); + projectBDriver.RunGeneratorsAndUpdateCompilation(projectB, out var projectBOutput, out var projectBDiagnostics); + + await Assert.That(projectBDiagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(projectBOutput.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(projectBOutput.GetTypeByMetadataName("AlephMapper.ExpressiveAttribute")!.DeclaredAccessibility) + .IsEqualTo(Accessibility.Internal); + } + public static IEnumerable GetTestCases() { var groupedByTestCase = Nones.GetMatches("Files/**/*.cs") From 21f09b0395fbbc2c4eb79d6a59383ef75c9ebba6 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Mon, 31 Aug 2026 19:42:59 +0200 Subject: [PATCH 03/22] Improve attribute discovery, embedding, and incremental coverage --- README.md | 4 + source/AlephMapper.csproj | 2 +- source/AlephSourceGenerator.cs | 48 +++++- source/Attributes.cs | 8 + source/EmbeddedAttribute.cs | 11 ++ source/Generation/MapperCandidate.cs | 61 ++++++-- source/Generation/MapperSourceOutput.cs | 93 +++++++++-- .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../Expected/AlephMapper.Attributes.g.cs | 8 + .../AlephMapper.Tests/SourceGeneratorTests.cs | 144 +++++++++++++++++- 33 files changed, 539 insertions(+), 32 deletions(-) create mode 100644 source/EmbeddedAttribute.cs diff --git a/README.md b/README.md index 12b4351..68697da 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,10 @@ When referencing the generator directly from source: `PrivateAssets="all"` prevents AlephMapper from flowing transitively to consumers of your library. `IncludeAssets` makes its analyzer and source-generator assets available during compilation. +### Compiler compatibility + +AlephMapper 0.6.2 requires a Roslyn compiler host compatible with `Microsoft.CodeAnalysis` 4.14 or later. This version uses Roslyn's embedded-marker support so its generated configuration attributes remain private to the consuming assembly, including when `InternalsVisibleTo` is used. + ## Quick start Mapping methods must be `static`, expression-bodied, and declared in a `static partial` class. diff --git a/source/AlephMapper.csproj b/source/AlephMapper.csproj index 4e2e58c..f31af74 100644 --- a/source/AlephMapper.csproj +++ b/source/AlephMapper.csproj @@ -23,7 +23,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/source/AlephSourceGenerator.cs b/source/AlephSourceGenerator.cs index 7029c0b..eb5339b 100644 --- a/source/AlephSourceGenerator.cs +++ b/source/AlephSourceGenerator.cs @@ -12,15 +12,51 @@ public sealed class AlephSourceGenerator : IIncrementalGenerator { public void Initialize(IncrementalGeneratorInitializationContext context) { - context.RegisterPostInitializationOutput(AttributeSourceEmitter.AddAttributes); + context.RegisterPostInitializationOutput(static postInitializationContext => + { + postInitializationContext.AddEmbeddedAttributeDefinition(); + AttributeSourceEmitter.AddAttributes(postInitializationContext); + }); - var mapperCandidates = context.SyntaxProvider - .CreateSyntaxProvider( - MapperCandidate.IsCandidate, - static (syntaxContext, cancellationToken) => MapperCandidate.Create(syntaxContext.Node, cancellationToken)); + var expressiveMappers = context.SyntaxProvider.ForAttributeWithMetadataName( + typeof(ExpressiveAttribute).FullName, + MapperCandidate.IsAttributeTarget, + static (attributeContext, cancellationToken) => MapperCandidate.Create( + attributeContext, + MapperAttributeKind.Expressive, + cancellationToken)); + var updatableMappers = context.SyntaxProvider.ForAttributeWithMetadataName( + typeof(UpdatableAttribute).FullName, + MapperCandidate.IsAttributeTarget, + static (attributeContext, cancellationToken) => MapperCandidate.Create( + attributeContext, + MapperAttributeKind.Updatable, + cancellationToken)); + + var adaptableMappers = context.SyntaxProvider.ForAttributeWithMetadataName( + typeof(AdaptAttribute).FullName, + MapperCandidate.IsAttributeTarget, + static (attributeContext, cancellationToken) => MapperCandidate.Create( + attributeContext, + MapperAttributeKind.Adapt, + cancellationToken)); + + RegisterMapperOutput(context, expressiveMappers, "Expressive"); + RegisterMapperOutput(context, updatableMappers, "Updatable"); + RegisterMapperOutput(context, adaptableMappers, "Adapt"); + } + + private static void RegisterMapperOutput( + IncrementalGeneratorInitializationContext context, + IncrementalValuesProvider mapperCandidates, + string configurationKind) + { context.RegisterSourceOutput( - mapperCandidates.Combine(context.CompilationProvider), + mapperCandidates + .WithTrackingName($"AlephMapper.{configurationKind}Candidates") + .Combine(context.CompilationProvider) + .WithTrackingName($"AlephMapper.{configurationKind}GenerationInput"), MapperSourceOutput.Generate); } } diff --git a/source/Attributes.cs b/source/Attributes.cs index da5503f..5668336 100644 --- a/source/Attributes.cs +++ b/source/Attributes.cs @@ -1,10 +1,13 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -33,6 +36,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -45,6 +49,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -57,6 +62,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -79,6 +85,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -121,6 +128,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/source/EmbeddedAttribute.cs b/source/EmbeddedAttribute.cs new file mode 100644 index 0000000..ef21364 --- /dev/null +++ b/source/EmbeddedAttribute.cs @@ -0,0 +1,11 @@ +using System; + +namespace Microsoft.CodeAnalysis; + +// The generator host injects the real definition into consuming compilations +// through AddEmbeddedAttributeDefinition. This shim only lets Attributes.cs be +// compiled into the generator assembly before it is embedded as source. +[AttributeUsage(AttributeTargets.All)] +internal sealed class EmbeddedAttribute : Attribute +{ +} diff --git a/source/Generation/MapperCandidate.cs b/source/Generation/MapperCandidate.cs index 5e77042..33b8ed0 100644 --- a/source/Generation/MapperCandidate.cs +++ b/source/Generation/MapperCandidate.cs @@ -4,44 +4,70 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using System; -using System.Linq; using System.Threading; namespace AlephMapper.Generation; /// -/// Value-only identity for a mapper declaration. One instance drives one -/// generated mapper file and therefore forms the incremental output unit. +/// Value-only identity for an AlephMapper attribute target. The target is +/// kept separate from its containing mapper so multiple configuration kinds +/// can be normalized to one generated file without caching a symbol. /// internal sealed class MapperCandidate : IEquatable { - private MapperCandidate(string filePath, int start, int length) + internal MapperCandidate( + string filePath, + int start, + int length, + MapperAttributeKind attributeKind) { FilePath = filePath; Start = start; Length = length; + AttributeKind = attributeKind; } public string FilePath { get; } public int Start { get; } public int Length { get; } + public MapperAttributeKind AttributeKind { get; } - public static bool IsCandidate(SyntaxNode node, CancellationToken _) + public static bool IsAttributeTarget(SyntaxNode node, CancellationToken _) { - if (node is not ClassDeclarationSyntax containingClass || - !containingClass.Modifiers.Any(static modifier => modifier.IsKind(SyntaxKind.StaticKeyword))) + var containingClass = node switch + { + ClassDeclarationSyntax classDeclaration => classDeclaration, + MethodDeclarationSyntax { Parent: ClassDeclarationSyntax classDeclaration } => classDeclaration, + _ => null + }; + + if (containingClass is null) { return false; } - return containingClass.AttributeLists.Count != 0 || - containingClass.Members.OfType().Any(static method => - method.AttributeLists.Count != 0); + foreach (var modifier in containingClass.Modifiers) + { + if (modifier.IsKind(SyntaxKind.StaticKeyword)) + { + return true; + } + } + + return false; } - public static MapperCandidate Create(SyntaxNode node, CancellationToken _) + public static MapperCandidate Create( + GeneratorAttributeSyntaxContext context, + MapperAttributeKind attributeKind, + CancellationToken _) { - return new MapperCandidate(node.SyntaxTree.FilePath, node.SpanStart, node.Span.Length); + var targetNode = context.TargetNode; + return new MapperCandidate( + targetNode.SyntaxTree.FilePath, + targetNode.SpanStart, + targetNode.Span.Length, + attributeKind); } public bool Equals(MapperCandidate? other) @@ -49,6 +75,7 @@ public bool Equals(MapperCandidate? other) return other is not null && Start == other.Start && Length == other.Length && + AttributeKind == other.AttributeKind && string.Equals(FilePath, other.FilePath, StringComparison.Ordinal); } @@ -60,7 +87,15 @@ public override int GetHashCode() { var hash = StringComparer.Ordinal.GetHashCode(FilePath); hash = (hash * 397) ^ Start; - return (hash * 397) ^ Length; + hash = (hash * 397) ^ Length; + return (hash * 397) ^ (int)AttributeKind; } } } + +internal enum MapperAttributeKind +{ + Expressive, + Updatable, + Adapt +} diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index 7095749..ce78e2f 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -35,7 +35,7 @@ public static void Generate( return; } - if (!IsPrimaryMapperDeclaration(mapperType, mapperDeclaration, context.CancellationToken)) + if (!IsPrimaryMapperCandidate(input.Right, mapperType, input.Left, context.CancellationToken)) { return; } @@ -124,21 +124,25 @@ declaration.ExpressionBody is null || return null; } - private static bool IsPrimaryMapperDeclaration( + private static bool IsPrimaryMapperCandidate( + Compilation compilation, INamedTypeSymbol mapperType, - ClassDeclarationSyntax mapperDeclaration, + MapperCandidate candidate, CancellationToken cancellationToken) { - var primaryDeclaration = mapperType.DeclaringSyntaxReferences + var primaryCandidate = mapperType.DeclaringSyntaxReferences .OrderBy(static reference => reference.SyntaxTree.FilePath, StringComparer.Ordinal) .ThenBy(static reference => reference.Span.Start) .Select(reference => reference.GetSyntax(cancellationToken) as ClassDeclarationSyntax) - .FirstOrDefault(static declaration => declaration is not null && - MapperCandidate.IsCandidate(declaration, CancellationToken.None)); + .Where(static declaration => declaration is not null) + .SelectMany(declaration => GetMapperCandidates(compilation, declaration!, cancellationToken)) + .OrderBy(static current => current.FilePath, StringComparer.Ordinal) + .ThenBy(static current => current.Start) + .ThenBy(static current => current.Length) + .ThenBy(static current => current.AttributeKind) + .FirstOrDefault(); - return primaryDeclaration is not null && - primaryDeclaration.SyntaxTree == mapperDeclaration.SyntaxTree && - primaryDeclaration.Span == mapperDeclaration.Span; + return primaryCandidate is not null && primaryCandidate.Equals(candidate); } private static ClassDeclarationSyntax? FindMapperDeclaration( @@ -160,16 +164,83 @@ private static bool IsPrimaryMapperDeclaration( continue; } - if (root.FindNode(span, getInnermostNodeForTie: true) is ClassDeclarationSyntax declaration && - declaration.Span == span) + var target = root.FindNode(span, getInnermostNodeForTie: true); + if (target.Span != span) + { + continue; + } + + if (target is ClassDeclarationSyntax declaration) { return declaration; } + + if (target.FirstAncestorOrSelf() is { } containingClass) + { + return containingClass; + } } return null; } + private static IEnumerable GetMapperCandidates( + Compilation compilation, + ClassDeclarationSyntax mapperDeclaration, + CancellationToken cancellationToken) + { + var semanticModel = compilation.GetSemanticModel(mapperDeclaration.SyntaxTree); + + if (ContainsAlephMapperAttribute(mapperDeclaration.AttributeLists, semanticModel, cancellationToken, out var classKind)) + { + yield return CreateCandidate(mapperDeclaration, classKind); + } + + foreach (var method in mapperDeclaration.Members.OfType()) + { + if (ContainsAlephMapperAttribute(method.AttributeLists, semanticModel, cancellationToken, out var methodKind)) + { + yield return CreateCandidate(method, methodKind); + } + } + } + + private static bool ContainsAlephMapperAttribute( + SyntaxList attributeLists, + SemanticModel semanticModel, + CancellationToken cancellationToken, + out MapperAttributeKind attributeKind) + { + attributeKind = MapperAttributeKind.Adapt; + foreach (var attribute in attributeLists.SelectMany(static list => list.Attributes)) + { + var type = semanticModel.GetTypeInfo(attribute, cancellationToken).Type; + switch (type?.ToDisplayString()) + { + case "AlephMapper.ExpressiveAttribute": + attributeKind = MapperAttributeKind.Expressive; + return true; + case "AlephMapper.UpdatableAttribute": + attributeKind = MapperAttributeKind.Updatable; + return true; + case "AlephMapper.AdaptAttribute": + attributeKind = MapperAttributeKind.Adapt; + return true; + } + } + + return false; + } + + private static MapperCandidate CreateCandidate(SyntaxNode targetNode, MapperAttributeKind attributeKind) + { + return new MapperCandidate( + targetNode.SyntaxTree.FilePath, + targetNode.SpanStart, + targetNode.Span.Length, + attributeKind); + } + private static void GenerateMapper( SourceProductionContext sourceProductionContext, INamedTypeSymbol mapperType, diff --git a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs index a62e671..3d470ad 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs @@ -3,11 +3,14 @@ using System; +using Microsoft.CodeAnalysis; + namespace AlephMapper; /// /// Configures how null-conditional operators are handled /// +[Embedded] internal enum NullConditionalRewrite { /// @@ -36,6 +39,7 @@ internal enum NullConditionalRewrite /// /// Marks a class to generate expressive companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class ExpressiveAttribute : Attribute { @@ -48,6 +52,7 @@ internal sealed class ExpressiveAttribute : Attribute /// /// Marks a class to generate update companion methods. /// +[Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class UpdatableAttribute : Attribute { @@ -60,6 +65,7 @@ internal sealed class UpdatableAttribute : Attribute /// /// Defines which adapted companions are generated for an declaration. /// +[Embedded] [Flags] internal enum AdaptGeneration { @@ -82,6 +88,7 @@ internal enum AdaptGeneration /// /// Reuses a mapping method as a compile-time template for one explicitly specified source/destination pair. /// +[Embedded] [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] internal sealed class AdaptAttribute : Attribute { @@ -124,6 +131,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// /// Defines the policy for handling collection updates during mapping operations /// +[Embedded] internal enum CollectionPropertiesPolicy { /// diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index b850613..639eb76 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -1,9 +1,12 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Testing; using Microsoft.EntityFrameworkCore; using AlephMapper.Generation; +using System.Diagnostics; +using System.Text; namespace AlephMapper.Tests; @@ -107,10 +110,11 @@ public async Task GeneratedConfigurationTypesAreNotPublic() } [Test] - public async Task GeneratedConfigurationTypesDoNotConflictAcrossConsumerAssemblies() + public async Task EmbeddedConfigurationTypesDoNotConflictAcrossConsumerAssemblies() { const string projectASource = """ using AlephMapper; + [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("ProjectB")] namespace ProjectA; public static partial class Mapper { @@ -164,6 +168,144 @@ public static partial class Mapper await Assert.That(projectBOutput.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); await Assert.That(projectBOutput.GetTypeByMetadataName("AlephMapper.ExpressiveAttribute")!.DeclaredAccessibility) .IsEqualTo(Accessibility.Internal); + await Assert.That(projectBOutput.GetTypeByMetadataName("AlephMapper.ExpressiveAttribute")!.GetAttributes() + .Any(attribute => attribute.AttributeClass?.ToDisplayString() == "Microsoft.CodeAnalysis.EmbeddedAttribute")) + .IsTrue(); + } + + [Test] + public async Task AttributeDiscoveryGeneratesOneFileForCombinedConfiguration() + { + const string source = """ + using AlephMapper; + namespace Fixture; + public static partial class Mapper + { + [Expressive] + [Updatable] + [Adapt(typeof(AdaptedSource), typeof(AdaptedTarget), Name = "MapAdapted")] + public static Target Map(Source source) => new() { Value = source.Value }; + } + public sealed class Source { public int Value { get; set; } } + public sealed class Target { public int Value { get; set; } } + public sealed class AdaptedSource { public int Value { get; set; } } + public sealed class AdaptedTarget { public int Value { get; set; } } + """; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var compilation = CSharpCompilation.Create( + "CombinedConfiguration", + [CSharpSyntaxTree.ParseText(source, _parseOptions, "Mapper.cs")], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var driver = _driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics); + var result = driver.GetRunResult().Results.Single(); + + await Assert.That(diagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(outputCompilation.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(result.GeneratedSources + .Count(generated => generated.HintName.EndsWith("Mapper_GeneratedMappings.g.cs", StringComparison.Ordinal))) + .IsEqualTo(1); + } + + [Test] + public async Task AttributeCandidatesRemainUnchangedWhenOnlyUnrelatedSourceChanges() + { + const string mapperA = """ + using AlephMapper; + namespace Fixture; + public static partial class MapperA + { + [Expressive] + public static Target Map(Source source) => new() { Value = source.Value }; + } + public sealed class Source { public int Value { get; set; } } + public sealed class Target { public int Value { get; set; } } + """; + const string mapperB = """ + using AlephMapper; + namespace Fixture; + public static partial class MapperB + { + [Expressive] + public static Target Map(Source source) => new() { Value = source.Value }; + } + """; + const string unrelated = "namespace Fixture; public sealed class Unrelated { public int Value => 1; }"; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var mapperATree = CSharpSyntaxTree.ParseText(mapperA, _parseOptions, "MapperA.cs"); + var mapperBTree = CSharpSyntaxTree.ParseText(mapperB, _parseOptions, "MapperB.cs"); + var unrelatedTree = CSharpSyntaxTree.ParseText(unrelated, _parseOptions, "Unrelated.cs"); + var compilation = CSharpCompilation.Create( + "IncrementalTracking", + [mapperATree, mapperBTree, unrelatedTree], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var driver = CreateTrackingDriver().RunGeneratorsAndUpdateCompilation(compilation, out _, out _); + var updatedUnrelatedTree = unrelatedTree.WithChangedText(SourceText.From( + "namespace Fixture; public sealed class Unrelated { public int Value => 2; }")); + var updatedCompilation = compilation.ReplaceSyntaxTree(unrelatedTree, updatedUnrelatedTree); + driver = driver.RunGeneratorsAndUpdateCompilation(updatedCompilation, out _, out _); + + var trackedSteps = driver.GetRunResult().Results.Single().TrackedSteps; + var candidateOutputs = trackedSteps["AlephMapper.ExpressiveCandidates"] + .SelectMany(static step => step.Outputs) + .ToArray(); + + await Assert.That(candidateOutputs).Count().IsEqualTo(2); + await Assert.That(candidateOutputs.All(static output => output.Item2 == IncrementalStepRunReason.Unchanged)).IsTrue(); + } + + [Test] + public async Task LargeCompilationDiscoversOnlyAttributedMappers() + { + var source = new StringBuilder("using AlephMapper; namespace Fixture; public sealed class Source { public int Value { get; set; } } public sealed class Target { public int Value { get; set; } } public sealed class Unrelated {"); + for (var index = 0; index < 1_000; index++) + { + source.Append("public int Method").Append(index).Append("() => ").Append(index).Append(';'); + } + + source.Append('}'); + for (var index = 0; index < 10; index++) + { + source.Append("public static partial class Mapper").Append(index) + .Append(" { [Expressive] public static Target Map(Source source) => new() { Value = source.Value }; }"); + } + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var compilation = CSharpCompilation.Create( + "LargeDiscovery", + [CSharpSyntaxTree.ParseText(source.ToString(), _parseOptions, "Large.cs")], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var stopwatch = Stopwatch.StartNew(); + var driver = CreateTrackingDriver().RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics); + stopwatch.Stop(); + + var result = driver.GetRunResult().Results.Single(); + var candidateOutputs = result.TrackedSteps["AlephMapper.ExpressiveCandidates"] + .SelectMany(static step => step.Outputs) + .ToArray(); + + Console.WriteLine($"Large discovery completed in {stopwatch.ElapsedMilliseconds} ms."); + await Assert.That(diagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(outputCompilation.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(candidateOutputs).Count().IsEqualTo(10); + await Assert.That(result.GeneratedSources + .Count(generated => generated.HintName.EndsWith("_GeneratedMappings.g.cs", StringComparison.Ordinal))) + .IsEqualTo(10); + } + + private CSharpGeneratorDriver CreateTrackingDriver() + { + return CSharpGeneratorDriver.Create( + generators: [new AlephSourceGenerator().AsSourceGenerator()], + parseOptions: _parseOptions, + driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true)); } public static IEnumerable GetTestCases() From 3a5ddbb7bf5a3bfb211d9df8b1a2284252a1f8bc Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Mon, 31 Aug 2026 19:51:17 +0200 Subject: [PATCH 04/22] Move mapper generation to value-only incremental outputs --- source/Adaptation/AdaptationValidator.cs | 3 +- source/AlephSourceGenerator.cs | 15 +- .../Diagnostics/CrashDiagnosticsReporter.cs | 9 ++ .../Emitters/AdaptationMemberEmitter.cs | 18 +-- .../Emitters/ExpressiveMemberEmitter.cs | 6 +- .../Emitters/UpdatableMemberEmitter.cs | 4 +- source/Generation/MapperGenerationContext.cs | 11 +- source/Generation/MapperGenerationResult.cs | 128 ++++++++++++++++++ source/Generation/MapperSourceOutput.cs | 68 ++++++---- .../AlephMapper.Tests/SourceGeneratorTests.cs | 4 +- 10 files changed, 214 insertions(+), 52 deletions(-) create mode 100644 source/Generation/MapperGenerationResult.cs diff --git a/source/Adaptation/AdaptationValidator.cs b/source/Adaptation/AdaptationValidator.cs index ee7b0a0..24475c2 100644 --- a/source/Adaptation/AdaptationValidator.cs +++ b/source/Adaptation/AdaptationValidator.cs @@ -1,6 +1,7 @@ #nullable enable using AlephMapper.Diagnostics; +using AlephMapper.Generation; using AlephMapper.Models; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -17,7 +18,7 @@ namespace AlephMapper.Adaptation; internal static class AdaptationValidator { public static bool Validate( - SourceProductionContext context, + MapperGenerationContext context, MappingAnalysis mapping, AdaptationAnalysis adaptation, ExpressionSyntax inlinedBody) diff --git a/source/AlephSourceGenerator.cs b/source/AlephSourceGenerator.cs index eb5339b..613f5e1 100644 --- a/source/AlephSourceGenerator.cs +++ b/source/AlephSourceGenerator.cs @@ -21,7 +21,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var expressiveMappers = context.SyntaxProvider.ForAttributeWithMetadataName( typeof(ExpressiveAttribute).FullName, MapperCandidate.IsAttributeTarget, - static (attributeContext, cancellationToken) => MapperCandidate.Create( + static (attributeContext, cancellationToken) => MapperSourceOutput.Create( attributeContext, MapperAttributeKind.Expressive, cancellationToken)); @@ -29,7 +29,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var updatableMappers = context.SyntaxProvider.ForAttributeWithMetadataName( typeof(UpdatableAttribute).FullName, MapperCandidate.IsAttributeTarget, - static (attributeContext, cancellationToken) => MapperCandidate.Create( + static (attributeContext, cancellationToken) => MapperSourceOutput.Create( attributeContext, MapperAttributeKind.Updatable, cancellationToken)); @@ -37,7 +37,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var adaptableMappers = context.SyntaxProvider.ForAttributeWithMetadataName( typeof(AdaptAttribute).FullName, MapperCandidate.IsAttributeTarget, - static (attributeContext, cancellationToken) => MapperCandidate.Create( + static (attributeContext, cancellationToken) => MapperSourceOutput.Create( attributeContext, MapperAttributeKind.Adapt, cancellationToken)); @@ -49,14 +49,13 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private static void RegisterMapperOutput( IncrementalGeneratorInitializationContext context, - IncrementalValuesProvider mapperCandidates, + IncrementalValuesProvider mapperResults, string configurationKind) { context.RegisterSourceOutput( - mapperCandidates + mapperResults .WithTrackingName($"AlephMapper.{configurationKind}Candidates") - .Combine(context.CompilationProvider) - .WithTrackingName($"AlephMapper.{configurationKind}GenerationInput"), - MapperSourceOutput.Generate); + .WithTrackingName($"AlephMapper.{configurationKind}GenerationResult"), + MapperSourceOutput.Emit); } } diff --git a/source/Diagnostics/CrashDiagnosticsReporter.cs b/source/Diagnostics/CrashDiagnosticsReporter.cs index 065dbe1..4978eb9 100644 --- a/source/Diagnostics/CrashDiagnosticsReporter.cs +++ b/source/Diagnostics/CrashDiagnosticsReporter.cs @@ -1,4 +1,5 @@ using System; +using AlephMapper.Generation; using Microsoft.CodeAnalysis; namespace AlephMapper.Diagnostics; @@ -23,6 +24,14 @@ Exception exception ); } + internal static GenerationDiagnostic CreateDiagnostic(Exception exception) + { + return Generation.GenerationDiagnostic.From(Diagnostic.Create( + DiagnosticDescriptors.GeneratorCrash, + Location.None, + FormatCrashDiagnostic(exception))); + } + private static string FormatCrashDiagnostic(Exception exception) { var details = exception.ToString().Replace("\r", " ").Replace("\n", " "); diff --git a/source/Generation/Emitters/AdaptationMemberEmitter.cs b/source/Generation/Emitters/AdaptationMemberEmitter.cs index 1cfe7e2..282d0b9 100644 --- a/source/Generation/Emitters/AdaptationMemberEmitter.cs +++ b/source/Generation/Emitters/AdaptationMemberEmitter.cs @@ -26,7 +26,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co var generateUpdate = (adaptation.Generation & AdaptGeneration.Update) == AdaptGeneration.Update; if (generateExpression && string.IsNullOrWhiteSpace(adaptation.GeneratedName)) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.AdaptExpressionWithoutName, GetLocation(mapping, adaptation), mapping.MethodSymbol.Name)); @@ -44,7 +44,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co var pairSignature = MethodSignature.Build("", [sourceTypeName, destinationTypeName]); if (!adaptationPairs.Add(pairSignature)) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.AdaptDuplicatePair, GetLocation(mapping, adaptation), mapping.MethodSymbol.Name, @@ -58,7 +58,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co context.AddUsings(inliner.UsingDirectives.Concat(mapping.UsingDirectives)); if (inliner.CircularReferences.Any()) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.AdaptCircularHelper, mapping.MethodSymbol.Locations.FirstOrDefault(), mapping.MethodSymbol.Name)); @@ -68,7 +68,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co if ((generateMap || generateExpression) && inliner.UnsafeConditionalReceivers.FirstOrDefault() is { } unsafeReceiver) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.UnsafeNullConditionalReceiver, unsafeReceiver.Location, mapping.MethodSymbol.Name, @@ -79,7 +79,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co if (generateExpression && inliner.UnsupportedNullConditionals.FirstOrDefault() is { } unsupportedConditional) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.UnsupportedNullConditionalExpression, unsupportedConditional.Location, mapping.MethodSymbol.Name, @@ -87,7 +87,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co continue; } - if (!AdaptationValidator.Validate(context.SourceProductionContext, mapping, adaptation, inlinedBody)) + if (!AdaptationValidator.Validate(context, mapping, adaptation, inlinedBody)) { continue; } @@ -122,7 +122,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co out var conflict); if (generatedConflict || plannerConflict) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.AdaptNameConflict, GetLocation(mapping, adaptation), mapping.MethodSymbol.Name, @@ -153,7 +153,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co { if (adaptation.DestinationType.IsValueType && !SymbolHelpers.CanBeNull(adaptation.DestinationType)) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.UpdatableValueTypeReturn, GetLocation(mapping, adaptation), adaptationName, @@ -166,7 +166,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co context.AddUsings(updateInliner.UsingDirectives.Concat(mapping.UsingDirectives)); if (updateInliner.CircularReferences.Any()) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.UpdatableCircularReferences, GetLocation(mapping, adaptation), adaptationName)); diff --git a/source/Generation/Emitters/ExpressiveMemberEmitter.cs b/source/Generation/Emitters/ExpressiveMemberEmitter.cs index 250cef2..580e477 100644 --- a/source/Generation/Emitters/ExpressiveMemberEmitter.cs +++ b/source/Generation/Emitters/ExpressiveMemberEmitter.cs @@ -21,7 +21,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co if (inliner.CircularReferences.Any()) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.ExpressiveCircularReferences, mapping.MethodSymbol.Locations.FirstOrDefault(), mapping.MethodSymbol.Name)); @@ -30,7 +30,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co if (inliner.UnsafeConditionalReceivers.FirstOrDefault() is { } unsafeReceiver) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.UnsafeNullConditionalReceiver, unsafeReceiver.Location, mapping.MethodSymbol.Name, @@ -40,7 +40,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co if (inliner.UnsupportedNullConditionals.FirstOrDefault() is { } unsupportedConditional) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.UnsupportedNullConditionalExpression, unsupportedConditional.Location, mapping.MethodSymbol.Name, diff --git a/source/Generation/Emitters/UpdatableMemberEmitter.cs b/source/Generation/Emitters/UpdatableMemberEmitter.cs index 1567b0d..3db3a44 100644 --- a/source/Generation/Emitters/UpdatableMemberEmitter.cs +++ b/source/Generation/Emitters/UpdatableMemberEmitter.cs @@ -22,7 +22,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co context.AddUsings(inliner.UsingDirectives.Concat(mapping.UsingDirectives)); if (inliner.CircularReferences.Any()) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.UpdatableCircularReferences, mapping.MethodSymbol.Locations.FirstOrDefault(), mapping.MethodSymbol.Name)); @@ -31,7 +31,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co if (mapping.ReturnType.IsValueType && !SymbolHelpers.CanBeNull(mapping.ReturnType)) { - context.SourceProductionContext.ReportDiagnostic(Diagnostic.Create( + context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.UpdatableValueTypeReturn, mapping.MethodSymbol.Locations.FirstOrDefault(), mapping.MethodSymbol.Name, diff --git a/source/Generation/MapperGenerationContext.cs b/source/Generation/MapperGenerationContext.cs index 6bad2a2..b344173 100644 --- a/source/Generation/MapperGenerationContext.cs +++ b/source/Generation/MapperGenerationContext.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis; using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Text; namespace AlephMapper.Generation; @@ -17,22 +18,24 @@ internal sealed class MapperGenerationContext public MapperGenerationContext( INamedTypeSymbol mapperType, - MappingCatalog mappingsByMethod, - SourceProductionContext sourceProductionContext) + MappingCatalog mappingsByMethod) { MapperType = mapperType; MappingsByMethod = mappingsByMethod; - SourceProductionContext = sourceProductionContext; AdaptationMembers = new AdaptationMemberPlanner(mapperType); } public INamedTypeSymbol MapperType { get; } public MappingCatalog MappingsByMethod { get; } - public SourceProductionContext SourceProductionContext { get; } public AdaptationMemberPlanner AdaptationMembers { get; } public HashSet UsingDirectives { get; } = new(StringComparer.Ordinal); public HashSet GeneratedMemberSignatures { get; } = new(StringComparer.Ordinal); public StringBuilder Members { get; } = new(); + private List Diagnostics { get; } = new(); + + public ImmutableArray GetDiagnostics() => [.. Diagnostics]; + + public void ReportDiagnostic(Diagnostic diagnostic) => Diagnostics.Add(GenerationDiagnostic.From(diagnostic)); public void AddUsings(IEnumerable usingDirectives) { diff --git a/source/Generation/MapperGenerationResult.cs b/source/Generation/MapperGenerationResult.cs new file mode 100644 index 0000000..73807ee --- /dev/null +++ b/source/Generation/MapperGenerationResult.cs @@ -0,0 +1,128 @@ +#nullable enable + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; +using System; +using System.Collections.Immutable; +using System.Linq; + +namespace AlephMapper.Generation; + +/// +/// Value-only output from mapper analysis. This is the boundary between +/// compiler-bound semantic rewriting and incremental source production. +/// +internal sealed class MapperGenerationResult : IEquatable +{ + public MapperGenerationResult(string? hintName, string? source, ImmutableArray diagnostics) + { + HintName = hintName; + Source = source; + Diagnostics = diagnostics; + } + + public string? HintName { get; } + public string? Source { get; } + public ImmutableArray Diagnostics { get; } + + public static MapperGenerationResult Empty { get; } = new MapperGenerationResult(null, null, ImmutableArray.Empty); + + public bool Equals(MapperGenerationResult? other) + { + return other is not null && + string.Equals(HintName, other.HintName, StringComparison.Ordinal) && + string.Equals(Source, other.Source, StringComparison.Ordinal) && + Diagnostics.SequenceEqual(other.Diagnostics); + } + + public override bool Equals(object? obj) => Equals(obj as MapperGenerationResult); + public override int GetHashCode() => (HintName, Source).GetHashCode(); +} + +internal readonly struct GenerationDiagnostic : IEquatable +{ + public GenerationDiagnostic( + string id, + string title, + string message, + DiagnosticSeverity severity, + string category, + string? filePath, + int start, + int length, + int startLine, + int startCharacter, + int endLine, + int endCharacter) + { + Id = id; + Title = title; + Message = message; + Severity = severity; + Category = category; + FilePath = filePath; + Start = start; + Length = length; + StartLine = startLine; + StartCharacter = startCharacter; + EndLine = endLine; + EndCharacter = endCharacter; + } + + public string Id { get; } + public string Title { get; } + public string Message { get; } + public DiagnosticSeverity Severity { get; } + public string Category { get; } + public string? FilePath { get; } + public int Start { get; } + public int Length { get; } + public int StartLine { get; } + public int StartCharacter { get; } + public int EndLine { get; } + public int EndCharacter { get; } + public static GenerationDiagnostic From(Diagnostic diagnostic) + { + var location = diagnostic.Location; + var lineSpan = location == Location.None ? default : location.GetLineSpan(); + return new GenerationDiagnostic( + diagnostic.Id, + diagnostic.Descriptor.Title.ToString(), + diagnostic.GetMessage(), + diagnostic.Severity, + diagnostic.Descriptor.Category, + location == Location.None ? null : location.SourceTree?.FilePath, + location == Location.None ? 0 : location.SourceSpan.Start, + location == Location.None ? 0 : location.SourceSpan.Length, + location == Location.None ? 0 : lineSpan.StartLinePosition.Line, + location == Location.None ? 0 : lineSpan.StartLinePosition.Character, + location == Location.None ? 0 : lineSpan.EndLinePosition.Line, + location == Location.None ? 0 : lineSpan.EndLinePosition.Character); + } + + public Diagnostic ToDiagnostic() + { + var descriptor = new DiagnosticDescriptor(Id, Title, Message, Category, Severity, isEnabledByDefault: true); + if (string.IsNullOrEmpty(FilePath)) + { + return Diagnostic.Create(descriptor, Location.None); + } + + var span = new TextSpan(Start, Length); + var lineSpan = new LinePositionSpan( + new LinePosition(StartLine, StartCharacter), + new LinePosition(EndLine, EndCharacter)); + return Diagnostic.Create(descriptor, Location.Create(FilePath!, span, lineSpan)); + } + + public bool Equals(GenerationDiagnostic other) + { + return Id == other.Id && Title == other.Title && Message == other.Message && Severity == other.Severity && + Category == other.Category && FilePath == other.FilePath && Start == other.Start && Length == other.Length && + StartLine == other.StartLine && StartCharacter == other.StartCharacter && + EndLine == other.EndLine && EndCharacter == other.EndCharacter; + } + + public override bool Equals(object? obj) => obj is GenerationDiagnostic other && Equals(other); + public override int GetHashCode() => (Id, Message, Start, Length).GetHashCode(); +} diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index ce78e2f..07bd0b3 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -16,35 +16,42 @@ namespace AlephMapper.Generation; internal static class MapperSourceOutput { - public static void Generate( - SourceProductionContext context, - (MapperCandidate Left, Compilation Right) input) + public static MapperGenerationResult Create( + GeneratorAttributeSyntaxContext attributeContext, + MapperAttributeKind attributeKind, + CancellationToken cancellationToken) { try { - var mapperDeclaration = FindMapperDeclaration(input.Right, input.Left, context.CancellationToken); - if (mapperDeclaration is null) + var mapperDeclaration = attributeContext.TargetNode switch { - return; - } - - var mapperSemanticModel = input.Right.GetSemanticModel(mapperDeclaration.SyntaxTree); - var mapperType = mapperSemanticModel.GetDeclaredSymbol(mapperDeclaration, context.CancellationToken) as INamedTypeSymbol; - if (mapperType is null) + ClassDeclarationSyntax classDeclaration => classDeclaration, + MethodDeclarationSyntax { Parent: ClassDeclarationSyntax classDeclaration } => classDeclaration, + _ => null + }; + var mapperType = attributeContext.TargetSymbol switch { - return; + INamedTypeSymbol classSymbol => classSymbol, + IMethodSymbol methodSymbol => methodSymbol.ContainingType, + _ => null + }; + if (mapperDeclaration is null || mapperType is null) + { + return MapperGenerationResult.Empty; } - if (!IsPrimaryMapperCandidate(input.Right, mapperType, input.Left, context.CancellationToken)) + var compilation = attributeContext.SemanticModel.Compilation; + var candidate = MapperCandidate.Create(attributeContext, attributeKind, cancellationToken); + if (!IsPrimaryMapperCandidate(compilation, mapperType, candidate, cancellationToken)) { - return; + return MapperGenerationResult.Empty; } - var mappings = CreateMapperAnalyses(input.Right, mapperType, context.CancellationToken); + var mappings = CreateMapperAnalyses(compilation, mapperType, cancellationToken); if (mappings.Count == 0 || !mappings.Any(static mapping => (mapping.IsExpressive || mapping.IsUpdatable || mapping.Adaptations.Count > 0) && mapping.IsClassPartial)) { - return; + return MapperGenerationResult.Empty; } var mappingsByMethod = new Dictionary(SymbolHelpers.MethodComparer.Instance); @@ -55,18 +62,34 @@ public static void Generate( var catalog = new MappingCatalog( mappingsByMethod, - method => CreateExternalAnalysis(input.Right, method, context.CancellationToken)); - GenerateMapper(context, mapperType, mappings, catalog); + method => CreateExternalAnalysis(compilation, method, cancellationToken)); + return GenerateMapper(mapperType, mappings, catalog); } catch (Exception exception) { - CrashDiagnosticsReporter.Report(context, exception); + return new MapperGenerationResult( + null, + null, + [CrashDiagnosticsReporter.CreateDiagnostic(exception)]); #if DEBUG throw; #endif } } + public static void Emit(SourceProductionContext context, MapperGenerationResult result) + { + foreach (var diagnostic in result.Diagnostics) + { + context.ReportDiagnostic(diagnostic.ToDiagnostic()); + } + + if (result.HintName is not null && result.Source is not null) + { + context.AddSource(result.HintName, result.Source); + } + } + private static IReadOnlyList CreateMapperAnalyses( Compilation compilation, INamedTypeSymbol mapperType, @@ -241,13 +264,12 @@ private static MapperCandidate CreateCandidate(SyntaxNode targetNode, MapperAttr attributeKind); } - private static void GenerateMapper( - SourceProductionContext sourceProductionContext, + private static MapperGenerationResult GenerateMapper( INamedTypeSymbol mapperType, IReadOnlyList mappings, MappingCatalog catalog) { - var context = new MapperGenerationContext(mapperType, catalog, sourceProductionContext); + var context = new MapperGenerationContext(mapperType, catalog); foreach (var mapping in mappings) { if (!mapping.IsExpressive && !mapping.IsUpdatable && mapping.Adaptations.Count == 0) @@ -262,6 +284,6 @@ private static void GenerateMapper( } var generatedFile = MapperFileEmitter.Render(context); - sourceProductionContext.AddSource(generatedFile.HintName, generatedFile.Source); + return new MapperGenerationResult(generatedFile.HintName, generatedFile.Source, context.GetDiagnostics()); } } diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index 639eb76..24ee2f6 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -251,7 +251,7 @@ public static partial class MapperB driver = driver.RunGeneratorsAndUpdateCompilation(updatedCompilation, out _, out _); var trackedSteps = driver.GetRunResult().Results.Single().TrackedSteps; - var candidateOutputs = trackedSteps["AlephMapper.ExpressiveCandidates"] + var candidateOutputs = trackedSteps["AlephMapper.ExpressiveGenerationResult"] .SelectMany(static step => step.Outputs) .ToArray(); @@ -287,7 +287,7 @@ public async Task LargeCompilationDiscoversOnlyAttributedMappers() stopwatch.Stop(); var result = driver.GetRunResult().Results.Single(); - var candidateOutputs = result.TrackedSteps["AlephMapper.ExpressiveCandidates"] + var candidateOutputs = result.TrackedSteps["AlephMapper.ExpressiveGenerationResult"] .SelectMany(static step => step.Outputs) .ToArray(); From 20ea12961a646f324fb5c2b1b779a0d31d4ac142 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Mon, 31 Aug 2026 19:53:45 +0200 Subject: [PATCH 05/22] Remove obsolete mapper lookup and diagnostic reporting paths --- .../Diagnostics/CrashDiagnosticsReporter.cs | 14 ------- source/Generation/MapperSourceOutput.cs | 40 ------------------- 2 files changed, 54 deletions(-) diff --git a/source/Diagnostics/CrashDiagnosticsReporter.cs b/source/Diagnostics/CrashDiagnosticsReporter.cs index 4978eb9..3633768 100644 --- a/source/Diagnostics/CrashDiagnosticsReporter.cs +++ b/source/Diagnostics/CrashDiagnosticsReporter.cs @@ -10,20 +10,6 @@ internal static class CrashDiagnosticsReporter { private const int MaxCrashDiagnosticLength = 2_000; - internal static void Report( - in SourceProductionContext sourceProductionContext, - Exception exception - ) - { - sourceProductionContext.ReportDiagnostic( - Diagnostic.Create( - DiagnosticDescriptors.GeneratorCrash, - Location.None, - FormatCrashDiagnostic(exception) - ) - ); - } - internal static GenerationDiagnostic CreateDiagnostic(Exception exception) { return Generation.GenerationDiagnostic.From(Diagnostic.Create( diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index 07bd0b3..ea73fce 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -6,7 +6,6 @@ using AlephMapper.Models; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Text; using System; using System.Collections.Generic; using System.Linq; @@ -168,45 +167,6 @@ private static bool IsPrimaryMapperCandidate( return primaryCandidate is not null && primaryCandidate.Equals(candidate); } - private static ClassDeclarationSyntax? FindMapperDeclaration( - Compilation compilation, - MapperCandidate candidate, - CancellationToken cancellationToken) - { - var span = new TextSpan(candidate.Start, candidate.Length); - foreach (var tree in compilation.SyntaxTrees) - { - if (!string.Equals(tree.FilePath, candidate.FilePath, StringComparison.Ordinal)) - { - continue; - } - - var root = tree.GetRoot(cancellationToken); - if (span.End > root.FullSpan.End) - { - continue; - } - - var target = root.FindNode(span, getInnermostNodeForTie: true); - if (target.Span != span) - { - continue; - } - - if (target is ClassDeclarationSyntax declaration) - { - return declaration; - } - - if (target.FirstAncestorOrSelf() is { } containingClass) - { - return containingClass; - } - } - - return null; - } - private static IEnumerable GetMapperCandidates( Compilation compilation, ClassDeclarationSyntax mapperDeclaration, From 58e84b15994f939d66a1fafb16458bf4da1ab62b Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Mon, 31 Aug 2026 20:00:02 +0200 Subject: [PATCH 06/22] bump version to 0.7.0 --- README.md | 6 +++--- source/AlephMapper.csproj | 2 +- source/VersionInfo.cs | 4 ++-- .../Expected/Tests_PersonMapper_GeneratedMappings.g.cs | 2 +- .../Expected/Tests_PersonMapper_GeneratedMappings.g.cs | 2 +- .../Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs | 2 +- .../AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs | 2 +- ...pper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs | 2 +- ...lephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs | 2 +- ...er_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs | 2 +- ...phMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs | 2 +- .../AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs | 2 +- .../Expected/Tests_SampleMapper_GeneratedMappings.g.cs | 2 +- ...ditionalExtensionTestPersonMapper_GeneratedMappings.g.cs | 2 +- ..._Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs | 2 +- ...r_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs | 2 +- .../AlephMapper_Tests_Mapper_GeneratedMappings.g.cs | 2 +- ...phMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs | 2 +- ...hodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs | 2 +- ...nlining_PersonProductMapperIgnore_GeneratedMappings.g.cs | 2 +- ...lining_PersonProductMapperRewrite_GeneratedMappings.g.cs | 2 +- ...amExtensionInlining_ProductMapper_GeneratedMappings.g.cs | 2 +- ...lining_MultiParamExpressiveMapper_GeneratedMappings.g.cs | 2 +- ...iParameterInlining_NamedArgMapper_GeneratedMappings.g.cs | 2 +- ...erInlining_NestedMultiParamMapper_GeneratedMappings.g.cs | 2 +- ...ltiParameterInlining_PersonMapper_GeneratedMappings.g.cs | 2 +- ...nlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs | 2 +- ...per_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs | 2 +- ...sts_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs | 2 +- ...ts_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs | 2 +- ...NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs | 2 +- .../AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs | 2 +- .../AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs | 2 +- .../AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs | 2 +- .../Tests_NullableDisabledMapper_GeneratedMappings.g.cs | 2 +- .../Tests_NullableEnabledMapper_GeneratedMappings.g.cs | 2 +- ...apper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs | 2 +- ..._Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs | 2 +- ...er_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs | 2 +- ...Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs | 2 +- .../AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs | 2 +- ...ephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs | 2 +- ...lephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs | 2 +- .../Expected/Tests_SampleMapper_GeneratedMappings.g.cs | 2 +- ...apper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs | 2 +- ...pper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs | 2 +- .../AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs | 2 +- ...AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs | 2 +- ...per_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs | 2 +- ...per_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs | 2 +- ...ests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs | 2 +- ...pper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs | 2 +- ...AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs | 2 +- ...hMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs | 2 +- 54 files changed, 57 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 68697da..66d988a 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ dotnet add package AlephMapper Using `PackageReference`: ```xml - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -82,7 +82,7 @@ With Central Package Management: ```xml - + @@ -103,7 +103,7 @@ When referencing the generator directly from source: ### Compiler compatibility -AlephMapper 0.6.2 requires a Roslyn compiler host compatible with `Microsoft.CodeAnalysis` 4.14 or later. This version uses Roslyn's embedded-marker support so its generated configuration attributes remain private to the consuming assembly, including when `InternalsVisibleTo` is used. +AlephMapper 0.7.0 requires a Roslyn compiler host compatible with `Microsoft.CodeAnalysis` 4.14 or later. This version uses Roslyn's embedded-marker support so its generated configuration attributes remain private to the consuming assembly, including when `InternalsVisibleTo` is used. ## Quick start diff --git a/source/AlephMapper.csproj b/source/AlephMapper.csproj index f31af74..2504915 100644 --- a/source/AlephMapper.csproj +++ b/source/AlephMapper.csproj @@ -14,7 +14,7 @@ MIT https://github.com/Raffinert/AlephMapper README.md - 0.6.2 + 0.7.0 Mapping Companion git https://github.com/Raffinert/AlephMapper.git diff --git a/source/VersionInfo.cs b/source/VersionInfo.cs index 200252d..7991f57 100644 --- a/source/VersionInfo.cs +++ b/source/VersionInfo.cs @@ -2,5 +2,5 @@ internal static class VersionInfo { - public static string Version => "0.6.2"; -} \ No newline at end of file + public static string Version => "0.7.0"; +} diff --git a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index f6e5258..6d4a8e6 100644 --- a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class PersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index 576f3e3..11b2690 100644 --- a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class PersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs index d89967b..da2c667 100644 --- a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class AdaptUpdateMapper { /// diff --git a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs index 390f70b..4c043ec 100644 --- a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class CircularMapper { /// diff --git a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs index f391633..d8c7f9b 100644 --- a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class CircularPropertyMapper { /// diff --git a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs index 3802ac7..51cda79 100644 --- a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class CollectionMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs index d89b644..a584fcb 100644 --- a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ConditionalPatternMapper { /// diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs index a34276c..0d401c5 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class EfCoreIgnoreMapper { /// diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs index 2bb6acb..6c58133 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class EfCoreMapper { /// diff --git a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index 249b0e0..c60cd81 100644 --- a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class SampleMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs index 33d73b4..adbf96e 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ConditionalExtensionTestPersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs index 842d395..f7206f3 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ExtensionTestAddressMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs index a7b797d..93b8ea2 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ExtensionTestPersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs index 8a2d50d..c1edf08 100644 --- a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class Mapper { /// diff --git a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs index dced7d9..8c7fc4a 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class SimpleObjectMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs index 555aaa3..0fd80a4 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs @@ -10,7 +10,7 @@ namespace AlephMapper.Tests.MethodGroupToEntityList; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class PersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs index c133454..c255316 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParamExtensionInlining; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class PersonProductMapperIgnore { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs index 9268fcb..57e0722 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParamExtensionInlining; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class PersonProductMapperRewrite { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs index baed6ec..41fd8b2 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParamExtensionInlining; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ProductMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs index e2934e4..ef22db9 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class MultiParamExpressiveMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs index e15d052..ef48e00 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NamedArgMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs index 87393ca..d28da7b 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NestedMultiParamMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs index 1be614a..3afc6d5 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class PersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs index 809849b..d5a438a 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class UpdatableMultiParamMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs index caab30d..98c5364 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NestedExt_AddressMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs index 23e8157..9e0aced 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NestedExt_PersonMapper_Ignore { /// diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs index dda002a..c8837d7 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NestedExt_PersonMapper_Rewrite { /// diff --git a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs index c170be4..4d00ce4 100644 --- a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs @@ -10,7 +10,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NullCoalesceValueAssignmentMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs index 9b60a8c..c6eebde 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class IgnoreMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs index 2dc4305..671fa40 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NoneMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs index 339bcd6..8be6305 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class RewriteMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs index 886a907..d62083a 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NullableDisabledMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs index 8888671..deb64f5 100644 --- a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NullableEnabledMapper { /// diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs index 0df4018..4d99447 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class TechDebtAddressMapper { /// diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs index 38ec812..3d9eaf1 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class TechDebtPersonMapperIgnore { /// diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs index cf3d607..cf4d5cc 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class TechDebtPersonMapperNone { } diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs index 3bad366..47703c2 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class TechDebtPersonMapperRewrite { /// diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs index 4cffb42..197dcaa 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class Address1Mapper { /// diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs index a887d65..10f4c09 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class AddressLineMapper { /// diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs index 1b43175..d9cd4c5 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class TestModel1Mapper { /// diff --git a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index ddb1c0d..e3922da 100644 --- a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class SampleMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs index 938eade..cabd626 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ComplexPropertyMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs index e2d3b5a..8da8c32 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ComplexValueTypeMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs index 204cc15..2b58cff 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class EdgeCaseMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs index e341b64..ce04484 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class MixedTypeMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs index 248ec4a..c79bc96 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class NullableValueTypeMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs index fa09a20..6f208ff 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ReferenceTypeOnlyMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs index f15f07c..ced76f7 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class SimpleValueToReferenceMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs index eed0b2c..7fb18f0 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ValueToReferenceMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs index aaf12ff..08d44d0 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ValueTypeMapper { } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs index c5ee4b9..4375889 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.6.2")] +[GeneratedCode("AlephMapper", "0.7.0")] partial class ValueTypeOnlyMapper { /// From b21dc7b707d204e3a120a35fcbe72c87e73bd5d6 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Mon, 31 Aug 2026 20:10:44 +0200 Subject: [PATCH 07/22] Implemented conditional formatting. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - One-line source ternaries stay on one line. - Multi-line ternaries use aligned ? / : indentation. - Switch-expression lowering preserves whether the original switch was one or multi-line. - Multi-line rewritten branches still expand cleanly. - Added direct and switch formatting coverage. Verified: dotnet test AlephMapper.slnx --no-restore --verbosity quiet — 86 passed. --- source/GeneratedSyntaxAnnotations.cs | 7 +++ .../Emitters/AdaptationMemberEmitter.cs | 4 +- .../Emitters/ExpressiveMemberEmitter.cs | 4 +- source/PrettyPrinter.cs | 30 ++++++++++++- ...gResolver.ConditionalExpressionRewriter.cs | 32 ++++++++++++++ ...liningResolver.SwitchExpressionRewriter.cs | 28 ++++++++++-- .../AlephMapper.Tests/SourceGeneratorTests.cs | 43 +++++++++++++++++++ 7 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 source/GeneratedSyntaxAnnotations.cs create mode 100644 source/SyntaxRewriters/InliningResolver.ConditionalExpressionRewriter.cs diff --git a/source/GeneratedSyntaxAnnotations.cs b/source/GeneratedSyntaxAnnotations.cs new file mode 100644 index 0000000..5ddc287 --- /dev/null +++ b/source/GeneratedSyntaxAnnotations.cs @@ -0,0 +1,7 @@ +namespace AlephMapper; + +internal static class GeneratedSyntaxAnnotations +{ + internal const string MultilineConditional = "AlephMapper.MultilineConditional"; + internal const string SingleLineConditional = "AlephMapper.SingleLineConditional"; +} diff --git a/source/Generation/Emitters/AdaptationMemberEmitter.cs b/source/Generation/Emitters/AdaptationMemberEmitter.cs index 282d0b9..8f8ec00 100644 --- a/source/Generation/Emitters/AdaptationMemberEmitter.cs +++ b/source/Generation/Emitters/AdaptationMemberEmitter.cs @@ -54,7 +54,9 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co } var inliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, false, adaptation.NullStrategy); - var inlinedBody = (ExpressionSyntax)inliner.Visit(mapping.BodySyntax.Expression)!.WithoutTrivia(); + var inlinedBody = ((ExpressionSyntax)inliner.Visit(mapping.BodySyntax.Expression)!) + .WithoutLeadingTrivia() + .WithoutTrailingTrivia(); context.AddUsings(inliner.UsingDirectives.Concat(mapping.UsingDirectives)); if (inliner.CircularReferences.Any()) { diff --git a/source/Generation/Emitters/ExpressiveMemberEmitter.cs b/source/Generation/Emitters/ExpressiveMemberEmitter.cs index 580e477..43ed78c 100644 --- a/source/Generation/Emitters/ExpressiveMemberEmitter.cs +++ b/source/Generation/Emitters/ExpressiveMemberEmitter.cs @@ -16,7 +16,9 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co } var inliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, false, mapping.NullStrategy); - var inlinedBody = inliner.Visit(mapping.BodySyntax.Expression)!.WithoutTrivia(); + var inlinedBody = inliner.Visit(mapping.BodySyntax.Expression)! + .WithoutLeadingTrivia() + .WithoutTrailingTrivia(); context.AddUsings(inliner.UsingDirectives.Concat(mapping.UsingDirectives)); if (inliner.CircularReferences.Any()) diff --git a/source/PrettyPrinter.cs b/source/PrettyPrinter.cs index 0f5f549..f083e83 100644 --- a/source/PrettyPrinter.cs +++ b/source/PrettyPrinter.cs @@ -118,11 +118,21 @@ public override void DefaultVisit(SyntaxNode node) public override void VisitConditionalExpression(ConditionalExpressionSyntax node) { + if (!HasMultilineConditionalLayout(node)) + { + Visit(node.Condition.WithoutTrailingTrivia()); + WriteRaw(" ? "); + Visit(node.WhenTrue.WithoutLeadingTrivia().WithoutTrailingTrivia()); + WriteRaw(" : "); + Visit(node.WhenFalse.WithoutLeadingTrivia()); + return; + } + Visit(node.Condition.WithoutTrailingTrivia()); WriteLine(); Indent(); WriteRaw("? "); - Visit(node.WhenTrue.WithoutLeadingTrivia()); + Visit(node.WhenTrue.WithoutLeadingTrivia().WithoutTrailingTrivia()); WriteLine(); WriteRaw(": "); Visit(node.WhenFalse.WithoutLeadingTrivia()); @@ -354,6 +364,24 @@ private static bool HasLineBreakInLogicalChain(ExpressionSyntax expression, Synt HasLineBreakInLogicalChain(binaryExpression.Right, chainKind); } + private static bool HasMultilineConditionalLayout(ConditionalExpressionSyntax node) + { + if (node.GetAnnotations(GeneratedSyntaxAnnotations.MultilineConditional).Any()) + { + return true; + } + + if (node.GetAnnotations(GeneratedSyntaxAnnotations.SingleLineConditional).Any()) + { + return ContainsLineBreak(node.WhenTrue.ToFullString()) || + ContainsLineBreak(node.WhenFalse.ToFullString()); + } + + // Rewriters synthesize conditionals for null-conditional access. Keep their + // established, readable multi-line form unless the source layout was recorded. + return true; + } + private static bool ContainsLineBreak(SyntaxTriviaList trivia) { return trivia.Any(triviaItem => triviaItem.IsKind(SyntaxKind.EndOfLineTrivia)); diff --git a/source/SyntaxRewriters/InliningResolver.ConditionalExpressionRewriter.cs b/source/SyntaxRewriters/InliningResolver.ConditionalExpressionRewriter.cs new file mode 100644 index 0000000..1b04d7f --- /dev/null +++ b/source/SyntaxRewriters/InliningResolver.ConditionalExpressionRewriter.cs @@ -0,0 +1,32 @@ +#nullable enable + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace AlephMapper.SyntaxRewriters; + +internal sealed partial class InliningResolver +{ + public override SyntaxNode? VisitConditionalExpression(ConditionalExpressionSyntax node) + { + var rewritten = (ConditionalExpressionSyntax?)base.VisitConditionalExpression(node); + if (rewritten == null) + { + return null; + } + + var annotationKind = HasMultilineConditionalLayout(node) + ? GeneratedSyntaxAnnotations.MultilineConditional + : GeneratedSyntaxAnnotations.SingleLineConditional; + return rewritten.WithAdditionalAnnotations(new SyntaxAnnotation(annotationKind)); + } + + private static bool HasMultilineConditionalLayout(ConditionalExpressionSyntax node) + { + var text = node.ToFullString(); + return text.IndexOf('\n') >= 0 || text.IndexOf('\r') >= 0; + } +} + +#nullable restore diff --git a/source/SyntaxRewriters/InliningResolver.SwitchExpressionRewriter.cs b/source/SyntaxRewriters/InliningResolver.SwitchExpressionRewriter.cs index 2a64636..8b4c45f 100644 --- a/source/SyntaxRewriters/InliningResolver.SwitchExpressionRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.SwitchExpressionRewriter.cs @@ -20,6 +20,11 @@ internal sealed partial class InliningResolver return switchExpression?.WithSwitchKeyword(node.SwitchKeyword.WithLeadingTrivia(Space)); } + // Preserve the switch layout after lowering it to conditionals. The generated + // nodes have no trivia of their own, so the pretty printer needs this signal. + var switchText = node.ToFullString(); + var multiline = switchText.IndexOf('\n') >= 0 || switchText.IndexOf('\r') >= 0; + // Reverse arms order to start from the default value var arms = node.Arms.Reverse(); @@ -61,10 +66,11 @@ internal sealed partial class InliningResolver ); } - currentExpression = ConditionalExpression( + currentExpression = CreateConditional( expression, armExpression, - currentExpression + currentExpression, + multiline ); continue; @@ -99,10 +105,11 @@ internal sealed partial class InliningResolver armExpression, declaration, governingExpressionNode); - currentExpression = ConditionalExpression( + currentExpression = CreateConditional( condition, modifiedArmExpression, - currentExpression + currentExpression, + multiline ); continue; @@ -148,6 +155,19 @@ private ExpressionSyntax VisitClean(ExpressionSyntax expression) return (rewritten ?? stripped).WithoutTrivia(); } + private static ConditionalExpressionSyntax CreateConditional( + ExpressionSyntax condition, + ExpressionSyntax whenTrue, + ExpressionSyntax whenFalse, + bool multiline) + { + var conditional = ConditionalExpression(condition, whenTrue, whenFalse); + var annotationKind = multiline + ? GeneratedSyntaxAnnotations.MultilineConditional + : GeneratedSyntaxAnnotations.SingleLineConditional; + return conditional.WithAdditionalAnnotations(new SyntaxAnnotation(annotationKind)); + } + private static BinaryExpressionSyntax PadBinaryOperator(BinaryExpressionSyntax expression) { var token = expression.OperatorToken; diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index 24ee2f6..1157e95 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -898,6 +898,49 @@ public sealed class Invoice await Assert.That(generatedSource).Contains("line => line.Invoice.DataSetId == dataSetId && line.Invoice.InvoiceIdReference == invoiceId && line.CategoryId != null;"); } + [Test] + public async Task ExpressionOutputPreservesConditionalLayoutIncludingLoweredSwitches() + { + const string source = """ + using AlephMapper; + + namespace Fixture; + + public static partial class Mapper + { + [Expressive] + public static string SingleConditional(bool condition) => condition ? "yes" : "no"; + + [Expressive] + public static string MultilineConditional(bool condition) => + condition + ? "yes" + : "no"; + + [Expressive] + public static string SingleSwitch(int value) => value switch { 1 => "one", _ => "other" }; + + [Expressive] + public static string MultilineSwitch(int value) => + value switch + { + 1 => "one", + _ => "other" + }; + } + """; + + var generatedSources = await AssertAdaptedOutputCompiles(source, "ConditionalExpressionFormatting"); + var generatedSource = generatedSources.Single(sourceText => sourceText.Contains("SingleConditionalExpression")); + + await Assert.That(generatedSource).Contains("condition => condition ? \"yes\" : \"no\";"); + await Assert.That(generatedSource).Contains( + $"condition => condition{Environment.NewLine} ? \"yes\"{Environment.NewLine} : \"no\";"); + await Assert.That(generatedSource).Contains("value => value == 1 ? \"one\" : \"other\";"); + await Assert.That(generatedSource).Contains( + $"value => value == 1{Environment.NewLine} ? \"one\"{Environment.NewLine} : \"other\";"); + } + [Test] public async Task AdaptReportsIncompatibleDirectMemberAssignment() { From 9d0faa8b65d2a13cf3379bd49b378d51fc12a351 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Mon, 31 Aug 2026 20:28:18 +0200 Subject: [PATCH 08/22] =?UTF-8?q?=E2=80=A2=20Fixed=20the=20generator=20and?= =?UTF-8?q?=20generated-attribute=20warnings.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - source/AlephMapper.csproj rebuilds with 0 warnings. - Generated AdaptAttribute.Name now defaults to string.Empty, eliminating CS8618 in consumer-generated attribute code. - Fixed nullable contracts in the inliner and property collector. - Added analyzer release tracking and corrected diagnostic-message metadata. - Fixed analyzer package dependency metadata. Verified: - dotnet build source\AlephMapper.csproj --no-restore -t:Rebuild — 0 warnings - dotnet test AlephMapper.slnx --no-restore --verbosity quiet — 86 passed Remaining warnings are nullable-flow warnings from generated mapping bodies in integration/experiment fixtures, not generated attributes. --- README.md | 38 ++++++++++----- docs/Adapt-Attribute.md | 10 ++-- .../SampleApp/Mappers/AdaptExampleMapper.cs | 2 +- examples/SampleApp/Mappers/AddressMapper.cs | 4 +- examples/SampleApp/Mappers/EmployeeMapper.cs | 2 +- examples/SampleApp/Mappers/PersonMapper.cs | 6 +-- source/Adaptation/AdaptationValidator.cs | 2 +- source/AlephMapper.csproj | 2 + source/AlephSourceGenerator.cs | 8 ++-- source/AnalyzerReleases.Unshipped.md | 23 ++++++++++ source/Attributes.cs | 8 ++-- source/Diagnostics/DiagnosticDescriptors.cs | 24 +++++----- ...Emitter.cs => ProjectableMemberEmitter.cs} | 6 +-- source/Generation/MapperCandidate.cs | 2 +- source/Generation/MapperSourceOutput.cs | 10 ++-- source/Generation/MappingAnalysisFactory.cs | 18 ++++++-- source/Models/MappingAnalysis.cs | 6 +-- source/PropertyTypeInfoCollector.cs | 13 ++++-- .../InliningResolver.InvocationRewriter.cs | 43 +++++++++-------- .../ArticleMappingMappers.cs | 2 +- .../MultiParamMappers.cs | 28 +++++------ .../MultiParamTests.cs | 14 +++--- tests/AlephMapper.IntegrationTests/README.md | 10 ++-- .../SimpleMappers.cs | 4 +- .../SimpleTests.cs | 2 +- .../UpdatableMappers.cs | 6 +-- .../UpdatableTests.cs | 4 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../CircularMapper/Sources/CircularMapper.cs | 4 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Sources/CircularPropertyMapper.cs | 4 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Sources/CollectionMapper.cs | 4 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../EfCoreMapper/Sources/EfCoreMappers.cs | 6 +-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Files/Expressive/Sources/Source.cs | 4 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Sources/ExtensionMethodInliningTests.cs | 6 +-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Files/Mapper/Sources/Mapper.cs | 4 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../MethodGroupSpec/Sources/MethodGroup.cs | 4 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Sources/PersonMapper.cs | 2 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Sources/MultiParamExtMapper.cs | 10 ++-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- ...mProjectableMapper_GeneratedMappings.g.cs} | 2 +- .../Sources/PersonMapper.cs | 14 +++--- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../NestedConditionalExtensionInlining.cs | 10 ++-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../IgnoreNullCoalesceValueAssignment.cs | 2 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../NullConditionalRewrite/Sources/Mappers.cs | 8 ++-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Files/NullableDisabled/Sources/Source.cs | 2 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Files/NullableEnabled/Sources/Source.cs | 2 +- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Files/TechDebtFix/Sources/TechDebtFix.cs | 16 +++---- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../TestModel1Mapper/Sources/TestModel1.cs | 8 ++-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Expected/AlephMapper.Attributes.g.cs | 6 +-- .../Sources/ComplexValueType.cs | 4 +- .../Sources/EdgeCases.cs | 8 ++-- .../Sources/MixedType.cs | 2 +- .../Sources/ValueToReferenceType.cs | 4 +- .../Sources/ValueTypeUpdatableNullChecks.cs | 6 +-- .../AlephMapper.Tests/SourceGeneratorTests.cs | 46 ++++++++++--------- .../ExtensionMethodInliningTests.cs | 8 ++-- 78 files changed, 348 insertions(+), 289 deletions(-) create mode 100644 source/AnalyzerReleases.Unshipped.md rename source/Generation/Emitters/{ExpressiveMemberEmitter.cs => ProjectableMemberEmitter.cs} (96%) rename tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/{AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs => AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs} (95%) diff --git a/README.md b/README.md index 66d988a..6ac41b3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://stand-with-ukraine.pp.ua) +[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://stand-with-ukraine.pp.ua) ## Terms of use[?](https://github.com/Tyrrrz/.github/blob/master/docs/why-so-political.md) @@ -105,18 +105,32 @@ When referencing the generator directly from source: AlephMapper 0.7.0 requires a Roslyn compiler host compatible with `Microsoft.CodeAnalysis` 4.14 or later. This version uses Roslyn's embedded-marker support so its generated configuration attributes remain private to the consuming assembly, including when `InternalsVisibleTo` is used. +### Migration: `[Expressive]` to `[Projectable]` + +`[Expressive]` has been renamed to `[Projectable]`. Replace every attribute use directly; no compatibility attribute is emitted. + +```csharp +// Before +[Expressive] +public static PersonDto Map(Person person) => new(); + +// After +[Projectable] +public static PersonDto Map(Person person) => new(); +``` + ## Quick start Mapping methods must be `static`, expression-bodied, and declared in a `static partial` class. -Add `using AlephMapper;`, then apply `[Expressive]` to a mapping method or its containing class: +Add `using AlephMapper;`, then apply `[Projectable]` to a mapping method or its containing class: ```csharp using AlephMapper; public static partial class PersonMapper { - [Expressive] + [Projectable] public static PersonDto MapPerson(Employee employee) => new() { Id = employee.EmployeeId, @@ -167,7 +181,7 @@ Supported expression-bodied methods can call other mapping or helper methods. Al ```csharp public static partial class OrderMapper { - [Expressive] + [Projectable] public static OrderDto MapOrder(Order order) => new() { Id = order.Id, @@ -189,12 +203,12 @@ public static partial class OrderMapper } ``` -`[Expressive]` is not limited to object projections. A method returning `bool` generates an `Expression>`, allowing statically known conditions to be composed as ordinary methods: +`[Projectable]` is not limited to object projections. A method returning `bool` generates an `Expression>`, allowing statically known conditions to be composed as ordinary methods: ```csharp public static partial class EmployeeConditions { - [Expressive] + [Projectable] public static bool IsEligible(Employee employee) => IsActive(employee) && HasRequiredExperience(employee, 3); @@ -224,7 +238,7 @@ A mapping may accept values after its source parameter. AlephMapper moves those ```csharp public static partial class EmployeeMapper { - [Expressive] + [Projectable] public static EmployeeDto Map( Employee employee, int currentYear) => new() @@ -270,7 +284,7 @@ public static class ProductExtensions public static partial class ProductMapper { - [Expressive] + [Projectable] public static ProductDto Map(Product product) => new() { Name = product.Name, @@ -302,7 +316,7 @@ public static partial class AddressMapper }; } -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class PersonMapper { public static PersonDto ToDto(Person person) => new() @@ -351,7 +365,7 @@ Modern C# extension blocks are not currently supported. C# null-conditional access (`?.`) is not directly supported in expression trees. Configure its treatment with `NullConditionalRewrite`: ```csharp -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class PersonMapper { public static PersonDto Map(Person person) => new() @@ -474,11 +488,11 @@ Adaptation is explicit: AlephMapper does not scan for compatible types. Invalid | Attribute | Generated member | | --- | --- | -| `[Expressive]` | `Expression(...)` returning `Expression>` | +| `[Projectable]` | `Expression(...)` returning `Expression>` | | `[Updatable]` | An overload with a final destination parameter named `target` | | `[Adapt]` | The requested adapted map, expression, and/or update members | -Attributes can be applied to individual methods. `[Expressive]` and `[Updatable]` can also be applied to the containing class. +Attributes can be applied to individual methods. `[Projectable]` and `[Updatable]` can also be applied to the containing class. AlephMapper is best suited to object initializers, predicates, constructor calls, member access, conversions, LINQ operations, and small expression-bodied methods that it can inline. Not every valid C# construct can be represented in an expression tree, and not every expression-tree operation can be translated by every query provider. diff --git a/docs/Adapt-Attribute.md b/docs/Adapt-Attribute.md index 45540a4..7b1e204 100644 --- a/docs/Adapt-Attribute.md +++ b/docs/Adapt-Attribute.md @@ -25,7 +25,7 @@ Use `[Adapt]` when a mapping body should be shared by explicitly named type pair For example, `Person` and `Employee` can both contain the fields used by a template, while `PersonDto` and `EmployeeDto` can both receive the initializer assignments. A single `Person -> PersonDto` template can therefore produce a separate `Employee -> EmployeeDto` API. -Use `[Expressive]` when the generated expression is for the original method's declared signature. Use `[Adapt]` when the generated API should use a different, explicit source and/or destination type. The two attributes can be applied to the same template method. +Use `[Projectable]` when the generated expression is for the original method's declared signature. Use `[Adapt]` when the generated API should use a different, explicit source and/or destination type. The two attributes can be applied to the same template method. ## Public API @@ -55,7 +55,7 @@ public sealed class AdaptAttribute : Attribute `SourceType` and `DestinationType` are required `typeof(...)` constructor arguments. Each `[Adapt]` is independent, so a method may be adapted to multiple pairs. -`NullConditionalRewrite` applies while helper methods are inlined for that adaptation. It uses the same policies as `[Expressive]`: +`NullConditionalRewrite` applies while helper methods are inlined for that adaptation. It uses the same policies as `[Projectable]`: | Value | Effect | | --- | --- | @@ -217,7 +217,7 @@ The feature is implemented as part of the incremental source generator. The foll | [`source/Generation/MapperFileEmitter.cs`](../source/Generation/MapperFileEmitter.cs) | Recreates the namespace and containing partial-type hierarchy and renders the generated file. | | [`source/Diagnostics/DiagnosticDescriptors.cs`](../source/Diagnostics/DiagnosticDescriptors.cs) | Defines `AM0005`–`AM0015`. | -The older `[Expressive]` and `[Updatable]` behaviors are emitted by their own focused emitters. All three features share the mapping model, helper inliner, generated-file context, and output renderer. +`[Projectable]` and `[Updatable]` are emitted by their own focused emitters. All three features share the mapping model, helper inliner, generated-file context, and output renderer. ## Generation pipeline @@ -226,8 +226,8 @@ The incremental pipeline is registered in [`source/AlephSourceGenerator.cs`](../ 1. `AttributeSourceEmitter` adds `AlephMapper.Attributes.g.cs` after initialization so the consumer can use the attributes. 2. `MappingMethodCandidate` identifies method declarations contained in classes. 3. `MappingModelFactory` filters to static classes, resolves symbols, requires at least one parameter and an expression body, and collects the method's adaptation attributes. -4. `MapperSourceOutput` groups mapping models by containing mapper type. A mapper produces output when it is partial and contains an expressive, updatable, or adapted mapping. -5. For each eligible mapping, the output dispatcher runs `ExpressiveMemberEmitter`, `AdaptationMemberEmitter`, and `UpdatableMemberEmitter`. +4. `MapperSourceOutput` groups mapping models by containing mapper type. A mapper produces output when it is partial and contains a projectable, updatable, or adapted mapping. +5. For each eligible mapping, the output dispatcher runs `ProjectableMemberEmitter`, `AdaptationMemberEmitter`, and `UpdatableMemberEmitter`. 6. The adaptation emitter processes every `AdaptationModel` independently: 1. Decodes the requested flags and verifies the naming requirement. 2. Rejects duplicate source/destination pairs on the same template. diff --git a/examples/SampleApp/Mappers/AdaptExampleMapper.cs b/examples/SampleApp/Mappers/AdaptExampleMapper.cs index bd0faf3..657c3df 100644 --- a/examples/SampleApp/Mappers/AdaptExampleMapper.cs +++ b/examples/SampleApp/Mappers/AdaptExampleMapper.cs @@ -6,7 +6,7 @@ namespace SampleApp.Mappers; /// /// Demonstrates [Adapt]: one mapping template reused for an explicitly declared -/// different source/destination pair. Unlike [Expressive], [Adapt] is not for the +/// different source/destination pair. Unlike [Projectable], [Adapt] is not for the /// exact method signature types; it structurally substitutes the template source /// and destination with the explicit types from the attribute. /// diff --git a/examples/SampleApp/Mappers/AddressMapper.cs b/examples/SampleApp/Mappers/AddressMapper.cs index 4342be8..4552d6d 100644 --- a/examples/SampleApp/Mappers/AddressMapper.cs +++ b/examples/SampleApp/Mappers/AddressMapper.cs @@ -1,4 +1,4 @@ -using AlephMapper; +using AlephMapper; using SampleApp.Entities; using SampleApp.Models; @@ -7,7 +7,7 @@ namespace SampleApp.Mappers; public static partial class AddressMapper { // Entity to DTO mapping with expression-bodied syntax - [Expressive] + [Projectable] public static AddressDto ToDto(this Address entity) => new() { Street = entity.StreetAddress, diff --git a/examples/SampleApp/Mappers/EmployeeMapper.cs b/examples/SampleApp/Mappers/EmployeeMapper.cs index 8d02942..7f36107 100644 --- a/examples/SampleApp/Mappers/EmployeeMapper.cs +++ b/examples/SampleApp/Mappers/EmployeeMapper.cs @@ -11,7 +11,7 @@ namespace SampleApp.Mappers; /// public static partial class EmployeeMapper { - [Expressive] + [Projectable] [Updatable] public static EmployeeSummaryDto ToSummary(Employee emp, int year) => new() { diff --git a/examples/SampleApp/Mappers/PersonMapper.cs b/examples/SampleApp/Mappers/PersonMapper.cs index aba4030..9d1e478 100644 --- a/examples/SampleApp/Mappers/PersonMapper.cs +++ b/examples/SampleApp/Mappers/PersonMapper.cs @@ -1,4 +1,4 @@ -using AlephMapper; +using AlephMapper; using SampleApp.Entities; using SampleApp.Models; @@ -7,7 +7,7 @@ namespace SampleApp.Mappers; public static partial class PersonMapper { // Main entity to DTO mapping with expression-bodied syntax - [Expressive] + [Projectable] [Updatable(CollectionProperties = CollectionPropertiesPolicy.Skip)] public static PersonDto ToDto(Person entity) => entity == null ? null : new() { @@ -23,7 +23,7 @@ public static partial class PersonMapper // DTO to entity mapping with expression-bodied syntax //[Updatable] - [Expressive] + [Projectable] public static Person ToEntity(PersonDto dto) => new() { PersonId = dto.Id, diff --git a/source/Adaptation/AdaptationValidator.cs b/source/Adaptation/AdaptationValidator.cs index 24475c2..f5dfc2f 100644 --- a/source/Adaptation/AdaptationValidator.cs +++ b/source/Adaptation/AdaptationValidator.cs @@ -98,7 +98,7 @@ public static bool Validate( if (TryGetDirectSourcePath(assignment.Expression, mapping.SemanticModel, mapping.Parameters[0], out var path) && TryResolveReadablePath(adaptation.SourceType, path, out var sourceMember) && - !IsImplicitlyConvertible(mapping.SemanticModel.Compilation, GetMemberType(sourceMember), GetMemberType(destinationMember))) + !IsImplicitlyConvertible(mapping.SemanticModel.Compilation, GetMemberType(sourceMember!), GetMemberType(destinationMember))) { context.ReportDiagnostic(Diagnostic.Create( DiagnosticDescriptors.AdaptIncompatibleType, diff --git a/source/AlephMapper.csproj b/source/AlephMapper.csproj index 2504915..d73d393 100644 --- a/source/AlephMapper.csproj +++ b/source/AlephMapper.csproj @@ -18,6 +18,7 @@ Mapping Companion git https://github.com/Raffinert/AlephMapper.git + true netstandard2.0 Aleph Mapper @@ -33,6 +34,7 @@ + diff --git a/source/AlephSourceGenerator.cs b/source/AlephSourceGenerator.cs index 613f5e1..c2bf073 100644 --- a/source/AlephSourceGenerator.cs +++ b/source/AlephSourceGenerator.cs @@ -18,12 +18,12 @@ public void Initialize(IncrementalGeneratorInitializationContext context) AttributeSourceEmitter.AddAttributes(postInitializationContext); }); - var expressiveMappers = context.SyntaxProvider.ForAttributeWithMetadataName( - typeof(ExpressiveAttribute).FullName, + var projectableMappers = context.SyntaxProvider.ForAttributeWithMetadataName( + typeof(ProjectableAttribute).FullName, MapperCandidate.IsAttributeTarget, static (attributeContext, cancellationToken) => MapperSourceOutput.Create( attributeContext, - MapperAttributeKind.Expressive, + MapperAttributeKind.Projectable, cancellationToken)); var updatableMappers = context.SyntaxProvider.ForAttributeWithMetadataName( @@ -42,7 +42,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) MapperAttributeKind.Adapt, cancellationToken)); - RegisterMapperOutput(context, expressiveMappers, "Expressive"); + RegisterMapperOutput(context, projectableMappers, "Projectable"); RegisterMapperOutput(context, updatableMappers, "Updatable"); RegisterMapperOutput(context, adaptableMappers, "Adapt"); } diff --git a/source/AnalyzerReleases.Unshipped.md b/source/AnalyzerReleases.Unshipped.md new file mode 100644 index 0000000..c5de664 --- /dev/null +++ b/source/AnalyzerReleases.Unshipped.md @@ -0,0 +1,23 @@ +## Unshipped + +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +AM0001 | AlephMapper | Warning | Updatable method has a value-type return. +AM0002 | AlephMapper | Warning | Projectable method has circular references. +AM0003 | AlephMapper | Warning | Updatable method has circular references. +AM0004 | AlephMapper | Error | Source generator crashed. +AM0005 | AlephMapper | Error | Adaptation has an invalid source or destination type. +AM0006 | AlephMapper | Error | Adaptation source member is missing. +AM0007 | AlephMapper | Error | Adaptation destination member is missing or not writable. +AM0008 | AlephMapper | Error | Adaptation has an incompatible type. +AM0009 | AlephMapper | Error | Adapted generated member conflicts with an existing member. +AM0010 | AlephMapper | Warning | Adaptation uses unsupported syntax. +AM0011 | AlephMapper | Error | Adaptation expression generation has no name. +AM0012 | AlephMapper | Error | Adaptation duplicates an explicit type pair. +AM0013 | AlephMapper | Warning | Adaptation has a circular helper reference. +AM0014 | AlephMapper | Error | Adaptation uses an open generic type. +AM0015 | AlephMapper | Error | Adapted generated member fails Roslyn rebinding. +AM0016 | AlephMapper | Warning | Null-conditional receiver cannot be safely rewritten. +AM0017 | AlephMapper | Warning | Null-conditional access is unsupported in expression trees. diff --git a/source/Attributes.cs b/source/Attributes.cs index 5668336..e43bd06 100644 --- a/source/Attributes.cs +++ b/source/Attributes.cs @@ -1,4 +1,4 @@ -using System; +using System; using Microsoft.CodeAnalysis; @@ -34,11 +34,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -112,7 +112,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/source/Diagnostics/DiagnosticDescriptors.cs b/source/Diagnostics/DiagnosticDescriptors.cs index 31d8874..c5e26ec 100644 --- a/source/Diagnostics/DiagnosticDescriptors.cs +++ b/source/Diagnostics/DiagnosticDescriptors.cs @@ -18,9 +18,9 @@ public static class DiagnosticDescriptors isEnabledByDefault: true ); - public static readonly DiagnosticDescriptor ExpressiveCircularReferences = new( + public static readonly DiagnosticDescriptor ProjectableCircularReferences = new( "AM0002", - "Expressive method generation skipped due to circular references", + "Projectable method generation skipped due to circular references", "Expression method generation skipped for '{0}' due to circular references. Fix the circular dependencies to enable expression generation.", "AlephMapper", DiagnosticSeverity.Warning, @@ -50,7 +50,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor InvalidAdaptType = new( "AM0005", "Invalid adapted source or destination type", - "Adaptation for method '{0}' has an invalid source or destination type.", + "Adaptation for method '{0}' has an invalid source or destination type", "AlephMapper", DiagnosticSeverity.Error, isEnabledByDefault: true); @@ -58,7 +58,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor AdaptSourceMemberMissing = new( "AM0006", "Required adapted source member is missing", - "Cannot adapt '{0}': source member path '{1}' cannot be resolved on '{2}'.", + "Cannot adapt '{0}': source member path '{1}' cannot be resolved on '{2}'", "AlephMapper", DiagnosticSeverity.Error, isEnabledByDefault: true); @@ -66,7 +66,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor AdaptDestinationMemberMissing = new( "AM0007", "Required adapted destination member is missing or not writable", - "Cannot adapt '{0}': destination member '{1}' is missing or not writable on '{2}'.", + "Cannot adapt '{0}': destination member '{1}' is missing or not writable on '{2}'", "AlephMapper", DiagnosticSeverity.Error, isEnabledByDefault: true); @@ -74,7 +74,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor AdaptIncompatibleType = new( "AM0008", "Adapted expression or assignment has an incompatible type", - "Cannot adapt '{0}': adapted expression or assignment is not type-compatible for '{1}'.", + "Cannot adapt '{0}': adapted expression or assignment is not type-compatible for '{1}'", "AlephMapper", DiagnosticSeverity.Error, isEnabledByDefault: true); @@ -82,7 +82,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor AdaptNameConflict = new( "AM0009", "Generated adapted method name or signature conflicts", - "Cannot adapt '{0}': generated member name or signature '{1}' conflicts with an existing or generated member.", + "Cannot adapt '{0}': generated member name or signature '{1}' conflicts with an existing or generated member", "AlephMapper", DiagnosticSeverity.Error, isEnabledByDefault: true); @@ -90,7 +90,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor AdaptUnsupportedSyntax = new( "AM0010", "Template contains unsupported adaptation syntax", - "Cannot adapt '{0}': the template contains unsupported syntax '{1}'.", + "Cannot adapt '{0}': the template contains unsupported syntax '{1}'", "AlephMapper", DiagnosticSeverity.Warning, isEnabledByDefault: true); @@ -98,7 +98,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor AdaptExpressionWithoutName = new( "AM0011", "Expression generation requested without a generated name", - "Cannot adapt '{0}': Name is required when Generate includes Expression.", + "Cannot adapt '{0}': Name is required when Generate includes Expression", "AlephMapper", DiagnosticSeverity.Error, isEnabledByDefault: true); @@ -106,7 +106,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor AdaptDuplicatePair = new( "AM0012", "Duplicate adaptation for the same explicit type pair", - "Cannot adapt '{0}': duplicate adaptation for source '{1}' and destination '{2}'.", + "Cannot adapt '{0}': duplicate adaptation for source '{1}' and destination '{2}'", "AlephMapper", DiagnosticSeverity.Error, isEnabledByDefault: true); @@ -114,7 +114,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor AdaptCircularHelper = new( "AM0013", "Circular helper reference prevents adaptation", - "Adaptation skipped for '{0}' due to circular helper references.", + "Adaptation skipped for '{0}' due to circular helper references", "AlephMapper", DiagnosticSeverity.Warning, isEnabledByDefault: true); @@ -122,7 +122,7 @@ public static class DiagnosticDescriptors public static readonly DiagnosticDescriptor AdaptOpenGenericType = new( "AM0014", "Adapted source or destination type is open generic", - "Cannot adapt '{0}': adapted source or destination type must not be open generic.", + "Cannot adapt '{0}': adapted source or destination type must not be open generic", "AlephMapper", DiagnosticSeverity.Error, isEnabledByDefault: true); diff --git a/source/Generation/Emitters/ExpressiveMemberEmitter.cs b/source/Generation/Emitters/ProjectableMemberEmitter.cs similarity index 96% rename from source/Generation/Emitters/ExpressiveMemberEmitter.cs rename to source/Generation/Emitters/ProjectableMemberEmitter.cs index 43ed78c..2e221ff 100644 --- a/source/Generation/Emitters/ExpressiveMemberEmitter.cs +++ b/source/Generation/Emitters/ProjectableMemberEmitter.cs @@ -5,12 +5,12 @@ namespace AlephMapper.Generation.Emitters; -internal static class ExpressiveMemberEmitter +internal static class ProjectableMemberEmitter { public static void Emit(MappingMethodDetails details, MapperGenerationContext context) { var mapping = details.Mapping; - if (!mapping.IsExpressive) + if (!mapping.IsProjectable) { return; } @@ -24,7 +24,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co if (inliner.CircularReferences.Any()) { context.ReportDiagnostic(Diagnostic.Create( - DiagnosticDescriptors.ExpressiveCircularReferences, + DiagnosticDescriptors.ProjectableCircularReferences, mapping.MethodSymbol.Locations.FirstOrDefault(), mapping.MethodSymbol.Name)); return; diff --git a/source/Generation/MapperCandidate.cs b/source/Generation/MapperCandidate.cs index 33b8ed0..e7bde50 100644 --- a/source/Generation/MapperCandidate.cs +++ b/source/Generation/MapperCandidate.cs @@ -95,7 +95,7 @@ public override int GetHashCode() internal enum MapperAttributeKind { - Expressive, + Projectable, Updatable, Adapt } diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index ea73fce..d421b11 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -48,7 +48,7 @@ public static MapperGenerationResult Create( var mappings = CreateMapperAnalyses(compilation, mapperType, cancellationToken); if (mappings.Count == 0 || !mappings.Any(static mapping => - (mapping.IsExpressive || mapping.IsUpdatable || mapping.Adaptations.Count > 0) && mapping.IsClassPartial)) + (mapping.IsProjectable || mapping.IsUpdatable || mapping.Adaptations.Count > 0) && mapping.IsClassPartial)) { return MapperGenerationResult.Empty; } @@ -200,8 +200,8 @@ private static bool ContainsAlephMapperAttribute( var type = semanticModel.GetTypeInfo(attribute, cancellationToken).Type; switch (type?.ToDisplayString()) { - case "AlephMapper.ExpressiveAttribute": - attributeKind = MapperAttributeKind.Expressive; + case "AlephMapper.ProjectableAttribute": + attributeKind = MapperAttributeKind.Projectable; return true; case "AlephMapper.UpdatableAttribute": attributeKind = MapperAttributeKind.Updatable; @@ -232,13 +232,13 @@ private static MapperGenerationResult GenerateMapper( var context = new MapperGenerationContext(mapperType, catalog); foreach (var mapping in mappings) { - if (!mapping.IsExpressive && !mapping.IsUpdatable && mapping.Adaptations.Count == 0) + if (!mapping.IsProjectable && !mapping.IsUpdatable && mapping.Adaptations.Count == 0) { continue; } var details = new MappingMethodDetails(mapping); - ExpressiveMemberEmitter.Emit(details, context); + ProjectableMemberEmitter.Emit(details, context); AdaptationMemberEmitter.Emit(details, context); UpdatableMemberEmitter.Emit(details, context); } diff --git a/source/Generation/MappingAnalysisFactory.cs b/source/Generation/MappingAnalysisFactory.cs index 3917b65..4e48b24 100644 --- a/source/Generation/MappingAnalysisFactory.cs +++ b/source/Generation/MappingAnalysisFactory.cs @@ -45,7 +45,7 @@ internal static class MappingAnalysisFactory methodSymbol.ReturnType, bodyExpression, semanticModel, - HasAttribute(classSymbol, methodSymbol, typeof(ExpressiveAttribute).FullName), + HasAttribute(classSymbol, methodSymbol, typeof(ProjectableAttribute).FullName), HasAttribute(classSymbol, methodSymbol, typeof(UpdatableAttribute).FullName), classDeclaration.Modifiers.Any(static modifier => modifier.IsKind(SyntaxKind.PartialKeyword)), GetNullStrategy(methodSymbol) ?? GetNullStrategy(classSymbol) ?? NullConditionalRewrite.Ignore, @@ -108,8 +108,8 @@ attribute.ConstructorArguments[0].Value is not INamedTypeSymbol sourceType || { var value = SymbolHelpers.GetAttributeArgumentValue( symbol, - typeof(ExpressiveAttribute).FullName, - nameof(ExpressiveAttribute.NullConditionalRewrite)); + typeof(ProjectableAttribute).FullName, + nameof(ProjectableAttribute.NullConditionalRewrite)); return value is int intValue ? (NullConditionalRewrite)intValue : null; } @@ -137,17 +137,25 @@ private static IReadOnlyList ExtractUsingDirectives(SyntaxNode node) var usings = new HashSet(); foreach (var usingDirective in compilationUnit.Usings) { - usings.Add(usingDirective.Name.ToString()); + AddUsing(usings, usingDirective); } foreach (var namespaceDeclaration in compilationUnit.DescendantNodes().OfType()) { foreach (var usingDirective in namespaceDeclaration.Usings) { - usings.Add(usingDirective.Name.ToString()); + AddUsing(usings, usingDirective); } } return usings.OrderBy(static value => value).ToList(); } + + private static void AddUsing(ISet usings, UsingDirectiveSyntax usingDirective) + { + if (usingDirective.Name is { } name) + { + usings.Add(name.ToString()); + } + } } diff --git a/source/Models/MappingAnalysis.cs b/source/Models/MappingAnalysis.cs index 17ab7e0..ea1bda7 100644 --- a/source/Models/MappingAnalysis.cs +++ b/source/Models/MappingAnalysis.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Collections.Generic; @@ -16,7 +16,7 @@ internal sealed class MappingAnalysis( ITypeSymbol returnType, ArrowExpressionClauseSyntax bodySyntax, SemanticModel semanticModel, - bool isExpressive, + bool isProjectable, bool isUpdatable, bool classIsStaticAndPartial, NullConditionalRewrite nullStrategy, @@ -33,7 +33,7 @@ internal sealed class MappingAnalysis( public readonly ArrowExpressionClauseSyntax BodySyntax = bodySyntax; public readonly SemanticModel SemanticModel = semanticModel; - public readonly bool IsExpressive = isExpressive; + public readonly bool IsProjectable = isProjectable; public readonly bool IsUpdatable = isUpdatable; public readonly bool IsClassPartial = classIsStaticAndPartial; diff --git a/source/PropertyTypeInfoCollector.cs b/source/PropertyTypeInfoCollector.cs index f3c8068..aa1d0ad 100644 --- a/source/PropertyTypeInfoCollector.cs +++ b/source/PropertyTypeInfoCollector.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Linq; +#nullable enable + namespace AlephMapper; /// @@ -114,12 +116,13 @@ public override void VisitConditionalExpression(ConditionalExpressionSyntax node { try { - if (_currentTargetType != null) + if (_currentTargetType is not { } currentTargetType) { - _visitedTypes.Add(_currentTargetType); + return; } - - var trueCollector = new PropertyTypeInfoCollector(_currentTargetType, _rootPath) { TypeContext = TypeContext, _visitedTypes = _visitedTypes }; + + _visitedTypes.Add(currentTargetType); + var trueCollector = new PropertyTypeInfoCollector(currentTargetType, _rootPath) { TypeContext = TypeContext, _visitedTypes = _visitedTypes }; trueCollector.Visit(node.WhenTrue); trueCollector.Visit(node.WhenFalse); } @@ -129,3 +132,5 @@ public override void VisitConditionalExpression(ConditionalExpressionSyntax node } } } + +#nullable restore diff --git a/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs b/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs index 0729bb8..38721d6 100644 --- a/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs @@ -1,3 +1,5 @@ +#nullable enable + using AlephMapper.Helpers; using AlephMapper.Generation; using AlephMapper.Models; @@ -16,7 +18,7 @@ internal sealed partial class InliningResolver( MappingCatalog catalog, bool forUpdateMethod, NullConditionalRewrite rewriteSupport, - ITypeSymbol returnTypeToAnnotate = null) + ITypeSymbol? returnTypeToAnnotate = null) : CSharpSyntaxRewriter { internal const string InlinedConditionalAnnotation = "AlephMapper.InlinedConditional"; @@ -33,14 +35,14 @@ internal sealed partial class InliningResolver( public IReadOnlyList UnsafeConditionalReceivers => _unsafeConditionalReceivers; public IReadOnlyList UnsupportedNullConditionals => _unsupportedNullConditionals; - private IMethodSymbol ResolveMethodGroupSymbol(ExpressionSyntax expr) + private IMethodSymbol? ResolveMethodGroupSymbol(ExpressionSyntax expr) { var si = model.GetSymbolInfo(expr); if (si.Symbol is IMethodSymbol ms) return ms; return null; } - private static IMethodSymbol TryGetDelegateInvoke(IMethodSymbol invokedMethod, int argIndex) + private static IMethodSymbol? TryGetDelegateInvoke(IMethodSymbol invokedMethod, int argIndex) { if (argIndex < 0 || argIndex >= invokedMethod.Parameters.Length) return null; var p = invokedMethod.Parameters[argIndex].Type as INamedTypeSymbol; @@ -58,7 +60,7 @@ private void RecordCircularReference(IMethodSymbol method) _circularReferences.Add(circularRef); } - public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node) + public override SyntaxNode? VisitInvocationExpression(InvocationExpressionSyntax node) { if (node.Parent == null || model.GetSymbolInfo(node.Expression).Symbol is not IMethodSymbol invokedMethod) { @@ -109,7 +111,7 @@ public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax _inlinedMethods = _inlinedMethods, _unsafeConditionalReceivers = _unsafeConditionalReceivers, _unsupportedNullConditionals = _unsupportedNullConditionals - }.Visit(callee.BodySyntax.Expression); + }.Visit(callee.BodySyntax.Expression)!; var substitutions = callee.Parameters.ToDictionary( p => p.Name, @@ -184,10 +186,10 @@ public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax _inlinedMethods = _inlinedMethods, _unsafeConditionalReceivers = _unsafeConditionalReceivers, _unsupportedNullConditionals = _unsupportedNullConditionals - }.Visit(callee2.BodySyntax.Expression); + }.Visit(callee2.BodySyntax.Expression)!; - var substituted = new ParameterSubstitutionRewriter(substitutionsMap) - .Visit(inlinedBody2) + var substituted = ((ExpressionSyntax)new ParameterSubstitutionRewriter(substitutionsMap) + .Visit(inlinedBody2)!) .WithoutTrivia(); if (conditionalAccessExpression) @@ -219,7 +221,7 @@ private bool TryBuildParameterSubstitutions( // We need the original definition's parameters (which include 'this') for correct substitution. var isReducedExtension = invokedMethod.IsExtensionMethod && invokedMethod.ReducedFrom != null; var parameters = isReducedExtension - ? invokedMethod.ReducedFrom.Parameters + ? invokedMethod.ReducedFrom!.Parameters : invokedMethod.Parameters; if (parameters.Length == 0) @@ -237,18 +239,18 @@ private bool TryBuildParameterSubstitutions( conditionalAccessExpression = true; if (node.Expression is MemberAccessExpressionSyntax memberAccess) { - receiver = (ExpressionSyntax?)(Visit(memberAccess.Expression) ?? memberAccess.Expression); + receiver = (ExpressionSyntax)(Visit(memberAccess.Expression) ?? memberAccess.Expression); } else { receiver = rewriteSupport != NullConditionalRewrite.None - ? _conditionalAccessExpressionsStack.Peek() - : (ExpressionSyntax?)(Visit(caExpr.Expression) ?? caExpr.Expression); + ? _conditionalAccessExpressionsStack.Peek()! + : (ExpressionSyntax)(Visit(caExpr.Expression) ?? caExpr.Expression); } } else if (node.Expression is MemberAccessExpressionSyntax memberAccess) { - receiver = (ExpressionSyntax?)(Visit(memberAccess.Expression) ?? memberAccess.Expression); + receiver = (ExpressionSyntax)(Visit(memberAccess.Expression) ?? memberAccess.Expression); } else { @@ -261,14 +263,10 @@ private bool TryBuildParameterSubstitutions( foreach (var arg in args) { - IParameterSymbol targetParam; + IParameterSymbol? targetParam; if (arg.NameColon != null) { targetParam = parameters.FirstOrDefault(p => p.Name == arg.NameColon.Name.Identifier.Text); - if (targetParam == null) - { - return false; - } } else { @@ -280,7 +278,12 @@ private bool TryBuildParameterSubstitutions( targetParam = parameters[nextParamIndex++]; } - var rewrittenArg = (ExpressionSyntax?)(Visit(arg.Expression) ?? arg.Expression); + if (targetParam == null) + { + return false; + } + + var rewrittenArg = (ExpressionSyntax)(Visit(arg.Expression) ?? arg.Expression); substitutions[targetParam.Name] = rewrittenArg; } @@ -326,3 +329,5 @@ public UnsupportedNullConditionalInfo(ConditionalAccessExpressionSyntax expressi public ConditionalAccessExpressionSyntax Expression { get; } public Location Location { get; } } + +#nullable restore diff --git a/tests/AlephMapper.IntegrationTests/ArticleMappingMappers.cs b/tests/AlephMapper.IntegrationTests/ArticleMappingMappers.cs index a80f5de..b91cf0b 100644 --- a/tests/AlephMapper.IntegrationTests/ArticleMappingMappers.cs +++ b/tests/AlephMapper.IntegrationTests/ArticleMappingMappers.cs @@ -2,7 +2,7 @@ namespace AlephMapper.IntegrationTests; public static partial class ArticleOrderMapper { - [Expressive] + [Projectable] public static ArticleOrderDto Map(ArticleOrder order) => new( order.Id, diff --git a/tests/AlephMapper.IntegrationTests/MultiParamMappers.cs b/tests/AlephMapper.IntegrationTests/MultiParamMappers.cs index 5aca830..482cb7a 100644 --- a/tests/AlephMapper.IntegrationTests/MultiParamMappers.cs +++ b/tests/AlephMapper.IntegrationTests/MultiParamMappers.cs @@ -1,9 +1,9 @@ -namespace AlephMapper.IntegrationTests; +namespace AlephMapper.IntegrationTests; // ────────────────────────────────────────────────────────────────── -// 1. Expressive mapper with multi-parameter helper inlining +// 1. Projectable mapper with multi-parameter helper inlining // ────────────────────────────────────────────────────────────────── -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class MultiParamEmployeeMapper { // Two-parameter helper: concatenate first + last @@ -27,7 +27,7 @@ public static string GetDepartmentName(Employee employee) => employee.Department?.Name ?? "Unassigned"; // ── Expression mapping that uses all the above helpers ── - [Expressive] + [Projectable] public static EmployeeDto MapToDto(Employee e) => new() { Id = e.Id, @@ -38,7 +38,7 @@ public static string GetDepartmentName(Employee employee) => }; // Mapping that exercises three-parameter helper - [Expressive] + [Projectable] public static EmployeeSimpleDto MapToSimpleDto(Employee employee) => new() { Id = employee.Id, @@ -49,7 +49,7 @@ public static string GetDepartmentName(Employee employee) => }; // Mapping that exercises nested multi-param helper - [Expressive] + [Projectable] public static EmployeeDto MapToDtoWithEmail(Employee employee) => new() { Id = employee.Id, @@ -63,7 +63,7 @@ public static string GetDepartmentName(Employee employee) => // ────────────────────────────────────────────────────────────────── // 2. Named-argument mapper — arguments passed out of order // ────────────────────────────────────────────────────────────────── -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class NamedArgEmployeeMapper { public static string FormatName(string first, string last) => @@ -72,7 +72,7 @@ public static string FormatName(string first, string last) => public static string GetDepartmentName(Employee employee) => employee.Department?.Name ?? "Unassigned"; - [Expressive] + [Projectable] public static EmployeeDto MapToDto(Employee employee) => new() { Id = employee.Id, @@ -88,7 +88,7 @@ public static string GetDepartmentName(Employee employee) => // 3. Updatable mapper with multi-param helpers // (exercises the BinaryExpressionSyntax spacing fix) // ────────────────────────────────────────────────────────────────── -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class MultiParamUpdatableMapper { public static string FormatName(string first, string last) => @@ -112,11 +112,11 @@ public static string GetDepartmentName(Employee employee) => } // ────────────────────────────────────────────────────────────────── -// 4. Multi-parameter [Expressive] method itself +// 4. Multi-parameter [Projectable] method itself // Generates Expression> MapWithYearExpression(int currentYear) // ────────────────────────────────────────────────────────────────── -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] -public static partial class MultiParamExpressiveMapper +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +public static partial class MultiParamProjectableMapper { public static string FormatName(string first, string last) => first + " " + last; @@ -124,8 +124,8 @@ public static string FormatName(string first, string last) => public static string GetDepartmentName(Employee employee) => employee.Department?.Name ?? "Unassigned"; - // The [Expressive] method ITSELF takes two parameters - [Expressive] + // The [Projectable] method ITSELF takes two parameters + [Projectable] public static EmployeeDto MapWithYear(Employee employee, int currentYear) => new() { Id = employee.Id, diff --git a/tests/AlephMapper.IntegrationTests/MultiParamTests.cs b/tests/AlephMapper.IntegrationTests/MultiParamTests.cs index dcad37e..748d490 100644 --- a/tests/AlephMapper.IntegrationTests/MultiParamTests.cs +++ b/tests/AlephMapper.IntegrationTests/MultiParamTests.cs @@ -1,4 +1,4 @@ -using AgileObjects.ReadableExpressions; +using AgileObjects.ReadableExpressions; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; @@ -30,7 +30,7 @@ public async Task Cleanup() await _connection.DisposeAsync(); } - #region Multi-Param Expressive Tests + #region Multi-Param Projectable Tests [Test] public async Task MultiParam_FormatName_Expression_Should_Work_In_EFCore_Query() @@ -226,13 +226,13 @@ public async Task MultiParam_Updatable_Should_Preserve_Unmapped_Properties() #endregion - #region Multi-Param Expressive Method (method itself takes multiple params) + #region Multi-Param Projectable Method (method itself takes multiple params) [Test] - public async Task MultiParam_Expressive_Method_Should_Generate_Correct_Expression() + public async Task MultiParam_Projectable_Method_Should_Generate_Correct_Expression() { // Arrange — MapWithYear takes (Employee, int) and generates a single-parameter projection factory - var expression = MultiParamExpressiveMapper.MapWithYearExpression(2026); + var expression = MultiParamProjectableMapper.MapWithYearExpression(2026); // Act var result = await _context.Employees @@ -250,11 +250,11 @@ public async Task MultiParam_Expressive_Method_Should_Generate_Correct_Expressio } [Test] - public async Task MultiParam_Expressive_Method_Should_Have_Correct_Expression_Structure() + public async Task MultiParam_Projectable_Method_Should_Have_Correct_Expression_Structure() { // Arrange var currentYear = 2026; - var expression = MultiParamExpressiveMapper.MapWithYearExpression(currentYear); + var expression = MultiParamProjectableMapper.MapWithYearExpression(currentYear); var readable = expression.ToReadableString(); // Assert — the expression should reference both parameters diff --git a/tests/AlephMapper.IntegrationTests/README.md b/tests/AlephMapper.IntegrationTests/README.md index 359dd18..889d2d7 100644 --- a/tests/AlephMapper.IntegrationTests/README.md +++ b/tests/AlephMapper.IntegrationTests/README.md @@ -4,7 +4,7 @@ This test project provides comprehensive coverage of the AlephMapper source gene ## Test Coverage -### 1. Expressive Mapping Tests (`SimpleIntegrationTests`) +### 1. Projectable Mapping Tests (`SimpleIntegrationTests`) #### Basic Functionality - **Simple Property Expressions**: Tests basic property mapping with string interpolation @@ -56,13 +56,13 @@ The test project uses a comprehensive domain model representing an employee mana ### Mappers Tested -#### `SimpleEmployeeMapper` (Expressive with Rewrite Policy) +#### `SimpleEmployeeMapper` (Projectable with Rewrite Policy) - Basic property mapping - Null conditional operators with rewrite - Simple DTO creation - Method inlining demonstration -#### `SimpleIgnoreMapper` (Expressive with Ignore Policy) +#### `SimpleIgnoreMapper` (Projectable with Ignore Policy) - Same functionality as above but with ignore policy - Demonstrates different null handling behavior @@ -74,12 +74,12 @@ The test project uses a comprehensive domain model representing an employee mana ## Key Features Demonstrated ### 1. Expression Tree Generation -All Expressive mappers automatically generate corresponding expression tree methods: +All Projectable mappers automatically generate corresponding expression tree methods: - `GetFullName(Employee)` ? `GetFullNameExpression()` - `MapToSimpleDto(Employee)` ? `MapToSimpleDtoExpression()` ### 2. Method Inlining -When using Expressive mappers, method calls to other methods in the same class are automatically inlined: +When using Projectable mappers, method calls to other methods in the same class are automatically inlined: ```csharp public static EmployeeSimpleDto MapToSimpleDto(Employee employee) => new EmployeeSimpleDto { diff --git a/tests/AlephMapper.IntegrationTests/SimpleMappers.cs b/tests/AlephMapper.IntegrationTests/SimpleMappers.cs index dfe39d1..05446c3 100644 --- a/tests/AlephMapper.IntegrationTests/SimpleMappers.cs +++ b/tests/AlephMapper.IntegrationTests/SimpleMappers.cs @@ -1,6 +1,6 @@ namespace AlephMapper.IntegrationTests; -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class SimpleEmployeeMapper { // Basic property mapping @@ -41,7 +41,7 @@ public static int GetAddressCount(Employee employee) => }; } -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Ignore)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Ignore)] public static partial class SimpleIgnoreMapper { public static string GetFullName(Employee employee) => diff --git a/tests/AlephMapper.IntegrationTests/SimpleTests.cs b/tests/AlephMapper.IntegrationTests/SimpleTests.cs index a143572..81b9f03 100644 --- a/tests/AlephMapper.IntegrationTests/SimpleTests.cs +++ b/tests/AlephMapper.IntegrationTests/SimpleTests.cs @@ -30,7 +30,7 @@ public async Task Cleanup() await _connection.DisposeAsync(); } - #region Expressive Tests + #region Projectable Tests [Test] public async Task Simple_Property_Expressions_Should_Work() diff --git a/tests/AlephMapper.IntegrationTests/UpdatableMappers.cs b/tests/AlephMapper.IntegrationTests/UpdatableMappers.cs index 4b7e8fc..5169355 100644 --- a/tests/AlephMapper.IntegrationTests/UpdatableMappers.cs +++ b/tests/AlephMapper.IntegrationTests/UpdatableMappers.cs @@ -155,11 +155,11 @@ public static partial class EmployeeUpdateMapper }; } -// Test both Expressive and Updatable on the same class -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +// Test both Projectable and Updatable on the same class +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class EmployeeCombinedMapper { - // Expressive methods + // Projectable methods public static string GetFullName(Employee employee) => $"{employee.FirstName} {employee.LastName}"; diff --git a/tests/AlephMapper.IntegrationTests/UpdatableTests.cs b/tests/AlephMapper.IntegrationTests/UpdatableTests.cs index b0fea96..32a935f 100644 --- a/tests/AlephMapper.IntegrationTests/UpdatableTests.cs +++ b/tests/AlephMapper.IntegrationTests/UpdatableTests.cs @@ -368,10 +368,10 @@ public async Task Nested_Update_Should_Handle_Partial_Null_Chains() #endregion - #region Combined Expressive and Updatable Tests + #region Combined Projectable and Updatable Tests [Test] - public async Task Combined_Mapper_Expressive_Methods_Should_Work() + public async Task Combined_Mapper_Projectable_Methods_Should_Work() { // Arrange var fullNameExpression = EmployeeCombinedMapper.GetFullNameExpression(); diff --git a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/AnySourcesGeneratesAttribute/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/CircularMapper/Sources/CircularMapper.cs b/tests/AlephMapper.Tests/Files/CircularMapper/Sources/CircularMapper.cs index 921e85e..6e4c02d 100644 --- a/tests/AlephMapper.Tests/Files/CircularMapper/Sources/CircularMapper.cs +++ b/tests/AlephMapper.Tests/Files/CircularMapper/Sources/CircularMapper.cs @@ -1,7 +1,7 @@ -namespace AlephMapper.Tests; +namespace AlephMapper.Tests; // Mapper with intentional circular references to test detection -[Expressive] +[Projectable] internal static partial class CircularMapper { // Simple direct circular reference - this method calls itself diff --git a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Sources/CircularPropertyMapper.cs b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Sources/CircularPropertyMapper.cs index ea14e4f..4aa772a 100644 --- a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Sources/CircularPropertyMapper.cs +++ b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Sources/CircularPropertyMapper.cs @@ -1,8 +1,8 @@ -using System; +using System; namespace AlephMapper.Tests; -[Expressive] +[Projectable] internal static partial class CircularPropertyMapper { [Updatable] diff --git a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/CollectionMapper/Sources/CollectionMapper.cs b/tests/AlephMapper.Tests/Files/CollectionMapper/Sources/CollectionMapper.cs index 754946e..3af4e78 100644 --- a/tests/AlephMapper.Tests/Files/CollectionMapper/Sources/CollectionMapper.cs +++ b/tests/AlephMapper.Tests/Files/CollectionMapper/Sources/CollectionMapper.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace AlephMapper.Tests; @@ -30,7 +30,7 @@ public class NestedModel } // Mapper with collection properties to test skipping behavior -[Expressive] +[Projectable] internal static partial class CollectionMapper { [Updatable] diff --git a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Sources/EfCoreMappers.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Sources/EfCoreMappers.cs index aca1c27..724759d 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Sources/EfCoreMappers.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Sources/EfCoreMappers.cs @@ -1,8 +1,8 @@ -namespace AlephMapper.Tests; +namespace AlephMapper.Tests; // Projection mappers for EF Core integration tests -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class EfCoreMapper { public static PersonSummaryDto GetPersonComplex(Person p) => new PersonSummaryDto @@ -88,7 +88,7 @@ public static bool IsVipCustomer(Person person) => } // Mapper with Ignore policy for comparison -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Ignore)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Ignore)] public static partial class EfCoreIgnoreMapper { public static string GetPersonName(Person person) => person.Name; diff --git a/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/Expressive/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/Expressive/Sources/Source.cs b/tests/AlephMapper.Tests/Files/Expressive/Sources/Source.cs index ad2adb2..77c9613 100644 --- a/tests/AlephMapper.Tests/Files/Expressive/Sources/Source.cs +++ b/tests/AlephMapper.Tests/Files/Expressive/Sources/Source.cs @@ -1,8 +1,8 @@ -using AlephMapper; +using AlephMapper; namespace Tests; -[Expressive] +[Projectable] public static partial class SampleMapper { public static string ProjectName(SampleSource source) => source.Name; diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Sources/ExtensionMethodInliningTests.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Sources/ExtensionMethodInliningTests.cs index 83edfcb..b187391 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Sources/ExtensionMethodInliningTests.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Sources/ExtensionMethodInliningTests.cs @@ -35,7 +35,7 @@ public class ExtensionTestPersonDto // Extension method mapper public static partial class ExtensionTestAddressMapper { - [Expressive] + [Projectable] public static ExtensionTestAddressDto ToDto(this ExtensionTestAddress address) => new() { Street = address.Street, @@ -48,7 +48,7 @@ public static partial class ExtensionTestAddressMapper // Main mapper that uses the extension method public static partial class ExtensionTestPersonMapper { - [Expressive] + [Projectable] public static ExtensionTestPersonDto ToDto(ExtensionTestPerson person) => new() { Id = person.Id, @@ -60,7 +60,7 @@ public static partial class ExtensionTestPersonMapper // Main mapper that uses conditional access extension method public static partial class ConditionalExtensionTestPersonMapper { - [Expressive] + [Projectable] public static ExtensionTestPersonDto ToDto(ExtensionTestPerson person) => new() { Id = person.Id, diff --git a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/Mapper/Sources/Mapper.cs b/tests/AlephMapper.Tests/Files/Mapper/Sources/Mapper.cs index 3717cd2..72498c6 100644 --- a/tests/AlephMapper.Tests/Files/Mapper/Sources/Mapper.cs +++ b/tests/AlephMapper.Tests/Files/Mapper/Sources/Mapper.cs @@ -1,11 +1,11 @@ -namespace AlephMapper.Tests; +namespace AlephMapper.Tests; internal static class Mapper1 { public static bool Older35(BirthInfo? source) => source?.Age > 35; } -[Expressive] +[Projectable] internal static partial class Mapper { public static bool BornInKyivAndOlder35(SourceDto source) => BornInKyiv(source.BirthInfo) && Mapper1.Older35(source.BirthInfo) && Younger65(source.BirthInfo); diff --git a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Sources/MethodGroup.cs b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Sources/MethodGroup.cs index bc33bfc..808b78e 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Sources/MethodGroup.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Sources/MethodGroup.cs @@ -1,4 +1,4 @@ -using AgileObjects.ReadableExpressions; +using AgileObjects.ReadableExpressions; namespace AlephMapper.Tests; @@ -19,7 +19,7 @@ internal class SimpleDto internal static partial class SimpleObjectMapper { - [Expressive] + [Projectable] public static SimpleDto MapToDto(SimpleObject so) => new SimpleDto { Attributes = so.Attributes?.Select(MapFromAttribute).ToList() ?? [] diff --git a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Sources/PersonMapper.cs b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Sources/PersonMapper.cs index 8a3a553..f41981e 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Sources/PersonMapper.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Sources/PersonMapper.cs @@ -34,7 +34,7 @@ public static class PhoneMapper public static partial class PersonMapper { - [Expressive] + [Projectable] public static Person ToEntity(PersonDto dto) => new() { ContactNumbers = dto.PhoneNumbers.Select(PhoneMapper.ToEntity).ToList() diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Sources/MultiParamExtMapper.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Sources/MultiParamExtMapper.cs index b5ca190..6fbd45a 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Sources/MultiParamExtMapper.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Sources/MultiParamExtMapper.cs @@ -44,7 +44,7 @@ public static decimal ComputeTotal(this Product product, decimal taxRate, decima /// public static partial class ProductMapper { - [Expressive] + [Projectable] public static ProductDto ToDto(Product product) => new() { Label = product.Name, @@ -69,10 +69,10 @@ public class PersonProductDto public string FavoritePrice { get; set; } = string.Empty; } -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Ignore)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Ignore)] public static partial class PersonProductMapperIgnore { - [Expressive] + [Projectable] public static PersonProductDto ToDto(Person person) => new() { Name = person.Name, @@ -80,10 +80,10 @@ public static partial class PersonProductMapperIgnore }; } -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class PersonProductMapperRewrite { - [Expressive] + [Projectable] public static PersonProductDto ToDto(Person person) => new() { Name = person.Name, diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs similarity index 95% rename from tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs rename to tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs index ef22db9..732c204 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamExpressiveMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs @@ -10,7 +10,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; [GeneratedCode("AlephMapper", "0.7.0")] -partial class MultiParamExpressiveMapper +partial class MultiParamProjectableMapper { /// /// This is an auto-generated expression companion for . diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Sources/PersonMapper.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Sources/PersonMapper.cs index d0d397f..2264e61 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Sources/PersonMapper.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Sources/PersonMapper.cs @@ -26,7 +26,7 @@ public class PersonDto /// public static partial class PersonMapper { - [Expressive] + [Projectable] public static PersonDto ToDto(Person person) => new() { FullName = Combine(person.First, person.Last), @@ -52,7 +52,7 @@ public static string Describe(string first, string last, int age) => /// public static partial class NamedArgMapper { - [Expressive] + [Projectable] public static PersonDto ToDto(Person person) => new() { FullName = Combine(last: person.Last, first: person.First) @@ -67,7 +67,7 @@ public static partial class NamedArgMapper /// public static partial class NestedMultiParamMapper { - [Expressive] + [Projectable] public static PersonDto ToDto(Person person) => new() { FullName = DescribeWithAge(person.First, person.Last, person.Age) @@ -81,12 +81,12 @@ public static string DescribeWithAge(string first, string last, int age) => /// -/// Tests that a multi-parameter [Expressive] mapping method itself +/// Tests that a multi-parameter [Projectable] mapping method itself /// generates a single-parameter projection expression factory. /// -public static partial class MultiParamExpressiveMapper +public static partial class MultiParamProjectableMapper { - [Expressive] + [Projectable] public static PersonDto Map(Person person, int currentYear) => new() { FullName = person.First + " " + person.Last, @@ -100,7 +100,7 @@ public static partial class MultiParamExpressiveMapper /// public static partial class UpdatableMultiParamMapper { - [Expressive] + [Projectable] [Updatable] public static PersonDto ToDto(Person person, int currentYear) => new() { diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Sources/NestedConditionalExtensionInlining.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Sources/NestedConditionalExtensionInlining.cs index 950046e..9e31b65 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Sources/NestedConditionalExtensionInlining.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Sources/NestedConditionalExtensionInlining.cs @@ -27,7 +27,7 @@ public class NestedExt_PersonDto public static partial class NestedExt_AddressMapper { - [Expressive] + [Projectable] public static NestedExt_AddressDto ToDto(this NestedExt_Address a) => new() { Street = a.Street, @@ -37,20 +37,20 @@ public static partial class NestedExt_AddressMapper // Mapper using nested conditional access chains -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Ignore)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Ignore)] public static partial class NestedExt_PersonMapper_Ignore { - [Expressive] + [Projectable] public static NestedExt_PersonDto ToDto(NestedExt_Person p) => new() { HomeAddress = p?.Friend?.HomeAddress?.ToDto() }; } -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class NestedExt_PersonMapper_Rewrite { - [Expressive] + [Projectable] public static NestedExt_PersonDto ToDto(NestedExt_Person p) => new() { HomeAddress = p?.Friend?.HomeAddress?.ToDto() diff --git a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Sources/IgnoreNullCoalesceValueAssignment.cs b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Sources/IgnoreNullCoalesceValueAssignment.cs index a77480a..8a9cba0 100644 --- a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Sources/IgnoreNullCoalesceValueAssignment.cs +++ b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Sources/IgnoreNullCoalesceValueAssignment.cs @@ -17,7 +17,7 @@ public static partial class NullCoalesceValueAssignmentMapper { // In Ignore mode the null-conditional operator is dropped, but the coalesce (??) // must be preserved so the assignment to a non-nullable value property still compiles. - [Expressive(NullConditionalRewrite = NullConditionalRewrite.Ignore)] + [Projectable(NullConditionalRewrite = NullConditionalRewrite.Ignore)] public static ValueDest Map(ValueSource s) => new() { Must = s?.Maybe ?? 42 diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Sources/Mappers.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Sources/Mappers.cs index f767316..05fa9a3 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Sources/Mappers.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Sources/Mappers.cs @@ -1,9 +1,9 @@ -using System.CodeDom.Compiler; +using System.CodeDom.Compiler; namespace AlephMapper.Tests; // Test mapper with Ignore policy (now default, but being explicit) -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Ignore)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Ignore)] public static partial class IgnoreMapper { public static string GetAddress(SourceDto source) => source.BirthInfo?.Address ?? "Unknown"; @@ -12,7 +12,7 @@ public static partial class IgnoreMapper } // Test mapper with Rewrite policy -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class RewriteMapper { public static string GetAddress(SourceDto dto) => dto.BirthInfo?.Address ?? "Unknown"; @@ -21,7 +21,7 @@ public static partial class RewriteMapper } // Test mapper with None policy (should fail with null conditional operators) -[Expressive(NullConditionalRewrite = NullConditionalRewrite.None)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.None)] public static partial class NoneMapper { // This method should work because it doesn't use null conditional operators diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Sources/Source.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Sources/Source.cs index e02e48e..ccf190a 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Sources/Source.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Sources/Source.cs @@ -3,7 +3,7 @@ namespace Tests; -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class NullableDisabledMapper { public static string GetName(Person person) => person?.Name; diff --git a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/NullableEnabled/Sources/Source.cs b/tests/AlephMapper.Tests/Files/NullableEnabled/Sources/Source.cs index a738ba9..be49a48 100644 --- a/tests/AlephMapper.Tests/Files/NullableEnabled/Sources/Source.cs +++ b/tests/AlephMapper.Tests/Files/NullableEnabled/Sources/Source.cs @@ -3,7 +3,7 @@ namespace Tests; -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class NullableEnabledMapper { public static string? GetName(Person person) => person?.Name; diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Sources/TechDebtFix.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Sources/TechDebtFix.cs index 67ee3bc..d9760dd 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Sources/TechDebtFix.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Sources/TechDebtFix.cs @@ -29,16 +29,16 @@ public class TechDebtTestPersonDto // Extension method mapper that should trigger the tech debt public static partial class TechDebtAddressMapper { - [Expressive] + [Projectable] public static string FormatAddress(this TechDebtTestAddress address) => address.FormattedAddress; } // Mapper with nested conditional access that triggers ParseExpression tech debt -[Expressive(NullConditionalRewrite = NullConditionalRewrite.None)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.None)] public static partial class TechDebtPersonMapperNone { - [Expressive] + [Projectable] public static TechDebtTestPersonDto ToDto(TechDebtTestPerson person) => new() { Name = person.Name, @@ -47,10 +47,10 @@ public static partial class TechDebtPersonMapperNone }; } -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static partial class TechDebtPersonMapperRewrite { - [Expressive] + [Projectable] public static TechDebtTestPersonDto ToDto(TechDebtTestPerson person) => new() { Name = person.Name, @@ -61,13 +61,13 @@ public static partial class TechDebtPersonMapperRewrite }; } -[Expressive(NullConditionalRewrite = NullConditionalRewrite.Ignore)] +[Projectable(NullConditionalRewrite = NullConditionalRewrite.Ignore)] public static partial class TechDebtPersonMapperIgnore { - [Expressive] + [Projectable] public static TechDebtTestPersonDto ToDto(TechDebtTestPerson person) => new() { Name = person.Name, AddressStr = person.Address?.FormatAddress() ?? "No Address" }; -} \ No newline at end of file +} diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Sources/TestModel1.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Sources/TestModel1.cs index a924efb..0cfc234 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Sources/TestModel1.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Sources/TestModel1.cs @@ -1,4 +1,4 @@ -namespace AlephMapper.Tests; +namespace AlephMapper.Tests; internal class TestModel1 { @@ -42,7 +42,7 @@ internal class AddressLineDto } -[Expressive] +[Projectable] internal static partial class TestModel1Mapper { [Updatable] @@ -55,7 +55,7 @@ public static TestModel1Dto MapToTestModel1Dto(TestModel1 source) }; } -[Expressive] +[Projectable] internal static partial class Address1Mapper { public static Address1Dto MapToDto(Address1 sourceAddress) @@ -66,7 +66,7 @@ public static Address1Dto MapToDto(Address1 sourceAddress) }; } -[Expressive] +[Projectable] internal static partial class AddressLineMapper { public static AddressLineDto? MapToDto(AddressLine? sourceAddressLine1) diff --git a/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/Updatable/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs index 3d470ad..b810543 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper.Attributes.g.cs @@ -37,11 +37,11 @@ internal enum NullConditionalRewrite } /// -/// Marks a class to generate expressive companion methods. +/// Marks a class to generate projectable companion methods. /// [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -internal sealed class ExpressiveAttribute : Attribute +internal sealed class ProjectableAttribute : Attribute { /// /// Get or set how null-conditional operators are handled @@ -115,7 +115,7 @@ public AdaptAttribute(Type sourceType, Type destinationType) /// Gets or sets the generated method base name. /// Required when expression generation is requested. /// - public string Name { get; set; } + public string Name { get; set; } = string.Empty; /// /// Gets or sets which adapted companions are generated. diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ComplexValueType.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ComplexValueType.cs index a27fd0e..be61c37 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ComplexValueType.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ComplexValueType.cs @@ -1,4 +1,4 @@ -namespace AlephMapper.Tests; +namespace AlephMapper.Tests; // Complex nested value types internal struct ComplexValueTypeSource @@ -78,7 +78,7 @@ internal enum TagCategory Other = 2 } -[Expressive] +[Projectable] internal static partial class ComplexValueTypeMapper { [Updatable] diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/EdgeCases.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/EdgeCases.cs index 89c38f2..c355d24 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/EdgeCases.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/EdgeCases.cs @@ -1,4 +1,4 @@ -namespace AlephMapper.Tests; +namespace AlephMapper.Tests; // Simple test types internal struct SimpleValueTypeSource @@ -13,7 +13,7 @@ internal class SimpleReferenceTypeDestination public string Name { get; set; } } -[Expressive] +[Projectable] internal static partial class SimpleValueToReferenceMapper { [Updatable] @@ -57,7 +57,7 @@ internal class DeeplyNestedReferenceType public string DeepValue { get; set; } } -[Expressive] +[Projectable] internal static partial class ComplexPropertyMapper { [Updatable] @@ -109,7 +109,7 @@ internal class NestedEdgeCaseClass public string Value { get; set; } } -[Expressive] +[Projectable] internal static partial class EdgeCaseMapper { [Updatable] diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/MixedType.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/MixedType.cs index af91ec5..413a363 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/MixedType.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/MixedType.cs @@ -30,7 +30,7 @@ internal class TestObject public int Value { get; set; } } -[Expressive] +[Projectable] internal static partial class MixedTypeMapper { [Updatable] diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ValueToReferenceType.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ValueToReferenceType.cs index 60955d6..f1e195c 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ValueToReferenceType.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ValueToReferenceType.cs @@ -1,4 +1,4 @@ -namespace AlephMapper.Tests; +namespace AlephMapper.Tests; // Reference type equivalents of the value types internal class ComplexReferenceTypeDestination @@ -55,7 +55,7 @@ internal class TagsClass public TagCategory Category { get; set; } } -[Expressive] +[Projectable] internal static partial class ValueToReferenceMapper { [Updatable] diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ValueTypeUpdatableNullChecks.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ValueTypeUpdatableNullChecks.cs index 9d07ad6..2f64f6e 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ValueTypeUpdatableNullChecks.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Sources/ValueTypeUpdatableNullChecks.cs @@ -17,7 +17,7 @@ internal class ValueTypeOnlyDestination public decimal DecimalProperty { get; set; } } -[Expressive] +[Projectable] internal static partial class ValueTypeOnlyMapper { [Updatable] @@ -49,7 +49,7 @@ internal class SimpleReferenceObject public string Name { get; set; } } -[Expressive] +[Projectable] internal static partial class ReferenceTypeOnlyMapper { [Updatable] @@ -79,7 +79,7 @@ internal class NullableValueTypeDestination public DateTime? NullableDateTimeProperty { get; set; } } -[Expressive] +[Projectable] internal static partial class NullableValueTypeMapper { [Updatable] diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index 1157e95..f343fcc 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; @@ -37,7 +37,7 @@ public async Task UnrelatedMethodsAreRejectedBySyntaxCandidateFilter() public async Task MapperHelpersRemainCandidatesForInlining() { var tree = CSharpSyntaxTree.ParseText( - "using AlephMapper; public static partial class Mapper { [Expressive] public static int Map(int value) => Helper(value); public static int Helper(int value) => value; }", + "using AlephMapper; public static partial class Mapper { [Projectable] public static int Map(int value) => Helper(value); public static int Helper(int value) => value; }", _parseOptions); var methods = tree.GetRoot().DescendantNodes().OfType().ToArray(); @@ -51,7 +51,7 @@ public async Task ClassLevelConfigurationAcrossPartialDeclarationsGeneratesOnce( const string configuration = """ using AlephMapper; namespace Fixture; - [Expressive] + [Projectable] public static partial class Mapper { } """; const string mapping = """ @@ -93,7 +93,7 @@ public async Task GeneratedConfigurationTypesAreNotPublic() var assembly = typeof(AlephSourceGenerator).Assembly; var typeNames = new[] { - "ExpressiveAttribute", + "ProjectableAttribute", "UpdatableAttribute", "AdaptAttribute", "NullConditionalRewrite", @@ -107,6 +107,8 @@ public async Task GeneratedConfigurationTypesAreNotPublic() await Assert.That(type).IsNotNull(); await Assert.That(type!.IsPublic).IsFalse(); } + + await Assert.That(assembly.GetType("AlephMapper.ExpressiveAttribute")).IsNull(); } [Test] @@ -118,7 +120,7 @@ public async Task EmbeddedConfigurationTypesDoNotConflictAcrossConsumerAssemblie namespace ProjectA; public static partial class Mapper { - [Expressive] + [Projectable] public static Target Map(Source source) => new() { Value = source.Value }; } public sealed class Source { public int Value { get; set; } } @@ -130,7 +132,7 @@ public sealed class Target { public int Value { get; set; } } namespace ProjectB; public static partial class Mapper { - [Expressive] + [Projectable] public static Target Map(Source source) => new() { Value = source.Value }; } """; @@ -166,9 +168,9 @@ public static partial class Mapper await Assert.That(projectBDiagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); await Assert.That(projectBOutput.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); - await Assert.That(projectBOutput.GetTypeByMetadataName("AlephMapper.ExpressiveAttribute")!.DeclaredAccessibility) + await Assert.That(projectBOutput.GetTypeByMetadataName("AlephMapper.ProjectableAttribute")!.DeclaredAccessibility) .IsEqualTo(Accessibility.Internal); - await Assert.That(projectBOutput.GetTypeByMetadataName("AlephMapper.ExpressiveAttribute")!.GetAttributes() + await Assert.That(projectBOutput.GetTypeByMetadataName("AlephMapper.ProjectableAttribute")!.GetAttributes() .Any(attribute => attribute.AttributeClass?.ToDisplayString() == "Microsoft.CodeAnalysis.EmbeddedAttribute")) .IsTrue(); } @@ -181,7 +183,7 @@ public async Task AttributeDiscoveryGeneratesOneFileForCombinedConfiguration() namespace Fixture; public static partial class Mapper { - [Expressive] + [Projectable] [Updatable] [Adapt(typeof(AdaptedSource), typeof(AdaptedTarget), Name = "MapAdapted")] public static Target Map(Source source) => new() { Value = source.Value }; @@ -217,7 +219,7 @@ public async Task AttributeCandidatesRemainUnchangedWhenOnlyUnrelatedSourceChang namespace Fixture; public static partial class MapperA { - [Expressive] + [Projectable] public static Target Map(Source source) => new() { Value = source.Value }; } public sealed class Source { public int Value { get; set; } } @@ -228,7 +230,7 @@ public sealed class Target { public int Value { get; set; } } namespace Fixture; public static partial class MapperB { - [Expressive] + [Projectable] public static Target Map(Source source) => new() { Value = source.Value }; } """; @@ -251,7 +253,7 @@ public static partial class MapperB driver = driver.RunGeneratorsAndUpdateCompilation(updatedCompilation, out _, out _); var trackedSteps = driver.GetRunResult().Results.Single().TrackedSteps; - var candidateOutputs = trackedSteps["AlephMapper.ExpressiveGenerationResult"] + var candidateOutputs = trackedSteps["AlephMapper.ProjectableGenerationResult"] .SelectMany(static step => step.Outputs) .ToArray(); @@ -272,7 +274,7 @@ public async Task LargeCompilationDiscoversOnlyAttributedMappers() for (var index = 0; index < 10; index++) { source.Append("public static partial class Mapper").Append(index) - .Append(" { [Expressive] public static Target Map(Source source) => new() { Value = source.Value }; }"); + .Append(" { [Projectable] public static Target Map(Source source) => new() { Value = source.Value }; }"); } var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); @@ -287,7 +289,7 @@ public async Task LargeCompilationDiscoversOnlyAttributedMappers() stopwatch.Stop(); var result = driver.GetRunResult().Results.Single(); - var candidateOutputs = result.TrackedSteps["AlephMapper.ExpressiveGenerationResult"] + var candidateOutputs = result.TrackedSteps["AlephMapper.ProjectableGenerationResult"] .SelectMany(static step => step.Outputs) .ToArray(); @@ -865,13 +867,13 @@ namespace Fixture; public static partial class Criteria { - [Expressive] + [Projectable] public static bool HasCategoryLine(InvoiceLine line, Guid dataSetId, Guid invoiceId) => line.Invoice.DataSetId == dataSetId && line.Invoice.InvoiceIdReference == invoiceId && line.CategoryId != null; - [Expressive] + [Projectable] public static bool HasCategoryLineSingleLine(InvoiceLine line, Guid dataSetId, Guid invoiceId) => line.Invoice.DataSetId == dataSetId && line.Invoice.InvoiceIdReference == invoiceId && line.CategoryId != null; } @@ -908,19 +910,19 @@ namespace Fixture; public static partial class Mapper { - [Expressive] + [Projectable] public static string SingleConditional(bool condition) => condition ? "yes" : "no"; - [Expressive] + [Projectable] public static string MultilineConditional(bool condition) => condition ? "yes" : "no"; - [Expressive] + [Projectable] public static string SingleSwitch(int value) => value switch { 1 => "one", _ => "other" }; - [Expressive] + [Projectable] public static string MultilineSwitch(int value) => value switch { @@ -1025,7 +1027,7 @@ public static AddressDto ToDto(this Address source) => public static partial class Mapper { - [Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] + [Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static AddressDto? Map(Address source) => source.GetNested()?.ToDto(); } @@ -1073,7 +1075,7 @@ public static AddressDto ToDto(this Address source) => public static partial class Mapper { - [Expressive(NullConditionalRewrite = NullConditionalRewrite.None)] + [Projectable(NullConditionalRewrite = NullConditionalRewrite.None)] public static AddressDto? Map(Address? source) => source?.ToDto(); } diff --git a/tests/Experiments/ExtensionMethodInliningTests.cs b/tests/Experiments/ExtensionMethodInliningTests.cs index 70e9724..4f3b652 100644 --- a/tests/Experiments/ExtensionMethodInliningTests.cs +++ b/tests/Experiments/ExtensionMethodInliningTests.cs @@ -1,4 +1,4 @@ -using AgileObjects.ReadableExpressions; +using AgileObjects.ReadableExpressions; using AlephMapper; namespace Experiments; @@ -42,7 +42,7 @@ public class ExtensionTestPersonDto public static partial class ExtensionTestAddressMapper { - [Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] + [Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] public static ExtensionTestAddressDto ToDto(this ExtensionTestAddress address) => new() { Street = address.Street, @@ -55,7 +55,7 @@ public static partial class ExtensionTestAddressMapper // Main mapper that uses conditional access extension method public static partial class ConditionalExtensionTestPersonMapper { - [Expressive(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] + [Projectable(NullConditionalRewrite = NullConditionalRewrite.Rewrite)] [Updatable] public static ExtensionTestPersonDto ToDto(ExtensionTestPerson person) => new() { @@ -65,7 +65,7 @@ public static partial class ConditionalExtensionTestPersonMapper MyProperty = person?.MyProperty ?? 0 }; - [Expressive(NullConditionalRewrite = NullConditionalRewrite.Ignore)] + [Projectable(NullConditionalRewrite = NullConditionalRewrite.Ignore)] public static ExtensionTestPersonDto ToDto1(ExtensionTestPerson person) => new() { Name = person?.Name, From a49ef483f07387b408b6afca8ac8cb07d0ef18c4 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 07:36:24 +0200 Subject: [PATCH 09/22] fix: preserve nullability in rewritten null-conditional expressions --- .../InliningResolver.NullConditionalRewriter.cs | 8 ++++++-- tests/AlephMapper.IntegrationTests/Models.cs | 2 +- ...hMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs | 12 ++++++------ ...PersonProductMapperRewrite_GeneratedMappings.g.cs | 2 +- ...edExt_PersonMapper_Rewrite_GeneratedMappings.g.cs | 6 +++--- ...Mapper_Tests_RewriteMapper_GeneratedMappings.g.cs | 4 ++-- ...sts_NullableDisabledMapper_GeneratedMappings.g.cs | 2 +- ...echDebtPersonMapperRewrite_GeneratedMappings.g.cs | 2 +- 8 files changed, 21 insertions(+), 17 deletions(-) diff --git a/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs b/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs index a271751..9b6fe26 100644 --- a/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs @@ -56,11 +56,15 @@ internal partial class InliningResolver { var typeInfo = model.GetTypeInfo(node); var convertedType = typeInfo.ConvertedType ?? typeInfo.Type; - var nullableContext = model.GetNullableContext(node.SpanStart); if (convertedType is not null) { - var castTypeName = TypeDisplay.ForSymbol(convertedType, convertedType.NullableAnnotation, nullableContext); + // A null-conditional access always produces null when its receiver is null. + // Its converted type can still be non-nullable when it is immediately consumed + // by an expression such as `??`, so explicitly retain that nullability here. + // Generated files always enable nullable annotations, so render this cast in + // that context even when the input source has annotations disabled. + var castTypeName = TypeDisplay.ForSymbol(convertedType, NullableAnnotation.Annotated, NullableContext.Enabled); return ParenthesizedExpression( ConditionalExpression( diff --git a/tests/AlephMapper.IntegrationTests/Models.cs b/tests/AlephMapper.IntegrationTests/Models.cs index b03d9b4..139a6e4 100644 --- a/tests/AlephMapper.IntegrationTests/Models.cs +++ b/tests/AlephMapper.IntegrationTests/Models.cs @@ -75,7 +75,7 @@ public class Department public int Id { get; set; } [Required] - public string Name { get; set; } = ""; + public string? Name { get; set; } = ""; public string? Description { get; set; } diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs index 6c58133..ac81fb5 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs @@ -30,10 +30,10 @@ public static Expression> GetPersonComplexExpress : (int?)null), BirthPlace = (p.BirthInfo != null ? (p.BirthInfo.BirthPlace) - : (string)null) ?? "Unknown", + : (string?)null) ?? "Unknown", BirthAddress = (p.BirthInfo != null ? (p.BirthInfo.Address) - : (string)null) ?? "Not specified", + : (string?)null) ?? "Not specified", HasBirthInfo = p.BirthInfo != null, IsAdult = (p.BirthInfo != null ? (p.BirthInfo.Age) @@ -112,7 +112,7 @@ public static Expression> IsOlderThan30Expression() => public static Expression> GetBirthPlaceExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.BirthPlace) - : (string)null) ?? "Unknown"; + : (string?)null) ?? "Unknown"; /// /// This is an auto-generated expression companion for . @@ -125,7 +125,7 @@ public static Expression> GetBirthPlaceExpression() => public static Expression> GetBirthAddressExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.Address) - : (string)null) ?? "Not specified"; + : (string?)null) ?? "Not specified"; /// /// This is an auto-generated expression companion for . @@ -162,7 +162,7 @@ public static Expression> IsAdultExpression() => public static Expression> BornInUkraineExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.Address) - : (string)null) != null && person.BirthInfo.Address.Contains("Ukraine"); + : (string?)null) != null && person.BirthInfo.Address.Contains("Ukraine"); /// /// This is an auto-generated expression companion for . @@ -245,7 +245,7 @@ public static Expression> GetPersonSummaryExpression() => public static Expression> LivesInSamePlaceAsBornExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.BirthPlace) - : (string)null) != null + : (string?)null) != null && person.Addresses.Any(a => a.IsActive && a.City == person.BirthInfo.BirthPlace); /// diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs index 57e0722..193135b 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs @@ -26,6 +26,6 @@ public static Expression> ToDtoExpression() => Name = person.Name, FavoritePrice = (person.FavoriteProduct != null ? ("$" + person.FavoriteProduct.Price) - : (string)null) + : (string?)null) }; } diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs index c8837d7..0db20ba 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs @@ -31,8 +31,8 @@ public static Expression> ToDtoExpre Street = p.Friend.HomeAddress.Street, City = p.Friend.HomeAddress.City }) - : (NestedExt_AddressDto)null)) - : (NestedExt_AddressDto)null)) - : (NestedExt_AddressDto)null) + : (NestedExt_AddressDto?)null)) + : (NestedExt_AddressDto?)null)) + : (NestedExt_AddressDto?)null) }; } diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs index 8be6305..2b98706 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs @@ -22,7 +22,7 @@ partial class RewriteMapper public static Expression> GetAddressExpression() => dto => (dto.BirthInfo != null ? (dto.BirthInfo.Address) - : (string)null) ?? "Unknown"; + : (string?)null) ?? "Unknown"; /// /// This is an auto-generated expression companion for . @@ -35,5 +35,5 @@ public static Expression> GetAddressExpression() => public static Expression> HasAddressExpression() => source => (source.BirthInfo != null ? (source.BirthInfo.Address) - : (string)null) != null; + : (string?)null) != null; } diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs index d62083a..f0c4237 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs @@ -23,5 +23,5 @@ partial class NullableDisabledMapper public static Expression> GetNameExpression() => person => (person != null ? (person.Name) - : (string)null); + : (string?)null); } diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs index 47703c2..486b7e2 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs @@ -26,6 +26,6 @@ public static Expression> ToDtoE Name = person.Name, AddressStr = (person.Address != null ? (person.Address.FormattedAddress) - : (string)null) ?? "No Address" + : (string?)null) ?? "No Address" }; } From 40e887c3b0febb67107668cea510cde0b1c4a898 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 07:59:41 +0200 Subject: [PATCH 10/22] feat: support generic projectable and updatable mappings --- source/Adaptation/AdaptationMemberPlanner.cs | 3 +- source/AnalyzerReleases.Unshipped.md | 1 + source/Diagnostics/DiagnosticDescriptors.cs | 8 ++ .../Emitters/AdaptationMemberEmitter.cs | 13 +++ .../Emitters/ProjectableMemberEmitter.cs | 21 +++- .../Emitters/UpdatableMemberEmitter.cs | 6 +- source/Generation/MappingMethodDetails.cs | 55 +++++++++++ source/Generation/MethodSignature.cs | 5 +- .../AlephMapper.Tests/SourceGeneratorTests.cs | 98 +++++++++++++++++++ 9 files changed, 204 insertions(+), 6 deletions(-) diff --git a/source/Adaptation/AdaptationMemberPlanner.cs b/source/Adaptation/AdaptationMemberPlanner.cs index 5cbe9d0..d629725 100644 --- a/source/Adaptation/AdaptationMemberPlanner.cs +++ b/source/Adaptation/AdaptationMemberPlanner.cs @@ -26,7 +26,8 @@ public AdaptationMemberPlanner(INamedTypeSymbol mapperType) .Where(m => m.MethodKind == MethodKind.Ordinary) .Select(m => MethodSignature.Build( m.Name, - m.Parameters.Select(p => TypeDisplay.ForSymbol(p.Type, p.NullableAnnotation, NullableContext.Disabled)))), + m.Parameters.Select(p => TypeDisplay.ForSymbol(p.Type, p.NullableAnnotation, NullableContext.Disabled)), + m.TypeParameters.Length)), StringComparer.Ordinal); _existingNonMethodNames = new HashSet( diff --git a/source/AnalyzerReleases.Unshipped.md b/source/AnalyzerReleases.Unshipped.md index c5de664..bc7d19a 100644 --- a/source/AnalyzerReleases.Unshipped.md +++ b/source/AnalyzerReleases.Unshipped.md @@ -21,3 +21,4 @@ AM0014 | AlephMapper | Error | Adaptation uses an open generic type. AM0015 | AlephMapper | Error | Adapted generated member fails Roslyn rebinding. AM0016 | AlephMapper | Warning | Null-conditional receiver cannot be safely rewritten. AM0017 | AlephMapper | Warning | Null-conditional access is unsupported in expression trees. +AM0018 | AlephMapper | Warning | Adaptation of generic mapping methods is unsupported. diff --git a/source/Diagnostics/DiagnosticDescriptors.cs b/source/Diagnostics/DiagnosticDescriptors.cs index c5e26ec..cf7c667 100644 --- a/source/Diagnostics/DiagnosticDescriptors.cs +++ b/source/Diagnostics/DiagnosticDescriptors.cs @@ -152,4 +152,12 @@ public static class DiagnosticDescriptors DiagnosticSeverity.Warning, isEnabledByDefault: true, description: "Select NullConditionalRewrite.Ignore or NullConditionalRewrite.Rewrite to generate an expression-tree-compatible companion."); + + public static readonly DiagnosticDescriptor AdaptGenericMethodUnsupported = new( + "AM0018", + "Adaptation of generic mapping methods is unsupported", + "Cannot adapt '{0}': Adapt does not support generic mapping methods. Use the generic Projectable or Updatable companion directly.", + "AlephMapper", + DiagnosticSeverity.Warning, + isEnabledByDefault: true); } diff --git a/source/Generation/Emitters/AdaptationMemberEmitter.cs b/source/Generation/Emitters/AdaptationMemberEmitter.cs index 8f8ec00..3b6e524 100644 --- a/source/Generation/Emitters/AdaptationMemberEmitter.cs +++ b/source/Generation/Emitters/AdaptationMemberEmitter.cs @@ -18,6 +18,19 @@ internal static class AdaptationMemberEmitter public static void Emit(MappingMethodDetails details, MapperGenerationContext context) { var mapping = details.Mapping; + if (mapping.MethodSymbol.TypeParameters.Length != 0) + { + foreach (var adaptation in mapping.Adaptations) + { + context.ReportDiagnostic(Diagnostic.Create( + DiagnosticDescriptors.AdaptGenericMethodUnsupported, + GetLocation(mapping, adaptation), + mapping.MethodSymbol.Name)); + } + + return; + } + var adaptationPairs = new HashSet(StringComparer.Ordinal); foreach (var adaptation in mapping.Adaptations) { diff --git a/source/Generation/Emitters/ProjectableMemberEmitter.cs b/source/Generation/Emitters/ProjectableMemberEmitter.cs index 2e221ff..87f2523 100644 --- a/source/Generation/Emitters/ProjectableMemberEmitter.cs +++ b/source/Generation/Emitters/ProjectableMemberEmitter.cs @@ -51,7 +51,10 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co } var expressionMethodName = mapping.Name + "Expression"; - context.GeneratedMemberSignatures.Add(MethodSignature.Build(expressionMethodName, details.ExtraExpressionParameterTypeNames)); + context.GeneratedMemberSignatures.Add(MethodSignature.Build( + expressionMethodName, + details.ExtraExpressionParameterTypeNames, + details.MethodTypeParameterCount)); var nullStrategyDescription = mapping.NullStrategy switch { NullConditionalRewrite.None => "Null-conditional operators are preserved as-is in the expression tree.", @@ -75,7 +78,21 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co members.AppendLine($" /// Null handling strategy: {nullStrategyDescription}"); members.AppendLine(" /// "); members.AppendLine(" /// "); - members.AppendLine(" public static Expression> " + expressionMethodName + expressionMethodParameters + " => "); + var declaration = " public static Expression> " + + expressionMethodName + details.MethodTypeParameterList + expressionMethodParameters; + if (details.MethodConstraintClauses.Count == 0) + { + members.AppendLine(declaration + " => "); + } + else + { + members.AppendLine(declaration); + foreach (var constraintClause in details.MethodConstraintClauses) + { + members.AppendLine(" " + constraintClause); + } + members.AppendLine(" => "); + } members.Append(" " + details.ProjectionLambdaParameter + " => "); members.AppendLine(prettyBody + ";"); }); diff --git a/source/Generation/Emitters/UpdatableMemberEmitter.cs b/source/Generation/Emitters/UpdatableMemberEmitter.cs index 3db3a44..b3da2e6 100644 --- a/source/Generation/Emitters/UpdatableMemberEmitter.cs +++ b/source/Generation/Emitters/UpdatableMemberEmitter.cs @@ -65,7 +65,11 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co } members.AppendLine(" /// The destination object to update. If null, the new instance is created."); members.AppendLine(" /// The updated destination object for method chaining, or the new destination instance if either parameter is null."); - members.AppendLine(" public static " + details.DestinationTypeName + " " + mapping.Name + "(" + details.MethodParameterListWithNames + ", " + details.DestinationTypeName + " dest)"); + members.AppendLine(" public static " + details.DestinationTypeName + " " + mapping.Name + details.MethodTypeParameterList + "(" + details.MethodParameterListWithNames + ", " + details.DestinationTypeName + " dest)"); + foreach (var constraintClause in details.MethodConstraintClauses) + { + members.AppendLine(" " + constraintClause); + } members.AppendLine(" {"); foreach (var line in lines) { diff --git a/source/Generation/MappingMethodDetails.cs b/source/Generation/MappingMethodDetails.cs index f94082b..dbd2dd9 100644 --- a/source/Generation/MappingMethodDetails.cs +++ b/source/Generation/MappingMethodDetails.cs @@ -1,5 +1,8 @@ using AlephMapper.Helpers; using AlephMapper.Models; +using Microsoft.CodeAnalysis; +using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; namespace AlephMapper.Generation; @@ -31,6 +34,11 @@ public MappingMethodDetails(MappingAnalysis mapping) ? mapping.Parameters[0].Name : "(" + string.Join(", ", mapping.Parameters.Select(parameter => parameter.Name)) + ")"; ProjectionLambdaParameter = mapping.Parameters[0].Name; + MethodTypeParameterList = mapping.MethodSymbol.TypeParameters.Length == 0 + ? string.Empty + : "<" + string.Join(", ", mapping.MethodSymbol.TypeParameters.Select(static parameter => parameter.Name)) + ">"; + MethodTypeParameterCount = mapping.MethodSymbol.TypeParameters.Length; + MethodConstraintClauses = BuildConstraintClauses(mapping.MethodSymbol.TypeParameters, nullableContext); NullableContext = nullableContext; } @@ -45,5 +53,52 @@ public MappingMethodDetails(MappingAnalysis mapping) public string ExtraExpressionParameterListWithNames { get; } public string LambdaParameters { get; } public string ProjectionLambdaParameter { get; } + public string MethodTypeParameterList { get; } + public int MethodTypeParameterCount { get; } + public IReadOnlyList MethodConstraintClauses { get; } public Microsoft.CodeAnalysis.NullableContext NullableContext { get; } + + private static IReadOnlyList BuildConstraintClauses( + ImmutableArray typeParameters, + NullableContext nullableContext) + { + var clauses = new List(); + foreach (var typeParameter in typeParameters) + { + var constraints = new List(); + if (typeParameter.HasUnmanagedTypeConstraint) + { + constraints.Add("unmanaged"); + } + else if (typeParameter.HasValueTypeConstraint) + { + constraints.Add("struct"); + } + else if (typeParameter.HasReferenceTypeConstraint) + { + constraints.Add(typeParameter.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated + ? "class?" + : "class"); + } + else if (typeParameter.HasNotNullConstraint) + { + constraints.Add("notnull"); + } + + constraints.AddRange(typeParameter.ConstraintTypes.Select(type => + TypeDisplay.ForSymbol(type, type.NullableAnnotation, nullableContext))); + + if (typeParameter.HasConstructorConstraint && !typeParameter.HasValueTypeConstraint) + { + constraints.Add("new()"); + } + + if (constraints.Count > 0) + { + clauses.Add($"where {typeParameter.Name} : {string.Join(", ", constraints)}"); + } + } + + return clauses; + } } diff --git a/source/Generation/MethodSignature.cs b/source/Generation/MethodSignature.cs index 9a99ac0..135539f 100644 --- a/source/Generation/MethodSignature.cs +++ b/source/Generation/MethodSignature.cs @@ -6,9 +6,10 @@ namespace AlephMapper.Generation; internal static class MethodSignature { - public static string Build(string name, IEnumerable parameterTypeNames) + public static string Build(string name, IEnumerable parameterTypeNames, int typeParameterCount = 0) { - return name + "(" + string.Join(",", parameterTypeNames.Select(RemoveNullableMarker)) + ")"; + return name + (typeParameterCount == 0 ? string.Empty : "`" + typeParameterCount) + + "(" + string.Join(",", parameterTypeNames.Select(RemoveNullableMarker)) + ")"; } private static string RemoveNullableMarker(string typeName) diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index f343fcc..5a9501d 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -261,6 +261,104 @@ public static partial class MapperB await Assert.That(candidateOutputs.All(static output => output.Item2 == IncrementalStepRunReason.Unchanged)).IsTrue(); } + [Test] + public async Task GenericMethodsGenerateProjectableAndUpdatableCompanions() + { + const string source = """ + #nullable enable + using AlephMapper; + + namespace Fixture; + + public interface ISource + { + string Name { get; } + } + + public interface IDestination + { + string Name { get; set; } + } + + public static partial class Mapper + { + [Projectable] + [Updatable] + public static TResult Map(TSource source) + where TSource : ISource + where TResult : IDestination, new() => new() + { + Name = source.Name + }; + } + """; + + var generatedSources = await AssertAdaptedOutputCompiles(source, "GenericMethodMappings"); + var generatedSource = generatedSources.Single(sourceText => sourceText.Contains("MapExpression")); + + await Assert.That(generatedSource).Contains("MapExpression()"); + await Assert.That(generatedSource).Contains("Map(TSource source, TResult dest)"); + await Assert.That(generatedSource).Contains("where TSource : ISource"); + await Assert.That(generatedSource).Contains("where TResult : IDestination, new()"); + } + + [Test] + public async Task GenericMethodsDoNotGenerateAdaptedCompanions() + { + const string source = """ + using AlephMapper; + + namespace Fixture; + + public interface ISource + { + string Name { get; } + } + + public interface IDestination + { + string Name { get; set; } + } + + public sealed class AdaptedSource : ISource + { + public string Name { get; set; } = string.Empty; + } + + public sealed class AdaptedDestination : IDestination + { + public string Name { get; set; } = string.Empty; + } + + public static partial class Mapper + { + [Adapt(typeof(AdaptedSource), typeof(AdaptedDestination), Name = "MapAdapted")] + public static TResult Map(TSource source) + where TSource : ISource + where TResult : IDestination, new() => new() + { + Name = source.Name + }; + } + """; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var compilation = CSharpCompilation.Create( + "GenericAdaptation", + [CSharpSyntaxTree.ParseText(source, _parseOptions)], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var driver = _driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out _); + var result = driver.GetRunResult().Results.Single(); + + await Assert.That(result.Diagnostics.Any(diagnostic => diagnostic.Id == "AM0018")).IsTrue(); + await Assert.That(result.GeneratedSources.Any(generated => + generated.SourceText.ToString().Contains("MapAdapted", StringComparison.Ordinal))).IsFalse(); + await Assert.That(outputCompilation.GetDiagnostics() + .Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + } + [Test] public async Task LargeCompilationDiscoversOnlyAttributedMappers() { From eafc16719e0efdca0a6b11f77cb1eace312802e2 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 08:11:57 +0200 Subject: [PATCH 11/22] ci: add NuGet package build workflow --- .github/workflows/build-nuget.yml | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/build-nuget.yml diff --git a/.github/workflows/build-nuget.yml b/.github/workflows/build-nuget.yml new file mode 100644 index 0000000..748793c --- /dev/null +++ b/.github/workflows/build-nuget.yml @@ -0,0 +1,43 @@ +name: Build NuGet package + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Restore dependencies + run: dotnet restore AlephMapper.slnx + + - name: Build solution + run: dotnet build AlephMapper.slnx --configuration Release --no-restore -p:GeneratePackageOnBuild=false + + - name: Run tests + run: dotnet test AlephMapper.slnx --configuration Release --no-build --no-restore + + - name: Pack NuGet package + run: dotnet pack source/AlephMapper.csproj --configuration Release --no-build --no-restore --output artifacts/nuget + + - name: Upload NuGet package + uses: actions/upload-artifact@v4 + with: + name: AlephMapper-nuget + path: artifacts/nuget/*.nupkg + if-no-files-found: error From a2b569edcca3dbf4822a1e4b1d3757d63af4792a Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 08:41:08 +0200 Subject: [PATCH 12/22] build: harden generator validation and NuGet CI --- .github/workflows/build-nuget.yml | 69 +++++++++++++++++-- global.json | 7 +- source/AlephMapper.csproj | 5 +- source/Generation/MapperSourceOutput.cs | 10 ++- source/VersionInfo.cs | 9 ++- .../Tests_PersonMapper_GeneratedMappings.g.cs | 2 +- .../Tests_PersonMapper_GeneratedMappings.g.cs | 2 +- ...s_AdaptUpdateMapper_GeneratedMappings.g.cs | 2 +- ...ests_CircularMapper_GeneratedMappings.g.cs | 2 +- ...cularPropertyMapper_GeneratedMappings.g.cs | 2 +- ...ts_CollectionMapper_GeneratedMappings.g.cs | 2 +- ...tionalPatternMapper_GeneratedMappings.g.cs | 2 +- ..._EfCoreIgnoreMapper_GeneratedMappings.g.cs | 2 +- ..._Tests_EfCoreMapper_GeneratedMappings.g.cs | 2 +- .../Tests_SampleMapper_GeneratedMappings.g.cs | 2 +- ...ionTestPersonMapper_GeneratedMappings.g.cs | 2 +- ...onTestAddressMapper_GeneratedMappings.g.cs | 2 +- ...ionTestPersonMapper_GeneratedMappings.g.cs | 2 +- ...Mapper_Tests_Mapper_GeneratedMappings.g.cs | 2 +- ..._SimpleObjectMapper_GeneratedMappings.g.cs | 2 +- ...tyList_PersonMapper_GeneratedMappings.g.cs | 2 +- ...ProductMapperIgnore_GeneratedMappings.g.cs | 2 +- ...roductMapperRewrite_GeneratedMappings.g.cs | 2 +- ...ining_ProductMapper_GeneratedMappings.g.cs | 2 +- ...amProjectableMapper_GeneratedMappings.g.cs | 2 +- ...ning_NamedArgMapper_GeneratedMappings.g.cs | 2 +- ...tedMultiParamMapper_GeneratedMappings.g.cs | 2 +- ...lining_PersonMapper_GeneratedMappings.g.cs | 2 +- ...bleMultiParamMapper_GeneratedMappings.g.cs | 2 +- ...edExt_AddressMapper_GeneratedMappings.g.cs | 2 +- ...PersonMapper_Ignore_GeneratedMappings.g.cs | 2 +- ...ersonMapper_Rewrite_GeneratedMappings.g.cs | 2 +- ...lueAssignmentMapper_GeneratedMappings.g.cs | 2 +- ..._Tests_IgnoreMapper_GeneratedMappings.g.cs | 2 +- ...er_Tests_NoneMapper_GeneratedMappings.g.cs | 2 +- ...Tests_RewriteMapper_GeneratedMappings.g.cs | 2 +- ...lableDisabledMapper_GeneratedMappings.g.cs | 2 +- ...llableEnabledMapper_GeneratedMappings.g.cs | 2 +- ...chDebtAddressMapper_GeneratedMappings.g.cs | 2 +- ...tPersonMapperIgnore_GeneratedMappings.g.cs | 2 +- ...ebtPersonMapperNone_GeneratedMappings.g.cs | 2 +- ...PersonMapperRewrite_GeneratedMappings.g.cs | 2 +- ...ests_Address1Mapper_GeneratedMappings.g.cs | 2 +- ...s_AddressLineMapper_GeneratedMappings.g.cs | 2 +- ...ts_TestModel1Mapper_GeneratedMappings.g.cs | 2 +- .../Tests_SampleMapper_GeneratedMappings.g.cs | 2 +- ...mplexPropertyMapper_GeneratedMappings.g.cs | 2 +- ...plexValueTypeMapper_GeneratedMappings.g.cs | 2 +- ...ests_EdgeCaseMapper_GeneratedMappings.g.cs | 2 +- ...sts_MixedTypeMapper_GeneratedMappings.g.cs | 2 +- ...ableValueTypeMapper_GeneratedMappings.g.cs | 2 +- ...renceTypeOnlyMapper_GeneratedMappings.g.cs | 2 +- ...ueToReferenceMapper_GeneratedMappings.g.cs | 2 +- ...ueToReferenceMapper_GeneratedMappings.g.cs | 2 +- ...sts_ValueTypeMapper_GeneratedMappings.g.cs | 2 +- ...ValueTypeOnlyMapper_GeneratedMappings.g.cs | 2 +- .../AlephMapper.Tests/SourceGeneratorTests.cs | 16 ++++- 57 files changed, 154 insertions(+), 64 deletions(-) diff --git a/.github/workflows/build-nuget.yml b/.github/workflows/build-nuget.yml index 748793c..fff42b3 100644 --- a/.github/workflows/build-nuget.yml +++ b/.github/workflows/build-nuget.yml @@ -21,19 +21,80 @@ jobs: - name: Set up .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 10.0.x + dotnet-version: 10.0.400 + + - name: Cache NuGet packages + uses: actions/cache@v4 + with: + path: ~/.nuget/packages + key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', 'global.json') }} + restore-keys: | + ${{ runner.os }}-nuget- - name: Restore dependencies run: dotnet restore AlephMapper.slnx - name: Build solution - run: dotnet build AlephMapper.slnx --configuration Release --no-restore -p:GeneratePackageOnBuild=false + run: dotnet build AlephMapper.slnx --configuration Release --no-restore - name: Run tests - run: dotnet test AlephMapper.slnx --configuration Release --no-build --no-restore + run: dotnet test AlephMapper.slnx --configuration Release --no-build --no-restore -- --report-trx --results-directory artifacts/test-results + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results + path: artifacts/test-results + if-no-files-found: warn - name: Pack NuGet package - run: dotnet pack source/AlephMapper.csproj --configuration Release --no-build --no-restore --output artifacts/nuget + run: dotnet pack source/AlephMapper.csproj --configuration Release --no-restore -p:BuildNumber=${{ github.run_number }} --output artifacts/nuget + + - name: Verify package consumption + shell: bash + run: | + package_file=$(find artifacts/nuget -name 'AlephMapper.*.nupkg' -print -quit) + package_version=$(basename "$package_file" | sed -E 's/^AlephMapper\.(.*)\.nupkg$/\1/') + mkdir -p artifacts/package-smoke + + cat > artifacts/package-smoke/PackageSmoke.csproj < + + net10.0 + enable + enable + + + + + + EOF + + cat > artifacts/package-smoke/Mapper.cs <<'EOF' + using AlephMapper; + + namespace PackageSmoke; + + public sealed class Source + { + public string Name { get; set; } = string.Empty; + } + + public sealed class Destination + { + public string Name { get; set; } = string.Empty; + } + + public static partial class Mapper + { + [Projectable] + public static Destination Map(Source source) => new() { Name = source.Name }; + } + EOF + + dotnet restore artifacts/package-smoke/PackageSmoke.csproj --source artifacts/nuget + dotnet build artifacts/package-smoke/PackageSmoke.csproj --configuration Release --no-restore - name: Upload NuGet package uses: actions/upload-artifact@v4 diff --git a/global.json b/global.json index 802ab21..786b012 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,10 @@ { + "sdk": { + "version": "10.0.400", + "rollForward": "latestFeature", + "allowPrerelease": false + }, "test": { "runner": "Microsoft.Testing.Platform" } -} \ No newline at end of file +} diff --git a/source/AlephMapper.csproj b/source/AlephMapper.csproj index d73d393..7a10a4c 100644 --- a/source/AlephMapper.csproj +++ b/source/AlephMapper.csproj @@ -6,7 +6,6 @@ Your manual mapping companion. true true - true false true latest @@ -15,6 +14,10 @@ https://github.com/Raffinert/AlephMapper README.md 0.7.0 + 0 + $(PackageVersion) + $(PackageVersion).$(BuildNumber) + $(AssemblyVersion) Mapping Companion git https://github.com/Raffinert/AlephMapper.git diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index d421b11..87ab00b 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -64,16 +64,20 @@ public static MapperGenerationResult Create( method => CreateExternalAnalysis(compilation, method, cancellationToken)); return GenerateMapper(mapperType, mappings, catalog); } +#if DEBUG + catch + { + throw; + } +#else catch (Exception exception) { return new MapperGenerationResult( null, null, [CrashDiagnosticsReporter.CreateDiagnostic(exception)]); -#if DEBUG - throw; -#endif } +#endif } public static void Emit(SourceProductionContext context, MapperGenerationResult result) diff --git a/source/VersionInfo.cs b/source/VersionInfo.cs index 7991f57..b9628fb 100644 --- a/source/VersionInfo.cs +++ b/source/VersionInfo.cs @@ -2,5 +2,12 @@ internal static class VersionInfo { - public static string Version => "0.7.0"; + public static string Version { get; } = + System.Reflection.CustomAttributeExtensions + .GetCustomAttribute(typeof(VersionInfo).Assembly) + ?.InformationalVersion + ?.Split('+')[0] + is { } informationalVersion + ? $"{informationalVersion}.{typeof(VersionInfo).Assembly.GetName().Version?.Revision ?? 0}" + : typeof(VersionInfo).Assembly.GetName().Version?.ToString() ?? "unknown"; } diff --git a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index 6d4a8e6..092624f 100644 --- a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index 11b2690..8d622ec 100644 --- a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs index da2c667..13a1df0 100644 --- a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class AdaptUpdateMapper { /// diff --git a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs index 4c043ec..3cc9d43 100644 --- a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class CircularMapper { /// diff --git a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs index d8c7f9b..ebc6b5f 100644 --- a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class CircularPropertyMapper { /// diff --git a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs index 51cda79..ecdebc8 100644 --- a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class CollectionMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs index a584fcb..7885e3b 100644 --- a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ConditionalPatternMapper { /// diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs index 0d401c5..9a57d6a 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class EfCoreIgnoreMapper { /// diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs index ac81fb5..d3052db 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class EfCoreMapper { /// diff --git a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index c60cd81..a0840c8 100644 --- a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class SampleMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs index adbf96e..3dc2743 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ConditionalExtensionTestPersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs index f7206f3..c3bf1b8 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ExtensionTestAddressMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs index 93b8ea2..e68d4d4 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ExtensionTestPersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs index c1edf08..a97aecf 100644 --- a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class Mapper { /// diff --git a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs index 8c7fc4a..cff4ee1 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class SimpleObjectMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs index 0fd80a4..d950897 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs @@ -10,7 +10,7 @@ namespace AlephMapper.Tests.MethodGroupToEntityList; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs index c255316..6127a1e 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParamExtensionInlining; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonProductMapperIgnore { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs index 193135b..c3c60e6 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParamExtensionInlining; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonProductMapperRewrite { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs index 41fd8b2..3e1545d 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParamExtensionInlining; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ProductMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs index 732c204..019450d 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class MultiParamProjectableMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs index ef48e00..681745a 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NamedArgMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs index d28da7b..f4ecbe3 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedMultiParamMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs index 3afc6d5..ac92ebe 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { /// diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs index d5a438a..4128fd5 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class UpdatableMultiParamMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs index 98c5364..eaf9901 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedExt_AddressMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs index 9e0aced..9e7a8f3 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedExt_PersonMapper_Ignore { /// diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs index 0db20ba..738b74e 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedExt_PersonMapper_Rewrite { /// diff --git a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs index 4d00ce4..9bbc05a 100644 --- a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs @@ -10,7 +10,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullCoalesceValueAssignmentMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs index c6eebde..f0b6345 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class IgnoreMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs index 671fa40..9226078 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NoneMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs index 2b98706..dad96cb 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class RewriteMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs index f0c4237..fd01b37 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullableDisabledMapper { /// diff --git a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs index deb64f5..4a91816 100644 --- a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullableEnabledMapper { /// diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs index 4d99447..c4ecec8 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtAddressMapper { /// diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs index 3d9eaf1..cf5c37f 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtPersonMapperIgnore { /// diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs index cf4d5cc..132a838 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtPersonMapperNone { } diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs index 486b7e2..ab7c308 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtPersonMapperRewrite { /// diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs index 197dcaa..a4337ea 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class Address1Mapper { /// diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs index 10f4c09..8d95e1b 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class AddressLineMapper { /// diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs index d9cd4c5..d60d9cf 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class TestModel1Mapper { /// diff --git a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index e3922da..1220e2d 100644 --- a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class SampleMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs index cabd626..06144a4 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ComplexPropertyMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs index 8da8c32..e466627 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ComplexValueTypeMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs index 2b58cff..7780fe1 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class EdgeCaseMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs index ce04484..f45f12a 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class MixedTypeMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs index c79bc96..99f18ce 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullableValueTypeMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs index 6f208ff..507075f 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ReferenceTypeOnlyMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs index ced76f7..ed5d144 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class SimpleValueToReferenceMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs index 7fb18f0..547e4ec 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ValueToReferenceMapper { /// diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs index 08d44d0..dceac06 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ValueTypeMapper { } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs index 4375889..e0853fc 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs @@ -8,7 +8,7 @@ namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0")] +[GeneratedCode("AlephMapper", "0.7.0.0")] partial class ValueTypeOnlyMapper { /// diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index 5a9501d..68ee47a 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -463,7 +463,11 @@ public async Task GenerationMatchesBaseLine(string name, string[] sourceFiles, s var syntaxTrees = sourceTrees.Append(globalUsings).ToArray(); var references = (await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None)) - .Add(MetadataReference.CreateFromFile(typeof(DbContext).Assembly.Location)); + .Add(MetadataReference.CreateFromFile(typeof(DbContext).Assembly.Location)) + .Add(MetadataReference.CreateFromFile(Path.Combine(AppContext.BaseDirectory, "AgileObjects.NetStandardPolyfills.dll"))) + .Add(MetadataReference.CreateFromFile(Path.Combine(AppContext.BaseDirectory, "AgileObjects.ReadableExpressions.dll"))) + .Add(MetadataReference.CreateFromFile(Path.Combine(AppContext.BaseDirectory, "TUnit.Assertions.dll"))) + .Add(MetadataReference.CreateFromFile(Path.Combine(AppContext.BaseDirectory, "TUnit.Core.dll"))); var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); @@ -473,11 +477,17 @@ public async Task GenerationMatchesBaseLine(string name, string[] sourceFiles, s references, compilationOptions); - var driver = _driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out var generatorDiagnostics); + var driver = _driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var generatorDiagnostics); await Assert.That(generatorDiagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); - var result = driver.GetRunResult().Results.Single(); + var generatedSyntaxTrees = outputCompilation.SyntaxTrees + .Where(tree => !syntaxTrees.Contains(tree)) + .ToHashSet(); + await Assert.That(outputCompilation.GetDiagnostics() + .Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error && + diagnostic.Location.SourceTree is { } sourceTree && + generatedSyntaxTrees.Contains(sourceTree))).IsEmpty(); var actualSources = result.GeneratedSources.ToDictionary( source => Path.GetFileName(source.HintName), From da7fd92ce8521a58ac17f81d6d48272653e431f6 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 09:13:43 +0200 Subject: [PATCH 13/22] fix: eliminate nullable warnings across generated mappings --- examples/SampleApp/Mappers/PersonMapper.cs | 4 ++-- source/Generation/MappingMethodDetails.cs | 4 ++-- tests/AlephMapper.IntegrationTests/SimpleMappers.cs | 6 +++--- .../AlephMapper.IntegrationTests/UpdatableMappers.cs | 12 ++++++------ tests/AlephMapper.IntegrationTests/UpdatableTests.cs | 10 +++++----- tests/Experiments/ExtensionMethodInliningTests.cs | 12 ++++++------ 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/examples/SampleApp/Mappers/PersonMapper.cs b/examples/SampleApp/Mappers/PersonMapper.cs index 9d1e478..e0d44b9 100644 --- a/examples/SampleApp/Mappers/PersonMapper.cs +++ b/examples/SampleApp/Mappers/PersonMapper.cs @@ -9,7 +9,7 @@ public static partial class PersonMapper // Main entity to DTO mapping with expression-bodied syntax [Projectable] [Updatable(CollectionProperties = CollectionPropertiesPolicy.Skip)] - public static PersonDto ToDto(Person entity) => entity == null ? null : new() + public static PersonDto ToDto(Person entity) => entity == null ? null! : new() { Id = entity.PersonId, FirstName = entity.FirstName, @@ -62,4 +62,4 @@ private static void UpdateEntity(Person entity, string firstName, string lastNam entity.EmailAddress = email; entity.BirthDate = birthDate; } -} \ No newline at end of file +} diff --git a/source/Generation/MappingMethodDetails.cs b/source/Generation/MappingMethodDetails.cs index dbd2dd9..094bcc0 100644 --- a/source/Generation/MappingMethodDetails.cs +++ b/source/Generation/MappingMethodDetails.cs @@ -21,8 +21,8 @@ public MappingMethodDetails(MappingAnalysis mapping) ParameterTypeNames = mapping.Parameters .Select(parameter => TypeDisplay.ForSymbol(parameter.Type, parameter.NullableAnnotation, nullableContext)) .ToArray(); - DestinationTypeName = TypeDisplay.ForSymbol(mapping.ReturnType, mapping.MethodSymbol.ReturnNullableAnnotation, nullableContext); - SourceTypeName = TypeDisplay.ForSymbol(mapping.ParamType, mapping.Parameters[0].NullableAnnotation, nullableContext); + DestinationTypeName = TypeDisplay.ForSymbol(mapping.ReturnType, mapping.ReturnType.NullableAnnotation, nullableContext); + SourceTypeName = TypeDisplay.ForSymbol(mapping.ParamType, mapping.ParamType.NullableAnnotation, nullableContext); SourceName = mapping.Parameters[0].Name; MethodParameterList = string.Join(", ", ParameterTypeNames); MethodParameterListWithNames = string.Join(", ", mapping.Parameters.Select(parameter => diff --git a/tests/AlephMapper.IntegrationTests/SimpleMappers.cs b/tests/AlephMapper.IntegrationTests/SimpleMappers.cs index 05446c3..d76ba20 100644 --- a/tests/AlephMapper.IntegrationTests/SimpleMappers.cs +++ b/tests/AlephMapper.IntegrationTests/SimpleMappers.cs @@ -48,7 +48,7 @@ public static string GetFullName(Employee employee) => $"{employee.FirstName} {employee.LastName}"; public static string GetDepartmentName(Employee employee) => - employee.Department?.Name ?? "No Department"; + employee.Department!.Name ?? "No Department"; public static EmployeeSimpleDto MapToSimpleDto(Employee employee) => new() { @@ -75,8 +75,8 @@ public static partial class SimpleUpdateMapper public static DepartmentUpdateDto MapToDepartmentDto(Department department) => new() { Id = department.Id, - Name = department.Name, + Name = department.Name ?? "", Description = department.Description, IsActive = department.IsActive }; -} \ No newline at end of file +} diff --git a/tests/AlephMapper.IntegrationTests/UpdatableMappers.cs b/tests/AlephMapper.IntegrationTests/UpdatableMappers.cs index 5169355..3295f4e 100644 --- a/tests/AlephMapper.IntegrationTests/UpdatableMappers.cs +++ b/tests/AlephMapper.IntegrationTests/UpdatableMappers.cs @@ -6,7 +6,7 @@ public static partial class ConditionalUpdateMapper { // This method mimics the PersonMapper pattern: source == null ? null : new TargetType { ... } public static EmployeeSimpleDto ConditionalMapping(Employee? employee) => - employee == null ? null : new EmployeeSimpleDto + employee == null ? null! : new EmployeeSimpleDto { Id = employee.Id, FirstName = employee.FirstName, @@ -20,10 +20,10 @@ public static DepartmentUpdateDto ConditionalDepartmentMapping(Department? depar department != null ? new DepartmentUpdateDto { Id = department.Id, - Name = department.Name, + Name = department.Name ?? "", Description = department.Description, IsActive = department.IsActive - } : null; + } : null!; } // Mappers testing Updatable functionality @@ -56,7 +56,7 @@ public static partial class EmployeeUpdateMapper public static DepartmentUpdateDto UpdateDepartment(Department department) => new DepartmentUpdateDto { Id = department.Id, - Name = department.Name, + Name = department.Name ?? "", Description = department.Description, IsActive = department.IsActive }; @@ -197,7 +197,7 @@ public static string GetDepartmentName(Employee employee) => Department = employee.Department != null ? new DepartmentUpdateDto { Id = employee.Department.Id, - Name = employee.Department.Name, + Name = employee.Department.Name ?? "", Description = employee.Department.Description, IsActive = employee.Department.IsActive } : null @@ -229,4 +229,4 @@ public static string GetDepartmentName(Employee employee) => IsActive = dto.Department.IsActive } : null }; -} \ No newline at end of file +} diff --git a/tests/AlephMapper.IntegrationTests/UpdatableTests.cs b/tests/AlephMapper.IntegrationTests/UpdatableTests.cs index 32a935f..4a24501 100644 --- a/tests/AlephMapper.IntegrationTests/UpdatableTests.cs +++ b/tests/AlephMapper.IntegrationTests/UpdatableTests.cs @@ -468,7 +468,7 @@ public async Task Conditional_Expression_Update_Should_Work_With_Null_Check() }; // Act - var result = ConditionalUpdateMapper.ConditionalMapping(sourceEmployee, targetDto); + var result = ConditionalUpdateMapper.ConditionalMapping(sourceEmployee!, targetDto); // Assert await Assert.That(result).IsSameReferenceAs(targetDto); @@ -493,7 +493,7 @@ public async Task Conditional_Expression_Update_Should_Handle_Null_Source() }; // Act - var result = ConditionalUpdateMapper.ConditionalMapping(sourceEmployee, targetDto); + var result = ConditionalUpdateMapper.ConditionalMapping(sourceEmployee!, targetDto); // Assert - When source is null, target should remain unchanged await Assert.That(result).IsSameReferenceAs(targetDto); @@ -523,7 +523,7 @@ public async Task Conditional_Expression_Update_Should_Work_With_Inverted_Condit }; // Act - var result = ConditionalUpdateMapper.ConditionalDepartmentMapping(sourceDepartment, targetDto); + var result = ConditionalUpdateMapper.ConditionalDepartmentMapping(sourceDepartment!, targetDto); // Assert await Assert.That(result).IsSameReferenceAs(targetDto); @@ -546,7 +546,7 @@ public async Task Conditional_Expression_Update_Should_Handle_Null_Source_Invert }; // Act - var result = ConditionalUpdateMapper.ConditionalDepartmentMapping(sourceDepartment, targetDto); + var result = ConditionalUpdateMapper.ConditionalDepartmentMapping(sourceDepartment!, targetDto); // Assert - When source is null, target should remain unchanged await Assert.That(result).IsSameReferenceAs(targetDto); @@ -628,4 +628,4 @@ public async Task Update_Should_Preserve_Collections_If_Present() } #endregion -} \ No newline at end of file +} diff --git a/tests/Experiments/ExtensionMethodInliningTests.cs b/tests/Experiments/ExtensionMethodInliningTests.cs index 4f3b652..c764dc4 100644 --- a/tests/Experiments/ExtensionMethodInliningTests.cs +++ b/tests/Experiments/ExtensionMethodInliningTests.cs @@ -59,8 +59,8 @@ public static partial class ConditionalExtensionTestPersonMapper [Updatable] public static ExtensionTestPersonDto ToDto(ExtensionTestPerson person) => new() { - Name = person?.Name, - Addresses = person?.Addresses.Select(ExtensionTestAddressMapper.ToDto).ToList(), + Name = person.Name, + Addresses = person?.Addresses?.Select(ExtensionTestAddressMapper.ToDto).ToList(), HomeAddress = person?.HomeAddress?.ToDto(), MyProperty = person?.MyProperty ?? 0 }; @@ -68,9 +68,9 @@ public static partial class ConditionalExtensionTestPersonMapper [Projectable(NullConditionalRewrite = NullConditionalRewrite.Ignore)] public static ExtensionTestPersonDto ToDto1(ExtensionTestPerson person) => new() { - Name = person?.Name, - Addresses = person?.Addresses?.Select(a => a.ToDto()).ToList(), - HomeAddress = person?.HomeAddress.ToDto(), + Name = person.Name, + Addresses = person.Addresses!.Select(a => a.ToDto()).ToList(), + HomeAddress = person.HomeAddress!.ToDto(), MyProperty = person?.MyProperty ?? 0 }; } @@ -101,4 +101,4 @@ public async Task ConditionalAccessExtensionMethodShouldBeInlined() Console.WriteLine("Generated Expression (Conditional Access):"); Console.WriteLine(readable); } -} \ No newline at end of file +} From 5ccde31ec7f59793e4ae3f9535e73494da03c95d Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 09:48:33 +0200 Subject: [PATCH 14/22] fix: fully qualify type references in generated code --- .../Adaptation/AdaptedDestinationRewriter.cs | 7 +- .../UpdatableMethodGenerator.cs | 23 +++--- .../Emitters/AdaptationMemberEmitter.cs | 2 +- .../Emitters/ProjectableMemberEmitter.cs | 4 +- source/Generation/MapperFileEmitter.cs | 5 +- source/Helpers/TypeDisplay.cs | 10 ++- ...ngResolver.CollectionExpressionRewriter.cs | 56 ++++--------- ...Resolver.ImplicitObjectCreationRewriter.cs | 21 ++++- .../Tests_PersonMapper_GeneratedMappings.g.cs | 15 ++-- .../Tests_PersonMapper_GeneratedMappings.g.cs | 27 +++---- ...s_AdaptUpdateMapper_GeneratedMappings.g.cs | 15 ++-- ...ests_CircularMapper_GeneratedMappings.g.cs | 19 +++-- ...cularPropertyMapper_GeneratedMappings.g.cs | 23 +++--- ...ts_CollectionMapper_GeneratedMappings.g.cs | 35 ++++---- ...tionalPatternMapper_GeneratedMappings.g.cs | 59 +++++++------- ..._EfCoreIgnoreMapper_GeneratedMappings.g.cs | 19 +++-- ..._Tests_EfCoreMapper_GeneratedMappings.g.cs | 81 +++++++++---------- .../Tests_SampleMapper_GeneratedMappings.g.cs | 7 +- ...ionTestPersonMapper_GeneratedMappings.g.cs | 11 ++- ...onTestAddressMapper_GeneratedMappings.g.cs | 9 +-- ...ionTestPersonMapper_GeneratedMappings.g.cs | 11 ++- ...Mapper_Tests_Mapper_GeneratedMappings.g.cs | 57 +++++++------ ..._SimpleObjectMapper_GeneratedMappings.g.cs | 11 ++- ...tyList_PersonMapper_GeneratedMappings.g.cs | 9 +-- ...ProductMapperIgnore_GeneratedMappings.g.cs | 9 +-- ...roductMapperRewrite_GeneratedMappings.g.cs | 9 +-- ...ining_ProductMapper_GeneratedMappings.g.cs | 9 +-- ...amProjectableMapper_GeneratedMappings.g.cs | 9 +-- ...ning_NamedArgMapper_GeneratedMappings.g.cs | 9 +-- ...tedMultiParamMapper_GeneratedMappings.g.cs | 9 +-- ...lining_PersonMapper_GeneratedMappings.g.cs | 9 +-- ...bleMultiParamMapper_GeneratedMappings.g.cs | 15 ++-- ...edExt_AddressMapper_GeneratedMappings.g.cs | 9 +-- ...PersonMapper_Ignore_GeneratedMappings.g.cs | 11 ++- ...ersonMapper_Rewrite_GeneratedMappings.g.cs | 17 ++-- ...lueAssignmentMapper_GeneratedMappings.g.cs | 9 +-- ..._Tests_IgnoreMapper_GeneratedMappings.g.cs | 11 ++- ...er_Tests_NoneMapper_GeneratedMappings.g.cs | 7 +- ...Tests_RewriteMapper_GeneratedMappings.g.cs | 11 ++- .../NullConditionalRewrite/Sources/Mappers.cs | 4 +- ...lableDisabledMapper_GeneratedMappings.g.cs | 7 +- ...llableEnabledMapper_GeneratedMappings.g.cs | 7 +- ...chDebtAddressMapper_GeneratedMappings.g.cs | 7 +- ...tPersonMapperIgnore_GeneratedMappings.g.cs | 9 +-- ...ebtPersonMapperNone_GeneratedMappings.g.cs | 3 +- ...PersonMapperRewrite_GeneratedMappings.g.cs | 9 +-- ...ests_Address1Mapper_GeneratedMappings.g.cs | 13 ++- ...s_AddressLineMapper_GeneratedMappings.g.cs | 9 +-- ...ts_TestModel1Mapper_GeneratedMappings.g.cs | 27 +++---- .../Tests_SampleMapper_GeneratedMappings.g.cs | 9 +-- ...mplexPropertyMapper_GeneratedMappings.g.cs | 23 +++--- ...plexValueTypeMapper_GeneratedMappings.g.cs | 21 +++-- ...ests_EdgeCaseMapper_GeneratedMappings.g.cs | 23 +++--- ...sts_MixedTypeMapper_GeneratedMappings.g.cs | 19 +++-- ...ableValueTypeMapper_GeneratedMappings.g.cs | 15 ++-- ...renceTypeOnlyMapper_GeneratedMappings.g.cs | 19 +++-- ...ueToReferenceMapper_GeneratedMappings.g.cs | 15 ++-- ...ueToReferenceMapper_GeneratedMappings.g.cs | 39 +++++---- ...sts_ValueTypeMapper_GeneratedMappings.g.cs | 3 +- ...ValueTypeOnlyMapper_GeneratedMappings.g.cs | 15 ++-- .../AlephMapper.Tests/SourceGeneratorTests.cs | 55 +++++++++++-- 61 files changed, 513 insertions(+), 527 deletions(-) diff --git a/source/Adaptation/AdaptedDestinationRewriter.cs b/source/Adaptation/AdaptedDestinationRewriter.cs index 5575afd..eb62565 100644 --- a/source/Adaptation/AdaptedDestinationRewriter.cs +++ b/source/Adaptation/AdaptedDestinationRewriter.cs @@ -290,10 +290,12 @@ private static bool IsAdaptableObjectType(ITypeSymbol type) private static HashSet GetTypeTextCandidates(ITypeSymbol type) { + var fullyQualifiedName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); var candidates = new HashSet(System.StringComparer.Ordinal) { type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), - type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Replace("global::", string.Empty) + fullyQualifiedName, + fullyQualifiedName.Replace("global::", string.Empty) }; if (type is INamedTypeSymbol { TypeArguments.Length: 0 } namedType) @@ -303,7 +305,8 @@ private static HashSet GetTypeTextCandidates(ITypeSymbol type) } candidates.Add(type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat) + "?"); - candidates.Add(type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Replace("global::", string.Empty) + "?"); + candidates.Add(fullyQualifiedName + "?"); + candidates.Add(fullyQualifiedName.Replace("global::", string.Empty) + "?"); return candidates; } diff --git a/source/CodeGenerators/UpdatableMethodGenerator.cs b/source/CodeGenerators/UpdatableMethodGenerator.cs index fe6da7d..47f0f04 100644 --- a/source/CodeGenerators/UpdatableMethodGenerator.cs +++ b/source/CodeGenerators/UpdatableMethodGenerator.cs @@ -12,11 +12,6 @@ internal sealed class UpdatableMethodGenerator(string destPrefix, PropertyMappin private readonly List _lines = []; private readonly string _primarySourceParamName = sourceParamNames.FirstOrDefault() ?? "source"; - private static readonly SymbolDisplayFormat MinimallyQualifiedFormatWithoutNullability = - SymbolDisplayFormat.MinimallyQualifiedFormat.WithMiscellaneousOptions( - SymbolDisplayFormat.MinimallyQualifiedFormat.MiscellaneousOptions - & ~SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier); - public List ProcessObjectCreation(ObjectCreationExpressionSyntax objectCreation) { _lines.Clear(); @@ -26,7 +21,7 @@ public List ProcessObjectCreation(ObjectCreationExpressionSyntax objectC if (typeContext.ShouldPropertyBePreCreated(destPrefix, out var typeInfo)) { _lines.Add($"if ({destPrefix} == null)"); - _lines.Add($" {destPrefix} = new {typeInfo.Type.ToDisplayString(MinimallyQualifiedFormatWithoutNullability)}();"); + _lines.Add($" {destPrefix} = new {GetTypeName(typeInfo.Type)}();"); } foreach (var expr in objectCreation.Initializer.Expressions) @@ -81,7 +76,7 @@ private void ProcessExpression(ExpressionSyntax expression, string fullDestPath) if (typeContext.ShouldPropertyBePreCreated(fullDestPath, out var typeInfo)) { _lines.Add($"if ({fullDestPath} == null)"); - _lines.Add($" {fullDestPath} = new {typeInfo.Type.ToDisplayString(MinimallyQualifiedFormatWithoutNullability)}();"); + _lines.Add($" {fullDestPath} = new {GetTypeName(typeInfo.Type)}();"); } _lines.Add($"{fullDestPath} = {NormalizeConditionalMemberAccess(expression)};"); } @@ -177,7 +172,7 @@ private void ProcessObjectCreationWithIndent(ObjectCreationExpressionSyntax obje if (typeContext.ShouldPropertyBePreCreated(fullDestPath, out var typeInfo)) { _lines.Add($"{indent}if ({fullDestPath} == null)"); - _lines.Add($"{indent} {fullDestPath} = new {typeInfo.Type.ToDisplayString(MinimallyQualifiedFormatWithoutNullability)}();"); + _lines.Add($"{indent} {fullDestPath} = new {GetTypeName(typeInfo.Type)}();"); } // Process nested properties @@ -280,7 +275,7 @@ private void ProcessNestedObjectCreationInBranch(ObjectCreationExpressionSyntax if (typeContext.ShouldPropertyBePreCreated(fullDestPath, out var typeInfo)) { lines.Add($"{indent}if ({fullDestPath} == null)"); - lines.Add($"{indent} {fullDestPath} = new {typeInfo.Type.ToDisplayString(MinimallyQualifiedFormatWithoutNullability)}();"); + lines.Add($"{indent} {fullDestPath} = new {GetTypeName(typeInfo.Type)}();"); } // Process nested properties @@ -312,7 +307,7 @@ private void ProcessNestedObjectCreation(ObjectCreationExpressionSyntax objectCr if (typeContext.ShouldPropertyBePreCreated(fullDestPath, out var typeInfo)) { lines.Add($"{indent}if ({fullDestPath} == null)"); - lines.Add($"{indent} {fullDestPath} = new {typeInfo.Type.ToDisplayString(MinimallyQualifiedFormatWithoutNullability)}();"); + lines.Add($"{indent} {fullDestPath} = new {GetTypeName(typeInfo.Type)}();"); } @@ -354,7 +349,7 @@ private void ProcessDirectObjectCreation(ObjectCreationExpressionSyntax objectCr if (typeContext.ShouldPropertyBePreCreated(fullDestPath, out var typeInfo)) { _lines.Add($"if ({fullDestPath} == null)"); - _lines.Add($" {fullDestPath} = new {typeInfo.Type.ToDisplayString(MinimallyQualifiedFormatWithoutNullability)}();"); + _lines.Add($" {fullDestPath} = new {GetTypeName(typeInfo.Type)}();"); } if (objectCreation.Initializer?.Expressions != null) @@ -412,6 +407,12 @@ private static bool IsNullExpression(ExpressionSyntax expression) return expression?.ToString().Trim() == "null"; } + private static string GetTypeName(ITypeSymbol type) => + AlephMapper.Helpers.TypeDisplay.ForSymbol( + type, + NullableAnnotation.NotAnnotated, + NullableContext.Enabled); + private string NormalizeConditionalMemberAccess(ExpressionSyntax expression) { // Convert shapes like (conditional)?.WhenNotNull.Tail into a textual form that preserves the diff --git a/source/Generation/Emitters/AdaptationMemberEmitter.cs b/source/Generation/Emitters/AdaptationMemberEmitter.cs index 3b6e524..cf5893e 100644 --- a/source/Generation/Emitters/AdaptationMemberEmitter.cs +++ b/source/Generation/Emitters/AdaptationMemberEmitter.cs @@ -254,7 +254,7 @@ private static void EmitExpressionMember( var expressionMethodParameters = string.IsNullOrEmpty(details.ExtraExpressionParameterListWithNames) ? "()" : "(" + details.ExtraExpressionParameterListWithNames + ")"; - members.AppendLine(" public static Expression> " + expressionName + expressionMethodParameters + " => "); + members.AppendLine(" public static global::System.Linq.Expressions.Expression> " + expressionName + expressionMethodParameters + " =>"); members.Append(" " + details.ProjectionLambdaParameter + " => "); members.AppendLine(adaptedBodyText + ";"); }); diff --git a/source/Generation/Emitters/ProjectableMemberEmitter.cs b/source/Generation/Emitters/ProjectableMemberEmitter.cs index 87f2523..cf242df 100644 --- a/source/Generation/Emitters/ProjectableMemberEmitter.cs +++ b/source/Generation/Emitters/ProjectableMemberEmitter.cs @@ -78,11 +78,11 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co members.AppendLine($" /// Null handling strategy: {nullStrategyDescription}"); members.AppendLine(" /// "); members.AppendLine(" /// "); - var declaration = " public static Expression> " + + var declaration = " public static global::System.Linq.Expressions.Expression> " + expressionMethodName + details.MethodTypeParameterList + expressionMethodParameters; if (details.MethodConstraintClauses.Count == 0) { - members.AppendLine(declaration + " => "); + members.AppendLine(declaration + " =>"); } else { diff --git a/source/Generation/MapperFileEmitter.cs b/source/Generation/MapperFileEmitter.cs index 362755e..7502d83 100644 --- a/source/Generation/MapperFileEmitter.cs +++ b/source/Generation/MapperFileEmitter.cs @@ -11,8 +11,7 @@ internal static class MapperFileEmitter [ "System", "System.Linq", - "System.Linq.Expressions", - "System.CodeDom.Compiler" + "System.Linq.Expressions" ]; public static GeneratedMapperFile Render(MapperGenerationContext context) @@ -42,7 +41,7 @@ public static GeneratedMapperFile Render(MapperGenerationContext context) output.AppendLine(); } - output.AppendLine($"[GeneratedCode(\"AlephMapper\", \"{VersionInfo.Version}\")]" ); + output.AppendLine($"[global::System.CodeDom.Compiler.GeneratedCode(\"AlephMapper\", \"{VersionInfo.Version}\")]" ); var containingTypes = GetContainingTypes(mapperType); foreach (var containingType in containingTypes) { diff --git a/source/Helpers/TypeDisplay.cs b/source/Helpers/TypeDisplay.cs index 018f142..6bf1412 100644 --- a/source/Helpers/TypeDisplay.cs +++ b/source/Helpers/TypeDisplay.cs @@ -9,13 +9,13 @@ namespace AlephMapper.Helpers; internal static class TypeDisplay { private static readonly SymbolDisplayFormat NullableFormat = - SymbolDisplayFormat.MinimallyQualifiedFormat.WithMiscellaneousOptions( + SymbolDisplayFormat.FullyQualifiedFormat.WithMiscellaneousOptions( SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier); private static readonly SymbolDisplayFormat NonNullableFormat = - SymbolDisplayFormat.MinimallyQualifiedFormat.WithMiscellaneousOptions( + SymbolDisplayFormat.FullyQualifiedFormat.WithMiscellaneousOptions( SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers); @@ -29,11 +29,13 @@ or NullableContext.AnnotationsEnabled or NullableContext.AnnotationsContextInherited; var format = annotationsEnabled ? NullableFormat : NonNullableFormat; - var display = symbol.ToDisplayString(format); - var effectiveAnnotation = annotationOverride != NullableAnnotation.None ? annotationOverride : symbol.NullableAnnotation; + var displaySymbol = annotationOverride != NullableAnnotation.None + ? symbol.WithNullableAnnotation(annotationOverride) + : symbol; + var display = displaySymbol.ToDisplayString(format); if (annotationsEnabled && effectiveAnnotation == NullableAnnotation.Annotated && diff --git a/source/SyntaxRewriters/InliningResolver.CollectionExpressionRewriter.cs b/source/SyntaxRewriters/InliningResolver.CollectionExpressionRewriter.cs index 61962ae..5fba912 100644 --- a/source/SyntaxRewriters/InliningResolver.CollectionExpressionRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.CollectionExpressionRewriter.cs @@ -235,58 +235,36 @@ private static ExpressionSyntax CreateConstructorExpression(ITypeSymbol? targetT } // Ultimate fallback - create a generic empty list with string type for common scenarios - return ObjectCreationExpression( - GenericName(Identifier("List")) - .WithTypeArgumentList( - TypeArgumentList( - SingletonSeparatedList( - PredefinedType(Token(SyntaxKind.StringKeyword)) - ) - ) - ).WithLeadingTrivia(Space) - ).WithArgumentList(ArgumentList()) - .WithLeadingTrivia(originalExpression.GetLeadingTrivia()) - .WithTrailingTrivia(originalExpression.GetTrailingTrivia()); + return ParseExpression("new global::System.Collections.Generic.List()") + .WithLeadingTrivia(originalExpression.GetLeadingTrivia()) + .WithTrailingTrivia(originalExpression.GetTrailingTrivia()); } private static ExpressionSyntax CreateListConstructor(ITypeSymbol elementType) { - var elementTypeSyntax = IdentifierName(elementType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); - - return ObjectCreationExpression( - GenericName(Identifier("List")) - .WithTypeArgumentList( - TypeArgumentList( - SingletonSeparatedList(elementTypeSyntax) - ) - ) - .WithLeadingTrivia(Space) - ).WithArgumentList(ArgumentList()) - .WithNewKeyword(Token(SyntaxKind.NewKeyword).WithTrailingTrivia(Space)); + var elementTypeName = TypeDisplay.ForSymbol( + elementType, + elementType.NullableAnnotation, + NullableContext.Enabled); + return ParseExpression($"new global::System.Collections.Generic.List<{elementTypeName}>()"); } private static ExpressionSyntax CreateArrayExpression(ITypeSymbol elementType) { // Create Array.Empty() for better performance - var elementTypeSyntax = IdentifierName(elementType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); - - return InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - IdentifierName("Array"), - GenericName(Identifier("Empty")) - .WithTypeArgumentList( - TypeArgumentList( - SingletonSeparatedList(elementTypeSyntax) - ) - ) - ) - ).WithArgumentList(ArgumentList()); + var elementTypeName = TypeDisplay.ForSymbol( + elementType, + elementType.NullableAnnotation, + NullableContext.Enabled); + return ParseExpression($"global::System.Array.Empty<{elementTypeName}>()"); } private static ExpressionSyntax CreateGenericConstructor(INamedTypeSymbol namedType) { - var typeSyntax = IdentifierName(namedType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); + var typeSyntax = ParseTypeName(TypeDisplay.ForSymbol( + namedType, + NullableAnnotation.NotAnnotated, + NullableContext.Enabled)); return ObjectCreationExpression(typeSyntax.WithLeadingTrivia(Space)) .WithArgumentList(ArgumentList()); diff --git a/source/SyntaxRewriters/InliningResolver.ImplicitObjectCreationRewriter.cs b/source/SyntaxRewriters/InliningResolver.ImplicitObjectCreationRewriter.cs index 67d3013..232c58a 100644 --- a/source/SyntaxRewriters/InliningResolver.ImplicitObjectCreationRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.ImplicitObjectCreationRewriter.cs @@ -9,7 +9,16 @@ internal sealed partial class InliningResolver { public override SyntaxNode VisitObjectCreationExpression(ObjectCreationExpressionSyntax node) { - var rewritten = base.VisitObjectCreationExpression(node)!; + var rewritten = (ObjectCreationExpressionSyntax)base.VisitObjectCreationExpression(node)!; + if (model.GetTypeInfo(node).Type is { } typeSymbol) + { + var typeName = AlephMapper.Helpers.TypeDisplay.ForSymbol( + typeSymbol, + NullableAnnotation.NotAnnotated, + model.GetNullableContext(node.SpanStart)); + rewritten = rewritten.WithType(ParseTypeName(typeName).WithTriviaFrom(rewritten.Type)); + } + return IsAnnotatedReturnCreation(node) ? rewritten.WithAdditionalAnnotations(new SyntaxAnnotation(InlinedReturnCreationAnnotation)) : rewritten; @@ -17,14 +26,20 @@ public override SyntaxNode VisitObjectCreationExpression(ObjectCreationExpressio public override SyntaxNode VisitImplicitObjectCreationExpression(ImplicitObjectCreationExpressionSyntax implicitNew) { - var type = model.GetTypeInfo(implicitNew).Type?.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); + var typeSymbol = model.GetTypeInfo(implicitNew).Type; + var type = typeSymbol == null + ? null + : AlephMapper.Helpers.TypeDisplay.ForSymbol( + typeSymbol, + NullableAnnotation.NotAnnotated, + model.GetNullableContext(implicitNew.SpanStart)); if (type == null) { return base.VisitImplicitObjectCreationExpression(implicitNew); } - var objectCreation = ObjectCreationExpression(IdentifierName(type).WithTrailingTrivia(ElasticCarriageReturn)); + var objectCreation = ObjectCreationExpression(ParseTypeName(type).WithTrailingTrivia(ElasticCarriageReturn)); if (implicitNew.Initializer != null) { diff --git a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index 092624f..bf6d888 100644 --- a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -3,20 +3,19 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { /// - /// This is an auto-generated adapted mapping method for . + /// This is an auto-generated adapted mapping method for . /// - public static EmployeeDto MapEmployee(Employee source) => - new EmployeeDto + public static global::Tests.EmployeeDto MapEmployee(global::Tests.Employee source) => + new global::Tests.EmployeeDto { Id = source.Id, Name = source.FirstName + " " + source.LastName, @@ -24,10 +23,10 @@ public static EmployeeDto MapEmployee(Employee source) => }; /// - /// This is an auto-generated adapted expression companion for . + /// This is an auto-generated adapted expression companion for . /// - public static Expression> MapEmployeeExpression() => - source => new EmployeeDto + public static global::System.Linq.Expressions.Expression> MapEmployeeExpression() => + source => new global::Tests.EmployeeDto { Id = source.Id, Name = source.FirstName + " " + source.LastName, diff --git a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index 8d622ec..b3932b2 100644 --- a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -3,27 +3,26 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { /// - /// This is an auto-generated adapted mapping method for . + /// This is an auto-generated adapted mapping method for . /// - public static EmployeeDto MapEmployee(Employee source, bool includeEmail) => + public static global::Tests.EmployeeDto MapEmployee(global::Tests.Employee source, bool includeEmail) => includeEmail - ? new EmployeeDto + ? new global::Tests.EmployeeDto { Id = source.Id, Name = source.FirstName + " " + source.LastName, Email = source.Email } - : new EmployeeDto + : new global::Tests.EmployeeDto { Id = source.Id, Name = source.FirstName + " " + source.LastName, @@ -31,17 +30,17 @@ public static EmployeeDto MapEmployee(Employee source, bool includeEmail) => }; /// - /// This is an auto-generated adapted expression companion for . + /// This is an auto-generated adapted expression companion for . /// - public static Expression> MapEmployeeExpression(bool includeEmail) => + public static global::System.Linq.Expressions.Expression> MapEmployeeExpression(bool includeEmail) => source => includeEmail - ? new EmployeeDto + ? new global::Tests.EmployeeDto { Id = source.Id, Name = source.FirstName + " " + source.LastName, Email = source.Email } - : new EmployeeDto + : new global::Tests.EmployeeDto { Id = source.Id, Name = source.FirstName + " " + source.LastName, @@ -49,14 +48,14 @@ public static Expression> MapEmployeeExpression(bool }; /// - /// This is an auto-generated adapted expression companion for . + /// This is an auto-generated adapted expression companion for . /// - public static Expression> MapEmployeeWithDetailExpression(string userLanguageCode) => - source => new EmployeeWithDetailDto + public static global::System.Linq.Expressions.Expression> MapEmployeeWithDetailExpression(string userLanguageCode) => + source => new global::Tests.EmployeeWithDetailDto { Id = source.Id, Details = source.Details - .Select(detail => new DetailDto + .Select(detail => new global::Tests.DetailDto { Code = detail.Code, Description = detail.Descriptions diff --git a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs index 13a1df0..9fe803f 100644 --- a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs @@ -3,33 +3,32 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class AdaptUpdateMapper { /// - /// This is an auto-generated adapted mapping method for . + /// This is an auto-generated adapted mapping method for . /// - public static Employee MapEmployee(EmployeeUpdateDto source, string prefix) => - new Employee + public static global::Tests.Employee MapEmployee(global::Tests.EmployeeUpdateDto source, string prefix) => + new global::Tests.Employee { Name = prefix + source.Name, Email = source.Email }; /// - /// This is an auto-generated adapted update method for . + /// This is an auto-generated adapted update method for . /// - public static Employee MapEmployee(EmployeeUpdateDto source, string prefix, Employee dest) + public static global::Tests.Employee MapEmployee(global::Tests.EmployeeUpdateDto source, string prefix, global::Tests.Employee dest) { if (source == null) return dest; if (dest == null) - dest = new Employee(); + dest = new global::Tests.Employee(); dest.Name = prefix + source.Name; dest.Email = source.Email; return dest; diff --git a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs index 3cc9d43..595bdee 100644 --- a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs @@ -2,51 +2,50 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class CircularMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ProcessValueExpression() => + public static global::System.Linq.Expressions.Expression> ProcessValueExpression() => source => source.Value.ToUpper() ?? ""; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> UpdateSimpleDtoExpression() => - source => new CircularDto + public static global::System.Linq.Expressions.Expression> UpdateSimpleDtoExpression() => + source => new global::AlephMapper.Tests.CircularDto { ProcessedValue = source.Value.ToUpper() ?? "" // Direct assignment without method call }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static CircularDto UpdateSimpleDto(CircularTestModel source, CircularDto dest) + public static global::AlephMapper.Tests.CircularDto UpdateSimpleDto(global::AlephMapper.Tests.CircularTestModel source, global::AlephMapper.Tests.CircularDto dest) { if (source == null) return dest; if (dest == null) - dest = new CircularDto(); + dest = new global::AlephMapper.Tests.CircularDto(); dest.ProcessedValue = source?.Value?.ToUpper() ?? ""; return dest; } diff --git a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs index ebc6b5f..60dec50 100644 --- a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs @@ -2,30 +2,29 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class CircularPropertyMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> UpdateTypeAExpression() => - source => new TypeA + public static global::System.Linq.Expressions.Expression> UpdateTypeAExpression() => + source => new global::AlephMapper.Tests.TypeA { Name = source.Name, - B = new TypeB + B = new global::AlephMapper.Tests.TypeB { - A = new TypeA + A = new global::AlephMapper.Tests.TypeA { Name = source.Name } @@ -33,21 +32,21 @@ public static Expression> UpdateTypeAExpression }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static TypeA UpdateTypeA(CircularPropsSource source, TypeA dest) + public static global::AlephMapper.Tests.TypeA UpdateTypeA(global::AlephMapper.Tests.CircularPropsSource source, global::AlephMapper.Tests.TypeA dest) { if (source == null) return dest; if (dest == null) - dest = new TypeA(); + dest = new global::AlephMapper.Tests.TypeA(); dest.Name = source?.Name; if (dest.B == null) - dest.B = new TypeB(); + dest.B = new global::AlephMapper.Tests.TypeB(); if (dest.B.A == null) - dest.B.A = new TypeA(); + dest.B.A = new global::AlephMapper.Tests.TypeA(); dest.B.A.Name = source?.Name; return dest; } diff --git a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs index ecdebc8..2e611c1 100644 --- a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs @@ -2,32 +2,31 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class CollectionMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDestWithCollectionsExpression() => - source => new DestWithCollections + public static global::System.Linq.Expressions.Expression> MapToDestWithCollectionsExpression() => + source => new global::AlephMapper.Tests.DestWithCollections { Name = source.Name, Tags = source.Tags, Categories = source.Categories, NestedObject = source.NestedObject != null - ? new NestedModel + ? new global::AlephMapper.Tests.NestedModel { Value = source.NestedObject.Value, NestedList = source.NestedObject.NestedList @@ -36,23 +35,23 @@ public static Expression> MapTo }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestWithCollections MapToDestWithCollections(SourceWithCollections source, DestWithCollections dest) + public static global::AlephMapper.Tests.DestWithCollections MapToDestWithCollections(global::AlephMapper.Tests.SourceWithCollections source, global::AlephMapper.Tests.DestWithCollections dest) { if (source == null) return dest; if (dest == null) - dest = new DestWithCollections(); + dest = new global::AlephMapper.Tests.DestWithCollections(); dest.Name = source.Name; // Skipping collection property: dest.Tags // Skipping collection property: dest.Categories if (source.NestedObject != null) { if (dest.NestedObject == null) - dest.NestedObject = new NestedModel(); + dest.NestedObject = new global::AlephMapper.Tests.NestedModel(); dest.NestedObject.Value = source.NestedObject.Value; // Skipping collection property: dest.NestedObject.NestedList } @@ -64,19 +63,19 @@ public static DestWithCollections MapToDestWithCollections(SourceWithCollections } /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDestSimpleExpression() => - source => new DestWithCollections + public static global::System.Linq.Expressions.Expression> MapToDestSimpleExpression() => + source => new global::AlephMapper.Tests.DestWithCollections { Name = source.Name, NestedObject = source.NestedObject != null - ? new NestedModel + ? new global::AlephMapper.Tests.NestedModel { Value = source.NestedObject.Value } @@ -84,21 +83,21 @@ public static Expression> MapTo }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestWithCollections MapToDestSimple(SourceWithCollections source, DestWithCollections dest) + public static global::AlephMapper.Tests.DestWithCollections MapToDestSimple(global::AlephMapper.Tests.SourceWithCollections source, global::AlephMapper.Tests.DestWithCollections dest) { if (source == null) return dest; if (dest == null) - dest = new DestWithCollections(); + dest = new global::AlephMapper.Tests.DestWithCollections(); dest.Name = source.Name; if (source.NestedObject != null) { if (dest.NestedObject == null) - dest.NestedObject = new NestedModel(); + dest.NestedObject = new global::AlephMapper.Tests.NestedModel(); dest.NestedObject.Value = source.NestedObject.Value; } else diff --git a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs index 7885e3b..90c6084 100644 --- a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs @@ -2,38 +2,37 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ConditionalPatternMapper { /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestModel BothSidesObjects(SourceModel source, DestModel dest) + public static global::AlephMapper.Tests.DestModel BothSidesObjects(global::AlephMapper.Tests.SourceModel source, global::AlephMapper.Tests.DestModel dest) { if (source == null) return dest; if (dest == null) - dest = new DestModel(); + dest = new global::AlephMapper.Tests.DestModel(); dest.Name = source.Name; if (source.Value == null) { if (dest.Nested == null) - dest.Nested = new NestedDest(); + dest.Nested = new global::AlephMapper.Tests.NestedDest(); dest.Nested.Content = "Default"; dest.Nested.Number = 0; } else { if (dest.Nested == null) - dest.Nested = new NestedDest(); + dest.Nested = new global::AlephMapper.Tests.NestedDest(); dest.Nested.Content = source.Name; dest.Nested.Number = source.Value.Value; } @@ -41,21 +40,21 @@ public static DestModel BothSidesObjects(SourceModel source, DestModel dest) } /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestModel ObjectThenNull(SourceModel source, DestModel dest) + public static global::AlephMapper.Tests.DestModel ObjectThenNull(global::AlephMapper.Tests.SourceModel source, global::AlephMapper.Tests.DestModel dest) { if (source == null) return dest; if (dest == null) - dest = new DestModel(); + dest = new global::AlephMapper.Tests.DestModel(); dest.Name = source.Name; if (source.Name != null) { if (dest.Nested == null) - dest.Nested = new NestedDest(); + dest.Nested = new global::AlephMapper.Tests.NestedDest(); dest.Nested.Content = source.Name; dest.Nested.Number = 42; } @@ -67,16 +66,16 @@ public static DestModel ObjectThenNull(SourceModel source, DestModel dest) } /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestModel NullThenObject(SourceModel source, DestModel dest) + public static global::AlephMapper.Tests.DestModel NullThenObject(global::AlephMapper.Tests.SourceModel source, global::AlephMapper.Tests.DestModel dest) { if (source == null) return dest; if (dest == null) - dest = new DestModel(); + dest = new global::AlephMapper.Tests.DestModel(); dest.Name = source.Name; if (source.Name == null) { @@ -85,7 +84,7 @@ public static DestModel NullThenObject(SourceModel source, DestModel dest) else { if (dest.Nested == null) - dest.Nested = new NestedDest(); + dest.Nested = new global::AlephMapper.Tests.NestedDest(); dest.Nested.Content = source.Name; dest.Nested.Number = 42; } @@ -93,28 +92,28 @@ public static DestModel NullThenObject(SourceModel source, DestModel dest) } /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestModel NestedBothSides(SourceModel source, DestModel dest) + public static global::AlephMapper.Tests.DestModel NestedBothSides(global::AlephMapper.Tests.SourceModel source, global::AlephMapper.Tests.DestModel dest) { if (source == null) return dest; if (dest == null) - dest = new DestModel(); + dest = new global::AlephMapper.Tests.DestModel(); dest.Name = source.Name; if (source.Nested?.Content == null) { if (dest.Nested == null) - dest.Nested = new NestedDest(); + dest.Nested = new global::AlephMapper.Tests.NestedDest(); dest.Nested.Content = "Fallback"; dest.Nested.Number = -1; } else { if (dest.Nested == null) - dest.Nested = new NestedDest(); + dest.Nested = new global::AlephMapper.Tests.NestedDest(); dest.Nested.Content = source.Nested.Content; dest.Nested.Number = source.Nested.Number; } @@ -122,51 +121,51 @@ public static DestModel NestedBothSides(SourceModel source, DestModel dest) } /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestModel ObjectThenThrow(SourceModel source, DestModel dest) + public static global::AlephMapper.Tests.DestModel ObjectThenThrow(global::AlephMapper.Tests.SourceModel source, global::AlephMapper.Tests.DestModel dest) { if (source == null) return dest; if (dest == null) - dest = new DestModel(); + dest = new global::AlephMapper.Tests.DestModel(); dest.Name = source.Name; if (source.Name != null) { if (dest.Nested == null) - dest.Nested = new NestedDest(); + dest.Nested = new global::AlephMapper.Tests.NestedDest(); dest.Nested.Content = source.Name; dest.Nested.Number = 42; } else { - throw new ArgumentNullException(nameof(source.Name)); + throw new global::System.ArgumentNullException(nameof(source.Name)); } return dest; } /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestModel ThrowThenObject(SourceModel source, DestModel dest) + public static global::AlephMapper.Tests.DestModel ThrowThenObject(global::AlephMapper.Tests.SourceModel source, global::AlephMapper.Tests.DestModel dest) { if (source == null) return dest; if (dest == null) - dest = new DestModel(); + dest = new global::AlephMapper.Tests.DestModel(); dest.Name = source.Name; if (source.Name == null) { - throw new ArgumentNullException(nameof(source.Name)); + throw new global::System.ArgumentNullException(nameof(source.Name)); } else { if (dest.Nested == null) - dest.Nested = new NestedDest(); + dest.Nested = new global::AlephMapper.Tests.NestedDest(); dest.Nested.Content = source.Name; dest.Nested.Number = 42; } diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs index 9a57d6a..b3fbdd4 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs @@ -2,56 +2,55 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class EfCoreIgnoreMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> GetPersonNameExpression() => + public static global::System.Linq.Expressions.Expression> GetPersonNameExpression() => person => person.Name; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> GetPersonEmailExpression() => + public static global::System.Linq.Expressions.Expression> GetPersonEmailExpression() => person => person.Email; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> GetPersonAgeExpression() => + public static global::System.Linq.Expressions.Expression> GetPersonAgeExpression() => person => person.BirthInfo.Age; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> GetBirthPlaceExpression() => + public static global::System.Linq.Expressions.Expression> GetBirthPlaceExpression() => person => person.BirthInfo.BirthPlace ?? "Unknown"; } diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs index d3052db..8bd890f 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs @@ -2,25 +2,24 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class EfCoreMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetPersonComplexExpression() => - p => new PersonSummaryDto + public static global::System.Linq.Expressions.Expression> GetPersonComplexExpression() => + p => new global::AlephMapper.Tests.PersonSummaryDto { Id = p.Id, Name = p.Name, @@ -54,209 +53,209 @@ public static Expression> GetPersonComplexExpress }; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetPersonNameExpression() => + public static global::System.Linq.Expressions.Expression> GetPersonNameExpression() => person => person.Name; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetPersonEmailExpression() => + public static global::System.Linq.Expressions.Expression> GetPersonEmailExpression() => person => person.Email; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetPersonAgeExpression() => + public static global::System.Linq.Expressions.Expression> GetPersonAgeExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.Age) : (int?)null); /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> IsOlderThan30Expression() => + public static global::System.Linq.Expressions.Expression> IsOlderThan30Expression() => person => (person.BirthInfo != null ? (person.BirthInfo.Age) : (int?)null) > 30; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetBirthPlaceExpression() => + public static global::System.Linq.Expressions.Expression> GetBirthPlaceExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.BirthPlace) : (string?)null) ?? "Unknown"; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetBirthAddressExpression() => + public static global::System.Linq.Expressions.Expression> GetBirthAddressExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.Address) : (string?)null) ?? "Not specified"; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> HasBirthInfoExpression() => + public static global::System.Linq.Expressions.Expression> HasBirthInfoExpression() => person => person.BirthInfo != null; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> IsAdultExpression() => + public static global::System.Linq.Expressions.Expression> IsAdultExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.Age) : (int?)null) >= 18; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> BornInUkraineExpression() => + public static global::System.Linq.Expressions.Expression> BornInUkraineExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.Address) : (string?)null) != null && person.BirthInfo.Address.Contains("Ukraine"); /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetAddressCountExpression() => + public static global::System.Linq.Expressions.Expression> GetAddressCountExpression() => person => person.Addresses.Count; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetOrderCountExpression() => + public static global::System.Linq.Expressions.Expression> GetOrderCountExpression() => person => person.Orders.Count; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> HasActiveAddressExpression() => + public static global::System.Linq.Expressions.Expression> HasActiveAddressExpression() => person => person.Addresses.Any(a => a.IsActive); /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> HasCompletedOrdersExpression() => + public static global::System.Linq.Expressions.Expression> HasCompletedOrdersExpression() => person => person.Orders.Any(o => o.IsCompleted); /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetTotalOrderAmountExpression() => + public static global::System.Linq.Expressions.Expression> GetTotalOrderAmountExpression() => person => person.Orders .Where(o => o.IsCompleted) .Sum(o => o.Amount); /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetPersonSummaryExpression() => + public static global::System.Linq.Expressions.Expression> GetPersonSummaryExpression() => person => person.BirthInfo != null ? person.Name + " (" + person.BirthInfo.Age + " years old) from " + (person.BirthInfo.BirthPlace ?? "Unknown") : person.Name + " (unknown age) from Unknown"; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> LivesInSamePlaceAsBornExpression() => + public static global::System.Linq.Expressions.Expression> LivesInSamePlaceAsBornExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.BirthPlace) : (string?)null) != null && person.Addresses.Any(a => a.IsActive && a.City == person.BirthInfo.BirthPlace); /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetPersonCategoryExpression() => + public static global::System.Linq.Expressions.Expression> GetPersonCategoryExpression() => person => person.BirthInfo == null ? "Unknown Age" : person.BirthInfo.Age < 18 @@ -266,14 +265,14 @@ public static Expression> GetPersonCategoryExpression() => : "Senior"; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> IsVipCustomerExpression() => + public static global::System.Linq.Expressions.Expression> IsVipCustomerExpression() => person => person.Orders .Where(o => o.IsCompleted) .Sum(o => o.Amount) >= 1000m; diff --git a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index a0840c8..bce4069 100644 --- a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -3,23 +3,22 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class SampleMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ProjectNameExpression() => + public static global::System.Linq.Expressions.Expression> ProjectNameExpression() => source => source.Name; } diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs index 3dc2743..74e9b17 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -3,29 +3,28 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ConditionalExtensionTestPersonMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - person => new ExtensionTestPersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + person => new global::AlephMapper.Tests.ExtensionTestPersonDto { Id = person.Id, Name = person.Name, - Address = new ExtensionTestAddressDto + Address = new global::AlephMapper.Tests.ExtensionTestAddressDto { Street = person.Address.Street, City = person.Address.City, diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs index c3bf1b8..c6d57c0 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ExtensionTestAddressMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - address => new ExtensionTestAddressDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + address => new global::AlephMapper.Tests.ExtensionTestAddressDto { Street = address.Street, City = address.City, diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs index e68d4d4..9f1627c 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -3,29 +3,28 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ExtensionTestPersonMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - person => new ExtensionTestPersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + person => new global::AlephMapper.Tests.ExtensionTestPersonDto { Id = person.Id, Name = person.Name, - Address = new ExtensionTestAddressDto + Address = new global::AlephMapper.Tests.ExtensionTestAddressDto { Street = person.Address.Street, City = person.Address.City, diff --git a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs index a97aecf..3b8f4cd 100644 --- a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs @@ -2,73 +2,72 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class Mapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> BornInKyivAndOlder35Expression() => + public static global::System.Linq.Expressions.Expression> BornInKyivAndOlder35Expression() => source => source.BirthInfo.Address == "Kyiv" && Mapper1.Older35(source.BirthInfo) && source.BirthInfo.Age < 65; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> BornInKyivExpression() => + public static global::System.Linq.Expressions.Expression> BornInKyivExpression() => source => source.Address == "Kyiv"; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> Younger65Expression() => + public static global::System.Linq.Expressions.Expression> Younger65Expression() => source => source.Age < 65; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> LivesInExpression() => + public static global::System.Linq.Expressions.Expression> LivesInExpression() => source => source.Address == "Kyiv"; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDestDtoExpression() => - source => new DestDto + public static global::System.Linq.Expressions.Expression> MapToDestDtoExpression() => + source => new global::AlephMapper.Tests.DestDto { Name = source.Name, BirthInfo = source.BirthInfo != null - ? new BirthInfoDto + ? new global::AlephMapper.Tests.BirthInfoDto { Age = source.BirthInfo.Age, Address = source.BirthInfo.Address @@ -78,21 +77,21 @@ public static Expression> MapToDestDtoExpression() => }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestDto MapToDestDto(SourceDto source, DestDto dest) + public static global::AlephMapper.Tests.DestDto MapToDestDto(global::AlephMapper.Tests.SourceDto source, global::AlephMapper.Tests.DestDto dest) { if (source == null) return dest; if (dest == null) - dest = new DestDto(); + dest = new global::AlephMapper.Tests.DestDto(); dest.Name = source.Name; if (source.BirthInfo != null) { if (dest.BirthInfo == null) - dest.BirthInfo = new BirthInfoDto(); + dest.BirthInfo = new global::AlephMapper.Tests.BirthInfoDto(); dest.BirthInfo.Age = source.BirthInfo.Age; dest.BirthInfo.Address = source.BirthInfo.Address; } @@ -105,20 +104,20 @@ public static DestDto MapToDestDto(SourceDto source, DestDto dest) } /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDestDto1Expression() => - source => new DestDto + public static global::System.Linq.Expressions.Expression> MapToDestDto1Expression() => + source => new global::AlephMapper.Tests.DestDto { Name = source.Name, BirthInfo = source.BirthInfo == null ? null - : new BirthInfoDto + : new global::AlephMapper.Tests.BirthInfoDto { Age = source.BirthInfo.Age, Address = source.BirthInfo.Address @@ -127,16 +126,16 @@ public static Expression> MapToDestDto1Expression() => }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static DestDto MapToDestDto1(SourceDto source, DestDto dest) + public static global::AlephMapper.Tests.DestDto MapToDestDto1(global::AlephMapper.Tests.SourceDto source, global::AlephMapper.Tests.DestDto dest) { if (source == null) return dest; if (dest == null) - dest = new DestDto(); + dest = new global::AlephMapper.Tests.DestDto(); dest.Name = source.Name; if (source.BirthInfo == null) { @@ -145,7 +144,7 @@ public static DestDto MapToDestDto1(SourceDto source, DestDto dest) else { if (dest.BirthInfo == null) - dest.BirthInfo = new BirthInfoDto(); + dest.BirthInfo = new global::AlephMapper.Tests.BirthInfoDto(); dest.BirthInfo.Age = source.BirthInfo.Age; dest.BirthInfo.Address = source.BirthInfo.Address; } @@ -154,15 +153,15 @@ public static DestDto MapToDestDto1(SourceDto source, DestDto dest) } /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToBirthInfoDtoExpression() => - bi => new BirthInfoDto + public static global::System.Linq.Expressions.Expression> MapToBirthInfoDtoExpression() => + bi => new global::AlephMapper.Tests.BirthInfoDto { Age = bi.Age, Address = bi.Address diff --git a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs index cff4ee1..8b7c6b8 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs @@ -3,28 +3,27 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class SimpleObjectMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDtoExpression() => - so => new SimpleDto + public static global::System.Linq.Expressions.Expression> MapToDtoExpression() => + so => new global::AlephMapper.Tests.SimpleDto { Attributes = so.Attributes .Select(attr => attr.Name) - .ToList() ?? new List() + .ToList() ?? new global::System.Collections.Generic.List() }; } diff --git a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs index d950897..cbc6d9d 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs @@ -3,26 +3,25 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests.MethodGroupToEntityList; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToEntityExpression() => - dto => new Person + public static global::System.Linq.Expressions.Expression> ToEntityExpression() => + dto => new global::AlephMapper.Tests.MethodGroupToEntityList.Person { ContactNumbers = dto.PhoneNumbers .Select(PhoneMapper.ToEntity) diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs index 6127a1e..fee68e2 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests.MultiParamExtensionInlining; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonProductMapperIgnore { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - person => new PersonProductDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + person => new global::AlephMapper.Tests.MultiParamExtensionInlining.PersonProductDto { Name = person.Name, FavoritePrice = "$" + person.FavoriteProduct.Price diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs index c3c60e6..d9a05ca 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests.MultiParamExtensionInlining; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonProductMapperRewrite { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> ToDtoExpression() => - person => new PersonProductDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + person => new global::AlephMapper.Tests.MultiParamExtensionInlining.PersonProductDto { Name = person.Name, FavoritePrice = (person.FavoriteProduct != null diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs index 3e1545d..42024b2 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests.MultiParamExtensionInlining; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ProductMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - product => new ProductDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + product => new global::AlephMapper.Tests.MultiParamExtensionInlining.ProductDto { Label = product.Name, PriceTag = "$" + product.Price, diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs index 019450d..1610eb0 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class MultiParamProjectableMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapExpression(int currentYear) => - person => new PersonDto + public static global::System.Linq.Expressions.Expression> MapExpression(int currentYear) => + person => new global::AlephMapper.Tests.MultiParameterInlining.PersonDto { FullName = person.First + " " + person.Last, BirthYear = currentYear - person.Age diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs index 681745a..ab6f4db 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NamedArgMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - person => new PersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + person => new global::AlephMapper.Tests.MultiParameterInlining.PersonDto { FullName = person.First + " " + person.Last }; diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs index f4ecbe3..c0131ce 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedMultiParamMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - person => new PersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + person => new global::AlephMapper.Tests.MultiParameterInlining.PersonDto { FullName = person.First + " " + person.Last + " (age " + person.Age + ")" }; diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs index ac92ebe..7c59695 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - person => new PersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + person => new global::AlephMapper.Tests.MultiParameterInlining.PersonDto { FullName = person.First + " " + person.Last, Address = person.Street + ", " + person.City + " " + person.Zip, diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs index 4128fd5..4f8681b 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs @@ -3,42 +3,41 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests.MultiParameterInlining; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class UpdatableMultiParamMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression(int currentYear) => - person => new PersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression(int currentYear) => + person => new global::AlephMapper.Tests.MultiParameterInlining.PersonDto { FullName = person.First + " " + person.Last, BirthYear = currentYear - person.Age }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static PersonDto ToDto(Person person, int currentYear, PersonDto dest) + public static global::AlephMapper.Tests.MultiParameterInlining.PersonDto ToDto(global::AlephMapper.Tests.MultiParameterInlining.Person person, int currentYear, global::AlephMapper.Tests.MultiParameterInlining.PersonDto dest) { if (person == null) return dest; if (dest == null) - dest = new PersonDto(); + dest = new global::AlephMapper.Tests.MultiParameterInlining.PersonDto(); dest.FullName = person.First + " " + person.Last; dest.BirthYear = currentYear - person.Age; return dest; diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs index eaf9901..71962b5 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedExt_AddressMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - a => new NestedExt_AddressDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + a => new global::AlephMapper.Tests.NestedExt_AddressDto { Street = a.Street, City = a.City diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs index 9e7a8f3..bbb9e3f 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs @@ -3,27 +3,26 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedExt_PersonMapper_Ignore { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - p => new NestedExt_PersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + p => new global::AlephMapper.Tests.NestedExt_PersonDto { - HomeAddress = new NestedExt_AddressDto + HomeAddress = new global::AlephMapper.Tests.NestedExt_AddressDto { Street = p.Friend.HomeAddress.Street, City = p.Friend.HomeAddress.City diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs index 738b74e..1fb72e8 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs @@ -3,36 +3,35 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedExt_PersonMapper_Rewrite { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> ToDtoExpression() => - p => new NestedExt_PersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + p => new global::AlephMapper.Tests.NestedExt_PersonDto { HomeAddress = (p != null ? ((p.Friend != null ? ((p.Friend.HomeAddress != null - ? (new NestedExt_AddressDto + ? (new global::AlephMapper.Tests.NestedExt_AddressDto { Street = p.Friend.HomeAddress.Street, City = p.Friend.HomeAddress.City }) - : (NestedExt_AddressDto?)null)) - : (NestedExt_AddressDto?)null)) - : (NestedExt_AddressDto?)null) + : (global::AlephMapper.Tests.NestedExt_AddressDto?)null)) + : (global::AlephMapper.Tests.NestedExt_AddressDto?)null)) + : (global::AlephMapper.Tests.NestedExt_AddressDto?)null) }; } diff --git a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs index 9bbc05a..efa6f00 100644 --- a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs @@ -4,25 +4,24 @@ using AgileObjects.ReadableExpressions; using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullCoalesceValueAssignmentMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapExpression() => - s => new ValueDest + public static global::System.Linq.Expressions.Expression> MapExpression() => + s => new global::AlephMapper.Tests.ValueDest { Must = s.Maybe ?? 42 }; diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs index f0b6345..4f3c8e0 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs @@ -2,34 +2,33 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class IgnoreMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> GetAddressExpression() => + public static global::System.Linq.Expressions.Expression> GetAddressExpression() => source => source.BirthInfo.Address ?? "Unknown"; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> HasAddressExpression() => + public static global::System.Linq.Expressions.Expression> HasAddressExpression() => source => source.BirthInfo.Address != null; } diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs index 9226078..ff22f28 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs @@ -2,23 +2,22 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NoneMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are preserved as-is in the expression tree. /// /// - public static Expression> GetNameExpression() => + public static global::System.Linq.Expressions.Expression> GetNameExpression() => source => source.Name; } diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs index dad96cb..0c40df2 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs @@ -2,37 +2,36 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class RewriteMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetAddressExpression() => + public static global::System.Linq.Expressions.Expression> GetAddressExpression() => dto => (dto.BirthInfo != null ? (dto.BirthInfo.Address) : (string?)null) ?? "Unknown"; /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> HasAddressExpression() => + public static global::System.Linq.Expressions.Expression> HasAddressExpression() => source => (source.BirthInfo != null ? (source.BirthInfo.Address) : (string?)null) != null; diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Sources/Mappers.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Sources/Mappers.cs index 05fa9a3..5989333 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Sources/Mappers.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Sources/Mappers.cs @@ -1,5 +1,3 @@ -using System.CodeDom.Compiler; - namespace AlephMapper.Tests; // Test mapper with Ignore policy (now default, but being explicit) @@ -26,4 +24,4 @@ public static partial class NoneMapper { // This method should work because it doesn't use null conditional operators public static string GetName(SourceDto source) => source.Name; -} \ No newline at end of file +} diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs index fd01b37..3123169 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs @@ -3,24 +3,23 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullableDisabledMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetNameExpression() => + public static global::System.Linq.Expressions.Expression> GetNameExpression() => person => (person != null ? (person.Name) : (string?)null); diff --git a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs index 4a91816..24f3290 100644 --- a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs @@ -3,24 +3,23 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullableEnabledMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> GetNameExpression() => + public static global::System.Linq.Expressions.Expression> GetNameExpression() => person => (person != null ? (person.Name) : (string?)null); diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs index c4ecec8..e50675b 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs @@ -3,23 +3,22 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtAddressMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> FormatAddressExpression() => + public static global::System.Linq.Expressions.Expression> FormatAddressExpression() => address => address.FormattedAddress; } diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs index cf5c37f..3f22308 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtPersonMapperIgnore { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> ToDtoExpression() => - person => new TechDebtTestPersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + person => new global::AlephMapper.Tests.TechDebtTestPersonDto { Name = person.Name, AddressStr = person.Address.FormattedAddress ?? "No Address" diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs index 132a838..e1998cc 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs @@ -3,13 +3,12 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtPersonMapperNone { } diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs index ab7c308..6dd30f6 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs @@ -3,25 +3,24 @@ using AgileObjects.ReadableExpressions; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtPersonMapperRewrite { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are rewritten as explicit null checks for better compatibility. /// /// - public static Expression> ToDtoExpression() => - person => new TechDebtTestPersonDto + public static global::System.Linq.Expressions.Expression> ToDtoExpression() => + person => new global::AlephMapper.Tests.TechDebtTestPersonDto { Name = person.Name, AddressStr = (person.Address != null diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs index a4337ea..a1f26a9 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs @@ -2,36 +2,35 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class Address1Mapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDtoExpression() => - sourceAddress => new Address1Dto + public static global::System.Linq.Expressions.Expression> MapToDtoExpression() => + sourceAddress => new global::AlephMapper.Tests.Address1Dto { Line1 = sourceAddress.Line1 == null ? null - : new AddressLineDto + : new global::AlephMapper.Tests.AddressLineDto { Street = sourceAddress.Line1.Street, HouseNumber = sourceAddress.Line1.HouseNumber }, Line2 = sourceAddress.Line2 == null ? null - : new AddressLineDto + : new global::AlephMapper.Tests.AddressLineDto { Street = sourceAddress.Line2.Street, HouseNumber = sourceAddress.Line2.HouseNumber diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs index 8d95e1b..cedca79 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs @@ -2,27 +2,26 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class AddressLineMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDtoExpression() => + public static global::System.Linq.Expressions.Expression> MapToDtoExpression() => sourceAddressLine1 => sourceAddressLine1 == null ? null - : new AddressLineDto + : new global::AlephMapper.Tests.AddressLineDto { Street = sourceAddressLine1.Street, HouseNumber = sourceAddressLine1.HouseNumber diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs index d60d9cf..39569d5 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs @@ -2,41 +2,40 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class TestModel1Mapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToTestModel1DtoExpression() => - source => new TestModel1Dto + public static global::System.Linq.Expressions.Expression> MapToTestModel1DtoExpression() => + source => new global::AlephMapper.Tests.TestModel1Dto { Name = source.Name, SurName = source.SurName, Address = source.Address != null - ? new Address1Dto + ? new global::AlephMapper.Tests.Address1Dto { Line1 = source.Address.Line1 == null ? null - : new AddressLineDto + : new global::AlephMapper.Tests.AddressLineDto { Street = source.Address.Line1.Street, HouseNumber = source.Address.Line1.HouseNumber }, Line2 = source.Address.Line2 == null ? null - : new AddressLineDto + : new global::AlephMapper.Tests.AddressLineDto { Street = source.Address.Line2.Street, HouseNumber = source.Address.Line2.HouseNumber @@ -46,22 +45,22 @@ public static Expression> MapToTestModel1DtoExpr }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static TestModel1Dto MapToTestModel1Dto(TestModel1 source, TestModel1Dto dest) + public static global::AlephMapper.Tests.TestModel1Dto MapToTestModel1Dto(global::AlephMapper.Tests.TestModel1 source, global::AlephMapper.Tests.TestModel1Dto dest) { if (source == null) return dest; if (dest == null) - dest = new TestModel1Dto(); + dest = new global::AlephMapper.Tests.TestModel1Dto(); dest.Name = source.Name; dest.SurName = source.SurName; if (source.Address != null) { if (dest.Address == null) - dest.Address = new Address1Dto(); + dest.Address = new global::AlephMapper.Tests.Address1Dto(); if (source.Address.Line1== null) { dest.Address.Line1 = null; @@ -69,7 +68,7 @@ public static TestModel1Dto MapToTestModel1Dto(TestModel1 source, TestModel1Dto else { if (dest.Address.Line1 == null) - dest.Address.Line1 = new AddressLineDto(); + dest.Address.Line1 = new global::AlephMapper.Tests.AddressLineDto(); dest.Address.Line1.Street = source.Address.Line1.Street; dest.Address.Line1.HouseNumber = source.Address.Line1.HouseNumber; } @@ -80,7 +79,7 @@ public static TestModel1Dto MapToTestModel1Dto(TestModel1 source, TestModel1Dto else { if (dest.Address.Line2 == null) - dest.Address.Line2 = new AddressLineDto(); + dest.Address.Line2 = new global::AlephMapper.Tests.AddressLineDto(); dest.Address.Line2.Street = source.Address.Line2.Street; dest.Address.Line2.HouseNumber = source.Address.Line2.HouseNumber; } diff --git a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index 1220e2d..2c21a4e 100644 --- a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -3,26 +3,25 @@ using AlephMapper; using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class SampleMapper { /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static Destination Map(Source source, Destination dest) + public static global::Tests.Destination Map(global::Tests.Source source, global::Tests.Destination dest) { if (source == null) return dest; if (dest == null) - dest = new Destination(); + dest = new global::Tests.Destination(); dest.Name = source.Name; dest.Age = source.Age; return dest; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs index 06144a4..043a2ad 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs @@ -2,30 +2,29 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ComplexPropertyMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapExpression() => - source => new ComplexPropertyTestDestination + public static global::System.Linq.Expressions.Expression> MapExpression() => + source => new global::AlephMapper.Tests.ComplexPropertyTestDestination { - NestedClass = new NestedReferenceType + NestedClass = new global::AlephMapper.Tests.NestedReferenceType { InnerValue = source.NestedStruct.InnerValue, - InnerClass = new DeeplyNestedReferenceType + InnerClass = new global::AlephMapper.Tests.DeeplyNestedReferenceType { DeepValue = source.NestedStruct.InnerStruct.DeepValue } @@ -33,20 +32,20 @@ public static Expression - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static ComplexPropertyTestDestination Map(ComplexPropertyTestSource source, ComplexPropertyTestDestination dest) + public static global::AlephMapper.Tests.ComplexPropertyTestDestination Map(global::AlephMapper.Tests.ComplexPropertyTestSource source, global::AlephMapper.Tests.ComplexPropertyTestDestination dest) { if (dest == null) - dest = new ComplexPropertyTestDestination(); + dest = new global::AlephMapper.Tests.ComplexPropertyTestDestination(); if (dest.NestedClass == null) - dest.NestedClass = new NestedReferenceType(); + dest.NestedClass = new global::AlephMapper.Tests.NestedReferenceType(); dest.NestedClass.InnerValue = source.NestedStruct.InnerValue; if (dest.NestedClass.InnerClass == null) - dest.NestedClass.InnerClass = new DeeplyNestedReferenceType(); + dest.NestedClass.InnerClass = new global::AlephMapper.Tests.DeeplyNestedReferenceType(); dest.NestedClass.InnerClass.DeepValue = source.NestedStruct.InnerStruct.DeepValue; return dest; } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs index e466627..db2f93d 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs @@ -2,58 +2,57 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ComplexValueTypeMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDestinationExpression() => - source => new ComplexValueTypeDestination + public static global::System.Linq.Expressions.Expression> MapToDestinationExpression() => + source => new global::AlephMapper.Tests.ComplexValueTypeDestination { Id = source.Id, Name = source.Name, - Address = new AddressStruct + Address = new global::AlephMapper.Tests.AddressStruct { Street = source.Address.Street, City = source.Address.City, ZipCode = source.Address.ZipCode, - Coordinates = new CoordinatesStruct + Coordinates = new global::AlephMapper.Tests.CoordinatesStruct { Latitude = source.Address.Coordinates.Latitude, Longitude = source.Address.Coordinates.Longitude, Elevation = source.Address.Coordinates.Elevation } }, - ContactInfo = new ContactInfoStruct + ContactInfo = new global::AlephMapper.Tests.ContactInfoStruct { Email = source.ContactInfo.Email, Phone = source.ContactInfo.Phone, PreferredMethod = source.ContactInfo.PreferredMethod, - EmergencyContact = new EmergencyContactStruct + EmergencyContact = new global::AlephMapper.Tests.EmergencyContactStruct { Name = source.ContactInfo.EmergencyContact.Name, Relationship = source.ContactInfo.EmergencyContact.Relationship, Phone = source.ContactInfo.EmergencyContact.Phone } }, - Metadata = new MetadataStruct + Metadata = new global::AlephMapper.Tests.MetadataStruct { CreatedAt = source.Metadata.CreatedAt, UpdatedAt = source.Metadata.UpdatedAt, Version = source.Metadata.Version, - Tags = new TagsStruct + Tags = new global::AlephMapper.Tests.TagsStruct { Primary = source.Metadata.Tags.Primary, Secondary = source.Metadata.Tags.Secondary, diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs index 7780fe1..4c3e590 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs @@ -2,31 +2,30 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class EdgeCaseMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapExpression() => - source => new EdgeCaseReferenceTypeDestination + public static global::System.Linq.Expressions.Expression> MapExpression() => + source => new global::AlephMapper.Tests.EdgeCaseReferenceTypeDestination { SimpleValue = source.SimpleValue, - ComplexValue = new EdgeCaseReferenceTypeClass + ComplexValue = new global::AlephMapper.Tests.EdgeCaseReferenceTypeClass { StructValue = source.ComplexValue.StructValue, - NestedClass = new NestedEdgeCaseClass + NestedClass = new global::AlephMapper.Tests.NestedEdgeCaseClass { Value = source.ComplexValue.NestedStruct.Value } @@ -34,21 +33,21 @@ public static Expression - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static EdgeCaseReferenceTypeDestination Map(EdgeCaseValueTypeSource source, EdgeCaseReferenceTypeDestination dest) + public static global::AlephMapper.Tests.EdgeCaseReferenceTypeDestination Map(global::AlephMapper.Tests.EdgeCaseValueTypeSource source, global::AlephMapper.Tests.EdgeCaseReferenceTypeDestination dest) { if (dest == null) - dest = new EdgeCaseReferenceTypeDestination(); + dest = new global::AlephMapper.Tests.EdgeCaseReferenceTypeDestination(); dest.SimpleValue = source.SimpleValue; if (dest.ComplexValue == null) - dest.ComplexValue = new EdgeCaseReferenceTypeClass(); + dest.ComplexValue = new global::AlephMapper.Tests.EdgeCaseReferenceTypeClass(); dest.ComplexValue.StructValue = source.ComplexValue.StructValue; if (dest.ComplexValue.NestedClass == null) - dest.ComplexValue.NestedClass = new NestedEdgeCaseClass(); + dest.ComplexValue.NestedClass = new global::AlephMapper.Tests.NestedEdgeCaseClass(); dest.ComplexValue.NestedClass.Value = source.ComplexValue.NestedStruct.Value; return dest; } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs index f45f12a..4340282 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs @@ -2,26 +2,25 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; using TUnit.Core; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class MixedTypeMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDestinationExpression() => - source => new MixedTypeDestination + public static global::System.Linq.Expressions.Expression> MapToDestinationExpression() => + source => new global::AlephMapper.Tests.MixedTypeDestination { IntValue = source.IntValue, StringValue = source.StringValue, @@ -30,7 +29,7 @@ public static Expression> MapToDesti DateTimeValue = source.DateTimeValue, NullableIntValue = source.NullableIntValue, ReferenceObject = source.ReferenceObject != null - ? new TestObject + ? new global::AlephMapper.Tests.TestObject { Name = source.ReferenceObject.Name, Value = source.ReferenceObject.Value @@ -39,16 +38,16 @@ public static Expression> MapToDesti }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static MixedTypeDestination MapToDestination(MixedTypeSource source, MixedTypeDestination dest) + public static global::AlephMapper.Tests.MixedTypeDestination MapToDestination(global::AlephMapper.Tests.MixedTypeSource source, global::AlephMapper.Tests.MixedTypeDestination dest) { if (source == null) return dest; if (dest == null) - dest = new MixedTypeDestination(); + dest = new global::AlephMapper.Tests.MixedTypeDestination(); dest.IntValue = source.IntValue; dest.StringValue = source.StringValue; dest.BoolValue = source.BoolValue; @@ -58,7 +57,7 @@ public static MixedTypeDestination MapToDestination(MixedTypeSource source, Mixe if (source.ReferenceObject != null) { if (dest.ReferenceObject == null) - dest.ReferenceObject = new TestObject(); + dest.ReferenceObject = new global::AlephMapper.Tests.TestObject(); dest.ReferenceObject.Name = source.ReferenceObject.Name; dest.ReferenceObject.Value = source.ReferenceObject.Value; } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs index 99f18ce..f3c156f 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs @@ -2,25 +2,24 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullableValueTypeMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDestinationExpression() => - source => new NullableValueTypeDestination + public static global::System.Linq.Expressions.Expression> MapToDestinationExpression() => + source => new global::AlephMapper.Tests.NullableValueTypeDestination { NullableIntProperty = source.NullableIntProperty, NullableBoolProperty = source.NullableBoolProperty, @@ -28,16 +27,16 @@ public static Expression - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static NullableValueTypeDestination MapToDestination(NullableValueTypeSource source, NullableValueTypeDestination dest) + public static global::AlephMapper.Tests.NullableValueTypeDestination MapToDestination(global::AlephMapper.Tests.NullableValueTypeSource source, global::AlephMapper.Tests.NullableValueTypeDestination dest) { if (source == null) return dest; if (dest == null) - dest = new NullableValueTypeDestination(); + dest = new global::AlephMapper.Tests.NullableValueTypeDestination(); dest.NullableIntProperty = source.NullableIntProperty; dest.NullableBoolProperty = source.NullableBoolProperty; dest.NullableDateTimeProperty = source.NullableDateTimeProperty; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs index 507075f..7320f3a 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs @@ -2,29 +2,28 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ReferenceTypeOnlyMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDestinationExpression() => - source => new ReferenceTypeOnlyDestination + public static global::System.Linq.Expressions.Expression> MapToDestinationExpression() => + source => new global::AlephMapper.Tests.ReferenceTypeOnlyDestination { StringProperty = source.StringProperty, ObjectProperty = source.ObjectProperty != null - ? new SimpleReferenceObject + ? new global::AlephMapper.Tests.SimpleReferenceObject { Name = source.ObjectProperty.Name } @@ -32,21 +31,21 @@ public static Expression - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static ReferenceTypeOnlyDestination MapToDestination(ReferenceTypeOnlySource source, ReferenceTypeOnlyDestination dest) + public static global::AlephMapper.Tests.ReferenceTypeOnlyDestination MapToDestination(global::AlephMapper.Tests.ReferenceTypeOnlySource source, global::AlephMapper.Tests.ReferenceTypeOnlyDestination dest) { if (source == null) return dest; if (dest == null) - dest = new ReferenceTypeOnlyDestination(); + dest = new global::AlephMapper.Tests.ReferenceTypeOnlyDestination(); dest.StringProperty = source.StringProperty; if (source.ObjectProperty != null) { if (dest.ObjectProperty == null) - dest.ObjectProperty = new SimpleReferenceObject(); + dest.ObjectProperty = new global::AlephMapper.Tests.SimpleReferenceObject(); dest.ObjectProperty.Name = source.ObjectProperty.Name; } else diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs index ed5d144..8533fce 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs @@ -2,40 +2,39 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class SimpleValueToReferenceMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapExpression() => - source => new SimpleReferenceTypeDestination + public static global::System.Linq.Expressions.Expression> MapExpression() => + source => new global::AlephMapper.Tests.SimpleReferenceTypeDestination { Value = source.Value, Name = source.Name }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static SimpleReferenceTypeDestination Map(SimpleValueTypeSource source, SimpleReferenceTypeDestination dest) + public static global::AlephMapper.Tests.SimpleReferenceTypeDestination Map(global::AlephMapper.Tests.SimpleValueTypeSource source, global::AlephMapper.Tests.SimpleReferenceTypeDestination dest) { if (dest == null) - dest = new SimpleReferenceTypeDestination(); + dest = new global::AlephMapper.Tests.SimpleReferenceTypeDestination(); dest.Value = source.Value; dest.Name = source.Name; return dest; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs index 547e4ec..a46a7da 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs @@ -2,58 +2,57 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ValueToReferenceMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToReferenceDestinationExpression() => - source => new ComplexReferenceTypeDestination + public static global::System.Linq.Expressions.Expression> MapToReferenceDestinationExpression() => + source => new global::AlephMapper.Tests.ComplexReferenceTypeDestination { Id = source.Id, Name = source.Name, - Address = new AddressClass + Address = new global::AlephMapper.Tests.AddressClass { Street = source.Address.Street, City = source.Address.City, ZipCode = source.Address.ZipCode, - Coordinates = new CoordinatesClass + Coordinates = new global::AlephMapper.Tests.CoordinatesClass { Latitude = source.Address.Coordinates.Latitude, Longitude = source.Address.Coordinates.Longitude, Elevation = source.Address.Coordinates.Elevation } }, - ContactInfo = new ContactInfoClass + ContactInfo = new global::AlephMapper.Tests.ContactInfoClass { Email = source.ContactInfo.Email, Phone = source.ContactInfo.Phone, PreferredMethod = source.ContactInfo.PreferredMethod, - EmergencyContact = new EmergencyContactClass + EmergencyContact = new global::AlephMapper.Tests.EmergencyContactClass { Name = source.ContactInfo.EmergencyContact.Name, Relationship = source.ContactInfo.EmergencyContact.Relationship, Phone = source.ContactInfo.EmergencyContact.Phone } }, - Metadata = new MetadataClass + Metadata = new global::AlephMapper.Tests.MetadataClass { CreatedAt = source.Metadata.CreatedAt, UpdatedAt = source.Metadata.UpdatedAt, Version = source.Metadata.Version, - Tags = new TagsClass + Tags = new global::AlephMapper.Tests.TagsClass { Primary = source.Metadata.Tags.Primary, Secondary = source.Metadata.Tags.Secondary, @@ -63,44 +62,44 @@ public static Expression - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static ComplexReferenceTypeDestination MapToReferenceDestination(ComplexValueTypeSource source, ComplexReferenceTypeDestination dest) + public static global::AlephMapper.Tests.ComplexReferenceTypeDestination MapToReferenceDestination(global::AlephMapper.Tests.ComplexValueTypeSource source, global::AlephMapper.Tests.ComplexReferenceTypeDestination dest) { if (dest == null) - dest = new ComplexReferenceTypeDestination(); + dest = new global::AlephMapper.Tests.ComplexReferenceTypeDestination(); dest.Id = source.Id; dest.Name = source.Name; if (dest.Address == null) - dest.Address = new AddressClass(); + dest.Address = new global::AlephMapper.Tests.AddressClass(); dest.Address.Street = source.Address.Street; dest.Address.City = source.Address.City; dest.Address.ZipCode = source.Address.ZipCode; if (dest.Address.Coordinates == null) - dest.Address.Coordinates = new CoordinatesClass(); + dest.Address.Coordinates = new global::AlephMapper.Tests.CoordinatesClass(); dest.Address.Coordinates.Latitude = source.Address.Coordinates.Latitude; dest.Address.Coordinates.Longitude = source.Address.Coordinates.Longitude; dest.Address.Coordinates.Elevation = source.Address.Coordinates.Elevation; if (dest.ContactInfo == null) - dest.ContactInfo = new ContactInfoClass(); + dest.ContactInfo = new global::AlephMapper.Tests.ContactInfoClass(); dest.ContactInfo.Email = source.ContactInfo.Email; dest.ContactInfo.Phone = source.ContactInfo.Phone; dest.ContactInfo.PreferredMethod = source.ContactInfo.PreferredMethod; if (dest.ContactInfo.EmergencyContact == null) - dest.ContactInfo.EmergencyContact = new EmergencyContactClass(); + dest.ContactInfo.EmergencyContact = new global::AlephMapper.Tests.EmergencyContactClass(); dest.ContactInfo.EmergencyContact.Name = source.ContactInfo.EmergencyContact.Name; dest.ContactInfo.EmergencyContact.Relationship = source.ContactInfo.EmergencyContact.Relationship; dest.ContactInfo.EmergencyContact.Phone = source.ContactInfo.EmergencyContact.Phone; if (dest.Metadata == null) - dest.Metadata = new MetadataClass(); + dest.Metadata = new global::AlephMapper.Tests.MetadataClass(); dest.Metadata.CreatedAt = source.Metadata.CreatedAt; dest.Metadata.UpdatedAt = source.Metadata.UpdatedAt; dest.Metadata.Version = source.Metadata.Version; if (dest.Metadata.Tags == null) - dest.Metadata.Tags = new TagsClass(); + dest.Metadata.Tags = new global::AlephMapper.Tests.TagsClass(); dest.Metadata.Tags.Primary = source.Metadata.Tags.Primary; dest.Metadata.Tags.Secondary = source.Metadata.Tags.Secondary; dest.Metadata.Tags.Category = source.Metadata.Tags.Category; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs index dceac06..a4973fe 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs @@ -2,13 +2,12 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ValueTypeMapper { } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs index e0853fc..9f842f7 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs @@ -2,25 +2,24 @@ #nullable enable using System; -using System.CodeDom.Compiler; using System.Linq; using System.Linq.Expressions; namespace AlephMapper.Tests; -[GeneratedCode("AlephMapper", "0.7.0.0")] +[global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ValueTypeOnlyMapper { /// - /// This is an auto-generated expression companion for . + /// This is an auto-generated expression companion for . /// /// /// /// Null handling strategy: Null-conditional operators are ignored and treated as regular member access. /// /// - public static Expression> MapToDestinationExpression() => - source => new ValueTypeOnlyDestination + public static global::System.Linq.Expressions.Expression> MapToDestinationExpression() => + source => new global::AlephMapper.Tests.ValueTypeOnlyDestination { IntProperty = source.IntProperty, BoolProperty = source.BoolProperty, @@ -29,16 +28,16 @@ public static Expression> Ma }; /// - /// This is an auto-generated update method for . + /// This is an auto-generated update method for . /// /// The source object to map values from. If null, no updates are performed. /// The destination object to update. If null, the new instance is created. /// The updated destination object for method chaining, or the new destination instance if either parameter is null. - public static ValueTypeOnlyDestination MapToDestination(ValueTypeOnlySource source, ValueTypeOnlyDestination dest) + public static global::AlephMapper.Tests.ValueTypeOnlyDestination MapToDestination(global::AlephMapper.Tests.ValueTypeOnlySource source, global::AlephMapper.Tests.ValueTypeOnlyDestination dest) { if (source == null) return dest; if (dest == null) - dest = new ValueTypeOnlyDestination(); + dest = new global::AlephMapper.Tests.ValueTypeOnlyDestination(); dest.IntProperty = source.IntProperty; dest.BoolProperty = source.BoolProperty; dest.DateTimeProperty = source.DateTimeProperty; diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index 68ee47a..d421d1f 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -111,6 +111,47 @@ public async Task GeneratedConfigurationTypesAreNotPublic() await Assert.That(assembly.GetType("AlephMapper.ExpressiveAttribute")).IsNull(); } + [Test] + public async Task GeneratedTypeReferencesAreGloballyQualified() + { + const string source = """ + using AlephMapper; + + namespace Collision; + + public sealed class Func { } + public sealed class Expression { } + public sealed class Source { public string Name { get; set; } = ""; } + public sealed class Destination { public string Name { get; set; } = ""; } + + public static partial class Mapper + { + [Projectable] + [Updatable] + public static Destination Map(Source source) => new() { Name = source.Name }; + } + """; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var compilation = CSharpCompilation.Create( + "GloballyQualifiedTypes", + [CSharpSyntaxTree.ParseText(source, _parseOptions)], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var driver = _driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics); + var generated = driver.GetRunResult().Results.Single().GeneratedSources + .Single(result => result.HintName.EndsWith("Mapper_GeneratedMappings.g.cs", StringComparison.Ordinal)) + .SourceText + .ToString(); + + await Assert.That(diagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(outputCompilation.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(generated).Contains("global::System.Linq.Expressions.Expression>"); + await Assert.That(generated).Contains("new global::Collision.Destination"); + await Assert.That(generated).Contains("dest = new global::Collision.Destination();"); + } + [Test] public async Task EmbeddedConfigurationTypesDoNotConflictAcrossConsumerAssemblies() { @@ -298,8 +339,8 @@ public static TResult Map(TSource source) await Assert.That(generatedSource).Contains("MapExpression()"); await Assert.That(generatedSource).Contains("Map(TSource source, TResult dest)"); - await Assert.That(generatedSource).Contains("where TSource : ISource"); - await Assert.That(generatedSource).Contains("where TResult : IDestination, new()"); + await Assert.That(generatedSource).Contains("where TSource : global::Fixture.ISource"); + await Assert.That(generatedSource).Contains("where TResult : global::Fixture.IDestination, new()"); } [Test] @@ -743,8 +784,8 @@ public sealed class EmployeeTaxInfo { public decimal Rate { get; set; } } await Assert.That(generatedSource).DoesNotContain("?."); await Assert.That(generatedSource).DoesNotContain("MapNonNullPerson"); await Assert.That(generatedSource).Contains("source != null"); - await Assert.That(generatedSource).Contains("new EmployeeDto"); - await Assert.That(generatedSource).Contains("Tax = new EmployeeTaxInfo"); + await Assert.That(generatedSource).Contains("new global::Fixture.EmployeeDto"); + await Assert.That(generatedSource).Contains("Tax = new global::Fixture.EmployeeTaxInfo"); } [Test] @@ -856,8 +897,8 @@ public sealed class ReadOnlyTaxInfo await Assert.That(generatedSource).DoesNotContain("?."); await Assert.That(generatedSource).DoesNotContain("MapNonNullInputToItem"); await Assert.That(generatedSource).Contains("source != null"); - await Assert.That(generatedSource).Contains("new ReadOnlyOrderItem"); - await Assert.That(generatedSource).Contains("Tax = new ReadOnlyTaxInfo"); + await Assert.That(generatedSource).Contains("new global::Fixture.ReadOnlyOrderItem"); + await Assert.That(generatedSource).Contains("Tax = new global::Fixture.ReadOnlyTaxInfo"); await Assert.That(generatedSource).Contains("TotalAmount = decimal.Round((source.Subtotal * (1m + source.TaxRate / 100m)), 2)"); } @@ -913,7 +954,7 @@ public sealed class Description { public string Language { get; set; } = string. var generatedSource = generatedSources.Single(sourceText => sourceText.Contains("MapEmployeeExpression")); await Assert.That(generatedSource).DoesNotContain("new string"); - await Assert.That(generatedSource).Contains("new DescriptionWithOrder"); + await Assert.That(generatedSource).Contains("new global::Fixture.Mapper.DescriptionWithOrder"); } [Test] From e72d3444feeb6e8f3d5f40aa0eb6757c573cbc90 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 13:31:33 +0200 Subject: [PATCH 15/22] fix(generator): centralize nullable policy and preserve source context --- source/Adaptation/AdaptationMemberPlanner.cs | 2 +- .../Adaptation/AdaptedDestinationRewriter.cs | 14 +- .../UpdatableMethodGenerator.cs | 10 +- source/Diagnostics/DiagnosticDescriptors.cs | 25 +++ .../Emitters/AdaptationMemberEmitter.cs | 21 +- .../Emitters/ProjectableMemberEmitter.cs | 4 +- .../Emitters/UpdatableMemberEmitter.cs | 5 +- source/Generation/MapperFileEmitter.cs | 1 - source/Generation/MapperGenerationContext.cs | 7 +- source/Generation/MapperGenerationResult.cs | 6 +- source/Generation/MapperSourceOutput.cs | 3 +- source/Generation/MappingMethodDetails.cs | 22 +- source/Helpers/EmitHelpers.cs | 3 +- source/Helpers/NullablePolicy.cs | 55 +++++ source/Helpers/TypeDisplay.cs | 12 +- source/Models/AdaptationAnalysis.cs | 35 +++- ...ngResolver.CollectionExpressionRewriter.cs | 14 +- ...Resolver.ImplicitObjectCreationRewriter.cs | 4 +- .../InliningResolver.InvocationRewriter.cs | 5 +- ...nliningResolver.NullConditionalRewriter.cs | 43 +++- .../Tests_PersonMapper_GeneratedMappings.g.cs | 5 +- .../Tests_PersonMapper_GeneratedMappings.g.cs | 7 +- ...s_AdaptUpdateMapper_GeneratedMappings.g.cs | 5 +- ...ests_CircularMapper_GeneratedMappings.g.cs | 7 +- ...cularPropertyMapper_GeneratedMappings.g.cs | 5 +- ...ts_CollectionMapper_GeneratedMappings.g.cs | 9 +- ...tionalPatternMapper_GeneratedMappings.g.cs | 13 +- ..._EfCoreIgnoreMapper_GeneratedMappings.g.cs | 9 +- ..._Tests_EfCoreMapper_GeneratedMappings.g.cs | 51 ++++- .../Tests_SampleMapper_GeneratedMappings.g.cs | 3 +- ...ionTestPersonMapper_GeneratedMappings.g.cs | 3 +- ...onTestAddressMapper_GeneratedMappings.g.cs | 3 +- ...ionTestPersonMapper_GeneratedMappings.g.cs | 3 +- ...Mapper_Tests_Mapper_GeneratedMappings.g.cs | 21 +- ..._SimpleObjectMapper_GeneratedMappings.g.cs | 3 +- ...tyList_PersonMapper_GeneratedMappings.g.cs | 8 +- ...ProductMapperIgnore_GeneratedMappings.g.cs | 3 +- ...roductMapperRewrite_GeneratedMappings.g.cs | 5 +- ...ining_ProductMapper_GeneratedMappings.g.cs | 3 +- ...amProjectableMapper_GeneratedMappings.g.cs | 3 +- ...ning_NamedArgMapper_GeneratedMappings.g.cs | 3 +- ...tedMultiParamMapper_GeneratedMappings.g.cs | 3 +- ...lining_PersonMapper_GeneratedMappings.g.cs | 3 +- ...bleMultiParamMapper_GeneratedMappings.g.cs | 5 +- ...edExt_AddressMapper_GeneratedMappings.g.cs | 3 +- ...PersonMapper_Ignore_GeneratedMappings.g.cs | 3 +- ...ersonMapper_Rewrite_GeneratedMappings.g.cs | 9 +- ...lueAssignmentMapper_GeneratedMappings.g.cs | 3 +- ..._Tests_IgnoreMapper_GeneratedMappings.g.cs | 5 +- ...er_Tests_NoneMapper_GeneratedMappings.g.cs | 3 +- ...Tests_RewriteMapper_GeneratedMappings.g.cs | 9 +- ...lableDisabledMapper_GeneratedMappings.g.cs | 5 +- ...llableEnabledMapper_GeneratedMappings.g.cs | 3 +- ...chDebtAddressMapper_GeneratedMappings.g.cs | 3 +- ...tPersonMapperIgnore_GeneratedMappings.g.cs | 3 +- ...ebtPersonMapperNone_GeneratedMappings.g.cs | 1 - ...PersonMapperRewrite_GeneratedMappings.g.cs | 5 +- ...ests_Address1Mapper_GeneratedMappings.g.cs | 3 +- ...s_AddressLineMapper_GeneratedMappings.g.cs | 3 +- ...ts_TestModel1Mapper_GeneratedMappings.g.cs | 5 +- .../Tests_SampleMapper_GeneratedMappings.g.cs | 3 +- ...mplexPropertyMapper_GeneratedMappings.g.cs | 5 +- ...plexValueTypeMapper_GeneratedMappings.g.cs | 3 +- ...ests_EdgeCaseMapper_GeneratedMappings.g.cs | 5 +- ...sts_MixedTypeMapper_GeneratedMappings.g.cs | 5 +- ...ableValueTypeMapper_GeneratedMappings.g.cs | 5 +- ...renceTypeOnlyMapper_GeneratedMappings.g.cs | 5 +- ...ueToReferenceMapper_GeneratedMappings.g.cs | 5 +- ...ueToReferenceMapper_GeneratedMappings.g.cs | 5 +- ...sts_ValueTypeMapper_GeneratedMappings.g.cs | 1 - ...ValueTypeOnlyMapper_GeneratedMappings.g.cs | 5 +- .../AlephMapper.Tests/SourceGeneratorTests.cs | 191 +++++++++++++++++- 72 files changed, 635 insertions(+), 143 deletions(-) create mode 100644 source/Helpers/NullablePolicy.cs diff --git a/source/Adaptation/AdaptationMemberPlanner.cs b/source/Adaptation/AdaptationMemberPlanner.cs index d629725..ce5d036 100644 --- a/source/Adaptation/AdaptationMemberPlanner.cs +++ b/source/Adaptation/AdaptationMemberPlanner.cs @@ -26,7 +26,7 @@ public AdaptationMemberPlanner(INamedTypeSymbol mapperType) .Where(m => m.MethodKind == MethodKind.Ordinary) .Select(m => MethodSignature.Build( m.Name, - m.Parameters.Select(p => TypeDisplay.ForSymbol(p.Type, p.NullableAnnotation, NullableContext.Disabled)), + m.Parameters.Select(p => TypeDisplay.ForSymbol(p.Type, p.NullableAnnotation, NullablePolicy.Disabled)), m.TypeParameters.Length)), StringComparer.Ordinal); diff --git a/source/Adaptation/AdaptedDestinationRewriter.cs b/source/Adaptation/AdaptedDestinationRewriter.cs index eb62565..3cfbaf5 100644 --- a/source/Adaptation/AdaptedDestinationRewriter.cs +++ b/source/Adaptation/AdaptedDestinationRewriter.cs @@ -22,7 +22,7 @@ internal sealed class AdaptedDestinationRewriter : CSharpSyntaxRewriter private readonly HashSet _destinationCreationTypeTexts; private readonly TypeSyntax _adaptedDestinationType; private readonly ITypeSymbol _adaptedDestinationTypeSymbol; - private readonly NullableContext _nullableContext; + private readonly NullablePolicy _nullablePolicy; private readonly HashSet _originalDestinationTypeTexts; private readonly ExpressionSyntax _root; private readonly Stack _objectInitializerTypeStack = new(); @@ -34,14 +34,14 @@ private AdaptedDestinationRewriter( IEnumerable originalDestinationTypeTexts, string adaptedDestinationTypeName, ITypeSymbol adaptedDestinationTypeSymbol, - NullableContext nullableContext, + NullablePolicy nullablePolicy, ExpressionSyntax root) { _destinationCreationSpans = new HashSet(destinationCreationSpans); _destinationCreationTypeTexts = new HashSet(destinationCreationTypeTexts); _adaptedDestinationType = SyntaxFactory.ParseTypeName(adaptedDestinationTypeName); _adaptedDestinationTypeSymbol = adaptedDestinationTypeSymbol; - _nullableContext = nullableContext; + _nullablePolicy = nullablePolicy; _originalDestinationTypeTexts = new HashSet(originalDestinationTypeTexts); _root = root; } @@ -53,7 +53,7 @@ public static ExpressionSyntax Rewrite( ITypeSymbol originalDestinationType, string adaptedDestinationTypeName, ITypeSymbol adaptedDestinationType, - NullableContext nullableContext) + NullablePolicy nullablePolicy) { if (bodyToRewrite is ImplicitObjectCreationExpressionSyntax implicitCreation) { @@ -89,7 +89,7 @@ public static ExpressionSyntax Rewrite( originalDestinationTypeTexts, adaptedDestinationTypeName, adaptedDestinationType, - nullableContext, + nullablePolicy, bodyToRewrite) .Visit(bodyToRewrite)!; } @@ -270,7 +270,7 @@ private static IEnumerable GetMembersIncludingBaseTypes(ITypeSymbol typ private string GetObjectCreationTypeName(ITypeSymbol type) { - return TypeDisplay.ForSymbol(type, NullableAnnotation.NotAnnotated, _nullableContext); + return TypeDisplay.ForSymbol(type, NullableAnnotation.NotAnnotated, _nullablePolicy); } private string GetCastTypeName(ITypeSymbol type) @@ -278,7 +278,7 @@ private string GetCastTypeName(ITypeSymbol type) var annotation = type.NullableAnnotation == NullableAnnotation.Annotated ? NullableAnnotation.Annotated : NullableAnnotation.NotAnnotated; - return TypeDisplay.ForSymbol(type, annotation, _nullableContext); + return TypeDisplay.ForSymbol(type, annotation, _nullablePolicy); } private static bool IsAdaptableObjectType(ITypeSymbol type) diff --git a/source/CodeGenerators/UpdatableMethodGenerator.cs b/source/CodeGenerators/UpdatableMethodGenerator.cs index 47f0f04..0573861 100644 --- a/source/CodeGenerators/UpdatableMethodGenerator.cs +++ b/source/CodeGenerators/UpdatableMethodGenerator.cs @@ -7,7 +7,11 @@ namespace AlephMapper.CodeGenerators; -internal sealed class UpdatableMethodGenerator(string destPrefix, PropertyMappingContext typeContext, IReadOnlyList sourceParamNames) +internal sealed class UpdatableMethodGenerator( + string destPrefix, + PropertyMappingContext typeContext, + IReadOnlyList sourceParamNames, + AlephMapper.Helpers.NullablePolicy nullablePolicy) { private readonly List _lines = []; private readonly string _primarySourceParamName = sourceParamNames.FirstOrDefault() ?? "source"; @@ -407,11 +411,11 @@ private static bool IsNullExpression(ExpressionSyntax expression) return expression?.ToString().Trim() == "null"; } - private static string GetTypeName(ITypeSymbol type) => + private string GetTypeName(ITypeSymbol type) => AlephMapper.Helpers.TypeDisplay.ForSymbol( type, NullableAnnotation.NotAnnotated, - NullableContext.Enabled); + nullablePolicy); private string NormalizeConditionalMemberAccess(ExpressionSyntax expression) { diff --git a/source/Diagnostics/DiagnosticDescriptors.cs b/source/Diagnostics/DiagnosticDescriptors.cs index cf7c667..93cc09d 100644 --- a/source/Diagnostics/DiagnosticDescriptors.cs +++ b/source/Diagnostics/DiagnosticDescriptors.cs @@ -1,3 +1,5 @@ +#nullable enable + using Microsoft.CodeAnalysis; namespace AlephMapper.Diagnostics; @@ -160,4 +162,27 @@ public static class DiagnosticDescriptors "AlephMapper", DiagnosticSeverity.Warning, isEnabledByDefault: true); + + public static DiagnosticDescriptor? GetById(string id) => id switch + { + "AM0001" => UpdatableValueTypeReturn, + "AM0002" => ProjectableCircularReferences, + "AM0003" => UpdatableCircularReferences, + "AM0004" => GeneratorCrash, + "AM0005" => InvalidAdaptType, + "AM0006" => AdaptSourceMemberMissing, + "AM0007" => AdaptDestinationMemberMissing, + "AM0008" => AdaptIncompatibleType, + "AM0009" => AdaptNameConflict, + "AM0010" => AdaptUnsupportedSyntax, + "AM0011" => AdaptExpressionWithoutName, + "AM0012" => AdaptDuplicatePair, + "AM0013" => AdaptCircularHelper, + "AM0014" => AdaptOpenGenericType, + "AM0015" => AdaptRebindingFailed, + "AM0016" => UnsafeNullConditionalReceiver, + "AM0017" => UnsupportedNullConditionalExpression, + "AM0018" => AdaptGenericMethodUnsupported, + _ => null + }; } diff --git a/source/Generation/Emitters/AdaptationMemberEmitter.cs b/source/Generation/Emitters/AdaptationMemberEmitter.cs index cf5893e..af6c823 100644 --- a/source/Generation/Emitters/AdaptationMemberEmitter.cs +++ b/source/Generation/Emitters/AdaptationMemberEmitter.cs @@ -47,10 +47,10 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co } var adaptationName = string.IsNullOrWhiteSpace(adaptation.GeneratedName) ? mapping.Name : adaptation.GeneratedName!; - var sourceTypeName = TypeDisplay.ForSymbol(adaptation.SourceType, NullableAnnotation.None, details.NullableContext); - var destinationTypeName = TypeDisplay.ForSymbol(adaptation.DestinationType, NullableAnnotation.None, details.NullableContext); + var sourceTypeName = TypeDisplay.ForSymbol(adaptation.SourceType, NullableAnnotation.None, details.NullablePolicy); + var destinationTypeName = TypeDisplay.ForSymbol(adaptation.DestinationType, NullableAnnotation.None, details.NullablePolicy); var additionalParametersWithNames = string.Join(", ", mapping.Parameters.Skip(1).Select(parameter => - $"{TypeDisplay.ForSymbol(parameter.Type, parameter.NullableAnnotation, details.NullableContext)} {parameter.Name}")); + $"{TypeDisplay.ForSymbol(parameter.Type, parameter.NullableAnnotation, details.NullablePolicy)} {parameter.Name}")); var adaptationParametersWithNames = sourceTypeName + " " + details.SourceName + (string.IsNullOrEmpty(additionalParametersWithNames) ? "" : ", " + additionalParametersWithNames); @@ -66,7 +66,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co continue; } - var inliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, false, adaptation.NullStrategy); + var inliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, false, adaptation.NullStrategy, details.NullablePolicy); var inlinedBody = ((ExpressionSyntax)inliner.Visit(mapping.BodySyntax.Expression)!) .WithoutLeadingTrivia() .WithoutTrailingTrivia(); @@ -114,7 +114,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co mapping.ReturnType, destinationTypeName, adaptation.DestinationType, - details.NullableContext); + details.NullablePolicy); var adaptedBodyText = PrettyPrinter.Print(adaptedBody, 2); var adaptationParameterTypes = new[] { sourceTypeName }.Concat(details.ParameterTypeNames.Skip(1)).ToArray(); @@ -176,7 +176,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co continue; } - var updateInliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, true, NullConditionalRewrite.None); + var updateInliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, true, NullConditionalRewrite.None, details.NullablePolicy); var inlinedUpdateBody = (ExpressionSyntax)updateInliner.Visit(mapping.BodySyntax.Expression)!.WithoutTrivia(); context.AddUsings(updateInliner.UsingDirectives.Concat(mapping.UsingDirectives)); if (updateInliner.CircularReferences.Any()) @@ -195,7 +195,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co mapping.ReturnType, destinationTypeName, adaptation.DestinationType, - details.NullableContext); + details.NullablePolicy); var lines = new List(); if (!EmitHelpers.TryBuildUpdateAssignmentsWithInlining( adaptedUpdateBody, @@ -204,6 +204,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co adaptation.SourceType, mapping.Parameters.Select(parameter => parameter.Name).ToArray(), mapping.CollectionPolicy, + details.NullablePolicy, lines)) { continue; @@ -229,7 +230,7 @@ private static void EmitMapMember( string adaptedBodyText, MapperGenerationContext context) { - context.AppendMember(members => + context.AppendMember(details.NullablePolicy, members => { members.AppendLine(" /// "); members.AppendLine($" /// This is an auto-generated adapted mapping method for ."); @@ -246,7 +247,7 @@ private static void EmitExpressionMember( string adaptedBodyText, MapperGenerationContext context) { - context.AppendMember(members => + context.AppendMember(details.NullablePolicy, members => { members.AppendLine(" /// "); members.AppendLine($" /// This is an auto-generated adapted expression companion for ."); @@ -268,7 +269,7 @@ private static void EmitUpdateMember( IEnumerable lines, MapperGenerationContext context) { - context.AppendMember(members => + context.AppendMember(details.NullablePolicy, members => { members.AppendLine(" /// "); members.AppendLine($" /// This is an auto-generated adapted update method for ."); diff --git a/source/Generation/Emitters/ProjectableMemberEmitter.cs b/source/Generation/Emitters/ProjectableMemberEmitter.cs index cf242df..a5b16e7 100644 --- a/source/Generation/Emitters/ProjectableMemberEmitter.cs +++ b/source/Generation/Emitters/ProjectableMemberEmitter.cs @@ -15,7 +15,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co return; } - var inliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, false, mapping.NullStrategy); + var inliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, false, mapping.NullStrategy, details.NullablePolicy); var inlinedBody = inliner.Visit(mapping.BodySyntax.Expression)! .WithoutLeadingTrivia() .WithoutTrailingTrivia(); @@ -68,7 +68,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co ? "()" : "(" + details.ExtraExpressionParameterListWithNames + ")"; - context.AppendMember(members => + context.AppendMember(details.NullablePolicy, members => { members.AppendLine(" /// "); members.AppendLine($" /// This is an auto-generated expression companion for ."); diff --git a/source/Generation/Emitters/UpdatableMemberEmitter.cs b/source/Generation/Emitters/UpdatableMemberEmitter.cs index b3da2e6..1367bf7 100644 --- a/source/Generation/Emitters/UpdatableMemberEmitter.cs +++ b/source/Generation/Emitters/UpdatableMemberEmitter.cs @@ -17,7 +17,7 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co return; } - var inliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, true, NullConditionalRewrite.None); + var inliner = new InliningResolver(mapping.SemanticModel, context.MappingsByMethod, true, NullConditionalRewrite.None, details.NullablePolicy); var inlinedBody = inliner.Visit(mapping.BodySyntax.Expression)!.WithoutTrivia(); context.AddUsings(inliner.UsingDirectives.Concat(mapping.UsingDirectives)); if (inliner.CircularReferences.Any()) @@ -48,12 +48,13 @@ public static void Emit(MappingMethodDetails details, MapperGenerationContext co mapping.ParamType, mapping.Parameters.Select(parameter => parameter.Name).ToArray(), mapping.CollectionPolicy, + details.NullablePolicy, lines)) { return; } - context.AppendMember(members => + context.AppendMember(details.NullablePolicy, members => { members.AppendLine(" /// "); members.AppendLine($" /// This is an auto-generated update method for ."); diff --git a/source/Generation/MapperFileEmitter.cs b/source/Generation/MapperFileEmitter.cs index 7502d83..2caaba9 100644 --- a/source/Generation/MapperFileEmitter.cs +++ b/source/Generation/MapperFileEmitter.cs @@ -24,7 +24,6 @@ public static GeneratedMapperFile Render(MapperGenerationContext context) var output = new StringBuilder(); output.AppendLine("// "); - output.AppendLine("#nullable enable"); output.AppendLine(); foreach (var usingDirective in context.UsingDirectives.OrderBy(static directive => directive)) { diff --git a/source/Generation/MapperGenerationContext.cs b/source/Generation/MapperGenerationContext.cs index b344173..13f6095 100644 --- a/source/Generation/MapperGenerationContext.cs +++ b/source/Generation/MapperGenerationContext.cs @@ -1,4 +1,5 @@ using AlephMapper.Adaptation; +using AlephMapper.Helpers; using AlephMapper.Models; using Microsoft.CodeAnalysis; using System; @@ -42,14 +43,18 @@ public void AddUsings(IEnumerable usingDirectives) UsingDirectives.UnionWith(usingDirectives); } - public void AppendMember(Action writeMember) + public void AppendMember(NullablePolicy nullablePolicy, Action writeMember) { if (_hasMembers) { Members.AppendLine(); } + Members.AppendLine($"#nullable {nullablePolicy.Directive}"); + writeMember(Members); + Members.AppendLine("#nullable restore"); + _hasMembers = true; } } diff --git a/source/Generation/MapperGenerationResult.cs b/source/Generation/MapperGenerationResult.cs index 73807ee..710d09a 100644 --- a/source/Generation/MapperGenerationResult.cs +++ b/source/Generation/MapperGenerationResult.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; +using AlephMapper.Diagnostics; using System; using System.Collections.Immutable; using System.Linq; @@ -91,7 +92,7 @@ public static GenerationDiagnostic From(Diagnostic diagnostic) diagnostic.GetMessage(), diagnostic.Severity, diagnostic.Descriptor.Category, - location == Location.None ? null : location.SourceTree?.FilePath, + location == Location.None ? null : location.SourceTree?.FilePath ?? lineSpan.Path, location == Location.None ? 0 : location.SourceSpan.Start, location == Location.None ? 0 : location.SourceSpan.Length, location == Location.None ? 0 : lineSpan.StartLinePosition.Line, @@ -102,7 +103,8 @@ public static GenerationDiagnostic From(Diagnostic diagnostic) public Diagnostic ToDiagnostic() { - var descriptor = new DiagnosticDescriptor(Id, Title, Message, Category, Severity, isEnabledByDefault: true); + var descriptor = DiagnosticDescriptors.GetById(Id) ?? + new DiagnosticDescriptor(Id, Title, Message, Category, Severity, isEnabledByDefault: true); if (string.IsNullOrEmpty(FilePath)) { return Diagnostic.Create(descriptor, Location.None); diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index 87ab00b..3c30dcb 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -137,8 +137,7 @@ private static IReadOnlyList CreateMapperAnalyses( .ThenBy(static reference => reference.Span.Start)) { if (declarationReference.GetSyntax(cancellationToken) is not MethodDeclarationSyntax declaration || - declaration.ExpressionBody is null || - !MappingMethodCandidate.IsCandidate(declaration, cancellationToken)) + declaration.ExpressionBody is null) { continue; } diff --git a/source/Generation/MappingMethodDetails.cs b/source/Generation/MappingMethodDetails.cs index 094bcc0..d0e128d 100644 --- a/source/Generation/MappingMethodDetails.cs +++ b/source/Generation/MappingMethodDetails.cs @@ -16,20 +16,20 @@ public MappingMethodDetails(MappingAnalysis mapping) { Mapping = mapping; var nullableContextPosition = mapping.MethodSymbol.Locations.FirstOrDefault()?.SourceSpan.Start ?? 0; - var nullableContext = mapping.SemanticModel.GetNullableContext(nullableContextPosition); + var nullablePolicy = NullablePolicy.From(mapping.SemanticModel, nullableContextPosition); ParameterTypeNames = mapping.Parameters - .Select(parameter => TypeDisplay.ForSymbol(parameter.Type, parameter.NullableAnnotation, nullableContext)) + .Select(parameter => TypeDisplay.ForSymbol(parameter.Type, parameter.NullableAnnotation, nullablePolicy)) .ToArray(); - DestinationTypeName = TypeDisplay.ForSymbol(mapping.ReturnType, mapping.ReturnType.NullableAnnotation, nullableContext); - SourceTypeName = TypeDisplay.ForSymbol(mapping.ParamType, mapping.ParamType.NullableAnnotation, nullableContext); + DestinationTypeName = TypeDisplay.ForSymbol(mapping.ReturnType, mapping.ReturnType.NullableAnnotation, nullablePolicy); + SourceTypeName = TypeDisplay.ForSymbol(mapping.ParamType, mapping.ParamType.NullableAnnotation, nullablePolicy); SourceName = mapping.Parameters[0].Name; MethodParameterList = string.Join(", ", ParameterTypeNames); MethodParameterListWithNames = string.Join(", ", mapping.Parameters.Select(parameter => - $"{TypeDisplay.ForSymbol(parameter.Type, parameter.NullableAnnotation, nullableContext)} {parameter.Name}")); + $"{TypeDisplay.ForSymbol(parameter.Type, parameter.NullableAnnotation, nullablePolicy)} {parameter.Name}")); ExtraExpressionParameterTypeNames = ParameterTypeNames.Skip(1).ToArray(); ExtraExpressionParameterListWithNames = string.Join(", ", mapping.Parameters.Skip(1).Select(parameter => - $"{TypeDisplay.ForSymbol(parameter.Type, parameter.NullableAnnotation, nullableContext)} {parameter.Name}")); + $"{TypeDisplay.ForSymbol(parameter.Type, parameter.NullableAnnotation, nullablePolicy)} {parameter.Name}")); LambdaParameters = mapping.Parameters.Count == 1 ? mapping.Parameters[0].Name : "(" + string.Join(", ", mapping.Parameters.Select(parameter => parameter.Name)) + ")"; @@ -38,8 +38,8 @@ public MappingMethodDetails(MappingAnalysis mapping) ? string.Empty : "<" + string.Join(", ", mapping.MethodSymbol.TypeParameters.Select(static parameter => parameter.Name)) + ">"; MethodTypeParameterCount = mapping.MethodSymbol.TypeParameters.Length; - MethodConstraintClauses = BuildConstraintClauses(mapping.MethodSymbol.TypeParameters, nullableContext); - NullableContext = nullableContext; + MethodConstraintClauses = BuildConstraintClauses(mapping.MethodSymbol.TypeParameters, nullablePolicy); + NullablePolicy = nullablePolicy; } public MappingAnalysis Mapping { get; } @@ -56,11 +56,11 @@ public MappingMethodDetails(MappingAnalysis mapping) public string MethodTypeParameterList { get; } public int MethodTypeParameterCount { get; } public IReadOnlyList MethodConstraintClauses { get; } - public Microsoft.CodeAnalysis.NullableContext NullableContext { get; } + public NullablePolicy NullablePolicy { get; } private static IReadOnlyList BuildConstraintClauses( ImmutableArray typeParameters, - NullableContext nullableContext) + NullablePolicy nullablePolicy) { var clauses = new List(); foreach (var typeParameter in typeParameters) @@ -86,7 +86,7 @@ private static IReadOnlyList BuildConstraintClauses( } constraints.AddRange(typeParameter.ConstraintTypes.Select(type => - TypeDisplay.ForSymbol(type, type.NullableAnnotation, nullableContext))); + TypeDisplay.ForSymbol(type, type.NullableAnnotation, nullablePolicy))); if (typeParameter.HasConstructorConstraint && !typeParameter.HasValueTypeConstraint) { diff --git a/source/Helpers/EmitHelpers.cs b/source/Helpers/EmitHelpers.cs index 14b0048..707ae2a 100644 --- a/source/Helpers/EmitHelpers.cs +++ b/source/Helpers/EmitHelpers.cs @@ -15,6 +15,7 @@ public static bool TryBuildUpdateAssignmentsWithInlining( ITypeSymbol sourceType, IReadOnlyList sourceParameterNames, CollectionPropertiesPolicy collectionPolicy, + NullablePolicy nullablePolicy, List lines) { // Seed type collection with the destination (return) type to reliably resolve @@ -28,7 +29,7 @@ public static bool TryBuildUpdateAssignmentsWithInlining( var typeContext = propertyInfoCollector.TypeContext; - var processor = new UpdatableMethodGenerator(destPrefix, typeContext, sourceParameterNames); + var processor = new UpdatableMethodGenerator(destPrefix, typeContext, sourceParameterNames, nullablePolicy); List processedLines; var srcName = sourceParameterNames[0]; diff --git a/source/Helpers/NullablePolicy.cs b/source/Helpers/NullablePolicy.cs new file mode 100644 index 0000000..ce3bb78 --- /dev/null +++ b/source/Helpers/NullablePolicy.cs @@ -0,0 +1,55 @@ +using Microsoft.CodeAnalysis; + +namespace AlephMapper.Helpers; + +/// +/// The effective nullable policy for one generated mapping member. +/// +internal readonly struct NullablePolicy +{ + private NullablePolicy(NullableContext context) + { + Context = context; + } + + public NullableContext Context { get; } + + public bool AnnotationsEnabled => Context is + NullableContext.Enabled or NullableContext.AnnotationsEnabled; + + public bool WarningsEnabled => Context is + NullableContext.Enabled or NullableContext.WarningsEnabled; + + public string Directive => Context switch + { + NullableContext.Enabled => "enable", + NullableContext.WarningsEnabled => "enable warnings", + NullableContext.AnnotationsEnabled => "enable annotations", + _ => "disable" + }; + + public static NullablePolicy Disabled { get; } = new(NullableContext.Disabled); + + public static NullablePolicy From(SemanticModel model, int position) + { + var context = model.GetNullableContext(position); + var projectOptions = model.Compilation.Options.NullableContextOptions; + var projectWarningsEnabled = projectOptions is + NullableContextOptions.Enable or NullableContextOptions.Warnings; + var projectAnnotationsEnabled = projectOptions is + NullableContextOptions.Enable or NullableContextOptions.Annotations; + var warningsEnabled = (context & NullableContext.WarningsEnabled) != 0 || + ((context & NullableContext.WarningsContextInherited) != 0 && projectWarningsEnabled); + var annotationsEnabled = (context & NullableContext.AnnotationsEnabled) != 0 || + ((context & NullableContext.AnnotationsContextInherited) != 0 && projectAnnotationsEnabled); + var effectiveContext = (warningsEnabled, annotationsEnabled) switch + { + (true, true) => NullableContext.Enabled, + (true, false) => NullableContext.WarningsEnabled, + (false, true) => NullableContext.AnnotationsEnabled, + _ => NullableContext.Disabled + }; + + return new NullablePolicy(effectiveContext); + } +} diff --git a/source/Helpers/TypeDisplay.cs b/source/Helpers/TypeDisplay.cs index 6bf1412..aa9ad3a 100644 --- a/source/Helpers/TypeDisplay.cs +++ b/source/Helpers/TypeDisplay.cs @@ -20,15 +20,11 @@ internal static class TypeDisplay SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers); public static string ForSymbol(ITypeSymbol symbol, SemanticModel model, int position) - => ForSymbol(symbol, symbol.NullableAnnotation, model.GetNullableContext(position)); + => ForSymbol(symbol, symbol.NullableAnnotation, NullablePolicy.From(model, position)); - public static string ForSymbol(ITypeSymbol symbol, NullableAnnotation annotationOverride, NullableContext nullableContext) + public static string ForSymbol(ITypeSymbol symbol, NullableAnnotation annotationOverride, NullablePolicy nullablePolicy) { - var annotationsEnabled = nullableContext is NullableContext.Enabled - or NullableContext.AnnotationsEnabled - or NullableContext.AnnotationsContextInherited; - - var format = annotationsEnabled ? NullableFormat : NonNullableFormat; + var format = nullablePolicy.AnnotationsEnabled ? NullableFormat : NonNullableFormat; var effectiveAnnotation = annotationOverride != NullableAnnotation.None ? annotationOverride : symbol.NullableAnnotation; @@ -37,7 +33,7 @@ or NullableContext.AnnotationsEnabled : symbol; var display = displaySymbol.ToDisplayString(format); - if (annotationsEnabled && + if (nullablePolicy.AnnotationsEnabled && effectiveAnnotation == NullableAnnotation.Annotated && !display.EndsWith("?", StringComparison.Ordinal)) { diff --git a/source/Models/AdaptationAnalysis.cs b/source/Models/AdaptationAnalysis.cs index 8132732..19ced32 100644 --- a/source/Models/AdaptationAnalysis.cs +++ b/source/Models/AdaptationAnalysis.cs @@ -1,7 +1,6 @@ #nullable enable using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Text; namespace AlephMapper.Models; @@ -36,16 +35,31 @@ public AdaptationAnalysis( internal sealed class SourceLocationModel { - private SourceLocationModel(string? filePath, int start, int length) + private SourceLocationModel( + string? filePath, + int start, + int length, + int startLine, + int startCharacter, + int endLine, + int endCharacter) { FilePath = filePath; Start = start; Length = length; + StartLine = startLine; + StartCharacter = startCharacter; + EndLine = endLine; + EndCharacter = endCharacter; } public string? FilePath { get; } public int Start { get; } public int Length { get; } + public int StartLine { get; } + public int StartCharacter { get; } + public int EndLine { get; } + public int EndCharacter { get; } public static SourceLocationModel? FromSyntax(SyntaxReference? syntaxReference) { @@ -55,13 +69,24 @@ private SourceLocationModel(string? filePath, int start, int length) } var syntax = syntaxReference.GetSyntax(); - return new SourceLocationModel(syntax.SyntaxTree.FilePath, syntax.Span.Start, syntax.Span.Length); + var location = syntax.GetLocation(); + var lineSpan = location.GetLineSpan(); + return new SourceLocationModel( + lineSpan.Path, + location.SourceSpan.Start, + location.SourceSpan.Length, + lineSpan.StartLinePosition.Line, + lineSpan.StartLinePosition.Character, + lineSpan.EndLinePosition.Line, + lineSpan.EndLinePosition.Character); } public Location ToLocation() { - var span = new TextSpan(Start, Length); - var lineSpan = new LinePositionSpan(new LinePosition(0, Start), new LinePosition(0, Start + Length)); + var span = new Microsoft.CodeAnalysis.Text.TextSpan(Start, Length); + var lineSpan = new Microsoft.CodeAnalysis.Text.LinePositionSpan( + new Microsoft.CodeAnalysis.Text.LinePosition(StartLine, StartCharacter), + new Microsoft.CodeAnalysis.Text.LinePosition(EndLine, EndCharacter)); return Microsoft.CodeAnalysis.Location.Create(FilePath ?? string.Empty, span, lineSpan); } } diff --git a/source/SyntaxRewriters/InliningResolver.CollectionExpressionRewriter.cs b/source/SyntaxRewriters/InliningResolver.CollectionExpressionRewriter.cs index 5fba912..e8e08e0 100644 --- a/source/SyntaxRewriters/InliningResolver.CollectionExpressionRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.CollectionExpressionRewriter.cs @@ -196,7 +196,7 @@ private static bool IsDescendantOf(SyntaxNode child, SyntaxNode potentialParent) return false; } - private static ExpressionSyntax CreateConstructorExpression(ITypeSymbol? targetType, SyntaxNode originalExpression) + private ExpressionSyntax CreateConstructorExpression(ITypeSymbol? targetType, SyntaxNode originalExpression) { if (targetType is INamedTypeSymbol namedType) { @@ -240,31 +240,31 @@ private static ExpressionSyntax CreateConstructorExpression(ITypeSymbol? targetT .WithTrailingTrivia(originalExpression.GetTrailingTrivia()); } - private static ExpressionSyntax CreateListConstructor(ITypeSymbol elementType) + private ExpressionSyntax CreateListConstructor(ITypeSymbol elementType) { var elementTypeName = TypeDisplay.ForSymbol( elementType, elementType.NullableAnnotation, - NullableContext.Enabled); + nullablePolicy); return ParseExpression($"new global::System.Collections.Generic.List<{elementTypeName}>()"); } - private static ExpressionSyntax CreateArrayExpression(ITypeSymbol elementType) + private ExpressionSyntax CreateArrayExpression(ITypeSymbol elementType) { // Create Array.Empty() for better performance var elementTypeName = TypeDisplay.ForSymbol( elementType, elementType.NullableAnnotation, - NullableContext.Enabled); + nullablePolicy); return ParseExpression($"global::System.Array.Empty<{elementTypeName}>()"); } - private static ExpressionSyntax CreateGenericConstructor(INamedTypeSymbol namedType) + private ExpressionSyntax CreateGenericConstructor(INamedTypeSymbol namedType) { var typeSyntax = ParseTypeName(TypeDisplay.ForSymbol( namedType, NullableAnnotation.NotAnnotated, - NullableContext.Enabled)); + nullablePolicy)); return ObjectCreationExpression(typeSyntax.WithLeadingTrivia(Space)) .WithArgumentList(ArgumentList()); diff --git a/source/SyntaxRewriters/InliningResolver.ImplicitObjectCreationRewriter.cs b/source/SyntaxRewriters/InliningResolver.ImplicitObjectCreationRewriter.cs index 232c58a..2240d2a 100644 --- a/source/SyntaxRewriters/InliningResolver.ImplicitObjectCreationRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.ImplicitObjectCreationRewriter.cs @@ -15,7 +15,7 @@ public override SyntaxNode VisitObjectCreationExpression(ObjectCreationExpressio var typeName = AlephMapper.Helpers.TypeDisplay.ForSymbol( typeSymbol, NullableAnnotation.NotAnnotated, - model.GetNullableContext(node.SpanStart)); + nullablePolicy); rewritten = rewritten.WithType(ParseTypeName(typeName).WithTriviaFrom(rewritten.Type)); } @@ -32,7 +32,7 @@ public override SyntaxNode VisitImplicitObjectCreationExpression(ImplicitObjectC : AlephMapper.Helpers.TypeDisplay.ForSymbol( typeSymbol, NullableAnnotation.NotAnnotated, - model.GetNullableContext(implicitNew.SpanStart)); + nullablePolicy); if (type == null) { diff --git a/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs b/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs index 38721d6..2bfdc15 100644 --- a/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs @@ -18,6 +18,7 @@ internal sealed partial class InliningResolver( MappingCatalog catalog, bool forUpdateMethod, NullConditionalRewrite rewriteSupport, + NullablePolicy nullablePolicy, ITypeSymbol? returnTypeToAnnotate = null) : CSharpSyntaxRewriter { @@ -104,7 +105,7 @@ private void RecordCircularReference(IMethodSymbol method) { _inlinedMethods[normalizedMethod] = callee; var inlinedBody = - (ExpressionSyntax)new InliningResolver(callee.SemanticModel, catalog, forUpdateMethod, rewriteSupport, callee.ReturnType) + (ExpressionSyntax)new InliningResolver(callee.SemanticModel, catalog, forUpdateMethod, rewriteSupport, nullablePolicy, callee.ReturnType) { _callStack = _callStack, _circularReferences = _circularReferences, @@ -179,7 +180,7 @@ private void RecordCircularReference(IMethodSymbol method) try { _inlinedMethods[directCallMethod] = callee2; - var inlinedBody2 = (ExpressionSyntax)new InliningResolver(callee2.SemanticModel, catalog, forUpdateMethod, rewriteSupport, callee2.ReturnType) + var inlinedBody2 = (ExpressionSyntax)new InliningResolver(callee2.SemanticModel, catalog, forUpdateMethod, rewriteSupport, nullablePolicy, callee2.ReturnType) { _callStack = _callStack, _circularReferences = _circularReferences, diff --git a/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs b/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs index 9b6fe26..9a4798d 100644 --- a/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.NullConditionalRewriter.cs @@ -49,7 +49,19 @@ internal partial class InliningResolver if (rewriteSupport is NullConditionalRewrite.Ignore) { // Ignore the conditional access and simply return the accessed expression - return rewrittenWhenNotNull; + // Preserve the source semantics while suppressing the nullable-flow warning + // introduced by replacing `?.` with a regular member access. + if (!nullablePolicy.WarningsEnabled) + { + return rewrittenWhenNotNull; + } + + return rewrittenWhenNotNull is PostfixUnaryExpressionSyntax postfix && + postfix.IsKind(SyntaxKind.SuppressNullableWarningExpression) + ? rewrittenWhenNotNull + : PostfixUnaryExpression( + SyntaxKind.SuppressNullableWarningExpression, + rewrittenWhenNotNull); } if (rewriteSupport is NullConditionalRewrite.Rewrite) @@ -62,9 +74,27 @@ internal partial class InliningResolver // A null-conditional access always produces null when its receiver is null. // Its converted type can still be non-nullable when it is immediately consumed // by an expression such as `??`, so explicitly retain that nullability here. - // Generated files always enable nullable annotations, so render this cast in - // that context even when the input source has annotations disabled. - var castTypeName = TypeDisplay.ForSymbol(convertedType, NullableAnnotation.Annotated, NullableContext.Enabled); + var castTypeName = TypeDisplay.ForSymbol( + convertedType, + NullableAnnotation.Annotated, + nullablePolicy); + + var nullValue = convertedType.IsReferenceType && + convertedType.NullableAnnotation != NullableAnnotation.Annotated && + nullablePolicy.WarningsEnabled + ? (ExpressionSyntax)PostfixUnaryExpression( + SyntaxKind.SuppressNullableWarningExpression, + LiteralExpression(SyntaxKind.NullLiteralExpression)) + : LiteralExpression(SyntaxKind.NullLiteralExpression); + var nullBranch = CastExpression( + ParseTypeName(convertedType.IsReferenceType && + convertedType.NullableAnnotation != NullableAnnotation.Annotated + ? TypeDisplay.ForSymbol( + convertedType, + NullableAnnotation.NotAnnotated, + nullablePolicy) + : castTypeName), + nullValue); return ParenthesizedExpression( ConditionalExpression( @@ -76,10 +106,7 @@ internal partial class InliningResolver ParenthesizedExpression(rewrittenWhenNotNull.WithoutTrivia()) .WithLeadingTrivia(Space) .WithTrailingTrivia(Space), - CastExpression( - ParseTypeName(castTypeName), - LiteralExpression(SyntaxKind.NullLiteralExpression) - ).WithLeadingTrivia(Space) + nullBranch.WithLeadingTrivia(Space) ) ); } diff --git a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index bf6d888..025b918 100644 --- a/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptBoth/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { +#nullable disable /// /// This is an auto-generated adapted mapping method for . /// @@ -21,7 +21,9 @@ partial class PersonMapper Name = source.FirstName + " " + source.LastName, Email = source.Email }; +#nullable restore +#nullable disable /// /// This is an auto-generated adapted expression companion for . /// @@ -32,4 +34,5 @@ partial class PersonMapper Name = source.FirstName + " " + source.LastName, Email = source.Email }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs index b3932b2..31b20cb 100644 --- a/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptNested/Expected/Tests_PersonMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { +#nullable disable /// /// This is an auto-generated adapted mapping method for . /// @@ -28,7 +28,9 @@ partial class PersonMapper Name = source.FirstName + " " + source.LastName, Email = string.Empty }; +#nullable restore +#nullable disable /// /// This is an auto-generated adapted expression companion for . /// @@ -46,7 +48,9 @@ partial class PersonMapper Name = source.FirstName + " " + source.LastName, Email = string.Empty }; +#nullable restore +#nullable disable /// /// This is an auto-generated adapted expression companion for . /// @@ -65,4 +69,5 @@ partial class PersonMapper }) .ToList() }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs index 9fe803f..bf99033 100644 --- a/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/AdaptUpdate/Expected/Tests_AdaptUpdateMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class AdaptUpdateMapper { +#nullable disable /// /// This is an auto-generated adapted mapping method for . /// @@ -20,7 +20,9 @@ partial class AdaptUpdateMapper Name = prefix + source.Name, Email = source.Email }; +#nullable restore +#nullable disable /// /// This is an auto-generated adapted update method for . /// @@ -33,4 +35,5 @@ partial class AdaptUpdateMapper dest.Email = source.Email; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs index 595bdee..6ee1325 100644 --- a/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularMapper/Expected/AlephMapper_Tests_CircularMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class CircularMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -20,7 +20,9 @@ partial class CircularMapper /// public static global::System.Linq.Expressions.Expression> ProcessValueExpression() => source => source.Value.ToUpper() ?? ""; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -34,7 +36,9 @@ partial class CircularMapper { ProcessedValue = source.Value.ToUpper() ?? "" // Direct assignment without method call }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -49,4 +53,5 @@ partial class CircularMapper dest.ProcessedValue = source?.Value?.ToUpper() ?? ""; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs index 60dec50..9df9f1a 100644 --- a/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CircularPropertyMapper/Expected/AlephMapper_Tests_CircularPropertyMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class CircularPropertyMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -30,7 +30,9 @@ partial class CircularPropertyMapper } } }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -50,4 +52,5 @@ partial class CircularPropertyMapper dest.B.A.Name = source?.Name; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs index 2e611c1..911f563 100644 --- a/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/CollectionMapper/Expected/AlephMapper_Tests_CollectionMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Collections.Generic; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class CollectionMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -33,7 +33,9 @@ partial class CollectionMapper } : null }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -61,7 +63,9 @@ partial class CollectionMapper } return dest; } +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -81,7 +85,9 @@ partial class CollectionMapper } : null }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -106,4 +112,5 @@ partial class CollectionMapper } return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs index 90c6084..ef2638f 100644 --- a/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ConditionalPatternMapper/Expected/AlephMapper_Tests_ConditionalPatternMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ConditionalPatternMapper { +#nullable disable /// /// This is an auto-generated update method for . /// @@ -38,7 +38,9 @@ partial class ConditionalPatternMapper } return dest; } +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -64,7 +66,9 @@ partial class ConditionalPatternMapper } return dest; } +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -90,7 +94,9 @@ partial class ConditionalPatternMapper } return dest; } +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -119,7 +125,9 @@ partial class ConditionalPatternMapper } return dest; } +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -145,7 +153,9 @@ partial class ConditionalPatternMapper } return dest; } +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -171,4 +181,5 @@ partial class ConditionalPatternMapper } return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs index b3fbdd4..f2f52da 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreIgnoreMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class EfCoreIgnoreMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -20,7 +20,9 @@ partial class EfCoreIgnoreMapper /// public static global::System.Linq.Expressions.Expression> GetPersonNameExpression() => person => person.Name; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -31,7 +33,9 @@ partial class EfCoreIgnoreMapper /// public static global::System.Linq.Expressions.Expression> GetPersonEmailExpression() => person => person.Email; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -42,7 +46,9 @@ partial class EfCoreIgnoreMapper /// public static global::System.Linq.Expressions.Expression> GetPersonAgeExpression() => person => person.BirthInfo.Age; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -53,4 +59,5 @@ partial class EfCoreIgnoreMapper /// public static global::System.Linq.Expressions.Expression> GetBirthPlaceExpression() => person => person.BirthInfo.BirthPlace ?? "Unknown"; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs index 8bd890f..9a11c53 100644 --- a/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/EfCoreMapper/Expected/AlephMapper_Tests_EfCoreMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class EfCoreMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -29,10 +29,10 @@ partial class EfCoreMapper : (int?)null), BirthPlace = (p.BirthInfo != null ? (p.BirthInfo.BirthPlace) - : (string?)null) ?? "Unknown", + : (string)null) ?? "Unknown", BirthAddress = (p.BirthInfo != null ? (p.BirthInfo.Address) - : (string?)null) ?? "Not specified", + : (string)null) ?? "Not specified", HasBirthInfo = p.BirthInfo != null, IsAdult = (p.BirthInfo != null ? (p.BirthInfo.Age) @@ -51,7 +51,9 @@ partial class EfCoreMapper ? p.Name + " (" + p.BirthInfo.Age + " years old) from " + (p.BirthInfo.BirthPlace ?? "Unknown") : p.Name + " (unknown age) from Unknown" }; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -62,7 +64,9 @@ partial class EfCoreMapper /// public static global::System.Linq.Expressions.Expression> GetPersonNameExpression() => person => person.Name; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -73,7 +77,9 @@ partial class EfCoreMapper /// public static global::System.Linq.Expressions.Expression> GetPersonEmailExpression() => person => person.Email; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -86,7 +92,9 @@ partial class EfCoreMapper person => (person.BirthInfo != null ? (person.BirthInfo.Age) : (int?)null); +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -99,7 +107,9 @@ partial class EfCoreMapper person => (person.BirthInfo != null ? (person.BirthInfo.Age) : (int?)null) > 30; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -111,8 +121,10 @@ partial class EfCoreMapper public static global::System.Linq.Expressions.Expression> GetBirthPlaceExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.BirthPlace) - : (string?)null) ?? "Unknown"; + : (string)null) ?? "Unknown"; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -124,8 +136,10 @@ partial class EfCoreMapper public static global::System.Linq.Expressions.Expression> GetBirthAddressExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.Address) - : (string?)null) ?? "Not specified"; + : (string)null) ?? "Not specified"; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -136,7 +150,9 @@ partial class EfCoreMapper /// public static global::System.Linq.Expressions.Expression> HasBirthInfoExpression() => person => person.BirthInfo != null; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -149,7 +165,9 @@ partial class EfCoreMapper person => (person.BirthInfo != null ? (person.BirthInfo.Age) : (int?)null) >= 18; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -161,8 +179,10 @@ partial class EfCoreMapper public static global::System.Linq.Expressions.Expression> BornInUkraineExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.Address) - : (string?)null) != null && person.BirthInfo.Address.Contains("Ukraine"); + : (string)null) != null && person.BirthInfo.Address.Contains("Ukraine"); +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -173,7 +193,9 @@ partial class EfCoreMapper /// public static global::System.Linq.Expressions.Expression> GetAddressCountExpression() => person => person.Addresses.Count; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -184,7 +206,9 @@ partial class EfCoreMapper /// public static global::System.Linq.Expressions.Expression> GetOrderCountExpression() => person => person.Orders.Count; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -195,7 +219,9 @@ partial class EfCoreMapper /// public static global::System.Linq.Expressions.Expression> HasActiveAddressExpression() => person => person.Addresses.Any(a => a.IsActive); +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -206,7 +232,9 @@ partial class EfCoreMapper /// public static global::System.Linq.Expressions.Expression> HasCompletedOrdersExpression() => person => person.Orders.Any(o => o.IsCompleted); +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -219,7 +247,9 @@ partial class EfCoreMapper person => person.Orders .Where(o => o.IsCompleted) .Sum(o => o.Amount); +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -232,7 +262,9 @@ partial class EfCoreMapper person => person.BirthInfo != null ? person.Name + " (" + person.BirthInfo.Age + " years old) from " + (person.BirthInfo.BirthPlace ?? "Unknown") : person.Name + " (unknown age) from Unknown"; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -244,9 +276,11 @@ partial class EfCoreMapper public static global::System.Linq.Expressions.Expression> LivesInSamePlaceAsBornExpression() => person => (person.BirthInfo != null ? (person.BirthInfo.BirthPlace) - : (string?)null) != null + : (string)null) != null && person.Addresses.Any(a => a.IsActive && a.City == person.BirthInfo.BirthPlace); +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -263,7 +297,9 @@ partial class EfCoreMapper : person.BirthInfo.Age < 65 ? "Adult" : "Senior"; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -276,4 +312,5 @@ partial class EfCoreMapper person => person.Orders .Where(o => o.IsCompleted) .Sum(o => o.Amount) >= 1000m; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index bce4069..c57a17b 100644 --- a/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Expressive/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class SampleMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -21,4 +21,5 @@ partial class SampleMapper /// public static global::System.Linq.Expressions.Expression> ProjectNameExpression() => source => source.Name; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs index 74e9b17..2552e45 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ConditionalExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ConditionalExtensionTestPersonMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -32,4 +32,5 @@ partial class ConditionalExtensionTestPersonMapper FormattedAddress = $"{person.Address.Street}, {person.Address.City} {person.Address.PostalCode}" } }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs index c6d57c0..f44a055 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestAddressMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ExtensionTestAddressMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -27,4 +27,5 @@ partial class ExtensionTestAddressMapper PostalCode = address.PostalCode, FormattedAddress = $"{address.Street}, {address.City} {address.PostalCode}" }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs index 9f1627c..c467f31 100644 --- a/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ExtensionMethodInlining/Expected/AlephMapper_Tests_ExtensionTestPersonMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ExtensionTestPersonMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -32,4 +32,5 @@ partial class ExtensionTestPersonMapper FormattedAddress = $"{person.Address.Street}, {person.Address.City} {person.Address.PostalCode}" } }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs index 3b8f4cd..0ee4b8c 100644 --- a/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Mapper/Expected/AlephMapper_Tests_Mapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class Mapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -19,8 +19,10 @@ partial class Mapper /// /// public static global::System.Linq.Expressions.Expression> BornInKyivAndOlder35Expression() => - source => source.BirthInfo.Address == "Kyiv" && Mapper1.Older35(source.BirthInfo) && source.BirthInfo.Age < 65; + source => source.BirthInfo.Address == "Kyiv" && source.BirthInfo.Age > 35 && source.BirthInfo.Age < 65; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -31,7 +33,9 @@ partial class Mapper /// public static global::System.Linq.Expressions.Expression> BornInKyivExpression() => source => source.Address == "Kyiv"; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -42,7 +46,9 @@ partial class Mapper /// public static global::System.Linq.Expressions.Expression> Younger65Expression() => source => source.Age < 65; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -53,7 +59,9 @@ partial class Mapper /// public static global::System.Linq.Expressions.Expression> LivesInExpression() => source => source.Address == "Kyiv"; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -75,7 +83,9 @@ partial class Mapper : null, ContactInfo = source.Email }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -102,7 +112,9 @@ partial class Mapper dest.ContactInfo = source.Email; return dest; } +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -124,7 +136,9 @@ partial class Mapper }, ContactInfo = source.Email }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -151,7 +165,9 @@ partial class Mapper dest.ContactInfo = source.Email; return dest; } +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -166,4 +182,5 @@ partial class Mapper Age = bi.Age, Address = bi.Address }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs index 8b7c6b8..50d064b 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupSpec/Expected/AlephMapper_Tests_SimpleObjectMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class SimpleObjectMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -26,4 +26,5 @@ partial class SimpleObjectMapper .Select(attr => attr.Name) .ToList() ?? new global::System.Collections.Generic.List() }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs index cbc6d9d..b132488 100644 --- a/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MethodGroupToEntityList/Expected/AlephMapper_Tests_MethodGroupToEntityList_PersonMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -12,6 +11,7 @@ namespace AlephMapper.Tests.MethodGroupToEntityList; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -24,7 +24,11 @@ partial class PersonMapper dto => new global::AlephMapper.Tests.MethodGroupToEntityList.Person { ContactNumbers = dto.PhoneNumbers - .Select(PhoneMapper.ToEntity) + .Select(dto => new global::AlephMapper.Tests.MethodGroupToEntityList.PhoneNumber + { + Number = dto.Number + }) .ToList() }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs index fee68e2..fe2fb07 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperIgnore_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests.MultiParamExtensionInlining; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonProductMapperIgnore { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -25,4 +25,5 @@ partial class PersonProductMapperIgnore Name = person.Name, FavoritePrice = "$" + person.FavoriteProduct.Price }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs index d9a05ca..9aab34d 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_PersonProductMapperRewrite_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests.MultiParamExtensionInlining; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonProductMapperRewrite { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -25,6 +25,7 @@ partial class PersonProductMapperRewrite Name = person.Name, FavoritePrice = (person.FavoriteProduct != null ? ("$" + person.FavoriteProduct.Price) - : (string?)null) + : (string)null) }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs index 42024b2..ef8a4bf 100644 --- a/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParamExtensionInlining/Expected/AlephMapper_Tests_MultiParamExtensionInlining_ProductMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests.MultiParamExtensionInlining; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ProductMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -26,4 +26,5 @@ partial class ProductMapper PriceTag = "$" + product.Price, Total = product.Price * product.Quantity * (1 + 0.1m) - 5m }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs index 1610eb0..8872dde 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_MultiParamProjectableMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class MultiParamProjectableMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -25,4 +25,5 @@ partial class MultiParamProjectableMapper FullName = person.First + " " + person.Last, BirthYear = currentYear - person.Age }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs index ab6f4db..c24874b 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NamedArgMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NamedArgMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -24,4 +24,5 @@ partial class NamedArgMapper { FullName = person.First + " " + person.Last }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs index c0131ce..fbde9d4 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_NestedMultiParamMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedMultiParamMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -24,4 +24,5 @@ partial class NestedMultiParamMapper { FullName = person.First + " " + person.Last + " (age " + person.Age + ")" }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs index 7c59695..891790d 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_PersonMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class PersonMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -27,4 +27,5 @@ partial class PersonMapper Description = person.First + " " + person.Last + " (age " + person.Age + ")", BirthYear = 2026 - person.Age }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs index 4f8681b..c07b2e3 100644 --- a/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/MultiParameterInlining/Expected/AlephMapper_Tests_MultiParameterInlining_UpdatableMultiParamMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests.MultiParameterInlining; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class UpdatableMultiParamMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -25,7 +25,9 @@ partial class UpdatableMultiParamMapper FullName = person.First + " " + person.Last, BirthYear = currentYear - person.Age }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -42,4 +44,5 @@ partial class UpdatableMultiParamMapper dest.BirthYear = currentYear - person.Age; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs index 71962b5..b8a94e4 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_AddressMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedExt_AddressMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -25,4 +25,5 @@ partial class NestedExt_AddressMapper Street = a.Street, City = a.City }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs index bbb9e3f..82a085a 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Ignore_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedExt_PersonMapper_Ignore { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -28,4 +28,5 @@ partial class NestedExt_PersonMapper_Ignore City = p.Friend.HomeAddress.City } }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs index 1fb72e8..37fe5fb 100644 --- a/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NestedConditionalExtensionInlining/Expected/AlephMapper_Tests_NestedExt_PersonMapper_Rewrite_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NestedExt_PersonMapper_Rewrite { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -30,8 +30,9 @@ partial class NestedExt_PersonMapper_Rewrite Street = p.Friend.HomeAddress.Street, City = p.Friend.HomeAddress.City }) - : (global::AlephMapper.Tests.NestedExt_AddressDto?)null)) - : (global::AlephMapper.Tests.NestedExt_AddressDto?)null)) - : (global::AlephMapper.Tests.NestedExt_AddressDto?)null) + : (global::AlephMapper.Tests.NestedExt_AddressDto)null)) + : (global::AlephMapper.Tests.NestedExt_AddressDto)null)) + : (global::AlephMapper.Tests.NestedExt_AddressDto)null) }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs index efa6f00..cc91a65 100644 --- a/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullCoalesceValueAssignment/Expected/AlephMapper_Tests_NullCoalesceValueAssignmentMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using AlephMapper; @@ -12,6 +11,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullCoalesceValueAssignmentMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -25,4 +25,5 @@ partial class NullCoalesceValueAssignmentMapper { Must = s.Maybe ?? 42 }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs index 4f3c8e0..27ed001 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_IgnoreMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class IgnoreMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -20,7 +20,9 @@ partial class IgnoreMapper /// public static global::System.Linq.Expressions.Expression> GetAddressExpression() => source => source.BirthInfo.Address ?? "Unknown"; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -31,4 +33,5 @@ partial class IgnoreMapper /// public static global::System.Linq.Expressions.Expression> HasAddressExpression() => source => source.BirthInfo.Address != null; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs index ff22f28..f62206c 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_NoneMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NoneMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -20,4 +20,5 @@ partial class NoneMapper /// public static global::System.Linq.Expressions.Expression> GetNameExpression() => source => source.Name; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs index 0c40df2..764589d 100644 --- a/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullConditionalRewrite/Expected/AlephMapper_Tests_RewriteMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class RewriteMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -21,8 +21,10 @@ partial class RewriteMapper public static global::System.Linq.Expressions.Expression> GetAddressExpression() => dto => (dto.BirthInfo != null ? (dto.BirthInfo.Address) - : (string?)null) ?? "Unknown"; + : (string)null) ?? "Unknown"; +#nullable restore +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -34,5 +36,6 @@ partial class RewriteMapper public static global::System.Linq.Expressions.Expression> HasAddressExpression() => source => (source.BirthInfo != null ? (source.BirthInfo.Address) - : (string?)null) != null; + : (string)null) != null; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs index 3123169..971db9a 100644 --- a/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableDisabled/Expected/Tests_NullableDisabledMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullableDisabledMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -22,5 +22,6 @@ partial class NullableDisabledMapper public static global::System.Linq.Expressions.Expression> GetNameExpression() => person => (person != null ? (person.Name) - : (string?)null); + : (string)null); +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs index 24f3290..e0aaf98 100644 --- a/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/NullableEnabled/Expected/Tests_NullableEnabledMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullableEnabledMapper { +#nullable enable /// /// This is an auto-generated expression companion for . /// @@ -23,4 +23,5 @@ partial class NullableEnabledMapper person => (person != null ? (person.Name) : (string?)null); +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs index e50675b..85cf493 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtAddressMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtAddressMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -21,4 +21,5 @@ partial class TechDebtAddressMapper /// public static global::System.Linq.Expressions.Expression> FormatAddressExpression() => address => address.FormattedAddress; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs index 3f22308..886acd3 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperIgnore_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtPersonMapperIgnore { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -25,4 +25,5 @@ partial class TechDebtPersonMapperIgnore Name = person.Name, AddressStr = person.Address.FormattedAddress ?? "No Address" }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs index e1998cc..d689bd1 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperNone_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; diff --git a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs index 6dd30f6..7925d0b 100644 --- a/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TechDebtFix/Expected/AlephMapper_Tests_TechDebtPersonMapperRewrite_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AgileObjects.ReadableExpressions; using System; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class TechDebtPersonMapperRewrite { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -25,6 +25,7 @@ partial class TechDebtPersonMapperRewrite Name = person.Name, AddressStr = (person.Address != null ? (person.Address.FormattedAddress) - : (string?)null) ?? "No Address" + : (string)null) ?? "No Address" }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs index a1f26a9..39d8242 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_Address1Mapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class Address1Mapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -36,4 +36,5 @@ partial class Address1Mapper HouseNumber = sourceAddress.Line2.HouseNumber } }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs index cedca79..a0c5b52 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_AddressLineMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class AddressLineMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -26,4 +26,5 @@ partial class AddressLineMapper Street = sourceAddressLine1.Street, HouseNumber = sourceAddressLine1.HouseNumber }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs index 39569d5..9d84d62 100644 --- a/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/TestModel1Mapper/Expected/AlephMapper_Tests_TestModel1Mapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class TestModel1Mapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -43,7 +43,9 @@ partial class TestModel1Mapper } : null }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -90,4 +92,5 @@ partial class TestModel1Mapper } return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs index 2c21a4e..535e387 100644 --- a/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/Updatable/Expected/Tests_SampleMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using AlephMapper; using System; @@ -11,6 +10,7 @@ namespace Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class SampleMapper { +#nullable disable /// /// This is an auto-generated update method for . /// @@ -26,4 +26,5 @@ partial class SampleMapper dest.Age = source.Age; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs index 043a2ad..59bc4c0 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexPropertyMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ComplexPropertyMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -30,7 +30,9 @@ partial class ComplexPropertyMapper } } }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -49,4 +51,5 @@ partial class ComplexPropertyMapper dest.NestedClass.InnerClass.DeepValue = source.NestedStruct.InnerStruct.DeepValue; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs index db2f93d..44ab02e 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ComplexValueTypeMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ComplexValueTypeMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -60,4 +60,5 @@ partial class ComplexValueTypeMapper } } }; +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs index 4c3e590..4564709 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_EdgeCaseMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class EdgeCaseMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -31,7 +31,9 @@ partial class EdgeCaseMapper } } }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -51,4 +53,5 @@ partial class EdgeCaseMapper dest.ComplexValue.NestedClass.Value = source.ComplexValue.NestedStruct.Value; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs index 4340282..2585acf 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_MixedTypeMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -11,6 +10,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class MixedTypeMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -36,7 +36,9 @@ partial class MixedTypeMapper } : null }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -67,4 +69,5 @@ partial class MixedTypeMapper } return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs index f3c156f..b3c314e 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_NullableValueTypeMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class NullableValueTypeMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -25,7 +25,9 @@ partial class NullableValueTypeMapper NullableBoolProperty = source.NullableBoolProperty, NullableDateTimeProperty = source.NullableDateTimeProperty }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -42,4 +44,5 @@ partial class NullableValueTypeMapper dest.NullableDateTimeProperty = source.NullableDateTimeProperty; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs index 7320f3a..50ccf17 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ReferenceTypeOnlyMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ReferenceTypeOnlyMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -29,7 +29,9 @@ partial class ReferenceTypeOnlyMapper } : null }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -54,4 +56,5 @@ partial class ReferenceTypeOnlyMapper } return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs index 8533fce..5da7337 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_SimpleValueToReferenceMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class SimpleValueToReferenceMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -24,7 +24,9 @@ partial class SimpleValueToReferenceMapper Value = source.Value, Name = source.Name }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -39,4 +41,5 @@ partial class SimpleValueToReferenceMapper dest.Name = source.Name; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs index a46a7da..8c750c0 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueToReferenceMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ValueToReferenceMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -60,7 +60,9 @@ partial class ValueToReferenceMapper } } }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -105,4 +107,5 @@ partial class ValueToReferenceMapper dest.Metadata.Tags.Category = source.Metadata.Tags.Category; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs index a4973fe..f821879 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; diff --git a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs index 9f842f7..a37fe0d 100644 --- a/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs +++ b/tests/AlephMapper.Tests/Files/ValueTypesAndReferenceTypes/Expected/AlephMapper_Tests_ValueTypeOnlyMapper_GeneratedMappings.g.cs @@ -1,5 +1,4 @@ // -#nullable enable using System; using System.Linq; @@ -10,6 +9,7 @@ namespace AlephMapper.Tests; [global::System.CodeDom.Compiler.GeneratedCode("AlephMapper", "0.7.0.0")] partial class ValueTypeOnlyMapper { +#nullable disable /// /// This is an auto-generated expression companion for . /// @@ -26,7 +26,9 @@ partial class ValueTypeOnlyMapper DateTimeProperty = source.DateTimeProperty, DecimalProperty = source.DecimalProperty }; +#nullable restore +#nullable disable /// /// This is an auto-generated update method for . /// @@ -44,4 +46,5 @@ partial class ValueTypeOnlyMapper dest.DecimalProperty = source.DecimalProperty; return dest; } +#nullable restore } diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index d421d1f..8573d4a 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis.Testing; using Microsoft.EntityFrameworkCore; using AlephMapper.Generation; +using AlephMapper.Diagnostics; using System.Diagnostics; using System.Text; @@ -33,6 +34,94 @@ public async Task UnrelatedMethodsAreRejectedBySyntaxCandidateFilter() await Assert.That(MappingMethodCandidate.IsCandidate(method, CancellationToken.None)).IsFalse(); } + [Test] + public async Task GenerationDiagnosticsPreserveDescriptorMetadata() + { + var original = Diagnostic.Create(DiagnosticDescriptors.GeneratorCrash, Location.None, "boom"); + var roundTripped = GenerationDiagnostic.From(original).ToDiagnostic(); + + await Assert.That(roundTripped.Descriptor.Description.ToString()) + .IsEqualTo(original.Descriptor.Description.ToString()); + await Assert.That(roundTripped.Descriptor.HelpLinkUri) + .IsEqualTo(original.Descriptor.HelpLinkUri); + } + + [Test] + public async Task GeneratedMembersUseOneTransparentNullablePolicy() + { + var cases = new[] + { + new { Directive = "#nullable disable", Expected = "disable", Annotations = false, ProjectDefault = NullableContextOptions.Disable }, + new { Directive = "#nullable enable", Expected = "enable", Annotations = true, ProjectDefault = NullableContextOptions.Disable }, + new { Directive = "#nullable enable warnings", Expected = "enable warnings", Annotations = false, ProjectDefault = NullableContextOptions.Disable }, + new { Directive = "#nullable enable annotations", Expected = "enable annotations", Annotations = true, ProjectDefault = NullableContextOptions.Disable }, + new { Directive = string.Empty, Expected = "enable", Annotations = true, ProjectDefault = NullableContextOptions.Enable } + }; + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + + foreach (var testCase in cases) + { + var nullableSuffix = testCase.Annotations ? "?" : string.Empty; + var source = $$""" + using AlephMapper; + + namespace NullablePolicyFixture; + + {{testCase.Directive}} + public static partial class Mapper + { + [Projectable] + [Updatable] + [Adapt(typeof(Employee), typeof(EmployeeDto), Name = "MapEmployee")] + public static PersonDto Map(Person source, string{{nullableSuffix}} prefix) => + new() { Name = prefix + source.Name }; + } + {{(testCase.Directive.Length == 0 ? string.Empty : "#nullable restore")}} + + public sealed class Person { public string Name { get; set; } = string.Empty; } + public sealed class Employee { public string Name { get; set; } = string.Empty; } + public sealed class PersonDto { public string Name { get; set; } = string.Empty; } + public sealed class EmployeeDto { public string Name { get; set; } = string.Empty; } + """; + var compilation = CSharpCompilation.Create( + "NullablePolicy_" + testCase.Expected.Replace(" ", "_", StringComparison.Ordinal), + [CSharpSyntaxTree.ParseText(source, _parseOptions)], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) + .WithNullableContextOptions(testCase.ProjectDefault)); + + var driver = _driver.RunGeneratorsAndUpdateCompilation( + compilation, + out var outputCompilation, + out var generatorDiagnostics); + var result = driver.GetRunResult().Results.Single(); + var mapperSource = result.GeneratedSources + .Select(generated => generated.SourceText.ToString()) + .Single(generated => generated.Contains("partial class Mapper", StringComparison.Ordinal)); + var generatedTrees = outputCompilation.SyntaxTrees + .Where(tree => !compilation.SyntaxTrees.Contains(tree)) + .ToHashSet(); + + await Assert.That(generatorDiagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(result.Diagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(outputCompilation.GetDiagnostics().Where(diagnostic => + diagnostic.Severity == DiagnosticSeverity.Error && + diagnostic.Location.SourceTree is { } tree && + generatedTrees.Contains(tree))).IsEmpty(); + await Assert.That(outputCompilation.GetDiagnostics().Where(diagnostic => + diagnostic.Severity == DiagnosticSeverity.Warning && + diagnostic.Id.StartsWith("CS86", StringComparison.Ordinal) && + diagnostic.Location.SourceTree is { } tree && + generatedTrees.Contains(tree))).IsEmpty(); + await Assert.That(mapperSource).Contains("#nullable " + testCase.Expected); + await Assert.That(mapperSource.StartsWith("// " + Environment.NewLine + Environment.NewLine, StringComparison.Ordinal)).IsTrue(); + await Assert.That(mapperSource.Contains("string? prefix", StringComparison.Ordinal)).IsEqualTo(testCase.Annotations); + await Assert.That(mapperSource).Contains("MapExpression"); + await Assert.That(mapperSource).Contains("MapEmployeeExpression"); + await Assert.That(mapperSource).Contains("MapEmployee("); + } + } + [Test] public async Task MapperHelpersRemainCandidatesForInlining() { @@ -45,6 +134,56 @@ public async Task MapperHelpersRemainCandidatesForInlining() await Assert.That(MappingMethodCandidate.IsCandidate(methods.Single(method => method.Identifier.ValueText == "Helper"), CancellationToken.None)).IsTrue(); } + [Test] + public async Task ExternalOrdinaryHelpersAreInlinedIntoProjectableMappings() + { + const string source = """ + using AlephMapper; + + namespace Fixture; + + public sealed class Person + { + public string FirstName { get; set; } = ""; + public string LastName { get; set; } = ""; + } + + public sealed class PersonDto + { + public string Name { get; set; } = ""; + } + + public static class ExternalHelpers + { + public static string FullName(Person person) => person.FirstName + " " + person.LastName; + } + + public static partial class PersonMapper + { + [Projectable] + public static PersonDto Map(Person person) => new() { Name = ExternalHelpers.FullName(person) }; + } + """; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var compilation = CSharpCompilation.Create( + "ExternalHelperInlining", + [CSharpSyntaxTree.ParseText(source, _parseOptions)], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var driver = _driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var diagnostics); + var generated = driver.GetRunResult().Results.Single().GeneratedSources + .Single(result => result.HintName.EndsWith("PersonMapper_GeneratedMappings.g.cs", StringComparison.Ordinal)) + .SourceText + .ToString(); + + await Assert.That(diagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(outputCompilation.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); + await Assert.That(generated).DoesNotContain("ExternalHelpers.FullName"); + await Assert.That(generated).Contains("person.FirstName + \" \" + person.LastName"); + } + [Test] public async Task ClassLevelConfigurationAcrossPartialDeclarationsGeneratesOnce() { @@ -253,7 +392,7 @@ await Assert.That(result.GeneratedSources } [Test] - public async Task AttributeCandidatesRemainUnchangedWhenOnlyUnrelatedSourceChanges() + public async Task MapperGenerationResultRemainsStableWhenUnrelatedSourceChanges() { const string mapperA = """ using AlephMapper; @@ -299,6 +438,7 @@ public static partial class MapperB .ToArray(); await Assert.That(candidateOutputs).Count().IsEqualTo(2); + // Unchanged means the step reran but produced an equal value; it is not a cache hit. await Assert.That(candidateOutputs.All(static output => output.Item2 == IncrementalStepRunReason.Unchanged)).IsTrue(); } @@ -529,6 +669,17 @@ await Assert.That(outputCompilation.GetDiagnostics() .Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error && diagnostic.Location.SourceTree is { } sourceTree && generatedSyntaxTrees.Contains(sourceTree))).IsEmpty(); + // The nullable-disabled fixture specifically verifies that generated output preserves + // the source nullable context without introducing nullable-flow warnings. Other + // fixtures intentionally exercise policies that dereference nullable values. + if (name == "NullableDisabled") + { + await Assert.That(outputCompilation.GetDiagnostics() + .Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Warning && + diagnostic.Id.StartsWith("CS86", StringComparison.Ordinal) && + diagnostic.Location.SourceTree is { } sourceTree && + generatedSyntaxTrees.Contains(sourceTree))).IsEmpty(); + } var actualSources = result.GeneratedSources.ToDictionary( source => Path.GetFileName(source.HintName), @@ -1148,6 +1299,44 @@ public async Task AdaptationDiagnosticsAreReported() } } + [Test] + public async Task AdaptationDiagnosticsPreserveSourceLocation() + { + const string source = """ + using AlephMapper; + + namespace Fixture; + + public static partial class Mapper + { + // Keep the attribute away from the first line to verify line mapping. + [Adapt(typeof(Employee), typeof(EmployeeDto), Name = "MapEmployee")] + public static PersonDto MapPerson(Person source) => new() { Name = source.Name }; + } + + public sealed class Person { public string Name { get; set; } = string.Empty; } + public sealed class Employee { public int Name { get; set; } } + public sealed class PersonDto { public string Name { get; set; } = string.Empty; } + public sealed class EmployeeDto { public string Name { get; set; } = string.Empty; } + """; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var syntaxTree = CSharpSyntaxTree.ParseText(source, _parseOptions, "AdaptLocation.cs"); + var compilation = CSharpCompilation.Create( + "AdaptationDiagnosticLocation", + [syntaxTree], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var driver = _driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out _); + var diagnostic = driver.GetRunResult().Results.Single().Diagnostics.Single(diagnostic => diagnostic.Id == "AM0008"); + var lineSpan = diagnostic.Location.GetLineSpan(); + + await Assert.That(diagnostic.Location).IsNotEqualTo(Location.None); + await Assert.That(lineSpan.Path).IsEqualTo("AdaptLocation.cs"); + await Assert.That(lineSpan.StartLinePosition.Line).IsEqualTo(7); + } + [Test] public async Task UnsafeNullConditionalReceiverReportsDiagnosticAndSkipsExpression() { From a1134262d3566fee9bad3241e8251c774294aa19 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 17:27:20 +0200 Subject: [PATCH 16/22] Fixed all actionable findings from PR Review Findings.md. - Preserved formatted diagnostic messages during round-trip. - Rebound diagnostics to original SyntaxTree instances at output time, restoring #pragma warning disable AM0018 suppression. - Corrected the crash-report link from IMP005 to AM0004. - Added regression coverage for message formatting, syntax-tree location, pragma suppression, and crash-link ID. --- source/AlephSourceGenerator.cs | 3 +- source/Diagnostics/DiagnosticDescriptors.cs | 2 +- source/Generation/MapperGenerationResult.cs | 30 ++++++++- source/Generation/MapperSourceOutput.cs | 12 ++-- .../AlephMapper.Tests/SourceGeneratorTests.cs | 61 ++++++++++++++++++- 5 files changed, 97 insertions(+), 11 deletions(-) diff --git a/source/AlephSourceGenerator.cs b/source/AlephSourceGenerator.cs index c2bf073..18408a8 100644 --- a/source/AlephSourceGenerator.cs +++ b/source/AlephSourceGenerator.cs @@ -55,7 +55,8 @@ private static void RegisterMapperOutput( context.RegisterSourceOutput( mapperResults .WithTrackingName($"AlephMapper.{configurationKind}Candidates") - .WithTrackingName($"AlephMapper.{configurationKind}GenerationResult"), + .WithTrackingName($"AlephMapper.{configurationKind}GenerationResult") + .Combine(context.CompilationProvider), MapperSourceOutput.Emit); } } diff --git a/source/Diagnostics/DiagnosticDescriptors.cs b/source/Diagnostics/DiagnosticDescriptors.cs index 93cc09d..32d31cc 100644 --- a/source/Diagnostics/DiagnosticDescriptors.cs +++ b/source/Diagnostics/DiagnosticDescriptors.cs @@ -9,7 +9,7 @@ namespace AlephMapper.Diagnostics; public static class DiagnosticDescriptors { private const string CrashIssueUrl = - "https://github.com/Raffinert/AlephMapper/issues/new?labels=bug&title=Generator%20crash:%20IMP005"; + "https://github.com/Raffinert/AlephMapper/issues/new?labels=bug&title=Generator%20crash:%20AM0004"; public static readonly DiagnosticDescriptor UpdatableValueTypeReturn = new( "AM0001", diff --git a/source/Generation/MapperGenerationResult.cs b/source/Generation/MapperGenerationResult.cs index 710d09a..d02bc1b 100644 --- a/source/Generation/MapperGenerationResult.cs +++ b/source/Generation/MapperGenerationResult.cs @@ -101,22 +101,46 @@ public static GenerationDiagnostic From(Diagnostic diagnostic) location == Location.None ? 0 : lineSpan.EndLinePosition.Character); } - public Diagnostic ToDiagnostic() + public Diagnostic ToDiagnostic(Compilation compilation) { - var descriptor = DiagnosticDescriptors.GetById(Id) ?? - new DiagnosticDescriptor(Id, Title, Message, Category, Severity, isEnabledByDefault: true); + var descriptor = CreateDescriptor(); if (string.IsNullOrEmpty(FilePath)) { return Diagnostic.Create(descriptor, Location.None); } var span = new TextSpan(Start, Length); + var filePath = FilePath; + var sourceTree = compilation.SyntaxTrees.FirstOrDefault(tree => + string.Equals(tree.FilePath, filePath, StringComparison.Ordinal)); + if (sourceTree is not null && span.End <= sourceTree.GetText().Length) + { + return Diagnostic.Create(descriptor, Location.Create(sourceTree, span)); + } + var lineSpan = new LinePositionSpan( new LinePosition(StartLine, StartCharacter), new LinePosition(EndLine, EndCharacter)); return Diagnostic.Create(descriptor, Location.Create(FilePath!, span, lineSpan)); } + private DiagnosticDescriptor CreateDescriptor() + { + var original = DiagnosticDescriptors.GetById(Id); + return original is null + ? new DiagnosticDescriptor(Id, Title, Message, Category, Severity, isEnabledByDefault: true) + : new DiagnosticDescriptor( + original.Id, + original.Title, + Message, + original.Category, + original.DefaultSeverity, + original.IsEnabledByDefault, + original.Description, + original.HelpLinkUri, + original.CustomTags.ToArray()); + } + public bool Equals(GenerationDiagnostic other) { return Id == other.Id && Title == other.Title && Message == other.Message && Severity == other.Severity && diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index 3c30dcb..9dce9bb 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -80,16 +80,18 @@ public static MapperGenerationResult Create( #endif } - public static void Emit(SourceProductionContext context, MapperGenerationResult result) + public static void Emit( + SourceProductionContext context, + (MapperGenerationResult Result, Compilation Compilation) output) { - foreach (var diagnostic in result.Diagnostics) + foreach (var diagnostic in output.Result.Diagnostics) { - context.ReportDiagnostic(diagnostic.ToDiagnostic()); + context.ReportDiagnostic(diagnostic.ToDiagnostic(output.Compilation)); } - if (result.HintName is not null && result.Source is not null) + if (output.Result.HintName is not null && output.Result.Source is not null) { - context.AddSource(result.HintName, result.Source); + context.AddSource(output.Result.HintName, output.Result.Source); } } diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index 8573d4a..130fc0b 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -37,13 +37,30 @@ public async Task UnrelatedMethodsAreRejectedBySyntaxCandidateFilter() [Test] public async Task GenerationDiagnosticsPreserveDescriptorMetadata() { + var compilation = CSharpCompilation.Create("DiagnosticMetadata"); var original = Diagnostic.Create(DiagnosticDescriptors.GeneratorCrash, Location.None, "boom"); - var roundTripped = GenerationDiagnostic.From(original).ToDiagnostic(); + var roundTripped = GenerationDiagnostic.From(original).ToDiagnostic(compilation); await Assert.That(roundTripped.Descriptor.Description.ToString()) .IsEqualTo(original.Descriptor.Description.ToString()); await Assert.That(roundTripped.Descriptor.HelpLinkUri) .IsEqualTo(original.Descriptor.HelpLinkUri); + await Assert.That(DiagnosticDescriptors.GeneratorCrash.HelpLinkUri).Contains("AM0004"); + await Assert.That(DiagnosticDescriptors.GeneratorCrash.HelpLinkUri).DoesNotContain("IMP005"); + } + + [Test] + public async Task DiagnosticRoundTripPreservesFormattedMessage() + { + var compilation = CSharpCompilation.Create("DiagnosticMessage"); + var original = Diagnostic.Create( + DiagnosticDescriptors.AdaptIncompatibleType, + Location.None, + "Map", + "Name"); + var roundTripped = GenerationDiagnostic.From(original).ToDiagnostic(compilation); + + await Assert.That(roundTripped.GetMessage()).IsEqualTo(original.GetMessage()); } [Test] @@ -540,6 +557,47 @@ await Assert.That(outputCompilation.GetDiagnostics() .Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)).IsEmpty(); } + [Test] + public async Task PragmaCanSuppressGenericAdaptationDiagnostic() + { + const string source = """ + using AlephMapper; + + namespace Fixture; + + public interface ISource { string Name { get; } } + public interface IDestination { string Name { get; set; } } + public sealed class AdaptedSource : ISource { public string Name { get; set; } = string.Empty; } + public sealed class AdaptedDestination : IDestination { public string Name { get; set; } = string.Empty; } + + public static partial class Mapper + { + #pragma warning disable AM0018 + [Adapt(typeof(AdaptedSource), typeof(AdaptedDestination), Name = "MapAdapted")] + public static TResult Map(TSource source) + where TSource : ISource + where TResult : IDestination, new() => new() { Name = source.Name }; + #pragma warning restore AM0018 + } + """; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var syntaxTree = CSharpSyntaxTree.ParseText(source, _parseOptions, "PragmaSuppression.cs"); + var compilation = CSharpCompilation.Create( + "PragmaSuppression", + [syntaxTree], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var driver = _driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out var generatorDiagnostics); + var result = driver.GetRunResult().Results.Single(); + + await Assert.That(generatorDiagnostics.Any(diagnostic => + diagnostic.Id == "AM0018" && !diagnostic.IsSuppressed)).IsFalse(); + await Assert.That(result.Diagnostics.Any(diagnostic => + diagnostic.Id == "AM0018" && !diagnostic.IsSuppressed)).IsFalse(); + } + [Test] public async Task LargeCompilationDiscoversOnlyAttributedMappers() { @@ -1333,6 +1391,7 @@ public sealed class EmployeeDto { public string Name { get; set; } = string.Empt var lineSpan = diagnostic.Location.GetLineSpan(); await Assert.That(diagnostic.Location).IsNotEqualTo(Location.None); + await Assert.That(diagnostic.Location.SourceTree).IsEqualTo(syntaxTree); await Assert.That(lineSpan.Path).IsEqualTo("AdaptLocation.cs"); await Assert.That(lineSpan.StartLinePosition.Line).IsEqualTo(7); } From 4e6eeeb3a68839d69a7d4c01d4c739e618c7543e Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 17:40:13 +0200 Subject: [PATCH 17/22] =?UTF-8?q?=E2=80=A2=20##=20Changes=20made?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - source/AlephSourceGenerator.cs - Split mapper output into source-only and diagnostics branches. - Removed misleading Candidates tracking name. - CompilationProvider is now used only by diagnostics. - source/Generation/MapperSourceOutput.cs - Replaced mixed Emit with EmitSource and EmitDiagnostics. - tests/AlephMapper.Tests/SourceGeneratorTests.cs - Updated incremental tracking coverage to assert the real source-output branch stays Unchanged after an unrelated compilation edit. This is not described as a cache hit. --- source/AlephSourceGenerator.cs | 20 ++++++++++++++----- source/Generation/MapperSourceOutput.cs | 18 +++++++++++------ .../AlephMapper.Tests/SourceGeneratorTests.cs | 8 ++++---- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/source/AlephSourceGenerator.cs b/source/AlephSourceGenerator.cs index 18408a8..27f89cf 100644 --- a/source/AlephSourceGenerator.cs +++ b/source/AlephSourceGenerator.cs @@ -52,11 +52,21 @@ private static void RegisterMapperOutput( IncrementalValuesProvider mapperResults, string configurationKind) { + var results = mapperResults + .WithTrackingName($"AlephMapper.{configurationKind}GenerationResult"); + + context.RegisterSourceOutput( + results.WithTrackingName($"AlephMapper.{configurationKind}SourceOutput"), + MapperSourceOutput.EmitSource); + context.RegisterSourceOutput( - mapperResults - .WithTrackingName($"AlephMapper.{configurationKind}Candidates") - .WithTrackingName($"AlephMapper.{configurationKind}GenerationResult") - .Combine(context.CompilationProvider), - MapperSourceOutput.Emit); + results + .Where(static result => !result.Diagnostics.IsDefaultOrEmpty) + .Combine(context.CompilationProvider) + .WithTrackingName($"AlephMapper.{configurationKind}Diagnostics"), + static (sourceProductionContext, output) => MapperSourceOutput.EmitDiagnostics( + sourceProductionContext, + output.Left, + output.Right)); } } diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index 9dce9bb..62f9d56 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -80,18 +80,24 @@ public static MapperGenerationResult Create( #endif } - public static void Emit( + public static void EmitSource( SourceProductionContext context, - (MapperGenerationResult Result, Compilation Compilation) output) + MapperGenerationResult result) { - foreach (var diagnostic in output.Result.Diagnostics) + if (result.HintName is not null && result.Source is not null) { - context.ReportDiagnostic(diagnostic.ToDiagnostic(output.Compilation)); + context.AddSource(result.HintName, result.Source); } + } - if (output.Result.HintName is not null && output.Result.Source is not null) + public static void EmitDiagnostics( + SourceProductionContext context, + MapperGenerationResult result, + Compilation compilation) + { + foreach (var diagnostic in result.Diagnostics) { - context.AddSource(output.Result.HintName, output.Result.Source); + context.ReportDiagnostic(diagnostic.ToDiagnostic(compilation)); } } diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index 130fc0b..75c8c0c 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -450,13 +450,13 @@ public static partial class MapperB driver = driver.RunGeneratorsAndUpdateCompilation(updatedCompilation, out _, out _); var trackedSteps = driver.GetRunResult().Results.Single().TrackedSteps; - var candidateOutputs = trackedSteps["AlephMapper.ProjectableGenerationResult"] + var sourceOutputs = trackedSteps["AlephMapper.ProjectableSourceOutput"] .SelectMany(static step => step.Outputs) .ToArray(); - await Assert.That(candidateOutputs).Count().IsEqualTo(2); + await Assert.That(sourceOutputs).Count().IsEqualTo(2); // Unchanged means the step reran but produced an equal value; it is not a cache hit. - await Assert.That(candidateOutputs.All(static output => output.Item2 == IncrementalStepRunReason.Unchanged)).IsTrue(); + await Assert.That(sourceOutputs.All(static output => output.Item2 == IncrementalStepRunReason.Unchanged)).IsTrue(); } [Test] @@ -626,7 +626,7 @@ public async Task LargeCompilationDiscoversOnlyAttributedMappers() stopwatch.Stop(); var result = driver.GetRunResult().Results.Single(); - var candidateOutputs = result.TrackedSteps["AlephMapper.ProjectableGenerationResult"] + var candidateOutputs = result.TrackedSteps["AlephMapper.ProjectableSourceOutput"] .SelectMany(static step => step.Outputs) .ToArray(); From 573fc115c023992f47d3c025dea84567eb3b822f Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 18:12:11 +0200 Subject: [PATCH 18/22] Improve source generator diagnostic incrementality --- source/AlephSourceGenerator.cs | 6 +- source/Generation/MapperGenerationResult.cs | 23 +++++++ source/Generation/MapperSourceOutput.cs | 2 +- .../AlephMapper.Tests/SourceGeneratorTests.cs | 63 ++++++++++++++++++- 4 files changed, 90 insertions(+), 4 deletions(-) diff --git a/source/AlephSourceGenerator.cs b/source/AlephSourceGenerator.cs index 27f89cf..81c1de5 100644 --- a/source/AlephSourceGenerator.cs +++ b/source/AlephSourceGenerator.cs @@ -55,8 +55,12 @@ private static void RegisterMapperOutput( var results = mapperResults .WithTrackingName($"AlephMapper.{configurationKind}GenerationResult"); + var sources = results + .Select(static (result, _) => new MapperSourceResult(result.HintName, result.Source)) + .WithTrackingName($"AlephMapper.{configurationKind}SourceOutput"); + context.RegisterSourceOutput( - results.WithTrackingName($"AlephMapper.{configurationKind}SourceOutput"), + sources, MapperSourceOutput.EmitSource); context.RegisterSourceOutput( diff --git a/source/Generation/MapperGenerationResult.cs b/source/Generation/MapperGenerationResult.cs index d02bc1b..8bcf87e 100644 --- a/source/Generation/MapperGenerationResult.cs +++ b/source/Generation/MapperGenerationResult.cs @@ -9,6 +9,29 @@ namespace AlephMapper.Generation; +/// +/// The source-only portion of a mapper generation result. Keeping this value +/// separate ensures diagnostic changes do not invalidate source emission. +/// +internal readonly struct MapperSourceResult : IEquatable +{ + public MapperSourceResult(string? hintName, string? source) + { + HintName = hintName; + Source = source; + } + + public string? HintName { get; } + public string? Source { get; } + + public bool Equals(MapperSourceResult other) => + string.Equals(HintName, other.HintName, StringComparison.Ordinal) && + string.Equals(Source, other.Source, StringComparison.Ordinal); + + public override bool Equals(object? obj) => obj is MapperSourceResult other && Equals(other); + public override int GetHashCode() => (HintName, Source).GetHashCode(); +} + /// /// Value-only output from mapper analysis. This is the boundary between /// compiler-bound semantic rewriting and incremental source production. diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index 62f9d56..9602bb9 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -82,7 +82,7 @@ public static MapperGenerationResult Create( public static void EmitSource( SourceProductionContext context, - MapperGenerationResult result) + MapperSourceResult result) { if (result.HintName is not null && result.Source is not null) { diff --git a/tests/AlephMapper.Tests/SourceGeneratorTests.cs b/tests/AlephMapper.Tests/SourceGeneratorTests.cs index 75c8c0c..d9a06f0 100644 --- a/tests/AlephMapper.Tests/SourceGeneratorTests.cs +++ b/tests/AlephMapper.Tests/SourceGeneratorTests.cs @@ -455,8 +455,67 @@ public static partial class MapperB .ToArray(); await Assert.That(sourceOutputs).Count().IsEqualTo(2); - // Unchanged means the step reran but produced an equal value; it is not a cache hit. - await Assert.That(sourceOutputs.All(static output => output.Item2 == IncrementalStepRunReason.Unchanged)).IsTrue(); + await Assert.That(sourceOutputs.All(static output => + output.Item2 is IncrementalStepRunReason.Cached or IncrementalStepRunReason.Unchanged)).IsTrue(); + } + + [Test] + public async Task SourceOutputRemainsUnchangedWhenOnlyDiagnosticLocationChanges() + { + const string source = """ + using AlephMapper; + + namespace Fixture; + + public interface ISource { string Name { get; } } + public interface IDestination { string Name { get; set; } } + public sealed class AdaptedSource : ISource { public string Name { get; set; } = string.Empty; } + public sealed class AdaptedDestination : IDestination { public string Name { get; set; } = string.Empty; } + + public static partial class Mapper + { + [Projectable] + [Adapt(typeof(AdaptedSource), typeof(AdaptedDestination), Name = "MapAdapted")] + public static TResult Map(TSource source) + where TSource : ISource + where TResult : IDestination, new() => new() { Name = source.Name }; + } + """; + + var references = await ReferenceAssemblies.Net.Net90.ResolveAsync(LanguageNames.CSharp, CancellationToken.None); + var syntaxTree = CSharpSyntaxTree.ParseText(source, _parseOptions, "Mapper.cs"); + var compilation = CSharpCompilation.Create( + "DiagnosticOnlyChange", + [syntaxTree], + references, + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var driver = CreateTrackingDriver().RunGeneratorsAndUpdateCompilation(compilation, out _, out _); + var initialResult = driver.GetRunResult().Results.Single(); + var generatedSource = initialResult.GeneratedSources + .Single(static generated => generated.HintName.EndsWith("Mapper_GeneratedMappings.g.cs", StringComparison.Ordinal)) + .SourceText + .ToString(); + var initialDiagnostic = initialResult.Diagnostics.Single(static diagnostic => diagnostic.Id == "AM0018"); + var updatedSyntaxTree = syntaxTree.WithChangedText(SourceText.From("\n" + source)); + var updatedCompilation = compilation.ReplaceSyntaxTree(syntaxTree, updatedSyntaxTree); + driver = driver.RunGeneratorsAndUpdateCompilation(updatedCompilation, out _, out _); + + var result = driver.GetRunResult().Results.Single(); + var updatedGeneratedSource = result.GeneratedSources + .Single(static generated => generated.HintName.EndsWith("Mapper_GeneratedMappings.g.cs", StringComparison.Ordinal)) + .SourceText + .ToString(); + var sourceOutputs = result.TrackedSteps["AlephMapper.ProjectableSourceOutput"] + .SelectMany(static step => step.Outputs) + .ToArray(); + var diagnostic = result.Diagnostics.Single(static diagnostic => diagnostic.Id == "AM0018"); + + await Assert.That(updatedGeneratedSource).IsEqualTo(generatedSource); + await Assert.That(diagnostic.Location.GetLineSpan().StartLinePosition.Line) + .IsEqualTo(initialDiagnostic.Location.GetLineSpan().StartLinePosition.Line + 1); + await Assert.That(sourceOutputs).Count().IsEqualTo(1); + await Assert.That(sourceOutputs.Single().Item2).IsEqualTo(IncrementalStepRunReason.Unchanged); } [Test] From 07f1771c8aceb7b2f7b44ff54e87ec858396d30a Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 18:29:38 +0200 Subject: [PATCH 19/22] extract MapperSourceResult to its own file, code cleanup --- .../Adaptation/AdaptedDestinationRewriter.cs | 1 - source/Generation/MapperGenerationContext.cs | 20 +--- source/Generation/MapperGenerationResult.cs | 108 ++++++------------ source/Generation/MapperSourceOutput.cs | 1 - source/Generation/MapperSourceResult.cs | 22 ++++ source/Generation/MappingCatalog.cs | 21 +--- source/Helpers/EmitHelpers.cs | 1 - source/Models/AdaptationAnalysis.cs | 36 +++--- ...gResolver.ConditionalExpressionRewriter.cs | 1 - .../InliningResolver.InvocationRewriter.cs | 24 +--- 10 files changed, 87 insertions(+), 148 deletions(-) create mode 100644 source/Generation/MapperSourceResult.cs diff --git a/source/Adaptation/AdaptedDestinationRewriter.cs b/source/Adaptation/AdaptedDestinationRewriter.cs index 3cfbaf5..f4e0724 100644 --- a/source/Adaptation/AdaptedDestinationRewriter.cs +++ b/source/Adaptation/AdaptedDestinationRewriter.cs @@ -4,7 +4,6 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; -using AlephMapper.SyntaxRewriters; using AlephMapper.Helpers; using System; using System.Collections.Generic; diff --git a/source/Generation/MapperGenerationContext.cs b/source/Generation/MapperGenerationContext.cs index 13f6095..b872801 100644 --- a/source/Generation/MapperGenerationContext.cs +++ b/source/Generation/MapperGenerationContext.cs @@ -1,6 +1,5 @@ using AlephMapper.Adaptation; using AlephMapper.Helpers; -using AlephMapper.Models; using Microsoft.CodeAnalysis; using System; using System.Collections.Generic; @@ -13,22 +12,15 @@ namespace AlephMapper.Generation; /// Holds the mutable state for one generated mapper file. Feature emitters use /// this instead of sharing source-output orchestration concerns. /// -internal sealed class MapperGenerationContext +internal sealed class MapperGenerationContext( + INamedTypeSymbol mapperType, + MappingCatalog mappingsByMethod) { private bool _hasMembers; - public MapperGenerationContext( - INamedTypeSymbol mapperType, - MappingCatalog mappingsByMethod) - { - MapperType = mapperType; - MappingsByMethod = mappingsByMethod; - AdaptationMembers = new AdaptationMemberPlanner(mapperType); - } - - public INamedTypeSymbol MapperType { get; } - public MappingCatalog MappingsByMethod { get; } - public AdaptationMemberPlanner AdaptationMembers { get; } + public INamedTypeSymbol MapperType { get; } = mapperType; + public MappingCatalog MappingsByMethod { get; } = mappingsByMethod; + public AdaptationMemberPlanner AdaptationMembers { get; } = new(mapperType); public HashSet UsingDirectives { get; } = new(StringComparer.Ordinal); public HashSet GeneratedMemberSignatures { get; } = new(StringComparer.Ordinal); public StringBuilder Members { get; } = new(); diff --git a/source/Generation/MapperGenerationResult.cs b/source/Generation/MapperGenerationResult.cs index 8bcf87e..c186727 100644 --- a/source/Generation/MapperGenerationResult.cs +++ b/source/Generation/MapperGenerationResult.cs @@ -9,45 +9,19 @@ namespace AlephMapper.Generation; -/// -/// The source-only portion of a mapper generation result. Keeping this value -/// separate ensures diagnostic changes do not invalidate source emission. -/// -internal readonly struct MapperSourceResult : IEquatable -{ - public MapperSourceResult(string? hintName, string? source) - { - HintName = hintName; - Source = source; - } - - public string? HintName { get; } - public string? Source { get; } - - public bool Equals(MapperSourceResult other) => - string.Equals(HintName, other.HintName, StringComparison.Ordinal) && - string.Equals(Source, other.Source, StringComparison.Ordinal); - - public override bool Equals(object? obj) => obj is MapperSourceResult other && Equals(other); - public override int GetHashCode() => (HintName, Source).GetHashCode(); -} - /// /// Value-only output from mapper analysis. This is the boundary between /// compiler-bound semantic rewriting and incremental source production. /// -internal sealed class MapperGenerationResult : IEquatable +internal sealed class MapperGenerationResult( + string? hintName, + string? source, + ImmutableArray diagnostics) + : IEquatable { - public MapperGenerationResult(string? hintName, string? source, ImmutableArray diagnostics) - { - HintName = hintName; - Source = source; - Diagnostics = diagnostics; - } - - public string? HintName { get; } - public string? Source { get; } - public ImmutableArray Diagnostics { get; } + public string? HintName { get; } = hintName; + public string? Source { get; } = source; + public ImmutableArray Diagnostics { get; } = diagnostics; public static MapperGenerationResult Empty { get; } = new MapperGenerationResult(null, null, ImmutableArray.Empty); @@ -63,48 +37,34 @@ public bool Equals(MapperGenerationResult? other) public override int GetHashCode() => (HintName, Source).GetHashCode(); } -internal readonly struct GenerationDiagnostic : IEquatable +internal readonly struct GenerationDiagnostic( + string id, + string title, + string message, + DiagnosticSeverity severity, + string category, + string? filePath, + int start, + int length, + int startLine, + int startCharacter, + int endLine, + int endCharacter) + : IEquatable { - public GenerationDiagnostic( - string id, - string title, - string message, - DiagnosticSeverity severity, - string category, - string? filePath, - int start, - int length, - int startLine, - int startCharacter, - int endLine, - int endCharacter) - { - Id = id; - Title = title; - Message = message; - Severity = severity; - Category = category; - FilePath = filePath; - Start = start; - Length = length; - StartLine = startLine; - StartCharacter = startCharacter; - EndLine = endLine; - EndCharacter = endCharacter; - } + public string Id { get; } = id; + public string Title { get; } = title; + public string Message { get; } = message; + public DiagnosticSeverity Severity { get; } = severity; + public string Category { get; } = category; + public string? FilePath { get; } = filePath; + public int Start { get; } = start; + public int Length { get; } = length; + public int StartLine { get; } = startLine; + public int StartCharacter { get; } = startCharacter; + public int EndLine { get; } = endLine; + public int EndCharacter { get; } = endCharacter; - public string Id { get; } - public string Title { get; } - public string Message { get; } - public DiagnosticSeverity Severity { get; } - public string Category { get; } - public string? FilePath { get; } - public int Start { get; } - public int Length { get; } - public int StartLine { get; } - public int StartCharacter { get; } - public int EndLine { get; } - public int EndCharacter { get; } public static GenerationDiagnostic From(Diagnostic diagnostic) { var location = diagnostic.Location; diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index 9602bb9..ddba95a 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -1,6 +1,5 @@ #nullable enable -using AlephMapper.Diagnostics; using AlephMapper.Generation.Emitters; using AlephMapper.Helpers; using AlephMapper.Models; diff --git a/source/Generation/MapperSourceResult.cs b/source/Generation/MapperSourceResult.cs new file mode 100644 index 0000000..14e1e13 --- /dev/null +++ b/source/Generation/MapperSourceResult.cs @@ -0,0 +1,22 @@ +#nullable enable + +using System; + +namespace AlephMapper.Generation; + +/// +/// The source-only portion of a mapper generation result. Keeping this value +/// separate ensures diagnostic changes do not invalidate source emission. +/// +internal readonly struct MapperSourceResult(string? hintName, string? source) : IEquatable +{ + public string? HintName { get; } = hintName; + public string? Source { get; } = source; + + public bool Equals(MapperSourceResult other) => + string.Equals(HintName, other.HintName, StringComparison.Ordinal) && + string.Equals(Source, other.Source, StringComparison.Ordinal); + + public override bool Equals(object? obj) => obj is MapperSourceResult other && Equals(other); + public override int GetHashCode() => (HintName, Source).GetHashCode(); +} diff --git a/source/Generation/MappingCatalog.cs b/source/Generation/MappingCatalog.cs index 7ca2991..d1982fa 100644 --- a/source/Generation/MappingCatalog.cs +++ b/source/Generation/MappingCatalog.cs @@ -13,35 +13,26 @@ namespace AlephMapper.Generation; /// This keeps each mapper output independent while preserving cross-mapper /// inlining support. /// -internal sealed class MappingCatalog +internal sealed class MappingCatalog( + Dictionary mappings, + Func createExternalMapping) { - private readonly Dictionary _mappings; - private readonly Func _createExternalMapping; - - public MappingCatalog( - Dictionary mappings, - Func createExternalMapping) - { - _mappings = mappings; - _createExternalMapping = createExternalMapping; - } - public bool TryGetValue(IMethodSymbol method, out MappingAnalysis mapping) { var normalizedMethod = SymbolHelpers.Normalize(method); - if (_mappings.TryGetValue(normalizedMethod, out mapping)) + if (mappings.TryGetValue(normalizedMethod, out mapping)) { return true; } - var externalMapping = _createExternalMapping(normalizedMethod); + var externalMapping = createExternalMapping(normalizedMethod); if (externalMapping is null) { mapping = null!; return false; } - _mappings[normalizedMethod] = externalMapping; + mappings[normalizedMethod] = externalMapping; mapping = externalMapping; return true; } diff --git a/source/Helpers/EmitHelpers.cs b/source/Helpers/EmitHelpers.cs index 707ae2a..17239ff 100644 --- a/source/Helpers/EmitHelpers.cs +++ b/source/Helpers/EmitHelpers.cs @@ -2,7 +2,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Collections.Generic; -using System.Linq; namespace AlephMapper.Helpers; diff --git a/source/Models/AdaptationAnalysis.cs b/source/Models/AdaptationAnalysis.cs index 19ced32..6984db1 100644 --- a/source/Models/AdaptationAnalysis.cs +++ b/source/Models/AdaptationAnalysis.cs @@ -7,30 +7,20 @@ namespace AlephMapper.Models; /// /// Compiler-bound adaptation analysis state used only while rendering output. /// -internal sealed class AdaptationAnalysis +internal sealed class AdaptationAnalysis( + INamedTypeSymbol sourceType, + INamedTypeSymbol destinationType, + string? generatedName, + AdaptGeneration generation, + NullConditionalRewrite nullStrategy, + SourceLocationModel? location) { - public AdaptationAnalysis( - INamedTypeSymbol sourceType, - INamedTypeSymbol destinationType, - string? generatedName, - AdaptGeneration generation, - NullConditionalRewrite nullStrategy, - SourceLocationModel? location) - { - SourceType = sourceType; - DestinationType = destinationType; - GeneratedName = generatedName; - Generation = generation; - NullStrategy = nullStrategy; - Location = location; - } - - public INamedTypeSymbol SourceType { get; } - public INamedTypeSymbol DestinationType { get; } - public string? GeneratedName { get; } - public AdaptGeneration Generation { get; } - public NullConditionalRewrite NullStrategy { get; } - public SourceLocationModel? Location { get; } + public INamedTypeSymbol SourceType { get; } = sourceType; + public INamedTypeSymbol DestinationType { get; } = destinationType; + public string? GeneratedName { get; } = generatedName; + public AdaptGeneration Generation { get; } = generation; + public NullConditionalRewrite NullStrategy { get; } = nullStrategy; + public SourceLocationModel? Location { get; } = location; } internal sealed class SourceLocationModel diff --git a/source/SyntaxRewriters/InliningResolver.ConditionalExpressionRewriter.cs b/source/SyntaxRewriters/InliningResolver.ConditionalExpressionRewriter.cs index 1b04d7f..abc6283 100644 --- a/source/SyntaxRewriters/InliningResolver.ConditionalExpressionRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.ConditionalExpressionRewriter.cs @@ -1,7 +1,6 @@ #nullable enable using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace AlephMapper.SyntaxRewriters; diff --git a/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs b/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs index 2bfdc15..253b499 100644 --- a/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs +++ b/source/SyntaxRewriters/InliningResolver.InvocationRewriter.cs @@ -307,28 +307,16 @@ internal class CircularReferenceInfo(IMethodSymbol method, IEnumerable ", callStack.Select(m => $"{m.ContainingType.Name}.{m.Name}")); } -internal sealed class UnsafeConditionalReceiverInfo +internal sealed class UnsafeConditionalReceiverInfo(ExpressionSyntax expression) { - public UnsafeConditionalReceiverInfo(ExpressionSyntax expression) - { - Expression = expression; - Location = expression.GetLocation(); - } - - public ExpressionSyntax Expression { get; } - public Location Location { get; } + public ExpressionSyntax Expression { get; } = expression; + public Location Location { get; } = expression.GetLocation(); } -internal sealed class UnsupportedNullConditionalInfo +internal sealed class UnsupportedNullConditionalInfo(ConditionalAccessExpressionSyntax expression) { - public UnsupportedNullConditionalInfo(ConditionalAccessExpressionSyntax expression) - { - Expression = expression; - Location = expression.GetLocation(); - } - - public ConditionalAccessExpressionSyntax Expression { get; } - public Location Location { get; } + public ConditionalAccessExpressionSyntax Expression { get; } = expression; + public Location Location { get; } = expression.GetLocation(); } #nullable restore From f6de3af519bb7849503bde9f226828aa9142f746 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 18:34:20 +0200 Subject: [PATCH 20/22] fix misssng using --- source/Generation/MapperSourceOutput.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/Generation/MapperSourceOutput.cs b/source/Generation/MapperSourceOutput.cs index ddba95a..d88938a 100644 --- a/source/Generation/MapperSourceOutput.cs +++ b/source/Generation/MapperSourceOutput.cs @@ -10,6 +10,10 @@ using System.Linq; using System.Threading; +#if !DEBUG +using AlephMapper.Diagnostics; +#endif + namespace AlephMapper.Generation; internal static class MapperSourceOutput From 00b63d17f6cdbdc7fa6522af430d1b33b42bf7bf Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 18:41:50 +0200 Subject: [PATCH 21/22] fix error message --- source/Diagnostics/CrashDiagnosticsReporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Diagnostics/CrashDiagnosticsReporter.cs b/source/Diagnostics/CrashDiagnosticsReporter.cs index 3633768..c3a9df6 100644 --- a/source/Diagnostics/CrashDiagnosticsReporter.cs +++ b/source/Diagnostics/CrashDiagnosticsReporter.cs @@ -27,6 +27,6 @@ private static string FormatCrashDiagnostic(Exception exception) return details; } - return $"{details.Substring(MaxCrashDiagnosticLength)}..."; + return $"{details[..MaxCrashDiagnosticLength]}..."; } } From 76046ecbdea4f6f958952bede8753192b03e0e28 Mon Sep 17 00:00:00 2001 From: Yevhen Cherkes Date: Tue, 1 Sep 2026 18:43:19 +0200 Subject: [PATCH 22/22] fix build --- source/Diagnostics/CrashDiagnosticsReporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Diagnostics/CrashDiagnosticsReporter.cs b/source/Diagnostics/CrashDiagnosticsReporter.cs index c3a9df6..e260908 100644 --- a/source/Diagnostics/CrashDiagnosticsReporter.cs +++ b/source/Diagnostics/CrashDiagnosticsReporter.cs @@ -27,6 +27,6 @@ private static string FormatCrashDiagnostic(Exception exception) return details; } - return $"{details[..MaxCrashDiagnosticLength]}..."; + return $"{details.Substring(0, MaxCrashDiagnosticLength)}..."; } }