@@ -87,7 +87,7 @@ public static ExitCode Run(string[] args)
87
87
var pathTransformer = new PathTransformer ( canonicalPathCache ) ;
88
88
89
89
using var analyser = new NonStandaloneAnalyser ( new LogProgressMonitor ( logger ) , logger , options . AssemblySensitiveTrap , pathTransformer ) ;
90
- using var references = new BlockingCollection < MetadataReference > ( ) ;
90
+
91
91
try
92
92
{
93
93
var compilerVersion = new CompilerVersion ( options ) ;
@@ -120,80 +120,7 @@ public static ExitCode Run(string[] args)
120
120
return ExitCode . Ok ;
121
121
}
122
122
123
- var referenceTasks = ResolveReferences ( compilerArguments , analyser , canonicalPathCache , references ) ;
124
-
125
- var syntaxTrees = new List < SyntaxTree > ( ) ;
126
- var syntaxTreeTasks = ReadSyntaxTrees (
127
- compilerArguments . SourceFiles .
128
- Select ( src => canonicalPathCache . GetCanonicalPath ( src . Path ) ) ,
129
- analyser ,
130
- compilerArguments . ParseOptions ,
131
- compilerArguments . Encoding ,
132
- syntaxTrees ) ;
133
-
134
- var sw1 = new Stopwatch ( ) ;
135
- sw1 . Start ( ) ;
136
-
137
- Parallel . Invoke (
138
- new ParallelOptions { MaxDegreeOfParallelism = options . Threads } ,
139
- referenceTasks . Interleave ( syntaxTreeTasks ) . ToArray ( ) ) ;
140
-
141
- if ( syntaxTrees . Count == 0 )
142
- {
143
- logger . Log ( Severity . Error , " No source files" ) ;
144
- ++ analyser . CompilationErrors ;
145
- return ExitCode . Failed ;
146
- }
147
-
148
- // csc.exe (CSharpCompiler.cs) also provides CompilationOptions
149
- // .WithMetadataReferenceResolver(),
150
- // .WithXmlReferenceResolver() and
151
- // .WithSourceReferenceResolver().
152
- // These would be needed if we hadn't explicitly provided the source/references
153
- // already.
154
- var compilation = CSharpCompilation . Create (
155
- compilerArguments . CompilationName ,
156
- syntaxTrees ,
157
- references ,
158
- compilerArguments . CompilationOptions .
159
- WithAssemblyIdentityComparer ( DesktopAssemblyIdentityComparer . Default ) .
160
- WithStrongNameProvider ( new DesktopStrongNameProvider ( compilerArguments . KeyFileSearchPaths ) )
161
- ) ;
162
-
163
- analyser . EndInitialize ( compilerArguments , options , compilation ) ;
164
- analyser . AnalyseCompilation ( ) ;
165
- analyser . AnalyseReferences ( ) ;
166
-
167
- foreach ( var tree in compilation . SyntaxTrees )
168
- {
169
- analyser . AnalyseTree ( tree ) ;
170
- }
171
-
172
- var currentProcess = Process . GetCurrentProcess ( ) ;
173
- var cpuTime1 = currentProcess . TotalProcessorTime ;
174
- var userTime1 = currentProcess . UserProcessorTime ;
175
- sw1 . Stop ( ) ;
176
- logger . Log ( Severity . Info , " Models constructed in {0}" , sw1 . Elapsed ) ;
177
-
178
- var sw2 = new Stopwatch ( ) ;
179
- sw2 . Start ( ) ;
180
- analyser . PerformExtraction ( options . Threads ) ;
181
- sw2 . Stop ( ) ;
182
- var cpuTime2 = currentProcess . TotalProcessorTime ;
183
- var userTime2 = currentProcess . UserProcessorTime ;
184
-
185
- var performance = new Entities . PerformanceMetrics ( )
186
- {
187
- Frontend = new Entities . Timings ( ) { Elapsed = sw1 . Elapsed , Cpu = cpuTime1 , User = userTime1 } ,
188
- Extractor = new Entities . Timings ( ) { Elapsed = sw2 . Elapsed , Cpu = cpuTime2 - cpuTime1 , User = userTime2 - userTime1 } ,
189
- Total = new Entities . Timings ( ) { Elapsed = stopwatch . Elapsed , Cpu = cpuTime2 , User = userTime2 } ,
190
- PeakWorkingSet = currentProcess . PeakWorkingSet64
191
- } ;
192
-
193
- analyser . LogPerformance ( performance ) ;
194
- logger . Log ( Severity . Info , " Extraction took {0}" , sw2 . Elapsed ) ;
195
-
196
- return analyser . TotalErrors == 0 ? ExitCode . Ok : ExitCode . Errors ;
123
+ return AnalyseNonStandalone ( analyser , compilerArguments , options , canonicalPathCache , stopwatch ) ;
197
124
}
198
125
catch ( Exception ex ) // lgtm[cs/catch-of-all-exceptions]
199
126
{
@@ -321,73 +248,175 @@ public static void ExtractStandalone(
321
248
ILogger logger ,
322
249
CommonOptions options )
323
250
{
251
+ var stopwatch = new Stopwatch ( ) ;
252
+ stopwatch . Start ( ) ;
253
+
324
254
var canonicalPathCache = CanonicalPathCache . Create ( logger , 1000 ) ;
325
255
var pathTransformer = new PathTransformer ( canonicalPathCache ) ;
326
256
327
257
using var analyser = new StandaloneAnalyser ( pm , logger , false , pathTransformer ) ;
328
- using var references = new BlockingCollection < MetadataReference > ( ) ;
329
258
try
330
259
{
331
- var referenceTasks = referencePaths . Select < string , Action > ( path => ( ) =>
332
- {
333
- var reference = MetadataReference . CreateFromFile ( path ) ;
334
- references . Add ( reference ) ;
335
- } ) ;
260
+ AnalyseStandalone ( analyser , sources , referencePaths , options , pm , stopwatch ) ;
261
+ }
262
+ catch ( Exception ex ) // lgtm[cs/catch-of-all-exceptions]
263
+ {
264
+ analyser . Logger . Log ( Severity . Error , " Unhandled exception: {0}" , ex ) ;
265
+ }
266
+ }
336
267
337
- var syntaxTrees = new List < SyntaxTree > ( ) ;
338
- var syntaxTreeTasks = ReadSyntaxTrees ( sources , analyser , null , null , syntaxTrees ) ;
268
+ private static ExitCode Analyse ( Stopwatch stopwatch , Analyser analyser , CommonOptions options ,
269
+ Func < BlockingCollection < MetadataReference > , IEnumerable < Action > > getResolvedReferenceTasks ,
270
+ Func < Analyser , List < SyntaxTree > , IEnumerable < Action > > getSyntaxTreeTasks ,
271
+ Func < IEnumerable < SyntaxTree > , IEnumerable < MetadataReference > , CSharpCompilation > getCompilation ,
272
+ Action < CSharpCompilation , CommonOptions > initializeAnalyser ,
273
+ Action analyseCompilation ,
274
+ Action < Entities . PerformanceMetrics > logPerformance ,
275
+ Action postProcess )
276
+ {
277
+ using var references = new BlockingCollection < MetadataReference > ( ) ;
278
+ var referenceTasks = getResolvedReferenceTasks ( references ) ;
339
279
340
- var sw = new Stopwatch ( ) ;
341
- sw . Start ( ) ;
280
+ var syntaxTrees = new List < SyntaxTree > ( ) ;
281
+ var syntaxTreeTasks = getSyntaxTreeTasks ( analyser , syntaxTrees ) ;
342
282
343
- Parallel . Invoke (
344
- new ParallelOptions { MaxDegreeOfParallelism = options . Threads } ,
345
- referenceTasks . Interleave ( syntaxTreeTasks ) . ToArray ( ) ) ;
283
+ var sw = new Stopwatch ( ) ;
284
+ sw . Start ( ) ;
346
285
347
- if ( syntaxTrees . Count == 0 )
286
+ Parallel . Invoke (
287
+ new ParallelOptions { MaxDegreeOfParallelism = options . Threads } ,
288
+ referenceTasks . Interleave ( syntaxTreeTasks ) . ToArray ( ) ) ;
289
+
290
+ if ( syntaxTrees . Count == 0 )
291
+ {
292
+ analyser . Logger . Log ( Severity . Error , " No source files" ) ;
293
+ ++ analyser . CompilationErrors ;
294
+ if ( analyser is NonStandaloneAnalyser )
348
295
{
349
- analyser . Logger . Log ( Severity . Error , " No source files" ) ;
350
- ++ analyser . CompilationErrors ;
296
+ return ExitCode . Failed ;
351
297
}
298
+ }
352
299
353
- var compilation = CSharpCompilation . Create (
354
- "csharp.dll" ,
355
- syntaxTrees ,
356
- references
357
- ) ;
300
+ var compilation = getCompilation ( syntaxTrees , references ) ;
358
301
359
- analyser . InitializeStandalone ( compilation , options ) ;
360
- analyser . AnalyseReferences ( ) ;
302
+ initializeAnalyser ( compilation , options ) ;
303
+ analyseCompilation ( ) ;
304
+ analyser . AnalyseReferences ( ) ;
361
305
362
- foreach ( var tree in compilation . SyntaxTrees )
363
- {
364
- analyser . AnalyseTree ( tree ) ;
365
- }
306
+ foreach ( var tree in compilation . SyntaxTrees )
307
+ {
308
+ analyser . AnalyseTree ( tree ) ;
309
+ }
366
310
367
- sw . Stop ( ) ;
368
- analyser . Logger . Log ( Severity . Info , " Models constructed in {0}" , sw . Elapsed ) ;
311
+ sw . Stop ( ) ;
312
+ analyser . Logger . Log ( Severity . Info , " Models constructed in {0}" , sw . Elapsed ) ;
313
+ var elapsed = sw . Elapsed ;
369
314
370
- sw . Restart ( ) ;
371
- analyser . PerformExtraction ( options . Threads ) ;
372
- sw . Stop ( ) ;
373
- analyser . Logger . Log ( Severity . Info , " Extraction took {0}" , sw . Elapsed ) ;
315
+ var currentProcess = Process . GetCurrentProcess ( ) ;
316
+ var cpuTime1 = currentProcess . TotalProcessorTime ;
317
+ var userTime1 = currentProcess . UserProcessorTime ;
374
318
375
- foreach ( var type in analyser . MissingNamespaces )
319
+ sw . Restart ( ) ;
320
+ analyser . PerformExtraction ( options . Threads ) ;
321
+ sw . Stop ( ) ;
322
+ var cpuTime2 = currentProcess . TotalProcessorTime ;
323
+ var userTime2 = currentProcess . UserProcessorTime ;
324
+
325
+ var performance = new Entities . PerformanceMetrics ( )
326
+ {
327
+ Frontend = new Entities . Timings ( ) { Elapsed = elapsed , Cpu = cpuTime1 , User = userTime1 } ,
328
+ Extractor = new Entities . Timings ( ) { Elapsed = sw . Elapsed , Cpu = cpuTime2 - cpuTime1 , User = userTime2 - userTime1 } ,
329
+ Total = new Entities . Timings ( ) { Elapsed = stopwatch . Elapsed , Cpu = cpuTime2 , User = userTime2 } ,
330
+ PeakWorkingSet = currentProcess . PeakWorkingSet64
331
+ } ;
332
+
333
+ logPerformance ( performance ) ;
334
+ analyser . Logger . Log ( Severity . Info , " Extraction took {0}" , sw . Elapsed ) ;
335
+
336
+ postProcess ( ) ;
337
+
338
+ return analyser . TotalErrors == 0 ? ExitCode . Ok : ExitCode . Errors ;
339
+ }
340
+
341
+ private static void AnalyseStandalone (
342
+ StandaloneAnalyser analyser ,
343
+ IEnumerable < string > sources ,
344
+ IEnumerable < string > referencePaths ,
345
+ CommonOptions options ,
346
+ IProgressMonitor progressMonitor ,
347
+ Stopwatch stopwatch )
348
+ {
349
+ Analyse ( stopwatch , analyser , options ,
350
+ references => GetResolvedReferencesStandalone ( referencePaths , references ) ,
351
+ ( analyser , syntaxTrees ) => ReadSyntaxTrees ( sources , analyser , null , null , syntaxTrees ) ,
352
+ ( syntaxTrees , references ) => CSharpCompilation . Create ( "csharp.dll" , syntaxTrees , references ) ,
353
+ ( compilation , options ) => analyser . InitializeStandalone ( compilation , options ) ,
354
+ ( ) => { } ,
355
+ _ => { } ,
356
+ ( ) =>
376
357
{
377
- pm . MissingNamespace ( type ) ;
378
- }
358
+ foreach ( var type in analyser . MissingNamespaces )
359
+ {
360
+ progressMonitor . MissingNamespace ( type ) ;
361
+ }
362
+
363
+ foreach ( var type in analyser . MissingTypes )
364
+ {
365
+ progressMonitor . MissingType ( type ) ;
366
+ }
379
367
380
- foreach ( var type in analyser . MissingTypes )
368
+ progressMonitor . MissingSummary ( analyser . MissingTypes . Count ( ) , analyser . MissingNamespaces . Count ( ) ) ;
369
+ } ) ;
370
+ }
371
+
372
+ private static ExitCode AnalyseNonStandalone (
373
+ NonStandaloneAnalyser analyser ,
374
+ CSharpCommandLineArguments compilerArguments ,
375
+ Options options ,
376
+ CanonicalPathCache canonicalPathCache ,
377
+ Stopwatch stopwatch )
378
+ {
379
+ return Analyse ( stopwatch , analyser , options ,
380
+ references => ResolveReferences ( compilerArguments , analyser , canonicalPathCache , references ) ,
381
+ ( analyser , syntaxTrees ) =>
381
382
{
382
- pm . MissingType ( type ) ;
383
- }
383
+ return ReadSyntaxTrees (
384
+ compilerArguments . SourceFiles . Select ( src => canonicalPathCache . GetCanonicalPath ( src . Path ) ) ,
385
+ analyser ,
386
+ compilerArguments . ParseOptions ,
387
+ compilerArguments . Encoding ,
388
+ syntaxTrees ) ;
389
+ } ,
390
+ ( syntaxTrees , references ) =>
391
+ {
392
+ // csc.exe (CSharpCompiler.cs) also provides CompilationOptions
393
+ // .WithMetadataReferenceResolver(),
394
+ // .WithXmlReferenceResolver() and
395
+ // .WithSourceReferenceResolver().
396
+ // These would be needed if we hadn't explicitly provided the source/references
397
+ // already.
398
+ return CSharpCompilation . Create (
399
+ compilerArguments . CompilationName ,
400
+ syntaxTrees ,
401
+ references ,
402
+ compilerArguments . CompilationOptions .
403
+ WithAssemblyIdentityComparer ( DesktopAssemblyIdentityComparer . Default ) .
404
+ WithStrongNameProvider ( new DesktopStrongNameProvider ( compilerArguments . KeyFileSearchPaths ) )
405
+ ) ;
406
+ } ,
407
+ ( compilation , options ) => analyser . EndInitialize ( compilerArguments , options , compilation ) ,
408
+ ( ) => analyser . AnalyseCompilation ( ) ,
409
+ performance => analyser . LogPerformance ( performance ) ,
410
+ ( ) => { } ) ;
411
+ }
384
412
385
- pm . MissingSummary ( analyser . MissingTypes . Count ( ) , analyser . MissingNamespaces . Count ( ) ) ;
386
- }
387
- catch ( Exception ex ) // lgtm[cs/catch-of-all-exceptions]
413
+ private static IEnumerable < Action > GetResolvedReferencesStandalone ( IEnumerable < string > referencePaths , BlockingCollection < MetadataReference > references )
414
+ {
415
+ return referencePaths . Select < string , Action > ( path => ( ) =>
388
416
{
389
- analyser . Logger . Log ( Severity . Error , " Unhandled exception: {0}" , ex ) ;
390
- }
417
+ var reference = MetadataReference . CreateFromFile ( path ) ;
418
+ references . Add ( reference ) ;
419
+ } ) ;
391
420
}
392
421
393
422
/// <summary>
0 commit comments