C#: Extract compilation DB entity in standalone mode

This commit is contained in:
Tamas Vajk
2023-10-02 12:48:58 +02:00
parent 5dccc8d33e
commit de45a9b137
16 changed files with 120 additions and 101 deletions

View File

@@ -19,6 +19,8 @@ namespace Semmle.Extraction.CSharp
protected Extraction.Extractor? extractor;
protected CSharpCompilation? compilation;
protected CommonOptions? options;
private protected Entities.Compilation? compilationEntity;
private IDisposable? compilationTrapFile;
private readonly object progressMutex = new object();
@@ -226,8 +228,35 @@ namespace Semmle.Extraction.CSharp
}
}
private void DoAnalyseCompilation()
{
try
{
var assemblyPath = extractor.OutputPath;
var transformedAssemblyPath = PathTransformer.Transform(assemblyPath);
var assembly = compilation.Assembly;
var trapWriter = transformedAssemblyPath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false);
compilationTrapFile = trapWriter; // Dispose later
var cx = new Context(extractor, compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), addAssemblyTrapPrefix);
compilationEntity = Entities.Compilation.Create(cx);
}
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{
Logger.Log(Severity.Error, " Unhandled exception analyzing {0}: {1}", "compilation", ex);
}
}
#nullable restore warnings
/// <summary>
/// Extracts compilation-wide entities, such as compilations and compiler diagnostics.
/// </summary>
public void AnalyseCompilation()
{
extractionTasks.Add(() => DoAnalyseCompilation());
}
private static bool FileIsUpToDate(string src, string dest)
{
return File.Exists(dest) &&
@@ -275,6 +304,8 @@ namespace Semmle.Extraction.CSharp
Logger.Log(Severity.Info, "EXTRACTION SUCCEEDED in {0}", stopWatch.Elapsed);
Logger.Dispose();
compilationTrapFile?.Dispose();
}
/// <summary>

View File

@@ -302,7 +302,6 @@ namespace Semmle.Extraction.CSharp
Func<Analyser, List<SyntaxTree>, IEnumerable<Action>> getSyntaxTreeTasks,
Func<IEnumerable<SyntaxTree>, IEnumerable<MetadataReference>, CSharpCompilation> getCompilation,
Action<CSharpCompilation, CommonOptions> initializeAnalyser,
Action analyseCompilation,
Action<Entities.PerformanceMetrics> logPerformance,
Action postProcess)
{
@@ -332,7 +331,7 @@ namespace Semmle.Extraction.CSharp
var compilation = getCompilation(syntaxTrees, references);
initializeAnalyser(compilation, options);
analyseCompilation();
analyser.AnalyseCompilation();
analyser.AnalyseReferences();
foreach (var tree in compilation.SyntaxTrees)
@@ -416,7 +415,6 @@ namespace Semmle.Extraction.CSharp
);
},
(compilation, options) => analyser.EndInitialize(compilerArguments, options, compilation),
() => analyser.AnalyseCompilation(),
performance => analyser.LogPerformance(performance),
() => { });
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.CodeAnalysis.CSharp;
using Semmle.Util.Logging;
namespace Semmle.Extraction.CSharp
{
public class StandaloneAnalyser : Analyser
{
public StandaloneAnalyser(IProgressMonitor pm, ILogger logger, bool addAssemblyTrapPrefix, PathTransformer pathTransformer)
: base(pm, logger, addAssemblyTrapPrefix, pathTransformer)
{
}
public void Initialize(string outputPath, CSharpCompilation compilationIn, CommonOptions options)
{
compilation = compilationIn;
extractor = new StandaloneExtractor(outputPath, Logger, PathTransformer, options);
this.options = options;
LogExtractorInfo(Extraction.Extractor.Version);
SetReferencePaths();
Entities.Compilation.Settings = (Directory.GetCurrentDirectory(), Array.Empty<string>());
}
#nullable disable warnings
public IEnumerable<string> MissingTypes => extractor.MissingTypes;
public IEnumerable<string> MissingNamespaces => extractor.MissingNamespaces;
#nullable restore warnings
}
}

View File

@@ -9,11 +9,8 @@ using Semmle.Util.Logging;
namespace Semmle.Extraction.CSharp
{
public class TracingAnalyser : Analyser, IDisposable
public class TracingAnalyser : Analyser
{
private Entities.Compilation? compilationEntity;
private IDisposable? compilationTrapFile;
private bool init;
public TracingAnalyser(IProgressMonitor pm, ILogger logger, bool addAssemblyTrapPrefix, PathTransformer pathTransformer)
@@ -55,20 +52,6 @@ namespace Semmle.Extraction.CSharp
CompilationErrors += FilteredDiagnostics.Count();
}
public override void Dispose()
{
compilationTrapFile?.Dispose();
base.Dispose();
}
/// <summary>
/// Extracts compilation-wide entities, such as compilations and compiler diagnostics.
/// </summary>
public void AnalyseCompilation()
{
extractionTasks.Add(() => DoAnalyseCompilation());
}
/// <summary>
/// Logs information about the extractor, as well as the arguments to Roslyn.
/// </summary>
@@ -193,25 +176,6 @@ namespace Semmle.Extraction.CSharp
}
}
private void DoAnalyseCompilation()
{
try
{
var assemblyPath = ((TracingExtractor?)extractor).OutputPath;
var transformedAssemblyPath = PathTransformer.Transform(assemblyPath);
var assembly = compilation.Assembly;
var trapWriter = transformedAssemblyPath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false);
compilationTrapFile = trapWriter; // Dispose later
var cx = new Context(extractor, compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), addAssemblyTrapPrefix);
compilationEntity = Entities.Compilation.Create(cx);
}
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{
Logger.Log(Severity.Error, " Unhandled exception analyzing {0}: {1}", "compilation", ex);
}
}
public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p);
#nullable restore warnings