5
5
using System . Text ;
6
6
using Microsoft . CodeAnalysis ;
7
7
using Microsoft . CodeAnalysis . CSharp ;
8
- using Microsoft . CodeAnalysis . CSharp . Syntax ;
9
8
using Microsoft . CodeAnalysis . Text ;
10
9
11
10
namespace Svg . Generators
@@ -26,78 +25,6 @@ public class AvailableElementsGenerator : ISourceGenerator
26
25
DiagnosticSeverity . Error ,
27
26
isEnabledByDefault : true ) ;
28
27
29
- #region Model
30
-
31
- /// <summary>
32
- /// The object model used to generate SvgElements descriptors.
33
- /// </summary>
34
- private const string ModelText = @"// <auto-generated />
35
- #nullable disable
36
- using System;
37
- using System.Collections.Generic;
38
- using System.ComponentModel;
39
- using System.Globalization;
40
-
41
- namespace Svg
42
- {
43
- [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
44
- public sealed class ElementFactoryAttribute : Attribute
45
- {
46
- }
47
-
48
- internal enum DescriptorType
49
- {
50
- Property,
51
- Event
52
- }
53
-
54
- internal interface ISvgPropertyDescriptor
55
- {
56
- DescriptorType DescriptorType { get; }
57
- string AttributeName { get; }
58
- string AttributeNamespace { get; }
59
- TypeConverter Converter { get; }
60
- Type Type { get; }
61
- object GetValue(object component);
62
- void SetValue(object component, ITypeDescriptorContext context, CultureInfo culture, object value);
63
- }
64
-
65
- internal class SvgPropertyDescriptor<T, TU> : ISvgPropertyDescriptor
66
- {
67
- public DescriptorType DescriptorType { get; }
68
- public string AttributeName { get; }
69
- public string AttributeNamespace { get; }
70
- public TypeConverter Converter { get; }
71
- public Type Type { get; } = typeof(TU);
72
- private Func<T, TU> Getter { get; }
73
- private Action<T, TU> Setter { get; }
74
-
75
- public SvgPropertyDescriptor(DescriptorType descriptorType, string attributeName, string attributeNamespace, TypeConverter converter, Func<T, TU> getter, Action<T, TU> setter)
76
- {
77
- DescriptorType = descriptorType;
78
- AttributeName = attributeName;
79
- AttributeNamespace = attributeNamespace;
80
- Converter = converter;
81
- Getter = getter;
82
- Setter = setter;
83
- }
84
-
85
- public object GetValue(object component)
86
- {
87
- return (object)Getter((T)component);
88
- }
89
-
90
- public void SetValue(object component, ITypeDescriptorContext context, CultureInfo culture, object value)
91
- {
92
- if (Converter != null)
93
- {
94
- Setter((T)component, (TU)Converter.ConvertFrom(context, culture, value));
95
- }
96
- }
97
- }
98
- }" ;
99
- #endregion
100
-
101
28
/// <inheritdoc/>
102
29
public void Initialize ( GeneratorInitializationContext context )
103
30
{
@@ -109,17 +36,13 @@ public void Initialize(GeneratorInitializationContext context)
109
36
/// <inheritdoc/>
110
37
public void Execute ( GeneratorExecutionContext context )
111
38
{
112
- // Add the ElementFactory model source to compilation.
113
- context . AddSource ( "Svg_Model" , SourceText . From ( ModelText , Encoding . UTF8 ) ) ;
114
-
115
39
// Check is we have our SyntaxReceiver object used to filter compiled code.
116
40
if ( ! ( context . SyntaxReceiver is SyntaxReceiver receiver ) )
117
41
{
118
42
return ;
119
43
}
120
44
121
- var options = ( context . Compilation as CSharpCompilation ) ? . SyntaxTrees [ 0 ] . Options as CSharpParseOptions ;
122
- var compilation = context . Compilation . AddSyntaxTrees ( CSharpSyntaxTree . ParseText ( SourceText . From ( ModelText , Encoding . UTF8 ) , options ) ) ;
45
+ var compilation = context . Compilation ;
123
46
124
47
var elementFactoryAttribute = compilation . GetTypeByMetadataName ( "Svg.ElementFactoryAttribute" ) ;
125
48
if ( elementFactoryAttribute is null )
@@ -367,7 +290,7 @@ internal virtual bool SetValue(string attributeName, ITypeDescriptorContext cont
367
290
}}
368
291
}}
369
292
" ) ;
370
- context . AddSource ( $ "Svg_SvgElement_Properties .cs", SourceText . From ( source . ToString ( ) , Encoding . UTF8 ) ) ;
293
+ context . AddSource ( $ "Svg.SvgElement.Properties.g .cs", SourceText . From ( source . ToString ( ) , Encoding . UTF8 ) ) ;
371
294
source . Clear ( ) ;
372
295
373
296
// Generate SvgElement derived classes with descriptor Properties dictionary.
@@ -456,7 +379,7 @@ internal override bool SetValue(string attributeName, ITypeDescriptorContext con
456
379
}}
457
380
}}
458
381
" ) ;
459
- context . AddSource ( $ "{ namespaceElement . Replace ( '.' , '_' ) } _ { element . Symbol . Name } _Properties .cs", SourceText . From ( source . ToString ( ) , Encoding . UTF8 ) ) ;
382
+ context . AddSource ( $ "{ namespaceElement } . { element . Symbol . Name } .Properties.g .cs", SourceText . From ( source . ToString ( ) , Encoding . UTF8 ) ) ;
460
383
source . Clear ( ) ;
461
384
}
462
385
@@ -492,7 +415,7 @@ internal static class SvgElements
492
415
}
493
416
}
494
417
" ) ;
495
- context . AddSource ( $ "Svg_SvgElements .cs", SourceText . From ( source . ToString ( ) , Encoding . UTF8 ) ) ;
418
+ context . AddSource ( $ "Svg.SvgElements.g .cs", SourceText . From ( source . ToString ( ) , Encoding . UTF8 ) ) ;
496
419
source . Clear ( ) ;
497
420
498
421
// Generate ElementFactory class.
@@ -586,7 +509,7 @@ internal partial class {classElementFactory}
586
509
}}
587
510
}}" ) ;
588
511
589
- context . AddSource ( $ "{ namespaceElementFactory . Replace ( '.' , '_' ) } _ { elementFactorySymbol . Name } _ElementFactory .cs", SourceText . From ( source . ToString ( ) , Encoding . UTF8 ) ) ;
512
+ context . AddSource ( $ "{ namespaceElementFactory } . { elementFactorySymbol . Name } .ElementFactory.g .cs", SourceText . From ( source . ToString ( ) , Encoding . UTF8 ) ) ;
590
513
source . Clear ( ) ;
591
514
}
592
515
@@ -755,6 +678,10 @@ private static IEnumerable<INamedTypeSymbol> GetBaseTypes(INamedTypeSymbol named
755
678
{
756
679
"System.String" => "System.ComponentModel.StringConverter" ,
757
680
"System.Single" => "System.ComponentModel.SingleConverter" ,
681
+ "System.Int16" => "System.ComponentModel.Int16Converter" ,
682
+ "System.Int32" => "System.ComponentModel.Int32Converter" ,
683
+ "System.Int64" => "System.ComponentModel.Int64Converter" ,
684
+ "System.Boolean" => "System.ComponentModel.BooleanConverter" ,
758
685
"System.Uri" => "System.UriTypeConverter" ,
759
686
_ => null
760
687
} ;
@@ -863,149 +790,5 @@ private static IEnumerable<Property> GetElementProperties(Compilation compilatio
863
790
}
864
791
}
865
792
}
866
-
867
- /// <summary>
868
- /// Symbol member type.
869
- /// </summary>
870
- private enum MemberType
871
- {
872
- /// <summary>
873
- /// Property symbol.
874
- /// </summary>
875
- Property ,
876
- /// <summary>
877
- /// Event symbol.
878
- /// </summary>
879
- Event
880
- }
881
-
882
- /// <summary>
883
- /// The SvgElement object property/event.
884
- /// </summary>
885
- private class Property
886
- {
887
- /// <summary>
888
- /// Gets or sets property/event symbol.
889
- /// </summary>
890
- public ISymbol Symbol { get ; }
891
-
892
- /// <summary>
893
- /// Gets or sets property/event symbol member type.
894
- /// </summary>
895
- public MemberType MemberType { get ; }
896
-
897
- /// <summary>
898
- /// Gets or sets property/event attribute name.
899
- /// </summary>
900
- public string AttributeName { get ; }
901
-
902
- /// <summary>
903
- /// Gets or sets property/event attribute namespace.
904
- /// </summary>
905
- public string AttributeNamespace { get ; }
906
-
907
- /// <summary>
908
- /// Gets or sets property/event type converter type string.
909
- /// </summary>
910
- public string ? Converter { get ; }
911
-
912
- /// <summary>
913
- /// Initializes a new instance of the <see cref="Property"/> class.
914
- /// </summary>
915
- /// <param name="symbol">The property/event symbol.</param>
916
- /// <param name="memberType">The property/event symbol member type.</param>
917
- /// <param name="attributeName">The property/event attribute name.</param>
918
- /// <param name="attributeNamespace">The property/event attribute namespace.</param>
919
- /// <param name="converter">The property/event type converter type string.</param>
920
- public Property ( ISymbol symbol , MemberType memberType , string attributeName , string attributeNamespace , string ? converter )
921
- {
922
- Symbol = symbol ;
923
- MemberType = memberType ;
924
- AttributeName = attributeName ;
925
- AttributeNamespace = attributeNamespace ;
926
- Converter = converter ;
927
- }
928
- }
929
-
930
- /// <summary>
931
- /// Custom <see cref="Property"/> equality comparer using <see cref="ISymbol"/> for cmparison.
932
- /// </summary>
933
- private class PropertyEqualityComparer : IEqualityComparer < Property >
934
- {
935
- /// <inheritdoc/>
936
- public bool Equals ( Property p1 , Property p2 )
937
- {
938
- return SymbolEqualityComparer . Default . Equals ( p1 . Symbol , p2 . Symbol ) ;
939
- }
940
-
941
- /// <inheritdoc/>
942
- public int GetHashCode ( Property p )
943
- {
944
- #pragma warning disable RS1024
945
- return p . Symbol . GetHashCode ( ) ;
946
- #pragma warning restore RS1024
947
- }
948
- }
949
-
950
- /// <summary>
951
- /// The SvgElement object.
952
- /// </summary>
953
- private class Element
954
- {
955
- /// <summary>
956
- /// Gets or sets element type symbol.
957
- /// </summary>
958
- public INamedTypeSymbol Symbol { get ; }
959
-
960
- /// <summary>
961
- /// Gets or sets element name.
962
- /// </summary>
963
- public string ? ElementName { get ; }
964
-
965
- /// <summary>
966
- /// Gets or sets classes that use element name.
967
- /// </summary>
968
- public List < string > ClassNames { get ; }
969
-
970
- /// <summary>
971
- /// Gets or sets element properties list.
972
- /// </summary>
973
- public List < Property > Properties { get ; }
974
-
975
- /// <summary>
976
- /// Initializes a new instance of the <see cref="Element"/> class.
977
- /// </summary>
978
- /// <param name="symbol">The element type symbol.</param>
979
- /// <param name="elementName">The element name.</param>
980
- /// <param name="classNames">The classes that use element name.</param>
981
- /// <param name="properties">The element properties list.</param>
982
- public Element ( INamedTypeSymbol symbol , string ? elementName , List < string > classNames , List < Property > properties )
983
- {
984
- Symbol = symbol ;
985
- ElementName = elementName ;
986
- ClassNames = classNames ;
987
- Properties = properties ;
988
- }
989
- }
990
-
991
- /// <summary>
992
- /// The SyntaxReceiver is used to filter compiled code. This enable quick and easy way to filter compiled code.
993
- /// </summary>
994
- private class SyntaxReceiver : ISyntaxReceiver
995
- {
996
- /// <summary>
997
- /// Gets the list of all candidate class.
998
- /// </summary>
999
- public List < ClassDeclarationSyntax > CandidateClasses { get ; } = new ( ) ;
1000
-
1001
- /// <inheritdoc/>
1002
- public void OnVisitSyntaxNode ( SyntaxNode syntaxNode )
1003
- {
1004
- if ( syntaxNode is ClassDeclarationSyntax classDeclarationSyntax )
1005
- {
1006
- CandidateClasses . Add ( classDeclarationSyntax ) ;
1007
- }
1008
- }
1009
- }
1010
793
}
1011
794
}
0 commit comments