1414using Microsoft . CodeAnalysis ;
1515using Microsoft . CodeAnalysis . CSharp ;
1616using Microsoft . CodeAnalysis . CSharp . Syntax ;
17+ using Microsoft . CodeAnalysis . Diagnostics ;
1718using Neo . Json ;
19+ using Neo . SmartContract . Analyzer ;
1820using System ;
1921using System . Collections . Concurrent ;
2022using System . Collections . Generic ;
23+ using System . Collections . Immutable ;
2124using System . ComponentModel ;
2225using System . Diagnostics ;
2326using System . IO ;
@@ -34,8 +37,10 @@ public class CompilationEngine(CompilationOptions options)
3437 {
3538 internal Compilation ? Compilation ;
3639 internal MetadataReference ? FrameworkReference ;
40+ internal ImmutableArray < Diagnostic > AnalyzerDiagnostics { get ; private set ; } = [ ] ;
3741 internal CompilationOptions Options { get ; private set ; } = options ;
3842 private static readonly MetadataReference [ ] CommonReferences ;
43+ private static readonly ImmutableArray < DiagnosticAnalyzer > NeoAnalyzers = NeoAnalyzerSuite . Create ( ) ;
3944 private static readonly Guid FrameworkModuleVersionId = typeof ( scfx ::Neo . SmartContract . Framework . Attributes . SafeAttribute ) . Assembly . ManifestModule . ModuleVersionId ;
4045 private const string FrameworkAssemblyName = "Neo.SmartContract.Framework" ;
4146 private static readonly StringComparison ProjectPathComparison = OperatingSystem . IsWindows ( ) ? StringComparison . OrdinalIgnoreCase : StringComparison . Ordinal ;
@@ -154,6 +159,7 @@ internal List<CompilationContext> Compile(IEnumerable<string> sourceFiles, IEnum
154159
155160 FrameworkReference = frameworkReference ?? referenceArray . FirstOrDefault ( IsTrustedFrameworkReference ) ;
156161 Compilation = CSharpCompilation . Create ( null , syntaxTrees , referenceArray , compilationOptions ) ;
162+ AnalyzeCompilation ( ) ;
157163 return CompileProjectContracts ( Compilation ) ;
158164 }
159165
@@ -224,6 +230,7 @@ private Compilation LoadProjectCompilation(string csproj, bool forceReload)
224230 ResetProjectState ( ) ;
225231 Compilation = GetCompilation ( projectPath ) ;
226232 FrameworkReference = ResolveProjectFrameworkReference ( Compilation ) ;
233+ AnalyzeCompilation ( ) ;
227234 ProjectPath = projectPath ;
228235 return Compilation ;
229236 }
@@ -232,6 +239,7 @@ private void ResetProjectState()
232239 {
233240 Compilation = null ;
234241 FrameworkReference = null ;
242+ AnalyzerDiagnostics = [ ] ;
235243 MetaReferences . Clear ( ) ;
236244 PreparedProjectPath = null ;
237245 ProjectPath = null ;
@@ -272,6 +280,27 @@ internal static bool IsTrustedFrameworkReference(MetadataReference reference)
272280 }
273281 }
274282
283+ private void AnalyzeCompilation ( )
284+ {
285+ if ( ! Options . RunAnalyzers )
286+ {
287+ AnalyzerDiagnostics = [ ] ;
288+ return ;
289+ }
290+
291+ AnalyzerDiagnostics = Compilation !
292+ . WithAnalyzers ( NeoAnalyzers )
293+ . GetAnalyzerDiagnosticsAsync ( )
294+ . GetAwaiter ( )
295+ . GetResult ( )
296+ . Where ( diagnostic => diagnostic . Severity != DiagnosticSeverity . Hidden )
297+ . OrderBy ( diagnostic => diagnostic . Location . SourceTree ? . FilePath ?? string . Empty , StringComparer . Ordinal )
298+ . ThenBy ( diagnostic => diagnostic . Location . IsInSource ? diagnostic . Location . SourceSpan . Start : - 1 )
299+ . ThenBy ( diagnostic => diagnostic . Id , StringComparer . Ordinal )
300+ . ThenBy ( diagnostic => diagnostic . GetMessage ( ) , StringComparer . Ordinal )
301+ . ToImmutableArray ( ) ;
302+ }
303+
275304 public List < CompilationContext > CompileProject ( string csproj , List < INamedTypeSymbol > sortedClasses , Dictionary < INamedTypeSymbol , List < INamedTypeSymbol > > classDependencies , List < INamedTypeSymbol ? > allClassSymbols , string ? targetContractName = null )
276305 {
277306 if ( sortedClasses == null || classDependencies == null || allClassSymbols == null )
0 commit comments