From 09d09430ef48300eaee087f442e1a1b3a0c8c229 Mon Sep 17 00:00:00 2001 From: Mohammadreza Taikandi Date: Thu, 31 Dec 2020 10:01:27 +0000 Subject: [PATCH] Add initial support for global configuration. --- src/MapTo/Configuration/AccessModifier.cs | 9 +++++++ .../Configuration/MapToConfigurations.cs | 26 +++++++++++++++++++ src/MapTo/MapTo.csproj | 10 +++---- src/MapTo/MapTo.props | 5 ++++ src/MapTo/MapToGenerator.cs | 18 ++++++++----- src/MapTo/Models/MapModel.cs | 9 +++++-- src/MapTo/SourceBuilder.cs | 2 +- test/TestConsoleApp/Program.cs | 16 +++--------- test/TestConsoleApp/TestConsoleApp.csproj | 7 ++++- 9 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 src/MapTo/Configuration/AccessModifier.cs create mode 100644 src/MapTo/Configuration/MapToConfigurations.cs create mode 100644 src/MapTo/MapTo.props diff --git a/src/MapTo/Configuration/AccessModifier.cs b/src/MapTo/Configuration/AccessModifier.cs new file mode 100644 index 0000000..5e321a0 --- /dev/null +++ b/src/MapTo/Configuration/AccessModifier.cs @@ -0,0 +1,9 @@ +namespace MapTo.Configuration +{ + internal enum AccessModifier + { + Public, + Internal, + Private + } +} \ No newline at end of file diff --git a/src/MapTo/Configuration/MapToConfigurations.cs b/src/MapTo/Configuration/MapToConfigurations.cs new file mode 100644 index 0000000..3639386 --- /dev/null +++ b/src/MapTo/Configuration/MapToConfigurations.cs @@ -0,0 +1,26 @@ +using System; +using Microsoft.CodeAnalysis; + +namespace MapTo.Configuration +{ + internal sealed class MapToConfigurations + { + private MapToConfigurations(AccessModifier constructorAccessModifier) + { + ConstructorAccessModifier = constructorAccessModifier; + } + + internal AccessModifier ConstructorAccessModifier { get; } + + internal static MapToConfigurations From(GeneratorExecutionContext context) + { + var constructorAccessModifier = + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.MapTo_ConstructorAccessModifier", out var ctorModifierValue) && + Enum.TryParse(ctorModifierValue, out var ctorModifier) ? ctorModifier : AccessModifier.Public; + + return new MapToConfigurations( + constructorAccessModifier + ); + } + } +} \ No newline at end of file diff --git a/src/MapTo/MapTo.csproj b/src/MapTo/MapTo.csproj index 8f9f41f..0988ea7 100644 --- a/src/MapTo/MapTo.csproj +++ b/src/MapTo/MapTo.csproj @@ -4,7 +4,7 @@ netstandard2.0 enable 9 - + MapTo An object to object mapping generator using Roslyn source generator. true @@ -25,7 +25,7 @@ <_Parameter1>$(AssemblyName).Tests - + all @@ -34,12 +34,10 @@ - - - - + + diff --git a/src/MapTo/MapTo.props b/src/MapTo/MapTo.props new file mode 100644 index 0000000..2082ff5 --- /dev/null +++ b/src/MapTo/MapTo.props @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/MapTo/MapToGenerator.cs b/src/MapTo/MapToGenerator.cs index 69f155f..5d55bf3 100644 --- a/src/MapTo/MapToGenerator.cs +++ b/src/MapTo/MapToGenerator.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using MapTo.Configuration; using MapTo.Extensions; using MapTo.Models; using Microsoft.CodeAnalysis; @@ -31,15 +32,19 @@ namespace MapTo private static void AddGeneratedMappingsClasses(GeneratorExecutionContext context, IEnumerable candidateClasses) { + var configs = MapToConfigurations.From(context); + foreach (var classSyntax in candidateClasses) { - var model = CreateModel(context, classSyntax); + + var model = CreateModel(context, classSyntax, configs); if (model is null) { continue; } - + var (source, hintName) = SourceBuilder.GenerateSource(model); + context.AddSource(hintName, source); context.ReportDiagnostic(Diagnostics.ClassMappingsGenerated(classSyntax.GetLocation(), model.ClassName)); } @@ -58,8 +63,8 @@ namespace MapTo return sourceTypeExpressionSyntax is not null ? model.GetTypeInfo(sourceTypeExpressionSyntax.Type).Type as INamedTypeSymbol : null; } - - private static MapModel? CreateModel(GeneratorExecutionContext context, ClassDeclarationSyntax classSyntax) + + private static MapModel? CreateModel(GeneratorExecutionContext context, ClassDeclarationSyntax classSyntax, MapToConfigurations configs) { var root = classSyntax.GetCompilationUnit(); var classSemanticModel = context.Compilation.GetSemanticModel(classSyntax.SyntaxTree); @@ -86,7 +91,7 @@ namespace MapTo context.ReportDiagnostic(Diagnostics.NoMatchingPropertyFoundError(classSyntax.GetLocation(), className, sourceClassName)); return null; } - + return new MapModel( root.GetNamespace(), classSyntax.Modifiers, @@ -94,7 +99,8 @@ namespace MapTo sourceTypeSymbol.ContainingNamespace.ToString(), sourceClassName, sourceTypeSymbol.ToString(), - mappedProperties); + mappedProperties, + configs.ConstructorAccessModifier); } private static ImmutableArray GetMappedProperties(ITypeSymbol classSymbol, ITypeSymbol sourceTypeSymbol) diff --git a/src/MapTo/Models/MapModel.cs b/src/MapTo/Models/MapModel.cs index 610882d..226e5d0 100644 --- a/src/MapTo/Models/MapModel.cs +++ b/src/MapTo/Models/MapModel.cs @@ -1,9 +1,10 @@ using System.Collections.Immutable; +using MapTo.Configuration; using Microsoft.CodeAnalysis; namespace MapTo.Models { - public class MapModel + internal class MapModel { internal MapModel( string? ns, @@ -12,7 +13,8 @@ namespace MapTo.Models string sourceNamespace, string sourceClassName, string sourceClassFullName, - ImmutableArray mappedProperties) + ImmutableArray mappedProperties, + AccessModifier constructorAccessModifier) { Namespace = ns; ClassModifiers = classModifiers; @@ -21,6 +23,7 @@ namespace MapTo.Models SourceClassName = sourceClassName; SourceClassFullName = sourceClassFullName; MappedProperties = mappedProperties; + ConstructorAccessModifier = constructorAccessModifier; } public string? Namespace { get; } @@ -36,5 +39,7 @@ namespace MapTo.Models public string SourceClassFullName { get; } public ImmutableArray MappedProperties { get; } + + public AccessModifier ConstructorAccessModifier { get; } } } \ No newline at end of file diff --git a/src/MapTo/SourceBuilder.cs b/src/MapTo/SourceBuilder.cs index 2db8920..bbbc2c5 100644 --- a/src/MapTo/SourceBuilder.cs +++ b/src/MapTo/SourceBuilder.cs @@ -132,7 +132,7 @@ namespace MapTo .PadLeft(Indent2).AppendFormat("/// using the property values from the specified .", sourceClassParameterName).AppendLine() .PadLeft(Indent2).AppendLine("/// ") .PadLeft(Indent2).AppendFormat("/// {0} is null", sourceClassParameterName).AppendLine() - .PadLeft(Indent2).AppendFormat("public {0}({1} {2})", model.ClassName, model.SourceClassFullName, sourceClassParameterName) + .PadLeft(Indent2).AppendFormat("{0} {1}({2} {3})", model.ConstructorAccessModifier.ToString().ToLower(), model.ClassName, model.SourceClassFullName, sourceClassParameterName) .AppendOpeningBracket(Indent2) .PadLeft(Indent3).AppendFormat("if ({0} == null) throw new ArgumentNullException(nameof({0}));", sourceClassParameterName).AppendLine() .AppendLine(); diff --git a/test/TestConsoleApp/Program.cs b/test/TestConsoleApp/Program.cs index be9106d..2126761 100644 --- a/test/TestConsoleApp/Program.cs +++ b/test/TestConsoleApp/Program.cs @@ -1,13 +1,5 @@ -using TestConsoleApp.ViewModels; +using VM = TestConsoleApp.ViewModels; +using Data = TestConsoleApp.Data.Models; -namespace TestConsoleApp -{ - internal class Program - { - private static void Main(string[] args) - { - var userViewModel = User.From(new Data.Models.User()); - var userViewModel2 = UserViewModel.From(new Data.Models.User()); - } - } -} \ No newline at end of file +var userViewModel = VM.User.From(new Data.User()); +var userViewModel2 = VM.UserViewModel.From(new Data.User()); \ No newline at end of file diff --git a/test/TestConsoleApp/TestConsoleApp.csproj b/test/TestConsoleApp/TestConsoleApp.csproj index f341935..7ce55d3 100644 --- a/test/TestConsoleApp/TestConsoleApp.csproj +++ b/test/TestConsoleApp/TestConsoleApp.csproj @@ -6,6 +6,11 @@ - + + + + + Internal +