1- using Microsoft . Extensions . Logging ;
2- using Consyzer . Analyzers ;
3- using Consyzer . Core . Models ;
4- using Consyzer . Output . Logging ;
5- using Consyzer . Output . Reporting ;
6-
7- namespace Consyzer ;
8-
9- internal sealed class AnalysisOrchestrator (
10- ILogger < AnalysisOrchestrator > logger ,
11- IAnalysisLogBuilder analysisLogBuilder ,
12- IAnalyzer < IEnumerable < FileInfo > , AnalysisFileClassification > fileClassificationAnalyzer ,
13- IAnalyzer < IEnumerable < FileInfo > , IEnumerable < AssemblyMetadata > > metadataAnalyzer ,
14- IAnalyzer < IEnumerable < FileInfo > , IReadOnlyList < PInvokeMethodGroup > > pInvokeAnalyzer ,
15- IAnalyzer < IEnumerable < PInvokeMethodGroup > , IReadOnlyList < LibraryResolutionResult > > libraryResolutionAnalyzer ,
16- IAnalyzer < IEnumerable < LibraryResolutionResult > , AnalysisExitCode > exitCodeAnalyzer ,
17- IEnumerable < IReportWriter > reportWriters
18- )
19- {
20- public ExitStatus Run ( IReadOnlyList < FileInfo > files )
21- {
22- logger . LogInformation ( "Analysis started." ) ;
23-
24- if ( logger . IsEnabled ( LogLevel . Debug ) )
25- {
26- logger . LogDebug ( "{Message}" , analysisLogBuilder . BuildFoundFilesLog ( files ) ) ;
27- }
28-
29- var fileClassification = fileClassificationAnalyzer . Analyze ( files ) ;
30- if ( logger . IsEnabled ( LogLevel . Information ) )
31- {
32- logger . LogInformation ( "{Message}" , analysisLogBuilder . BuildFileClassificationLog ( fileClassification ) ) ;
33- }
34-
35- var ecmaAssemblies = fileClassification . EcmaAssemblies . ToList ( ) ;
36- if ( ecmaAssemblies . Count == 0 )
37- {
38- logger . LogWarning ( "No valid ECMA assemblies found." ) ;
39- return ExitStatus . InvalidInput ( InvalidInputReason . AllFilesInvalid ) ;
40- }
41-
42- logger . LogInformation ( "Analyzing assembly metadata..." ) ;
43- var metadataList = metadataAnalyzer . Analyze ( ecmaAssemblies ) . ToList ( ) ;
44-
45- logger . LogInformation ( "Analyzing P/Invoke methods..." ) ;
46- var pInvokeGroups = pInvokeAnalyzer . Analyze ( ecmaAssemblies ) . ToList ( ) ;
47-
48- if ( pInvokeGroups . Count == 0 )
49- {
50- logger . LogWarning ( "No P/Invoke methods found in the assemblies." ) ;
51- return ExitStatus . InvalidInput ( InvalidInputReason . NoPInvokeMethodsFound ) ;
52- }
53-
54- logger . LogInformation ( "Analyzing native library resolution..." ) ;
55- var libraryResolutions = libraryResolutionAnalyzer . Analyze ( pInvokeGroups ) . ToList ( ) ;
56-
57- var summary = new AnalysisSummary
58- {
59- TotalFiles = files . Count ,
60- EcmaAssemblies = metadataList . Count ,
61- AssembliesWithPInvoke = pInvokeGroups . Count ,
62- TotalPInvokeMethods = pInvokeGroups . Sum ( g => g . Methods . Count ) ,
63- ResolvedLibraries = libraryResolutions . Count ( r => r . State == ResolutionState . Resolved ) ,
64- MissingLibraries = libraryResolutions . Count ( r => r . State == ResolutionState . Missing ) ,
65- InconclusiveLibraries = libraryResolutions . Count ( r => r . State == ResolutionState . Inconclusive )
66- } ;
67-
68- var outcome = new AnalysisOutcome
69- {
70- AssemblyMetadataList = metadataList ,
71- PInvokeMethodGroups = pInvokeGroups ,
72- LibraryResolutions = libraryResolutions ,
73- Summary = summary
74- } ;
75-
76- foreach ( var writer in reportWriters )
77- {
78- if ( logger . IsEnabled ( LogLevel . Information ) )
79- {
80- logger . LogInformation ( "Generating report using {WriterType}..." , writer . GetType ( ) . Name ) ;
81- }
82-
83- var destination = writer . Write ( outcome ) ;
84- if ( logger . IsEnabled ( LogLevel . Information ) )
85- {
86- logger . LogInformation ( "Report written to {Destination}." , destination ) ;
87- }
88- }
89-
90- var exitCode = exitCodeAnalyzer . Analyze ( libraryResolutions ) ;
91-
92- var logLevel = GetExitCodeLogLevel ( exitCode ) ;
93- if ( logger . IsEnabled ( logLevel ) )
94- {
95- logger . Log (
96- logLevel ,
97- "Analysis completed with exit code {ExitCode}." ,
98- exitCode
99- ) ;
100- }
101-
102- return exitCode switch
103- {
104- AnalysisExitCode . Success => ExitStatus . Success ( ) ,
105- AnalysisExitCode . Missing => ExitStatus . Missing ( ) ,
106- AnalysisExitCode . Inconclusive => ExitStatus . Inconclusive ( ) ,
107- AnalysisExitCode . ToolError => ExitStatus . ToolError ( ) ,
108- _ => throw new InvalidOperationException ( $ "Unsupported analysis exit code '{ exitCode } '.")
109- } ;
110- }
111-
112- private static LogLevel GetExitCodeLogLevel ( AnalysisExitCode exitCode ) =>
113- exitCode switch
114- {
115- AnalysisExitCode . Success => LogLevel . Information ,
116- AnalysisExitCode . Missing => LogLevel . Warning ,
117- AnalysisExitCode . Inconclusive => LogLevel . Warning ,
118- AnalysisExitCode . InvalidInput => LogLevel . Warning ,
119- AnalysisExitCode . ToolError => LogLevel . Error ,
120- _ => LogLevel . Information
121- } ;
122- }
1+ using Microsoft . Extensions . Logging ;
2+ using Consyzer . Analyzers ;
3+ using Consyzer . Core . Models ;
4+ using Consyzer . Output . Logging ;
5+ using Consyzer . Output . Reporting ;
6+
7+ namespace Consyzer ;
8+
9+ internal sealed class AnalysisOrchestrator (
10+ ILogger < AnalysisOrchestrator > logger ,
11+ IAnalysisLogBuilder analysisLogBuilder ,
12+ IAnalyzer < IEnumerable < FileInfo > , AnalysisFileClassification > fileClassificationAnalyzer ,
13+ IAnalyzer < IEnumerable < FileInfo > , IEnumerable < AssemblyMetadata > > metadataAnalyzer ,
14+ IAnalyzer < IEnumerable < FileInfo > , IReadOnlyList < PInvokeMethodGroup > > pInvokeAnalyzer ,
15+ IAnalyzer < IEnumerable < PInvokeMethodGroup > , IReadOnlyList < LibraryResolutionResult > > libraryResolutionAnalyzer ,
16+ IAnalyzer < IEnumerable < LibraryResolutionResult > , AnalysisExitCode > exitCodeAnalyzer ,
17+ IEnumerable < IReportWriter > reportWriters
18+ )
19+ {
20+ public ExitStatus Run ( IReadOnlyList < FileInfo > files )
21+ {
22+ logger . LogInformation ( "Analysis started." ) ;
23+
24+ if ( logger . IsEnabled ( LogLevel . Debug ) )
25+ {
26+ logger . LogDebug ( "{Message}" , analysisLogBuilder . BuildFoundFilesLog ( files ) ) ;
27+ }
28+
29+ var fileClassification = fileClassificationAnalyzer . Analyze ( files ) ;
30+ if ( logger . IsEnabled ( LogLevel . Information ) )
31+ {
32+ logger . LogInformation ( "{Message}" , analysisLogBuilder . BuildFileClassificationLog ( fileClassification ) ) ;
33+ }
34+
35+ var ecmaAssemblies = fileClassification . EcmaAssemblies . ToList ( ) ;
36+ if ( ecmaAssemblies . Count == 0 )
37+ {
38+ logger . LogWarning ( "No valid ECMA assemblies found." ) ;
39+ return ExitStatus . InvalidInput ( InvalidInputReason . AllFilesInvalid ) ;
40+ }
41+
42+ logger . LogInformation ( "Analyzing assembly metadata..." ) ;
43+ var metadataList = metadataAnalyzer . Analyze ( ecmaAssemblies ) . ToList ( ) ;
44+
45+ logger . LogInformation ( "Analyzing P/Invoke methods..." ) ;
46+ var pInvokeGroups = pInvokeAnalyzer . Analyze ( ecmaAssemblies ) . ToList ( ) ;
47+
48+ if ( pInvokeGroups . Count == 0 )
49+ {
50+ logger . LogInformation ( "No P/Invoke methods found in the assemblies." ) ;
51+ }
52+
53+ logger . LogInformation ( "Analyzing native library resolution..." ) ;
54+ var libraryResolutions = libraryResolutionAnalyzer . Analyze ( pInvokeGroups ) . ToList ( ) ;
55+
56+ var summary = new AnalysisSummary
57+ {
58+ TotalFiles = files . Count ,
59+ EcmaAssemblies = metadataList . Count ,
60+ AssembliesWithPInvoke = pInvokeGroups . Count ,
61+ TotalPInvokeMethods = pInvokeGroups . Sum ( g => g . Methods . Count ) ,
62+ ResolvedLibraries = libraryResolutions . Count ( r => r . ResolutionState == ResolutionState . Resolved ) ,
63+ MissingLibraries = libraryResolutions . Count ( r => r . ResolutionState == ResolutionState . Missing ) ,
64+ InconclusiveLibraries = libraryResolutions . Count ( r => r . ResolutionState == ResolutionState . Inconclusive )
65+ } ;
66+
67+ var outcome = new AnalysisOutcome
68+ {
69+ AssemblyMetadataList = metadataList ,
70+ PInvokeMethodGroups = pInvokeGroups ,
71+ LibraryResolutions = libraryResolutions ,
72+ Summary = summary
73+ } ;
74+
75+ foreach ( var writer in reportWriters )
76+ {
77+ if ( logger . IsEnabled ( LogLevel . Information ) )
78+ {
79+ logger . LogInformation ( "Generating report using {WriterType}..." , writer . GetType ( ) . Name ) ;
80+ }
81+
82+ var destination = writer . Write ( outcome ) ;
83+ if ( logger . IsEnabled ( LogLevel . Information ) )
84+ {
85+ logger . LogInformation ( "Report written to {Destination}." , destination ) ;
86+ }
87+ }
88+
89+ var exitCode = exitCodeAnalyzer . Analyze ( libraryResolutions ) ;
90+
91+ var logLevel = GetExitCodeLogLevel ( exitCode ) ;
92+ if ( logger . IsEnabled ( logLevel ) )
93+ {
94+ logger . Log (
95+ logLevel ,
96+ "Analysis completed with exit code {ExitCode}." ,
97+ exitCode
98+ ) ;
99+ }
100+
101+ return exitCode switch
102+ {
103+ AnalysisExitCode . Success => ExitStatus . Success ( ) ,
104+ AnalysisExitCode . Missing => ExitStatus . Missing ( ) ,
105+ AnalysisExitCode . Inconclusive => ExitStatus . Inconclusive ( ) ,
106+ AnalysisExitCode . ToolError => ExitStatus . ToolError ( ) ,
107+ _ => throw new InvalidOperationException ( $ "Unsupported analysis exit code '{ exitCode } '.")
108+ } ;
109+ }
110+
111+ private static LogLevel GetExitCodeLogLevel ( AnalysisExitCode exitCode ) =>
112+ exitCode switch
113+ {
114+ AnalysisExitCode . Success => LogLevel . Information ,
115+ AnalysisExitCode . Missing => LogLevel . Warning ,
116+ AnalysisExitCode . Inconclusive => LogLevel . Warning ,
117+ AnalysisExitCode . InvalidInput => LogLevel . Warning ,
118+ AnalysisExitCode . ToolError => LogLevel . Error ,
119+ _ => LogLevel . Information
120+ } ;
121+ }
0 commit comments