Add initial support for global configuration.
This commit is contained in:
parent
f13f8783c3
commit
09d09430ef
|
@ -0,0 +1,9 @@
|
||||||
|
namespace MapTo.Configuration
|
||||||
|
{
|
||||||
|
internal enum AccessModifier
|
||||||
|
{
|
||||||
|
Public,
|
||||||
|
Internal,
|
||||||
|
Private
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<AccessModifier>(ctorModifierValue, out var ctorModifier) ? ctorModifier : AccessModifier.Public;
|
||||||
|
|
||||||
|
return new MapToConfigurations(
|
||||||
|
constructorAccessModifier
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<LangVersion>9</LangVersion>
|
<LangVersion>9</LangVersion>
|
||||||
|
|
||||||
<AssemblyName>MapTo</AssemblyName>
|
<AssemblyName>MapTo</AssemblyName>
|
||||||
<Description>An object to object mapping generator using Roslyn source generator.</Description>
|
<Description>An object to object mapping generator using Roslyn source generator.</Description>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
<_Parameter1>$(AssemblyName).Tests</_Parameter1>
|
<_Parameter1>$(AssemblyName).Tests</_Parameter1>
|
||||||
</AssemblyAttribute>
|
</AssemblyAttribute>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
|
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
@ -34,12 +34,10 @@
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.8.0" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.8.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Remove="bin\Debug\netstandard2.0\MapTo.dll" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" Visible="false" />
|
<None Include="..\..\LICENSE" Pack="true" PackagePath="" Visible="false" />
|
||||||
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
||||||
|
<None Include="MapTo.props" Pack="true" PackagePath="build" Visible="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<Project>
|
||||||
|
<ItemGroup>
|
||||||
|
<CompilerVisibleProperty Include="MapTo_ConstructorAccessModifier" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MapTo.Configuration;
|
||||||
using MapTo.Extensions;
|
using MapTo.Extensions;
|
||||||
using MapTo.Models;
|
using MapTo.Models;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
@ -31,15 +32,19 @@ namespace MapTo
|
||||||
|
|
||||||
private static void AddGeneratedMappingsClasses(GeneratorExecutionContext context, IEnumerable<ClassDeclarationSyntax> candidateClasses)
|
private static void AddGeneratedMappingsClasses(GeneratorExecutionContext context, IEnumerable<ClassDeclarationSyntax> candidateClasses)
|
||||||
{
|
{
|
||||||
|
var configs = MapToConfigurations.From(context);
|
||||||
|
|
||||||
foreach (var classSyntax in candidateClasses)
|
foreach (var classSyntax in candidateClasses)
|
||||||
{
|
{
|
||||||
var model = CreateModel(context, classSyntax);
|
|
||||||
|
var model = CreateModel(context, classSyntax, configs);
|
||||||
if (model is null)
|
if (model is null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (source, hintName) = SourceBuilder.GenerateSource(model);
|
var (source, hintName) = SourceBuilder.GenerateSource(model);
|
||||||
|
|
||||||
context.AddSource(hintName, source);
|
context.AddSource(hintName, source);
|
||||||
context.ReportDiagnostic(Diagnostics.ClassMappingsGenerated(classSyntax.GetLocation(), model.ClassName));
|
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;
|
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 root = classSyntax.GetCompilationUnit();
|
||||||
var classSemanticModel = context.Compilation.GetSemanticModel(classSyntax.SyntaxTree);
|
var classSemanticModel = context.Compilation.GetSemanticModel(classSyntax.SyntaxTree);
|
||||||
|
@ -86,7 +91,7 @@ namespace MapTo
|
||||||
context.ReportDiagnostic(Diagnostics.NoMatchingPropertyFoundError(classSyntax.GetLocation(), className, sourceClassName));
|
context.ReportDiagnostic(Diagnostics.NoMatchingPropertyFoundError(classSyntax.GetLocation(), className, sourceClassName));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MapModel(
|
return new MapModel(
|
||||||
root.GetNamespace(),
|
root.GetNamespace(),
|
||||||
classSyntax.Modifiers,
|
classSyntax.Modifiers,
|
||||||
|
@ -94,7 +99,8 @@ namespace MapTo
|
||||||
sourceTypeSymbol.ContainingNamespace.ToString(),
|
sourceTypeSymbol.ContainingNamespace.ToString(),
|
||||||
sourceClassName,
|
sourceClassName,
|
||||||
sourceTypeSymbol.ToString(),
|
sourceTypeSymbol.ToString(),
|
||||||
mappedProperties);
|
mappedProperties,
|
||||||
|
configs.ConstructorAccessModifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ImmutableArray<string> GetMappedProperties(ITypeSymbol classSymbol, ITypeSymbol sourceTypeSymbol)
|
private static ImmutableArray<string> GetMappedProperties(ITypeSymbol classSymbol, ITypeSymbol sourceTypeSymbol)
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using MapTo.Configuration;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
namespace MapTo.Models
|
namespace MapTo.Models
|
||||||
{
|
{
|
||||||
public class MapModel
|
internal class MapModel
|
||||||
{
|
{
|
||||||
internal MapModel(
|
internal MapModel(
|
||||||
string? ns,
|
string? ns,
|
||||||
|
@ -12,7 +13,8 @@ namespace MapTo.Models
|
||||||
string sourceNamespace,
|
string sourceNamespace,
|
||||||
string sourceClassName,
|
string sourceClassName,
|
||||||
string sourceClassFullName,
|
string sourceClassFullName,
|
||||||
ImmutableArray<string> mappedProperties)
|
ImmutableArray<string> mappedProperties,
|
||||||
|
AccessModifier constructorAccessModifier)
|
||||||
{
|
{
|
||||||
Namespace = ns;
|
Namespace = ns;
|
||||||
ClassModifiers = classModifiers;
|
ClassModifiers = classModifiers;
|
||||||
|
@ -21,6 +23,7 @@ namespace MapTo.Models
|
||||||
SourceClassName = sourceClassName;
|
SourceClassName = sourceClassName;
|
||||||
SourceClassFullName = sourceClassFullName;
|
SourceClassFullName = sourceClassFullName;
|
||||||
MappedProperties = mappedProperties;
|
MappedProperties = mappedProperties;
|
||||||
|
ConstructorAccessModifier = constructorAccessModifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? Namespace { get; }
|
public string? Namespace { get; }
|
||||||
|
@ -36,5 +39,7 @@ namespace MapTo.Models
|
||||||
public string SourceClassFullName { get; }
|
public string SourceClassFullName { get; }
|
||||||
|
|
||||||
public ImmutableArray<string> MappedProperties { get; }
|
public ImmutableArray<string> MappedProperties { get; }
|
||||||
|
|
||||||
|
public AccessModifier ConstructorAccessModifier { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -132,7 +132,7 @@ namespace MapTo
|
||||||
.PadLeft(Indent2).AppendFormat("/// using the property values from the specified <paramref name=\"{0}\"/>.", sourceClassParameterName).AppendLine()
|
.PadLeft(Indent2).AppendFormat("/// using the property values from the specified <paramref name=\"{0}\"/>.", sourceClassParameterName).AppendLine()
|
||||||
.PadLeft(Indent2).AppendLine("/// </summary>")
|
.PadLeft(Indent2).AppendLine("/// </summary>")
|
||||||
.PadLeft(Indent2).AppendFormat("/// <exception cref=\"ArgumentNullException\">{0} is null</exception>", sourceClassParameterName).AppendLine()
|
.PadLeft(Indent2).AppendFormat("/// <exception cref=\"ArgumentNullException\">{0} is null</exception>", 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)
|
.AppendOpeningBracket(Indent2)
|
||||||
.PadLeft(Indent3).AppendFormat("if ({0} == null) throw new ArgumentNullException(nameof({0}));", sourceClassParameterName).AppendLine()
|
.PadLeft(Indent3).AppendFormat("if ({0} == null) throw new ArgumentNullException(nameof({0}));", sourceClassParameterName).AppendLine()
|
||||||
.AppendLine();
|
.AppendLine();
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
using TestConsoleApp.ViewModels;
|
using VM = TestConsoleApp.ViewModels;
|
||||||
|
using Data = TestConsoleApp.Data.Models;
|
||||||
|
|
||||||
namespace TestConsoleApp
|
var userViewModel = VM.User.From(new Data.User());
|
||||||
{
|
var userViewModel2 = VM.UserViewModel.From(new Data.User());
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,6 +6,11 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\MapTo\MapTo.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
<ProjectReference Include="..\..\src\MapTo\MapTo.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Import Project="..\..\src\MapTo\MapTo.props"/>
|
||||||
|
<PropertyGroup>
|
||||||
|
<MapTo_ConstructorAccessModifier>Internal</MapTo_ConstructorAccessModifier>
|
||||||
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Loading…
Reference in New Issue