55//////////////////////////////////////////////
66
77using EppNet . SourceGen ;
8+ using EppNet . SourceGen . Errors ;
89using EppNet . SourceGen . Models ;
910
1011using Microsoft . CodeAnalysis ;
1112using Microsoft . CodeAnalysis . CSharp ;
1213using Microsoft . CodeAnalysis . CSharp . Syntax ;
1314using Microsoft . CodeAnalysis . Diagnostics ;
1415
15- using System ;
1616using System . Collections . Concurrent ;
17+ using System . Collections . Generic ;
1718using System . Collections . Immutable ;
18- using System . Reflection ;
1919
2020namespace EppNet . Source . Analysis
2121{
@@ -24,14 +24,13 @@ public class NetworkObjectAnalysis : DiagnosticAnalyzer
2424 {
2525
2626 public static ConcurrentDictionary < string , string > Resolvers = new ( ) ;
27- public static ConcurrentDictionary < string , NetworkObjectModel ? > Objects = new ( ) ;
27+ public static ConcurrentDictionary < string , NetworkObjectModel > Objects = new ( ) ;
2828
2929 public override void Initialize ( AnalysisContext context )
3030 {
3131 context . ConfigureGeneratedCodeAnalysis ( GeneratedCodeAnalysisFlags . None ) ;
3232 context . EnableConcurrentExecution ( ) ;
3333
34-
3534 context . RegisterCompilationStartAction ( compContext =>
3635 {
3736
@@ -43,32 +42,13 @@ public override void Initialize(AnalysisContext context)
4342 if ( ! Globals . HasAttribute ( classNode , Globals . NetTypeResolverAttr ) )
4443 return ;
4544
46- ( ResolverModel ? , ResolverAnalysisError ) data = Globals . LocateResolver ( snac . Node , snac . SemanticModel , snac . CancellationToken ) ;
47- ResolverAnalysisError results = data . Item2 ;
48-
49- foreach ( ResolverAnalysisError error in Enum . GetValues ( typeof ( ResolverAnalysisError ) ) )
50- {
51- if ( error == ResolverAnalysisError . None )
52- continue ;
53-
54- if ( results . HasFlag ( error ) )
55- {
56- string message = error switch
57- {
58- ResolverAnalysisError . LacksSingleton => $ "{ classNode . Identifier . Text } : Resolvers must define a public static singleton field or property \" Instance\" ",
59- ResolverAnalysisError . LacksInheritance => $ "{ classNode . Identifier . Text } : Resolvers must inherit from { Globals . TypeResolverFullGenericName } ",
60- ResolverAnalysisError . NotClass => $ "{ classNode . Identifier . Text } : Resolvers must be a class!",
61- _ => ToString ( ) ,
62- } ;
63- snac . ReportDiagnostic ( Diagnostic . Create ( Globals . DescTypeResolverError ,
64- classNode . Identifier . GetLocation ( ) , message ) ) ;
65- }
66- }
67-
68- if ( results == ResolverAnalysisError . None && data . Item1 . HasValue )
69- {
70- Resolvers [ data . Item1 . Value . ResolvedTypeFullName ] = data . Item1 . Value . Name ;
71- }
45+ ( ResolverModel ? model , List < AnalysisError > errors ) = Globals . TryCreateResolver ( snac . Node as CSharpSyntaxNode , snac . SemanticModel , snac . CancellationToken ) ;
46+
47+ foreach ( AnalysisError error in errors )
48+ snac . ReportDiagnostic ( error . CreateDiagnostic ( ) ) ;
49+
50+ if ( model . HasValue && errors . Count == 0 )
51+ Resolvers [ model . Value . ResolvedTypeFullName ] = model . Value . Name ;
7252
7353 } , SyntaxKind . ClassDeclaration ) ;
7454
@@ -79,36 +59,14 @@ public override void Initialize(AnalysisContext context)
7959 if ( ! Globals . HasAttribute ( classNode , Globals . NetObjectAttr ) )
8060 return ;
8161
82- var data = Globals . LocateNetObject (
83- classNode , snac . SemanticModel , snac . CancellationToken ) ;
84-
85- NetworkObjectModel ? netModel = data . Item1 ;
86- NetworkObjectAnalysisError results = data . Item2 ;
87-
88- foreach ( NetworkObjectAnalysisError error in Enum . GetValues ( typeof ( NetworkObjectAnalysisError ) ) )
89- {
90- if ( error == NetworkObjectAnalysisError . None )
91- continue ;
92-
93- if ( results . HasFlag ( error ) )
94- {
95- string message = error switch
96- {
97- NetworkObjectAnalysisError . NotPartial => $ "{ classNode . Identifier . Text } : Network Object definitions must be partial! Num Resolvers: { Resolvers . Count } ",
98- NetworkObjectAnalysisError . LacksInheritance => $ "{ classNode . Identifier . Text } : Network Object definitions must inherit from { Globals . NetworkObjectInterfaceName } ",
99- NetworkObjectAnalysisError . NotClass => $ "{ classNode . Identifier . Text } : Network Object definitions must be a class!",
100- _ => ToString ( ) ,
101- } ;
102-
103- snac . ReportDiagnostic ( Diagnostic . Create ( Globals . DescNetObjError ,
104- classNode . Identifier . GetLocation ( ) , message ) ) ;
105- }
106- }
107-
108- if ( results == NetworkObjectAnalysisError . None && data . Item1 . HasValue )
109- {
110- Objects [ data . Item1 . Value . FullyQualifiedName ] = data . Item1 ;
111- }
62+ ( NetworkObjectModel ? netModel , List < AnalysisError > errors ) = Globals . TryCreateNetObject (
63+ classNode , snac . SemanticModel , Resolvers , snac . CancellationToken ) ;
64+
65+ foreach ( AnalysisError error in errors )
66+ snac . ReportDiagnostic ( error . CreateDiagnostic ( ) ) ;
67+
68+ if ( netModel . HasValue && errors . Count == 0 )
69+ Objects [ netModel . Value . FullyQualifiedName ] = netModel . Value ;
11270
11371 } , SyntaxKind . ClassDeclaration ) ;
11472
@@ -117,51 +75,18 @@ public override void Initialize(AnalysisContext context)
11775
11876 MethodDeclarationSyntax methodNode = snac . Node as MethodDeclarationSyntax ;
11977
120- if ( ! Globals . HasAttribute ( methodNode , Globals . NetMethodAttr ) )
78+ if ( methodNode is not null && ! Globals . HasAttribute ( methodNode , Globals . NetMethodAttr ) )
12179 return ;
12280
123- var data = Globals . LocateNetMethod ( methodNode , snac . SemanticModel , Resolvers , Objects ) ;
124- NetworkMethodAnalysisError results = data . Item2 ;
125-
126- foreach ( NetworkMethodAnalysisError error in Enum . GetValues ( typeof ( NetworkMethodAnalysisError ) ) )
127- {
128- if ( error == NetworkMethodAnalysisError . None )
129- continue ;
130-
131- if ( results . HasFlag ( error ) )
132- {
81+ ( NetworkMethodModel ? model , List < AnalysisError > errors )
82+ = Globals . TryCreateNetMethod ( methodNode , snac . SemanticModel , Resolvers , snac . CancellationToken ) ;
13383
134- if ( error == NetworkMethodAnalysisError . MissingResolver )
135- {
136- ITypeSymbol typeSymbol = snac . SemanticModel . GetTypeInfo ( data . Item4 ) . Type ;
137-
138- if ( typeSymbol == null )
139- continue ;
140-
141- string fullTypeName = $ "{ typeSymbol . ContainingNamespace . ToDisplayString ( ) } .{ typeSymbol . Name } ";
142-
143- snac . ReportDiagnostic ( Diagnostic . Create ( Globals . DescNetMethodError ,
144- data . Item3 . GetLocation ( ) , [ data . Item4 . GetLocation ( ) ] , $ "{ methodNode . Identifier . Text } : Type { fullTypeName } does not have a registered Resolver!") ) ;
145-
146- continue ;
147- }
148-
149- string message = error switch
150- {
151- NetworkMethodAnalysisError . NotNetworkObjectClass => $ "{ methodNode . Identifier . Text } : Network method must be within a class decorated with the NetworkObject attribute!",
152- NetworkMethodAnalysisError . Inaccessible => $ "{ methodNode . Identifier . Text } : Network method must be public!",
153- _ => $ "{ ToString ( ) } ",
154- } ;
155-
156- snac . ReportDiagnostic ( Diagnostic . Create ( Globals . DescNetMethodError ,
157- methodNode . Identifier . GetLocation ( ) , message ) ) ;
158- }
159- }
84+ foreach ( AnalysisError error in errors )
85+ snac . ReportDiagnostic ( error . CreateDiagnostic ( ) ) ;
16086
16187 } , SyntaxKind . MethodDeclaration ) ;
16288 } ) ;
16389
164-
16590 }
16691
16792 public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics =>
0 commit comments