33
44namespace RoyalCode . SmartSelector . Generators . Generators ;
55
6- internal static class AutoPropertyGenerator
6+ internal static class AutoPropertiesGenerator
77{
88 internal static MatchOptions MatchOptions { get ; } = new ( )
99 {
1010 OriginPropertiesRetriever = new AutoPropertyOriginPropertiesRetriever ( ) ,
1111 //TargetPropertiesRetriever = new AutoPropertyTargetPropertiesRetriever(),
1212 } ;
1313
14- internal static AutoPropertyInformation CreateInformation (
14+ internal static AutoPropertiesInformation CreateInformation (
1515 TypeDescriptor modelType ,
1616 TypeDescriptor fromType ,
1717 AttributeSyntax properties )
1818 {
1919 // collect excluded property names using extension helpers
2020 var excluded = new HashSet < string > ( StringComparer . Ordinal ) ;
2121
22- foreach ( var name in properties . GetConstructorStringSet ( ) )
23- excluded . Add ( name ) ;
22+ // removido por hora
23+ ////foreach (var name in properties.GetConstructorStringSet())
24+ //// excluded.Add(name);
2425
2526 foreach ( var name in properties . GetNamedArgumentStringSet ( "Exclude" ) )
2627 excluded . Add ( name ) ;
2728
2829 return CreateInformation ( modelType , fromType , excluded ) ;
2930 }
3031
31- internal static AutoPropertyInformation CreateInformation (
32+ internal static AutoPropertiesInformation CreateInformation (
3233 TypeDescriptor modelType ,
3334 ITypeSymbol fromType ,
3435 AttributeData autoPropertyAttribute )
3536 {
36- // obtém excluded do ctor ou propriedade Exclude
3737 var excluded = new HashSet < string > ( StringComparer . Ordinal ) ;
38- foreach ( var name in autoPropertyAttribute . ConstructorArguments )
39- if ( name . Kind == TypedConstantKind . Array && name . Values != null )
40- foreach ( var v in name . Values )
41- if ( v . Value is string s )
42- excluded . Add ( s ) ;
38+
39+ // removido por hora
40+ ////// obtém excluded do ctor ou propriedade Exclude
41+ ////foreach (var name in autoPropertyAttribute.ConstructorArguments)
42+ //// if (name.Kind == TypedConstantKind.Array && name.Values != null)
43+ //// foreach (var v in name.Values)
44+ //// if (v.Value is string s)
45+ //// excluded.Add(s);
46+
47+ // obtém Exclude de NamedArguments
4348 foreach ( var namedArg in autoPropertyAttribute . NamedArguments )
4449 if ( namedArg . Key == "Exclude" && namedArg . Value . Kind == TypedConstantKind . Array && namedArg . Value . Values != null )
4550 foreach ( var v in namedArg . Value . Values )
4651 if ( v . Value is string s )
4752 excluded . Add ( s ) ;
4853
4954 // gera o TypeDescriptor do fromType
50- var fromTypeDescriptor = TypeDescriptor . Create ( fromType ) ;
55+ var fromTypeDescriptor = fromType . CreateTypeDescriptor ( ) ;
5156
5257 return CreateInformation ( modelType , fromTypeDescriptor , excluded ) ;
5358 }
5459
55- internal static AutoPropertyInformation CreateInformation (
60+ internal static AutoPropertiesInformation CreateInformation (
5661 TypeDescriptor modelType ,
5762 TypeDescriptor fromType ,
5863 HashSet < string > excluded )
@@ -62,18 +67,82 @@ internal static AutoPropertyInformation CreateInformation(
6267 excluded . Add ( p . Name ) ;
6368
6469 var sourceProps = fromType . CreateProperties ( p => p . GetMethod is not null ) ;
70+
71+ // filtra propriedades do source,
72+ // remove propriedades que estão na lista de excluídas,
73+ // removendo o que não for tipo primitivo, string, decimal, DateTime,
74+ // enum ou nullable desses tipos, além de coleções de tipos primitivos,
75+ // aceita structs também.
76+ sourceProps = sourceProps
77+ . Where ( p => ! excluded . Contains ( p . Name ) )
78+ . Where ( IsSupportedType )
79+ . ToArray ( ) ;
80+
6581 var generated = new List < PropertyDescriptor > ( ) ;
6682 foreach ( var p in sourceProps )
6783 {
68- if ( excluded . Contains ( p . Name ) )
69- continue ;
7084 generated . Add ( new PropertyDescriptor ( p . Type , p . Name , p . Symbol ) ) ;
7185 }
7286
73- return new AutoPropertyInformation ( modelType , [ .. generated ] ) ;
87+ return new AutoPropertiesInformation ( modelType , [ .. generated ] ) ;
7488 }
7589
76- internal static void Generate ( AutoPropertyInformation propertiesInfo , SourceProductionContext context )
90+ private static readonly HashSet < string > SupportedPrimitiveTypes = new ( StringComparer . Ordinal )
91+ {
92+ "bool" ,
93+ "Boolean" ,
94+ "string" , "char" ,
95+ "String" , "Char" ,
96+ "byte" , "short" , "int" , "long" , "float" , "double" , "decimal" ,
97+ "Byte" , "Int16" , "Int32" , "Int64" , "Single" , "Double" , "Decimal" ,
98+ "sbyte" , "ushort" , "uint" , "ulong" ,
99+ "SByte" , "UInt16" , "UInt32" , "UInt64" ,
100+ "DateTime" , "DateTime?" ,
101+ } ;
102+
103+ private static bool IsSupportedType ( PropertyDescriptor descriptor )
104+ {
105+ var type = descriptor . Type ;
106+ var typeName = type . Name ;
107+
108+ if ( SupportedPrimitiveTypes . Contains ( typeName ) )
109+ return true ;
110+
111+ if ( ! type . HasNamedTypeSymbol ( out var namedType ) )
112+ return false ;
113+
114+ // se tem symbol, verifica se é enum
115+ if ( namedType . TypeKind == TypeKind . Enum )
116+ return true ;
117+
118+ // struct é considerado um value object, não é um tipo complexo e deve ser aceito
119+ if ( namedType . TypeKind == TypeKind . Struct )
120+ return true ;
121+
122+ // se for genérico, verifica se coleção suportada
123+ if ( namedType . IsGenericType )
124+ {
125+ // verifica se namedType implementa ou herda IEnumerable<>
126+ if ( ! namedType . AllInterfaces . Any ( i =>
127+ i . OriginalDefinition . SpecialType == SpecialType . System_Collections_Generic_IEnumerable_T ) )
128+ {
129+ return false ;
130+ }
131+
132+ var arg = namedType . TypeArguments . FirstOrDefault ( ) ;
133+ if ( arg != null )
134+ {
135+ var argType = arg . CreateTypeDescriptor ( ) ;
136+ return SupportedPrimitiveTypes . Contains ( argType . Name )
137+ || arg . TypeKind == TypeKind . Enum
138+ || arg . TypeKind == TypeKind . Struct ;
139+ }
140+ }
141+
142+ return false ;
143+ }
144+
145+ internal static void Generate ( AutoPropertiesInformation propertiesInfo , SourceProductionContext context )
77146 {
78147 // gera o código de propriedades automáticas em uma classe partial
79148
@@ -109,11 +178,15 @@ internal static void Generate(AutoPropertyInformation propertiesInfo, SourceProd
109178 // 2 - criação das propriedades
110179 foreach ( var p in properties )
111180 {
112- var prop = new PropertyGenerator ( p . Type , p . Name ) ;
113-
181+ var propertyType = p . Type . HasNamedTypeSymbol ( out var typeSymbol )
182+ ? typeSymbol . CreateTypeDescriptor ( )
183+ : p . Type ;
184+
185+ var prop = new PropertyGenerator ( propertyType , p . Name ) ;
186+
114187 // 2.1 modificadores
115188 prop . Modifiers . Public ( ) ;
116-
189+
117190 // 2.3 adiciona a propriedade na classe
118191 partialClass . Properties . Add ( prop ) ;
119192 }
@@ -157,7 +230,7 @@ public IReadOnlyList<PropertyDescriptor> GetProperties(TypeDescriptor origin)
157230 return MatchOptions . GetOriginProperties ( origin ) ;
158231
159232 // cria a informação
160- var info = AutoPropertyGenerator . CreateInformation ( origin , fromType , autoSelectAttribute ) ;
233+ var info = AutoPropertiesGenerator . CreateInformation ( origin , fromType , autoSelectAttribute ) ;
161234
162235 // pega as propriedades da origem mais as da informação
163236 return [ .. MatchOptions . GetOriginProperties ( origin ) , .. info . Properties ] ;
@@ -175,12 +248,12 @@ public IReadOnlyList<PropertyDescriptor> GetProperties(TypeDescriptor origin)
175248 return MatchOptions . GetOriginProperties ( origin ) ;
176249
177250 // cria a informação
178- var info = AutoPropertyGenerator . CreateInformation ( origin , fromType , autoPropertiesAttribute ) ;
251+ var info = AutoPropertiesGenerator . CreateInformation ( origin , fromType , autoPropertiesAttribute ) ;
179252
180253 // pega as propriedades da origem mais as da informação
181254 return [ .. MatchOptions . GetOriginProperties ( origin ) , .. info . Properties ] ;
182255 }
183-
256+
184257 return MatchOptions . GetOriginProperties ( origin ) ;
185258 }
186259}
0 commit comments