C#: Refactor static compilation state

This commit is contained in:
Tamas Vajk
2024-05-23 08:09:58 +02:00
parent 855fe12c6c
commit c58971e632
7 changed files with 33 additions and 33 deletions

View File

@@ -11,41 +11,33 @@ namespace Semmle.Extraction.CSharp.Entities
{ {
internal readonly ConcurrentDictionary<string, int> messageCounts = new(); internal readonly ConcurrentDictionary<string, int> messageCounts = new();
private static (string Cwd, string[] Args) settings; private readonly (string Cwd, string[] Args) settings;
private static int hashCode; private readonly int hashCode;
public static (string Cwd, string[] Args) Settings #nullable disable warnings
private Compilation(Context cx) : base(cx, null)
{ {
get { return settings; } settings = (cx.Extractor.Cwd, cx.Extractor.Args);
set
{
settings = value;
hashCode = settings.Cwd.GetHashCode(); hashCode = settings.Cwd.GetHashCode();
for (var i = 0; i < settings.Args.Length; i++) for (var i = 0; i < settings.Args.Length; i++)
{ {
hashCode = HashCode.Combine(hashCode, settings.Args[i].GetHashCode()); hashCode = HashCode.Combine(hashCode, settings.Args[i].GetHashCode());
} }
} }
}
#nullable disable warnings
private Compilation(Context cx) : base(cx, null)
{
}
#nullable restore warnings #nullable restore warnings
public override void Populate(TextWriter trapFile) public override void Populate(TextWriter trapFile)
{ {
var assembly = Assembly.CreateOutputAssembly(Context); var assembly = Assembly.CreateOutputAssembly(Context);
trapFile.compilations(this, FileUtils.ConvertToUnix(Compilation.Settings.Cwd)); trapFile.compilations(this, FileUtils.ConvertToUnix(settings.Cwd));
trapFile.compilation_assembly(this, assembly); trapFile.compilation_assembly(this, assembly);
// Arguments // Arguments
var expandedIndex = 0; var expandedIndex = 0;
for (var i = 0; i < Compilation.Settings.Args.Length; i++) for (var i = 0; i < settings.Args.Length; i++)
{ {
var arg = Compilation.Settings.Args[i]; var arg = settings.Args[i];
trapFile.compilation_args(this, i, arg); trapFile.compilation_args(this, i, arg);
if (CommandLineExtensions.IsFileArgument(arg)) if (CommandLineExtensions.IsFileArgument(arg))

View File

@@ -97,7 +97,8 @@ namespace Semmle.Extraction.CSharp
stopwatch.Start(); stopwatch.Start();
var options = Options.CreateWithEnvironment(args); var options = Options.CreateWithEnvironment(args);
Entities.Compilation.Settings = (Directory.GetCurrentDirectory(), options.CompilerArguments.ToArray()); var workingDirectory = Directory.GetCurrentDirectory();
var compilerArgs = options.CompilerArguments.ToArray();
using var logger = MakeLogger(options.Verbosity, options.Console); using var logger = MakeLogger(options.Verbosity, options.Console);
@@ -123,7 +124,7 @@ namespace Semmle.Extraction.CSharp
var compilerArguments = CSharpCommandLineParser.Default.Parse( var compilerArguments = CSharpCommandLineParser.Default.Parse(
compilerVersion.ArgsWithResponse, compilerVersion.ArgsWithResponse,
Entities.Compilation.Settings.Cwd, workingDirectory,
compilerVersion.FrameworkPath, compilerVersion.FrameworkPath,
compilerVersion.AdditionalReferenceDirectories compilerVersion.AdditionalReferenceDirectories
); );
@@ -131,7 +132,7 @@ namespace Semmle.Extraction.CSharp
if (compilerArguments is null) if (compilerArguments is null)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append(" Failed to parse command line: ").AppendList(" ", Entities.Compilation.Settings.Args); sb.Append(" Failed to parse command line: ").AppendList(" ", compilerArgs);
logger.Log(Severity.Error, sb.ToString()); logger.Log(Severity.Error, sb.ToString());
++analyser.CompilationErrors; ++analyser.CompilationErrors;
return ExitCode.Failed; return ExitCode.Failed;
@@ -143,7 +144,7 @@ namespace Semmle.Extraction.CSharp
return ExitCode.Ok; return ExitCode.Ok;
} }
return AnalyseTracing(analyser, compilerArguments, options, canonicalPathCache, stopwatch); return AnalyseTracing(workingDirectory, compilerArgs, analyser, compilerArguments, options, canonicalPathCache, stopwatch);
} }
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{ {
@@ -376,6 +377,8 @@ namespace Semmle.Extraction.CSharp
} }
private static ExitCode AnalyseTracing( private static ExitCode AnalyseTracing(
string cwd,
string[] args,
TracingAnalyser analyser, TracingAnalyser analyser,
CSharpCommandLineArguments compilerArguments, CSharpCommandLineArguments compilerArguments,
Options options, Options options,
@@ -420,7 +423,7 @@ namespace Semmle.Extraction.CSharp
.WithMetadataImportOptions(MetadataImportOptions.All) .WithMetadataImportOptions(MetadataImportOptions.All)
); );
}, },
(compilation, options) => analyser.EndInitialize(compilerArguments, options, compilation), (compilation, options) => analyser.EndInitialize(compilerArguments, options, compilation, cwd, args),
() => { }); () => { });
} }

View File

