88
99namespace MapDataReader
1010{
11- [ AttributeUsage ( AttributeTargets . Class , AllowMultiple = false ) ]
11+ /// <summary>
12+ /// An attribute used to mark a class for which a data reader mapper will be generated.
13+ /// </summary>
14+ /// <remarks>
15+ /// The auto-generated mappers will help in mapping data from a data reader to the class properties.
16+ /// </remarks>
17+ [ AttributeUsage ( AttributeTargets . Class ) ]
1218 public class GenerateDataReaderMapperAttribute : Attribute
1319 {
1420 }
1521
22+ /// <summary>
23+ /// A source generator responsible for creating mapping extensions that allow for setting properties of a class
24+ /// based on the property name using data from a data reader.
25+ /// </summary>
26+ /// <remarks>
27+ /// This generator scans for classes marked with specific attributes and generates an extension method
28+ /// that facilitates setting properties by their names.
29+ /// </remarks>
1630 [ Generator ]
1731 public class MapperGenerator : ISourceGenerator
1832 {
33+ private const string Newline = @"
34+ " ;
35+
36+ /// <summary>
37+ /// Executes the source generation logic, which scans for types needing generation,
38+ /// processes their properties, and generates the corresponding source code for mapping extensions.
39+ /// </summary>
1940 public void Execute ( GeneratorExecutionContext context )
2041 {
2142 if ( context . SyntaxContextReceiver is not TargetTypeTracker targetTypeTracker )
@@ -50,7 +71,7 @@ public static class {{typeNode.Identifier}}Extensions
5071 {
5172 public static void SetPropertyByName(this {{ typeNodeSymbol . FullName ( ) }} target, string name, object value)
5273 {
53- SetPropertyByUpperName(target, name.ToUpperInvariant(), value);
74+ SetPropertyByUpperName(target, name.ToUpperInvariant(), value);
5475 }
5576
5677 private static void SetPropertyByUpperName(this {{ typeNodeSymbol . FullName ( ) }} target, string name, object value)
@@ -85,42 +106,42 @@ private static void SetPropertyByUpperName(this {{typeNodeSymbol.FullName()}} ta
85106 return $ "\t \t if (value != null && name == \" { p . Name . ToUpperInvariant ( ) } \" ) {{ target.{ p . Name } = value.GetType() == typeof({ pTypeName } ) ? ({ pTypeName } )value : ({ pTypeName } )Convert.ChangeType(value, typeof({ pTypeName } )); return; }}";
86107 } ) . StringConcat ( Newline )
87108 }}
88- }
89-
109+ }
110+
90111 """ ;
91112
92113
93114 if ( typeNodeSymbol . InstanceConstructors . Any ( c => ! c . Parameters . Any ( ) ) ) //has a constructor without parameters?
94115 {
95116 src += $$ """
96-
117+
97118 public static List<{{ typeNodeSymbol . FullName ( ) }} > To<T>(this IDataReader dr) where T : {{ typeNodeSymbol . FullName ( ) }}
98119 {
99120 var list = new List<{{ typeNodeSymbol . FullName ( ) }} >();
100-
101- if (dr.Read())
121+
122+ if (dr.Read())
102123 {
103- string[] columnNames = new string[dr.FieldCount];
104-
105- for (int i = 0; i < columnNames.Length; i++)
106- columnNames[i] = dr.GetName(i).ToUpperInvariant();
107-
108- do
124+ string[] columnNames = new string[dr.FieldCount];
125+
126+ for (int i = 0; i < columnNames.Length; i++)
127+ columnNames[i] = dr.GetName(i).ToUpperInvariant();
128+
129+ do
109130 {
110131 var result = new {{ typeNodeSymbol . FullName ( ) }} ();
111- for (int i = 0; i < columnNames.Length; i++)
132+ for (int i = 0; i < columnNames.Length; i++)
112133 {
113- var value = dr[i];
114- if (value is DBNull) value = null;
115- SetPropertyByUpperName(result, columnNames[i], value);
134+ var value = dr[i];
135+ if (value is DBNull) value = null;
136+ SetPropertyByUpperName(result, columnNames[i], value);
116137 }
117- list.Add(result);
138+ list.Add(result);
118139 } while (dr.Read());
119140 }
120- dr.Close();
121- return list;
122- }
123-
141+ dr.Close();
142+ return list;
143+ }
144+
124145 """ ;
125146 }
126147
@@ -132,6 +153,10 @@ private static void SetPropertyByUpperName(this {{typeNodeSymbol.FullName()}} ta
132153 }
133154 }
134155
156+ /// <summary>
157+ /// Initializes the generator. This method is called before any generation occurs and allows
158+ /// for setting up any necessary context or registering for specific notifications.
159+ /// </summary>
135160 public void Initialize ( GeneratorInitializationContext context )
136161 {
137162 context . RegisterForSyntaxNotifications ( ( ) => new TargetTypeTracker ( ) ) ;
@@ -162,7 +187,9 @@ internal static bool IsDecoratedWithAttribute(this TypeDeclarationSyntax cdecl,
162187
163188 internal static string StringConcat ( this IEnumerable < string > source , string separator ) => string . Join ( separator , source ) ;
164189
165- // returns all properties with public setters
190+ /// <summary>
191+ /// Returns all properties with public setters
192+ /// </summary>
166193 internal static IEnumerable < IPropertySymbol > GetAllSettableProperties ( this ITypeSymbol typeSymbol )
167194 {
168195 var result = typeSymbol
@@ -179,7 +206,9 @@ internal static IEnumerable<IPropertySymbol> GetAllSettableProperties(this IType
179206 return result ;
180207 }
181208
182- //checks if type is a nullable num
209+ /// <summary>
210+ /// Checks if type is a nullable Enum
211+ /// </summary>
183212 internal static bool IsNullableEnum ( this ITypeSymbol symbol )
184213 {
185214 //tries to get underlying non-nullable type from nullable type
0 commit comments