Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Nullable>disable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>13.0</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
48 changes: 22 additions & 26 deletions AutoEntityGenerator.CodeGenerator/CodeFileGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,35 @@

[assembly: InternalsVisibleTo("AutoEntityGenerator.CodeGenerator.Tests")]

namespace AutoEntityGenerator.CodeGenerator
namespace AutoEntityGenerator.CodeGenerator;

internal class CodeFileGenerator : ICodeFileGenerator
{
internal class CodeFileGenerator : ICodeFileGenerator
{
private readonly IEntityGenerator _entityGenerator;
private readonly IMappingsClassGenerator _mappingsClassGenerator;
private readonly IEntityGenerator _entityGenerator;
private readonly IMappingsClassGenerator _mappingsClassGenerator;

public CodeFileGenerator(IEntityGenerator entityGenerator, IMappingsClassGenerator mappingsClassGenerator)
{
_entityGenerator = entityGenerator;
_mappingsClassGenerator = mappingsClassGenerator;
}
public CodeFileGenerator(IEntityGenerator entityGenerator, IMappingsClassGenerator mappingsClassGenerator)
=> (_entityGenerator, _mappingsClassGenerator) = (entityGenerator, mappingsClassGenerator);

public IGeneratedCodeFile GenerateEntityCodeFile(Entity entityInfo)
public IGeneratedCodeFile GenerateEntityCodeFile(Entity entityInfo)
{
if (entityInfo is null)
{
if (entityInfo is null)
{
return null;
}

var code = _entityGenerator.GenerateEntityCode(entityInfo);
return new GeneratedCodeFile(code, Path.GetFileName(entityInfo.SourceFilePath));
return null;
}

public IGeneratedCodeFile GenerateMappingCodeFile(Entity from, Entity to)
{
if (from is null || to is null)
{
return null;
}
var code = _entityGenerator.GenerateEntityCode(entityInfo);
return new GeneratedCodeFile(code, Path.GetFileName(entityInfo.SourceFilePath));
}

var code = _mappingsClassGenerator.GenerateMappingClassCode(from, to);
return new GeneratedCodeFile(code, Path.GetFileNameWithoutExtension(from.SourceFilePath) + "MappingExtensions.cs");
public IGeneratedCodeFile GenerateMappingCodeFile(Entity from, Entity to)
{
if (from is null || to is null)
{
return null;
}

var code = _mappingsClassGenerator.GenerateMappingClassCode(from, to);
return new GeneratedCodeFile(code, Path.GetFileNameWithoutExtension(from.SourceFilePath) + "MappingExtensions.cs");
}
}
41 changes: 20 additions & 21 deletions AutoEntityGenerator.CodeGenerator/CodeGeneratorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,34 @@
using System.Collections.Generic;
using System.Text;

namespace AutoEntityGenerator.CodeGenerator
namespace AutoEntityGenerator.CodeGenerator;

internal abstract class CodeGeneratorBase
{
internal abstract class CodeGeneratorBase
{
public string Comments =>
$@"/*
public string Comments =>
$@"/*
Generated by {nameof(AutoEntityGenerator)} on {DateTime.Now}
For more information about {nameof(AutoEntityGenerator)}, Visit https://github.com/Peled-Zohar/AutoEntityGenerator
*/
";
protected string GenerateProperties(IEnumerable<Property> properties, Func<Property, string> propertyFormat)
protected string GenerateProperties(IEnumerable<Property> properties, Func<Property, string> propertyFormat)
{
var propertiesBuilder = new StringBuilder();
foreach (var property in properties)
{
var propertiesBuilder = new StringBuilder();
foreach (var property in properties)
{
propertiesBuilder.AppendLine(propertyFormat(property));
}
return propertiesBuilder.ToString(0, propertiesBuilder.Length - Environment.NewLine.Length);
propertiesBuilder.AppendLine(propertyFormat(property));
}
return propertiesBuilder.ToString(0, propertiesBuilder.Length - Environment.NewLine.Length);
}

protected string GenerateTypeParameters(Entity entity)
=> entity.TypeParameters.Count > 0
? $"<{string.Join(", ", entity.TypeParameters)}>"
: "";
protected string GenerateTypeParameters(Entity entity)
=> entity.TypeParameters.Count > 0
? $"<{string.Join(", ", entity.TypeParameters)}>"
: "";

protected string GenerateGenericConstraints(Entity entity)
=> entity.GenericConstraints.Count > 0
? " " + string.Join(" ", entity.GenericConstraints)
: "";
protected string GenerateGenericConstraints(Entity entity)
=> entity.GenericConstraints.Count > 0
? " " + string.Join(" ", entity.GenericConstraints)
: "";

}
}
49 changes: 24 additions & 25 deletions AutoEntityGenerator.CodeGenerator/EntityGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,51 +1,50 @@
using AutoEntityGenerator.Common.CodeInfo;

namespace AutoEntityGenerator.CodeGenerator
namespace AutoEntityGenerator.CodeGenerator;

public interface IEntityGenerator
{
public interface IEntityGenerator
{
string GenerateEntityCode(Entity entity);
}
string GenerateEntityCode(Entity entity);
}

internal class EntityGenerator : CodeGeneratorBase, IEntityGenerator
internal class EntityGenerator : CodeGeneratorBase, IEntityGenerator
{
public string GenerateEntityCode(Entity entity)
{
public string GenerateEntityCode(Entity entity)
{

var entityType = entity.Project.CSharpVersion == CSharpVersion.Default
|| (int)entity.Project.CSharpVersion >= (int)CSharpVersion.CSharp9
? "record"
: "class";
var entityType = entity.Project.CSharpVersion == CSharpVersion.Default
|| (int)entity.Project.CSharpVersion >= (int)CSharpVersion.CSharp9
? "record"
: "class";

var indentationLevel = entity.Namespace.IsFileScoped ? 1 : 2;
var indentation = new string('\t', indentationLevel);
var properties = GenerateProperties(entity.Properties, p => $"{indentation}public {p.Type} {p.Name} {{get;set;}}");
var indentationLevel = entity.Namespace.IsFileScoped ? 1 : 2;
var indentation = new string('\t', indentationLevel);
var properties = GenerateProperties(entity.Properties, p => $"{indentation}public {p.Type} {p.Name} {{get;set;}}");

return GenerateCode(entity, entityType, properties);
}
return GenerateCode(entity, entityType, properties);
}


private string GenerateCode(Entity entity, string typeName, string properties)
{
var typeParameters = GenerateTypeParameters(entity);
var genericConstraints = GenerateGenericConstraints(entity);
private string GenerateCode(Entity entity, string typeName, string properties)
{
var typeParameters = GenerateTypeParameters(entity);
var genericConstraints = GenerateGenericConstraints(entity);

return entity.Namespace.IsFileScoped
?
return entity.Namespace.IsFileScoped
?
$@"{Comments}namespace {entity.Namespace.Name};

public partial {typeName} {entity.Name}{typeParameters}{genericConstraints}
{{
{properties}
}}"
:
:
$@"{Comments}namespace {entity.Namespace.Name}
{{
public partial {typeName} {entity.Name}{typeParameters}{genericConstraints}
{{
{properties}
}}
}}";
}
}
}
18 changes: 7 additions & 11 deletions AutoEntityGenerator.CodeGenerator/GeneratedCodeFile.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
using AutoEntityGenerator.Common.Interfaces;

namespace AutoEntityGenerator.CodeGenerator
namespace AutoEntityGenerator.CodeGenerator;

internal class GeneratedCodeFile : IGeneratedCodeFile
{
internal class GeneratedCodeFile : IGeneratedCodeFile
{
public GeneratedCodeFile(string content, string fileName)
{
Content = content;
FileName = fileName;
}
public GeneratedCodeFile(string content, string fileName)
=> (Content, FileName) = (content, fileName);

public string FileName { get; }
public string FileName { get; }

public string Content { get; }
public string Content { get; }

}
}
47 changes: 23 additions & 24 deletions AutoEntityGenerator.CodeGenerator/MappingsClassGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
using AutoEntityGenerator.Common.CodeInfo;

namespace AutoEntityGenerator.CodeGenerator
namespace AutoEntityGenerator.CodeGenerator;

public interface IMappingsClassGenerator
{
public interface IMappingsClassGenerator
{
string GenerateMappingClassCode(Entity from, Entity to);
}
string GenerateMappingClassCode(Entity from, Entity to);
}

internal class MappingsClassGenerator : CodeGeneratorBase, IMappingsClassGenerator
internal class MappingsClassGenerator : CodeGeneratorBase, IMappingsClassGenerator
{
public string GenerateMappingClassCode(Entity from, Entity to)
{
public string GenerateMappingClassCode(Entity from, Entity to)
{
var indentationLevel = from.Namespace.IsFileScoped ? 3 : 4;
var indentation = new string('\t', indentationLevel);
var properties = GenerateProperties(from.Properties, p => $"{indentation}{p.Name} = source.{p.Name},");
var indentationLevel = from.Namespace.IsFileScoped ? 3 : 4;
var indentation = new string('\t', indentationLevel);
var properties = GenerateProperties(from.Properties, p => $"{indentation}{p.Name} = source.{p.Name},");

return GenerateCode(from, to, properties);
}
return GenerateCode(from, to, properties);
}

private string GenerateCode(Entity from, Entity to, string properties)
{
private string GenerateCode(Entity from, Entity to, string properties)
{

var typeParameters = GenerateTypeParameters(to);
var genericConstraints = GenerateGenericConstraints(to);
var typeParameters = GenerateTypeParameters(to);
var genericConstraints = GenerateGenericConstraints(to);

var toFullName = string.IsNullOrEmpty(to.Namespace.Name)
? to.Name
: to.Namespace.Name + "." + to.Name;
var toFullName = string.IsNullOrEmpty(to.Namespace.Name)
? to.Name
: to.Namespace.Name + "." + to.Name;

return from.Namespace.IsFileScoped
?
return from.Namespace.IsFileScoped
?
$@"{Comments}namespace {from.Namespace.Name};

public static partial class {from.Name}MappingExtensions
Expand All @@ -42,7 +42,7 @@ public static partial class {from.Name}MappingExtensions
}};
}}
}}"
:
:
$@"{Comments}namespace {from.Namespace.Name}
{{
public static partial class {from.Name}MappingExtensions
Expand All @@ -56,6 +56,5 @@ public static partial class {from.Name}MappingExtensions
}}
}}
}}";
}
}
}
17 changes: 8 additions & 9 deletions AutoEntityGenerator.CodeGenerator/ServicesExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
using AutoEntityGenerator.Common.Interfaces;

namespace AutoEntityGenerator.CodeGenerator
namespace AutoEntityGenerator.CodeGenerator;

public static class ServicesExtensions
{
public static class ServicesExtensions
public static IServices AddCodeGenerator(this IServices services)
{
public static IServices AddCodeGenerator(this IServices services)
{
services.AddSingleton<IEntityGenerator, EntityGenerator>();
services.AddSingleton<IMappingsClassGenerator, MappingsClassGenerator>();
services.AddSingleton<ICodeFileGenerator, CodeFileGenerator>();
return services;
}
services.AddSingleton<IEntityGenerator, EntityGenerator>();
services.AddSingleton<IMappingsClassGenerator, MappingsClassGenerator>();
services.AddSingleton<ICodeFileGenerator, CodeFileGenerator>();
return services;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<LangVersion>13.0</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 2 additions & 4 deletions AutoEntityGenerator.Common/CodeInfo/Constructor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ namespace AutoEntityGenerator.Common.CodeInfo;
[ExcludeFromCodeCoverage] // There's no logic to test here...
public sealed class Constructor
{
public Constructor(IEnumerable<Parameter> parameters)
{
Parameters = new List<Parameter>(parameters);
}
public Constructor(IEnumerable<Parameter> parameters)
=> Parameters = [.. parameters];

public List<Parameter> Parameters { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Nullable>disable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
Expand Down
4 changes: 2 additions & 2 deletions AutoEntityGenerator/AutoEntityGenerator.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<LangVersion>latest</LangVersion>
<LangVersion>13.0</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var node = root.FindNode(context.Span);

if (!(node is ClassDeclarationSyntax || node is RecordDeclarationSyntax))
if (node is not (ClassDeclarationSyntax or RecordDeclarationSyntax))
{
return;
}
Expand Down
6 changes: 2 additions & 4 deletions AutoEntityGenerator/EntityGeneratorCodeAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ protected override Task<IEnumerable<CodeActionOperation>> ComputeOperationsAsync
]);
}

protected override Task<IEnumerable<CodeActionOperation>> ComputePreviewOperationsAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Enumerable.Empty<CodeActionOperation>());
}
protected override Task<IEnumerable<CodeActionOperation>> ComputePreviewOperationsAsync(CancellationToken cancellationToken)
=> Task.FromResult(Enumerable.Empty<CodeActionOperation>());
}