Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additional generator options #9

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions MapDataReader.Benchmarks/MapDataReader.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion MapDataReader.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public static void Setup()
}
}

[GenerateDataReaderMapper]
[GenerateDataReaderMapper(AccessModifier = "internal")]
public class TestClass
{
public string String1 { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion MapDataReader.Tests/MapDataReader.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
33 changes: 32 additions & 1 deletion MapDataReader.Tests/TestActualCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

Expand Down Expand Up @@ -147,7 +148,7 @@ public void TestStringAssign()
}

[TestMethod]
public void TestDatatReader()
public void TestDataReader()
{
//create datatable with test data
var dt = new DataTable();
Expand Down Expand Up @@ -227,6 +228,24 @@ public void TestWrongProperty()
o.SetPropertyByName("Name", 123); //try to assign string prop to int
Assert.IsTrue(o.Name == null); //wrong type. should be null
}

[TestMethod]
public void TestInternalAccessModifier()
{
var type = typeof(MapperExtensions);
var method = type.GetMethod("ToTestClassInternal", BindingFlags.Static | BindingFlags.NonPublic);

Assert.IsNotNull(method, "Expected method 'ToTestClassInternal' to be 'internal'.");
}

[TestMethod]
public void TestInternalAccessModifierNamed()
{
var type = typeof(MapperExtensions);
var method = type.GetMethod("ToTestClassInternalNamed", BindingFlags.Static | BindingFlags.NonPublic);

Assert.IsNotNull(method, "Expected method 'ToTestClassInternalNamed' to be 'internal'.");
}
}

public class BaseClass
Expand All @@ -239,5 +258,17 @@ public class ChildClass : BaseClass
{
public string Name { get; set; }
}

[GenerateDataReaderMapper("internal")]
internal class TestClassInternal
{
public int Id { get; set; }
}

[GenerateDataReaderMapper(AccessModifier = "internal")]
internal class TestClassInternalNamed
{
public int Id { get; set; }
}
}

46 changes: 46 additions & 0 deletions MapDataReader.Tests/TestGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,52 @@ public class MyClass
public decimal Price {get;set;}
}
}
";
var src = GetAndCheckOutputSource(userSource);
}

[TestMethod]
public void TestAccessModifier()
{
string userSource = @"
using MapDataReader;

namespace MyCode
{
[GenerateDataReaderMapper(""internal"")]
public class MyClass
{
public string Name {get;set;}
public int Size {get;set;}
public bool Enabled {get;set;}
public System.DateTime Created {get;set;}
public System.DateTimeOffset Offset {get;set;}
public decimal Price {get;set;}
}
}
";
var src = GetAndCheckOutputSource(userSource);
}

[TestMethod]
public void TestAttributes()
{
string userSource = @"
using MapDataReader;

namespace TestNamespace
{
[GenerateDataReaderMapper(AccessModifier = ""internal"", NamespaceName = ""TestNamespace"", MethodName = ""ConvertToCustom"")]
public class MyClass
{
public string Name {get;set;}
public int Size {get;set;}
public bool Enabled {get;set;}
public System.DateTime Created {get;set;}
public System.DateTimeOffset Offset {get;set;}
public decimal Price {get;set;}
}
}
";
var src = GetAndCheckOutputSource(userSource);
}
Expand Down
29 changes: 29 additions & 0 deletions MapDataReader/GenerateDataReaderMapperAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;

namespace MapDataReader;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class GenerateDataReaderMapperAttribute : Attribute
{
public string AccessModifier { get; set; }

/// <summary>
/// Gets or sets the namespace to be used in the generated methods.
/// </summary>
public string NamespaceName { get; set; }

/// <summary>
/// Gets or sets the method name to be used in the generated methods.
/// </summary>
public string MethodName { get; set; }

public GenerateDataReaderMapperAttribute()
{
AccessModifier = "public";
}

public GenerateDataReaderMapperAttribute(string access = "public")
{
AccessModifier = access;
}
}
52 changes: 52 additions & 0 deletions MapDataReader/Helpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace MapDataReader;

internal static class Helpers
{
internal static bool IsDecoratedWithAttribute(this TypeDeclarationSyntax cdecl, string attributeName) =>
cdecl.AttributeLists
.SelectMany(x => x.Attributes)
.Any(x => x.Name.ToString().Contains(attributeName));


internal static string FullName(this ITypeSymbol typeSymbol) => typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);

internal static string StringConcat(this IEnumerable<string> source, string separator) => string.Join(separator, source);

// returns all properties with public setters
internal static IEnumerable<IPropertySymbol> GetAllSettableProperties(this ITypeSymbol typeSymbol)
{
var result = typeSymbol
.GetMembers()
.Where(s => s.Kind == SymbolKind.Property).Cast<IPropertySymbol>() //get all properties
.Where(p => p.SetMethod?.DeclaredAccessibility == Accessibility.Public) //has a public setter?
.ToList();

//now get the base class
var baseType = typeSymbol.BaseType;
if (baseType != null)
result.AddRange(baseType.GetAllSettableProperties()); //recursion

return result;
}

//checks if type is a nullable num
internal static bool IsNullableEnum(this ITypeSymbol symbol)
{
//tries to get underlying non-nullable type from nullable type
//and then check if it's Enum
if (symbol.NullableAnnotation == NullableAnnotation.Annotated
&& symbol is INamedTypeSymbol namedType
&& namedType.IsValueType
&& namedType.IsGenericType
&& namedType.ConstructedFrom?.ToDisplayString() == "System.Nullable<T>"
)
return namedType.TypeArguments[0].TypeKind == TypeKind.Enum;

return false;
}
}
1 change: 1 addition & 0 deletions MapDataReader/MapDataReader.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<PackageTags>aot;source-generator</PackageTags>
<Description>Super fast mapping of DataReader to custom objects</Description>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading