@@ -10,6 +10,7 @@ namespace StyleCopTester
1010 using System . Diagnostics ;
1111 using System . Linq ;
1212 using System . Reflection ;
13+ using System . Text ;
1314 using System . Threading ;
1415 using System . Threading . Tasks ;
1516 using System . Windows . Threading ;
@@ -18,6 +19,8 @@ namespace StyleCopTester
1819 using Microsoft . CodeAnalysis . CodeFixes ;
1920 using Microsoft . CodeAnalysis . Diagnostics ;
2021 using Microsoft . CodeAnalysis . MSBuild ;
22+ using File = System . IO . File ;
23+ using Path = System . IO . Path ;
2124
2225 /// <summary>
2326 /// StyleCopTester is a tool that will analyze a solution, find diagnostics in it and will print out the number of
@@ -116,6 +119,13 @@ private static async Task MainAsync(string[] args, CancellationToken cancellatio
116119 }
117120 }
118121
122+ string logArgument = args . FirstOrDefault ( x => x . StartsWith ( "/log:" ) ) ;
123+ if ( logArgument != null )
124+ {
125+ string fileName = logArgument . Substring ( logArgument . IndexOf ( ':' ) + 1 ) ;
126+ WriteDiagnosticResults ( diagnostics . SelectMany ( i => i . Value . Select ( j => Tuple . Create ( i . Key , j ) ) ) . ToImmutableArray ( ) , fileName ) ;
127+ }
128+
119129 if ( args . Contains ( "/codefixes" ) )
120130 {
121131 await TestCodeFixesAsync ( stopwatch , solution , allDiagnostics , cancellationToken ) . ConfigureAwait ( true ) ;
@@ -128,6 +138,38 @@ private static async Task MainAsync(string[] args, CancellationToken cancellatio
128138 }
129139 }
130140
141+ private static void WriteDiagnosticResults ( ImmutableArray < Tuple < ProjectId , Diagnostic > > diagnostics , string fileName )
142+ {
143+ var orderedDiagnostics =
144+ diagnostics
145+ . OrderBy ( i => i . Item2 . Id )
146+ . ThenBy ( i => i . Item2 . Location . SourceTree ? . FilePath , StringComparer . OrdinalIgnoreCase )
147+ . ThenBy ( i => i . Item2 . Location . SourceSpan . Start )
148+ . ThenBy ( i => i . Item2 . Location . SourceSpan . End ) ;
149+
150+ var uniqueLines = new HashSet < string > ( ) ;
151+ StringBuilder completeOutput = new StringBuilder ( ) ;
152+ StringBuilder uniqueOutput = new StringBuilder ( ) ;
153+ foreach ( var diagnostic in orderedDiagnostics )
154+ {
155+ string message = diagnostic . Item2 . ToString ( ) ;
156+ string uniqueMessage = $ "{ diagnostic . Item1 } : { diagnostic . Item2 } ";
157+ completeOutput . AppendLine ( message ) ;
158+ if ( uniqueLines . Add ( uniqueMessage ) )
159+ {
160+ uniqueOutput . AppendLine ( message ) ;
161+ }
162+ }
163+
164+ string directoryName = Path . GetDirectoryName ( fileName ) ;
165+ string fileNameWithoutExtension = Path . GetFileNameWithoutExtension ( fileName ) ;
166+ string extension = Path . GetExtension ( fileName ) ;
167+ string uniqueFileName = Path . Combine ( directoryName , $ "{ fileNameWithoutExtension } -Unique{ extension } ") ;
168+
169+ File . WriteAllText ( fileName , completeOutput . ToString ( ) , Encoding . UTF8 ) ;
170+ File . WriteAllText ( uniqueFileName , uniqueOutput . ToString ( ) , Encoding . UTF8 ) ;
171+ }
172+
131173 private static async Task TestFixAllAsync ( Stopwatch stopwatch , Solution solution , ImmutableDictionary < ProjectId , ImmutableArray < Diagnostic > > diagnostics , CancellationToken cancellationToken )
132174 {
133175 Console . WriteLine ( "Calculating fixes" ) ;
0 commit comments