Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9677653

Browse files
committed
Assign preprocessor directives to compilation + make compilation cached
1 parent 1ab4af2 commit 9677653

14 files changed

Lines changed: 236 additions & 181 deletions

File tree

csharp/extractor/Semmle.Extraction.CSharp/Analyser.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,12 @@ private static bool FileIsUpToDate(string src, string dest)
215215
/// <summary>
216216
/// Extracts compilation-wide entities, such as compilations and compiler diagnostics.
217217
/// </summary>
218-
public void AnalyseCompilation(string cwd, string[] args)
218+
public void AnalyseCompilation()
219219
{
220-
extractionTasks.Add(() => DoAnalyseCompilation(cwd, args));
220+
extractionTasks.Add(() => DoAnalyseCompilation());
221221
}
222222

223-
224-
225-
private void DoAnalyseCompilation(string cwd, string[] args)
223+
private void DoAnalyseCompilation()
226224
{
227225
try
228226
{
@@ -234,7 +232,7 @@ private void DoAnalyseCompilation(string cwd, string[] args)
234232
compilationTrapFile = trapWriter; // Dispose later
235233
var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), AddAssemblyTrapPrefix);
236234

237-
compilationEntity = new Entities.Compilation(cx, cwd, args);
235+
compilationEntity = Entities.Compilation.Create(cx);
238236
}
239237
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
240238
{

csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilation.cs

Lines changed: 0 additions & 125 deletions
This file was deleted.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using Microsoft.CodeAnalysis;
2+
using System;
3+
using System.IO;
4+
using System.Linq;
5+
using Semmle.Util;
6+
7+
namespace Semmle.Extraction.CSharp.Entities
8+
{
9+
public class Compilation : CachedEntity<object>
10+
{
11+
private static (string Cwd, string[] Args) settings;
12+
private static int hashCode;
13+
14+
public static (string Cwd, string[] Args) Settings
15+
{
16+
get { return settings; }
17+
set
18+
{
19+
settings = value;
20+
hashCode = settings.Cwd.GetHashCode();
21+
for (var i = 0; i < settings.Args.Length; i++)
22+
{
23+
hashCode = HashCode.Combine(hashCode, settings.Args[i].GetHashCode());
24+
}
25+
}
26+
}
27+
28+
private Compilation(Context cx) : base(cx, null)
29+
{
30+
}
31+
32+
public override void Populate(TextWriter trapFile)
33+
{
34+
var assembly = Extraction.Entities.Assembly.CreateOutputAssembly(Context);
35+
36+
trapFile.compilations(this, FileUtils.ConvertToUnix(Compilation.Settings.Cwd));
37+
trapFile.compilation_assembly(this, assembly);
38+
39+
// Arguments
40+
var index = 0;
41+
foreach (var arg in Compilation.Settings.Args)
42+
{
43+
trapFile.compilation_args(this, index++, arg);
44+
}
45+
46+
// Files
47+
index = 0;
48+
foreach (var file in Context.Compilation.SyntaxTrees.Select(tree => Extraction.Entities.File.Create(Context, tree.FilePath)))
49+
{
50+
trapFile.compilation_compiling_files(this, index++, file);
51+
}
52+
53+
// References
54+
index = 0;
55+
foreach (var file in Context.Compilation.References
56+
.OfType<PortableExecutableReference>()
57+
.Select(r => Extraction.Entities.File.Create(Context, r.FilePath)))
58+
{
59+
trapFile.compilation_referencing_files(this, index++, file);
60+
}
61+
62+
// Diagnostics
63+
index = 0;
64+
foreach (var diag in Context.Compilation.GetDiagnostics().Select(d => new Diagnostic(Context, d)))
65+
{
66+
trapFile.diagnostic_for(diag, this, 0, index++);
67+
}
68+
}
69+
70+
public void PopulatePerformance(PerformanceMetrics p)
71+
{
72+
var trapFile = Context.TrapWriter.Writer;
73+
var index = 0;
74+
foreach (var metric in p.Metrics)
75+
{
76+
trapFile.compilation_time(this, -1, index++, metric);
77+
}
78+
trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds);
79+
}
80+
81+
public override void WriteId(TextWriter trapFile)
82+
{
83+
trapFile.Write(hashCode);
84+
trapFile.Write(";compilation");
85+
}
86+
87+
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
88+
89+
public override Location ReportingLocation => throw new NotImplementedException();
90+
91+
public override bool NeedsPopulation => Context.IsAssemblyScope;
92+
93+
private class CompilationFactory : ICachedEntityFactory<object, Compilation>
94+
{
95+
public static CompilationFactory Instance { get; } = new CompilationFactory();
96+
97+
public Compilation Create(Context cx, object init) => new Compilation(cx);
98+
}
99+
100+
private static readonly object compilationCacheKey = new object();
101+
102+
public static Compilation Create(Context cx)
103+
=> CompilationFactory.Instance.CreateEntity(cx, compilationCacheKey, null);
104+
}
105+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.IO;
2+
3+
namespace Semmle.Extraction.CSharp.Entities
4+
{
5+
internal class Diagnostic : FreshEntity
6+
{
7+
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
8+
9+
private readonly Microsoft.CodeAnalysis.Diagnostic diagnostic;
10+
11+
public Diagnostic(Context cx, Microsoft.CodeAnalysis.Diagnostic diag) : base(cx)
12+
{
13+
diagnostic = diag;
14+
TryPopulate();
15+
}
16+
17+
protected override void Populate(TextWriter trapFile)
18+
{
19+
trapFile.diagnostics(this, (int)diagnostic.Severity, diagnostic.Id, diagnostic.Descriptor.Title.ToString(),
20+
diagnostic.GetMessage(), Extraction.Entities.Location.Create(cx, diagnostic.Location));
21+
}
22+
}
23+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Collections.Generic;
2+
3+
namespace Semmle.Extraction.CSharp.Entities
4+
{
5+
/// <summary>
6+
/// The various performance metrics to log.
7+
/// </summary>
8+
public struct PerformanceMetrics
9+
{
10+
public Timings Frontend { get; set; }
11+
public Timings Extractor { get; set; }
12+
public Timings Total { get; set; }
13+
public long PeakWorkingSet { get; set; }
14+
15+
/// <summary>
16+
/// These are in database order (0 indexed)
17+
/// </summary>
18+
public IEnumerable<float> Metrics
19+
{
20+
get
21+
{
22+
yield return (float)Frontend.Cpu.TotalSeconds;
23+
yield return (float)Frontend.Elapsed.TotalSeconds;
24+
yield return (float)Extractor.Cpu.TotalSeconds;
25+
yield return (float)Extractor.Elapsed.TotalSeconds;
26+
yield return (float)Frontend.User.TotalSeconds;
27+
yield return (float)Extractor.User.TotalSeconds;
28+
yield return PeakWorkingSet / 1024.0f / 1024.0f;
29+
}
30+
}
31+
}
32+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
3+
namespace Semmle.Extraction.CSharp.Entities
4+
{
5+
public struct Timings
6+
{
7+
public TimeSpan Elapsed { get; set; }
8+
public TimeSpan Cpu { get; set; }
9+
public TimeSpan User { get; set; }
10+
}
11+
}

csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PreprocessorDirective.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ protected sealed override void Populate(TextWriter trapFile)
2727

2828
if (!cx.Extractor.Standalone)
2929
{
30-
var assembly = Assembly.CreateOutputAssembly(cx);
31-
trapFile.preprocessor_directive_assembly(this, assembly);
30+
var compilation = Compilation.Create(cx);
31+
trapFile.preprocessor_directive_compilation(this, compilation);
3232
}
3333
}
3434

csharp/extractor/Semmle.Extraction.CSharp/Extractor.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ public static ExitCode Run(string[] args)
6868
{
6969
var stopwatch = new Stopwatch();
7070
stopwatch.Start();
71-
var commandLineArguments = Options.CreateWithEnvironment(args);
71+
72+
Entities.Compilation.Settings = (Directory.GetCurrentDirectory(), args);
73+
74+
var commandLineArguments = Options.CreateWithEnvironment(Entities.Compilation.Settings.Args);
7275
var fileLogger = new FileLogger(commandLineArguments.Verbosity, GetCSharpLogPath());
7376
using var logger = commandLineArguments.Console
7477
? new CombinedLogger(new ConsoleLogger(commandLineArguments.Verbosity), fileLogger)
@@ -95,18 +98,17 @@ public static ExitCode Run(string[] args)
9598
return ExitCode.Ok;
9699
}
97100

98-
var cwd = Directory.GetCurrentDirectory();
99101
var compilerArguments = CSharpCommandLineParser.Default.Parse(
100102
compilerVersion.ArgsWithResponse,
101-
cwd,
103+
Entities.Compilation.Settings.Cwd,
102104
compilerVersion.FrameworkPath,
103105
compilerVersion.AdditionalReferenceDirectories
104106
);
105107

106108
if (compilerArguments == null)
107109
{
108110
var sb = new StringBuilder();
109-
sb.Append(" Failed to parse command line: ").AppendList(" ", args);
111+
sb.Append(" Failed to parse command line: ").AppendList(" ", Entities.Compilation.Settings.Args);
110112
logger.Log(Severity.Error, sb.ToString());
111113
++analyser.CompilationErrors;
112114
return ExitCode.Failed;
@@ -159,7 +161,7 @@ public static ExitCode Run(string[] args)
159161
);
160162

161163
analyser.EndInitialize(compilerArguments, commandLineArguments, compilation);
162-
analyser.AnalyseCompilation(cwd, args);
164+
analyser.AnalyseCompilation();
163165
analyser.AnalyseReferences();
164166

165167
foreach (var tree in compilation.SyntaxTrees)

csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,11 +600,11 @@ internal static void preprocessor_directive_location<TDirective>(this TextWriter
600600
trapFile.WriteTuple("preprocessor_directive_location", directive, location);
601601
}
602602

603-
internal static void preprocessor_directive_assembly<TDirective>(this TextWriter trapFile,
604-
PreprocessorDirective<TDirective> directive, Assembly assembly)
603+
internal static void preprocessor_directive_compilation<TDirective>(this TextWriter trapFile,
604+
PreprocessorDirective<TDirective> directive, Compilation compilation)
605605
where TDirective : DirectiveTriviaSyntax
606606
{
607-
trapFile.WriteTuple("preprocessor_directive_assembly", directive, assembly);
607+
trapFile.WriteTuple("preprocessor_directive_compilation", directive, compilation);
608608
}
609609

610610
internal static void preprocessor_directive_active<TDirective>(this TextWriter trapFile,

0 commit comments

Comments
 (0)