99using System . Web ;
1010using Microsoft . Build . Framework ;
1111using Microsoft . Build . Utilities ;
12+ using System . Text . Json ;
13+
1214
1315/// <summary>
1416/// An MsBuild logger that emit compile_commands.json and link_commands.json files from a C++ project build.
1820/// </remarks>
1921public class CompileDatabase : Logger
2022{
23+ private class CompileCommand
24+ {
25+ public String command { get ; set ; }
26+ public String directory { get ; set ; }
27+ public String file { get ; set ; }
28+ }
29+
30+ private class LinkCommand
31+ {
32+ public String command { get ; set ; }
33+ public String directory { get ; set ; }
34+ public List < String > files { get ; set ; }
35+ }
36+
2137 public override void Initialize ( IEventSource eventSource )
2238 {
2339 string compileOutputFilePath = "compile_commands.json" ;
@@ -28,11 +44,10 @@ public override void Initialize(IEventSource eventSource)
2844 const bool append = false ;
2945 Encoding utf8WithoutBom = new UTF8Encoding ( false ) ;
3046 this . CompileStreamWriter = new StreamWriter ( compileOutputFilePath , append , utf8WithoutBom ) ;
31- this . firstLine = true ;
32- CompileStreamWriter . WriteLine ( "[" ) ;
33-
3447 this . LinkStreamWriter = new StreamWriter ( linkOutputFilePath , append , utf8WithoutBom ) ;
35- LinkStreamWriter . WriteLine ( "[" ) ;
48+
49+ compileCommands = new List < CompileCommand > ( ) ;
50+ linkCommands = new List < LinkCommand > ( ) ;
3651 }
3752 catch ( Exception ex )
3853 {
@@ -246,9 +261,9 @@ private void ProcessCompileCommand(string compilerPath, string[] cmdArgs, String
246261 }
247262
248263 // simplify the compile command to avoid .. etc.
249- string compileCommand = '"' + Path . GetFullPath ( compilerPath ) + " \ " " + String . Join ( " " , cmdArgs ) ;
264+ string compileCommand = Path . GetFullPath ( compilerPath ) + " " + String . Join ( " " , cmdArgs ) ;
250265
251- WriteCompileCommand ( compileCommand , filenames , dirname ) ;
266+ addCompileCommand ( compileCommand , filenames , dirname ) ;
252267 }
253268
254269 private void ProcessLinkCommand ( string compilerPath , string [ ] cmdArgs , String dirname )
@@ -300,88 +315,58 @@ private void ProcessLinkCommand(string compilerPath, string[] cmdArgs, String di
300315 }
301316
302317 // simplify the compile command to avoid .. etc.
303- string compileCommand = '"' + Path . GetFullPath ( compilerPath ) + " \ " " + String . Join ( " " , cmdArgs ) ;
318+ string linkCommand = Path . GetFullPath ( compilerPath ) + " " + String . Join ( " " , cmdArgs ) ;
304319
305- WriteLinkCommand ( compileCommand , filenames , dirname ) ;
320+ addLinkCommand ( linkCommand , filenames , dirname ) ;
306321 }
307322
308- private void WriteCompileCommand ( string compileCommand , List < string > files , string dirname )
323+ private void addCompileCommand ( string compileCommand , List < string > files , string dirname )
309324 {
310325 foreach ( string filename in files )
311326 {
312- // Terminate the preceding entry
313- if ( firstLine )
327+ CompileCommand commandVal = new CompileCommand
314328 {
315- firstLine = false ;
316- }
317- else
318- {
319- CompileStreamWriter . WriteLine ( "," ) ;
320- }
329+ command = compileCommand ,
330+ directory = dirname ,
331+ file = filename
332+ } ;
321333
322- // Write one entry
323- CompileStreamWriter . WriteLine ( " {" ) ;
324- CompileStreamWriter . WriteLine ( String . Format (
325- " \" command\" : \" {0}\" ," ,
326- HttpUtility . JavaScriptStringEncode ( compileCommand ) ) ) ;
327- CompileStreamWriter . WriteLine ( String . Format (
328- " \" file\" : \" {0}\" ," ,
329- HttpUtility . JavaScriptStringEncode ( filename ) ) ) ;
330- CompileStreamWriter . WriteLine ( String . Format (
331- " \" directory\" : \" {0}\" " ,
332- HttpUtility . JavaScriptStringEncode ( dirname ) ) ) ;
333- CompileStreamWriter . Write ( " }" ) ;
334+ compileCommands . Add ( commandVal ) ;
334335 }
335336 }
336337
337- private void WriteLinkCommand ( string linkCommand , List < string > files , string dirname )
338+ private void addLinkCommand ( string linkCommand , List < string > files , string dirname )
338339 {
339- LinkStreamWriter . WriteLine ( " {" ) ;
340- LinkStreamWriter . WriteLine ( String . Format (
341- " \" directory\" : \" {0}\" ," ,
342- HttpUtility . JavaScriptStringEncode ( dirname ) ) ) ;
343- LinkStreamWriter . WriteLine ( String . Format (
344- " \" command\" : \" {0}\" ," ,
345- HttpUtility . JavaScriptStringEncode ( linkCommand ) ) ) ;
346- LinkStreamWriter . WriteLine ( " \" files\" : [" ) ;
347- bool fl = true ;
348- foreach ( string filename in files )
340+ LinkCommand commandVal = new LinkCommand ( )
349341 {
350- if ( fl )
351- {
352- fl = false ;
353- }
354- else
355- {
356- LinkStreamWriter . WriteLine ( "," ) ;
357- }
358-
359- LinkStreamWriter . Write ( String . Format ( " \" {0}\" " ,
360- HttpUtility . JavaScriptStringEncode ( filename ) ) ) ;
361- }
342+ command = linkCommand ,
343+ directory = dirname ,
344+ files = files
345+ } ;
362346
363- LinkStreamWriter . WriteLine ( ) ;
364- LinkStreamWriter . WriteLine ( " ]" ) ;
365- LinkStreamWriter . WriteLine ( " }" ) ;
347+ linkCommands . Add ( commandVal ) ;
366348 }
367349
368350 public override void Shutdown ( )
369351 {
370- if ( ! firstLine )
352+ JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions
371353 {
372- CompileStreamWriter . WriteLine ( ) ;
373- }
374-
375- CompileStreamWriter . WriteLine ( "]" ) ;
354+ WriteIndented = true ,
355+ Encoder = System . Text . Encodings . Web . JavaScriptEncoder . UnsafeRelaxedJsonEscaping
356+ } ;
357+ CompileStreamWriter . WriteLine ( JsonSerializer . Serialize ( compileCommands , jsonSerializerOptions ) ) ;
376358 CompileStreamWriter . Close ( ) ;
377359
378- LinkStreamWriter . WriteLine ( "]" ) ;
360+
361+ LinkStreamWriter . WriteLine ( JsonSerializer . Serialize ( linkCommands , jsonSerializerOptions ) ) ;
379362 LinkStreamWriter . Close ( ) ;
380363
381364 base . Shutdown ( ) ;
382365 }
383366
367+
368+ private List < CompileCommand > compileCommands ;
369+ private List < LinkCommand > linkCommands ;
384370 private StreamWriter CompileStreamWriter ;
385371 private StreamWriter LinkStreamWriter ;
386- private bool firstLine ;
387372}
0 commit comments