@@ -16,12 +16,10 @@ namespace Semmle.Extraction.CSharp
public void Initialize(string outputPath, IEnumerable<(string, string)> compilationInfos, CSharpCompilation compilationIn, CommonOptions options) public void Initialize(string outputPath, IEnumerable<(string, string)> compilationInfos, CSharpCompilation compilationIn, CommonOptions options)
{ {
compilation = compilationIn; compilation = compilationIn;
extractor = new StandaloneExtractor(outputPath, compilationInfos, Logger, PathTransformer, options); extractor = new StandaloneExtractor(Directory.GetCurrentDirectory(), outputPath, compilationInfos, Logger, PathTransformer, options);
this.options = options; this.options = options;
LogExtractorInfo(Extraction.Extractor.Version); LogExtractorInfo(Extraction.Extractor.Version);
SetReferencePaths(); SetReferencePaths();
Entities.Compilation.Settings = (Directory.GetCurrentDirectory(), Array.Empty<string>());
} }
#nullable disable warnings #nullable disable warnings

View File

@@ -38,13 +38,15 @@ namespace Semmle.Extraction.CSharp
public void EndInitialize( public void EndInitialize(
CSharpCommandLineArguments commandLineArguments, CSharpCommandLineArguments commandLineArguments,
CommonOptions options, CommonOptions options,
CSharpCompilation compilation) CSharpCompilation compilation,
string cwd,
string[] args)
{ {
if (!init) if (!init)
throw new InternalError("EndInitialize called without BeginInitialize returning true"); throw new InternalError("EndInitialize called without BeginInitialize returning true");
this.options = options; this.options = options;
this.compilation = compilation; this.compilation = compilation;
this.extractor = new TracingExtractor(GetOutputName(compilation, commandLineArguments), Logger, PathTransformer, options); this.extractor = new TracingExtractor(cwd, args, GetOutputName(compilation, commandLineArguments), Logger, PathTransformer, options);
LogDiagnostics(); LogDiagnostics();
SetReferencePaths(); SetReferencePaths();

View File

@@ -10,6 +10,8 @@ namespace Semmle.Extraction
/// </summary> /// </summary>
public abstract class Extractor public abstract class Extractor
{ {
public string Cwd { get; init; }
public string[] Args { get; init; }
public abstract ExtractorMode Mode { get; } public abstract ExtractorMode Mode { get; }
public string OutputPath { get; } public string OutputPath { get; }
public IEnumerable<CompilationInfo> CompilationInfos { get; } public IEnumerable<CompilationInfo> CompilationInfos { get; }
@@ -19,12 +21,14 @@ namespace Semmle.Extraction
/// </summary> /// </summary>
/// <param name="logger">The object used for logging.</param> /// <param name="logger">The object used for logging.</param>
/// <param name="pathTransformer">The object used for path transformations.</param> /// <param name="pathTransformer">The object used for path transformations.</param>
protected Extractor(string outputPath, IEnumerable<CompilationInfo> compilationInfos, ILogger logger, PathTransformer pathTransformer) protected Extractor(string cwd, string[] args, string outputPath, IEnumerable<CompilationInfo> compilationInfos, ILogger logger, PathTransformer pathTransformer)
{ {
OutputPath = outputPath; OutputPath = outputPath;
Logger = logger; Logger = logger;
PathTransformer = pathTransformer; PathTransformer = pathTransformer;
CompilationInfos = compilationInfos; CompilationInfos = compilationInfos;
Cwd = cwd;
Args = args;
} }
// Limit the number of error messages in the log file // Limit the number of error messages in the log file

View File

@@ -12,7 +12,8 @@ namespace Semmle.Extraction
/// </summary> /// </summary>
/// <param name="logger">The object used for logging.</param> /// <param name="logger">The object used for logging.</param>
/// <param name="pathTransformer">The object used for path transformations.</param> /// <param name="pathTransformer">The object used for path transformations.</param>
public StandaloneExtractor(string outputPath, IEnumerable<(string, string)> compilationInfos, ILogger logger, PathTransformer pathTransformer, CommonOptions options) : base(outputPath, compilationInfos, logger, pathTransformer) public StandaloneExtractor(string cwd, string outputPath, IEnumerable<(string, string)> compilationInfos, ILogger logger, PathTransformer pathTransformer, CommonOptions options)
: base(cwd, [], outputPath, compilationInfos, logger, pathTransformer)
{ {
Mode = ExtractorMode.Standalone; Mode = ExtractorMode.Standalone;
if (options.QlTest) if (options.QlTest)

View File

@@ -1,4 +1,3 @@
using System.Linq;
using Semmle.Util.Logging; using Semmle.Util.Logging;
namespace Semmle.Extraction namespace Semmle.Extraction
@@ -13,7 +12,8 @@ namespace Semmle.Extraction
/// <param name="outputPath">The name of the output DLL/EXE, or null if not specified (standalone extraction).</param> /// <param name="outputPath">The name of the output DLL/EXE, or null if not specified (standalone extraction).</param>
/// <param name="logger">The object used for logging.</param> /// <param name="logger">The object used for logging.</param>
/// <param name="pathTransformer">The object used for path transformations.</param> /// <param name="pathTransformer">The object used for path transformations.</param>
public TracingExtractor(string outputPath, ILogger logger, PathTransformer pathTransformer, CommonOptions options) : base(outputPath, Enumerable.Empty<(string, string)>(), logger, pathTransformer) public TracingExtractor(string cwd, string[] args, string outputPath, ILogger logger, PathTransformer pathTransformer, CommonOptions options)
: base(cwd, args, outputPath, [], logger, pathTransformer)
{ {
Mode = ExtractorMode.None; Mode = ExtractorMode.None;
if (options.QlTest) if (options.QlTest)