Assign preprocessor directives to compilation + make compilation cached

This commit is contained in:
Tamas Vajk
2021-01-27 16:17:32 +01:00
parent 1ab4af275d
commit 967765342e
14 changed files with 236 additions and 181 deletions

View File

@@ -215,14 +215,12 @@ namespace Semmle.Extraction.CSharp
/// <summary> /// <summary>
/// Extracts compilation-wide entities, such as compilations and compiler diagnostics. /// Extracts compilation-wide entities, such as compilations and compiler diagnostics.
/// </summary> /// </summary>
public void AnalyseCompilation(string cwd, string[] args) public void AnalyseCompilation()
{ {
extractionTasks.Add(() => DoAnalyseCompilation(cwd, args)); extractionTasks.Add(() => DoAnalyseCompilation());
} }
private void DoAnalyseCompilation()
private void DoAnalyseCompilation(string cwd, string[] args)
{ {
try try
{ {
@@ -234,7 +232,7 @@ namespace Semmle.Extraction.CSharp
compilationTrapFile = trapWriter; // Dispose later compilationTrapFile = trapWriter; // Dispose later
var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), AddAssemblyTrapPrefix); var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), AddAssemblyTrapPrefix);
compilationEntity = new Entities.Compilation(cx, cwd, args); compilationEntity = Entities.Compilation.Create(cx);
} }
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{ {

View File

@@ -1,125 +0,0 @@
using Microsoft.CodeAnalysis;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Semmle.Util;
namespace Semmle.Extraction.CSharp.Entities
{
internal class Compilation : FreshEntity
{
private readonly string cwd;
private readonly string[] args;
public Compilation(Context cx, string cwd, string[] args) : base(cx)
{
this.cwd = cwd;
this.args = args;
TryPopulate();
}
protected override void Populate(TextWriter trapFile)
{
var assembly = Extraction.Entities.Assembly.CreateOutputAssembly(cx);
trapFile.compilations(this, FileUtils.ConvertToUnix(cwd));
trapFile.compilation_assembly(this, assembly);
// Arguments
var index = 0;
foreach (var arg in args)
{
trapFile.compilation_args(this, index++, arg);
}
// Files
index = 0;
foreach (var file in cx.Compilation.SyntaxTrees.Select(tree => Extraction.Entities.File.Create(cx, tree.FilePath)))
{
trapFile.compilation_compiling_files(this, index++, file);
}
// References
index = 0;
foreach (var file in cx.Compilation.References.OfType<PortableExecutableReference>().Select(r => Extraction.Entities.File.Create(cx, r.FilePath)))
{
trapFile.compilation_referencing_files(this, index++, file);
}
// Diagnostics
index = 0;
foreach (var diag in cx.Compilation.GetDiagnostics().Select(d => new Diagnostic(cx, d)))
{
trapFile.diagnostic_for(diag, this, 0, index++);
}
}
public void PopulatePerformance(PerformanceMetrics p)
{
var trapFile = cx.TrapWriter.Writer;
var index = 0;
foreach (var metric in p.Metrics)
{
trapFile.compilation_time(this, -1, index++, metric);
}
trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds);
}
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
}
internal class Diagnostic : FreshEntity
{
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
private readonly Microsoft.CodeAnalysis.Diagnostic diagnostic;
public Diagnostic(Context cx, Microsoft.CodeAnalysis.Diagnostic diag) : base(cx)
{
diagnostic = diag;
TryPopulate();
}
protected override void Populate(TextWriter trapFile)
{
trapFile.diagnostics(this, (int)diagnostic.Severity, diagnostic.Id, diagnostic.Descriptor.Title.ToString(),
diagnostic.GetMessage(), Extraction.Entities.Location.Create(cx, diagnostic.Location));
}
}
public struct Timings
{
public TimeSpan Elapsed { get; set; }
public TimeSpan Cpu { get; set; }
public TimeSpan User { get; set; }
}
/// <summary>
/// The various performance metrics to log.
/// </summary>
public struct PerformanceMetrics
{
public Timings Frontend { get; set; }
public Timings Extractor { get; set; }
public Timings Total { get; set; }
public long PeakWorkingSet { get; set; }
/// <summary>
/// These are in database order (0 indexed)
/// </summary>
public IEnumerable<float> Metrics
{
get
{
yield return (float)Frontend.Cpu.TotalSeconds;
yield return (float)Frontend.Elapsed.TotalSeconds;
yield return (float)Extractor.Cpu.TotalSeconds;
yield return (float)Extractor.Elapsed.TotalSeconds;
yield return (float)Frontend.User.TotalSeconds;
yield return (float)Extractor.User.TotalSeconds;
yield return PeakWorkingSet / 1024.0f / 1024.0f;
}
}
}
}

View File

@@ -0,0 +1,105 @@
using Microsoft.CodeAnalysis;
using System;
using System.IO;
using System.Linq;
using Semmle.Util;
namespace Semmle.Extraction.CSharp.Entities
{
public class Compilation : CachedEntity<object>
{
private static (string Cwd, string[] Args) settings;
private static int hashCode;
public static (string Cwd, string[] Args) Settings
{
get { return settings; }
set
{
settings = value;
hashCode = settings.Cwd.GetHashCode();
for (var i = 0; i < settings.Args.Length; i++)
{
hashCode = HashCode.Combine(hashCode, settings.Args[i].GetHashCode());
}
}
}
private Compilation(Context cx) : base(cx, null)
{
}
public override void Populate(TextWriter trapFile)
{
var assembly = Extraction.Entities.Assembly.CreateOutputAssembly(Context);
trapFile.compilations(this, FileUtils.ConvertToUnix(Compilation.Settings.Cwd));
trapFile.compilation_assembly(this, assembly);
// Arguments
var index = 0;
foreach (var arg in Compilation.Settings.Args)
{
trapFile.compilation_args(this, index++, arg);
}
// Files
index = 0;
foreach (var file in Context.Compilation.SyntaxTrees.Select(tree => Extraction.Entities.File.Create(Context, tree.FilePath)))
{
trapFile.compilation_compiling_files(this, index++, file);
}
// References
index = 0;
foreach (var file in Context.Compilation.References
.OfType<PortableExecutableReference>()
.Select(r => Extraction.Entities.File.Create(Context, r.FilePath)))
{
trapFile.compilation_referencing_files(this, index++, file);
}
// Diagnostics
index = 0;
foreach (var diag in Context.Compilation.GetDiagnostics().Select(d => new Diagnostic(Context, d)))
{
trapFile.diagnostic_for(diag, this, 0, index++);
}
}
public void PopulatePerformance(PerformanceMetrics p)
{
var trapFile = Context.TrapWriter.Writer;
var index = 0;
foreach (var metric in p.Metrics)
{
trapFile.compilation_time(this, -1, index++, metric);
}
trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds);
}
public override void WriteId(TextWriter trapFile)
{
trapFile.Write(hashCode);
trapFile.Write(";compilation");
}
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
public override Location ReportingLocation => throw new NotImplementedException();
public override bool NeedsPopulation => Context.IsAssemblyScope;
private class CompilationFactory : ICachedEntityFactory<object, Compilation>
{
public static CompilationFactory Instance { get; } = new CompilationFactory();
public Compilation Create(Context cx, object init) => new Compilation(cx);
}
private static readonly object compilationCacheKey = new object();
public static Compilation Create(Context cx)
=> CompilationFactory.Instance.CreateEntity(cx, compilationCacheKey, null);
}
}

View File

@@ -0,0 +1,23 @@
using System.IO;
namespace Semmle.Extraction.CSharp.Entities
{
internal class Diagnostic : FreshEntity
{
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
private readonly Microsoft.CodeAnalysis.Diagnostic diagnostic;
public Diagnostic(Context cx, Microsoft.CodeAnalysis.Diagnostic diag) : base(cx)
{
diagnostic = diag;
TryPopulate();
}
protected override void Populate(TextWriter trapFile)
{
trapFile.diagnostics(this, (int)diagnostic.Severity, diagnostic.Id, diagnostic.Descriptor.Title.ToString(),
diagnostic.GetMessage(), Extraction.Entities.Location.Create(cx, diagnostic.Location));
}
}
}

View File

@@ -0,0 +1,32 @@
using System.Collections.Generic;
namespace Semmle.Extraction.CSharp.Entities
{
/// <summary>
/// The various performance metrics to log.
/// </summary>
public struct PerformanceMetrics
{
public Timings Frontend { get; set; }
public Timings Extractor { get; set; }
public Timings Total { get; set; }
public long PeakWorkingSet { get; set; }
/// <summary>
/// These are in database order (0 indexed)
/// </summary>
public IEnumerable<float> Metrics
{
get
{
yield return (float)Frontend.Cpu.TotalSeconds;
yield return (float)Frontend.Elapsed.TotalSeconds;
yield return (float)Extractor.Cpu.TotalSeconds;
yield return (float)Extractor.Elapsed.TotalSeconds;
yield return (float)Frontend.User.TotalSeconds;
yield return (float)Extractor.User.TotalSeconds;
yield return PeakWorkingSet / 1024.0f / 1024.0f;
}
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Semmle.Extraction.CSharp.Entities
{
public struct Timings
{
public TimeSpan Elapsed { get; set; }
public TimeSpan Cpu { get; set; }
public TimeSpan User { get; set; }
}
}

View File

@@ -27,8 +27,8 @@ namespace Semmle.Extraction.CSharp.Entities
if (!cx.Extractor.Standalone) if (!cx.Extractor.Standalone)
{ {
var assembly = Assembly.CreateOutputAssembly(cx); var compilation = Compilation.Create(cx);
trapFile.preprocessor_directive_assembly(this, assembly); trapFile.preprocessor_directive_compilation(this, compilation);
} }
} }

View File

@@ -68,7 +68,10 @@ namespace Semmle.Extraction.CSharp
{ {
var stopwatch = new Stopwatch(); var stopwatch = new Stopwatch();
stopwatch.Start(); stopwatch.Start();
var commandLineArguments = Options.CreateWithEnvironment(args);
Entities.Compilation.Settings = (Directory.GetCurrentDirectory(), args);
var commandLineArguments = Options.CreateWithEnvironment(Entities.Compilation.Settings.Args);
var fileLogger = new FileLogger(commandLineArguments.Verbosity, GetCSharpLogPath()); var fileLogger = new FileLogger(commandLineArguments.Verbosity, GetCSharpLogPath());
using var logger = commandLineArguments.Console using var logger = commandLineArguments.Console
? new CombinedLogger(new ConsoleLogger(commandLineArguments.Verbosity), fileLogger) ? new CombinedLogger(new ConsoleLogger(commandLineArguments.Verbosity), fileLogger)
@@ -95,10 +98,9 @@ namespace Semmle.Extraction.CSharp
return ExitCode.Ok; return ExitCode.Ok;
} }
var cwd = Directory.GetCurrentDirectory();
var compilerArguments = CSharpCommandLineParser.Default.Parse( var compilerArguments = CSharpCommandLineParser.Default.Parse(
compilerVersion.ArgsWithResponse, compilerVersion.ArgsWithResponse,
cwd, Entities.Compilation.Settings.Cwd,
compilerVersion.FrameworkPath, compilerVersion.FrameworkPath,
compilerVersion.AdditionalReferenceDirectories compilerVersion.AdditionalReferenceDirectories
); );
@@ -106,7 +108,7 @@ namespace Semmle.Extraction.CSharp
if (compilerArguments == null) if (compilerArguments == null)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append(" Failed to parse command line: ").AppendList(" ", args); sb.Append(" Failed to parse command line: ").AppendList(" ", Entities.Compilation.Settings.Args);
logger.Log(Severity.Error, sb.ToString()); logger.Log(Severity.Error, sb.ToString());
++analyser.CompilationErrors; ++analyser.CompilationErrors;
return ExitCode.Failed; return ExitCode.Failed;
@@ -159,7 +161,7 @@ namespace Semmle.Extraction.CSharp
); );
analyser.EndInitialize(compilerArguments, commandLineArguments, compilation); analyser.EndInitialize(compilerArguments, commandLineArguments, compilation);
analyser.AnalyseCompilation(cwd, args); analyser.AnalyseCompilation();
analyser.AnalyseReferences(); analyser.AnalyseReferences();
foreach (var tree in compilation.SyntaxTrees) foreach (var tree in compilation.SyntaxTrees)

View File

@@ -600,11 +600,11 @@ namespace Semmle.Extraction.CSharp
trapFile.WriteTuple("preprocessor_directive_location", directive, location); trapFile.WriteTuple("preprocessor_directive_location", directive, location);
} }
internal static void preprocessor_directive_assembly<TDirective>(this TextWriter trapFile, internal static void preprocessor_directive_compilation<TDirective>(this TextWriter trapFile,
PreprocessorDirective<TDirective> directive, Assembly assembly) PreprocessorDirective<TDirective> directive, Compilation compilation)
where TDirective : DirectiveTriviaSyntax where TDirective : DirectiveTriviaSyntax
{ {
trapFile.WriteTuple("preprocessor_directive_assembly", directive, assembly); trapFile.WriteTuple("preprocessor_directive_compilation", directive, compilation);
} }
internal static void preprocessor_directive_active<TDirective>(this TextWriter trapFile, internal static void preprocessor_directive_active<TDirective>(this TextWriter trapFile,

View File

@@ -246,7 +246,9 @@ namespace Semmle.Extraction
public ICommentGenerator CommentGenerator { get; } = new CommentProcessor(); public ICommentGenerator CommentGenerator { get; } = new CommentProcessor();
private IExtractionScope scope { get; } private IExtractionScope scope;
public bool IsAssemblyScope => scope is AssemblyScope;
public SyntaxTree? SourceTree => scope is SourceScope sc ? sc.SourceTree : null; public SyntaxTree? SourceTree => scope is SourceScope sc ? sc.SourceTree : null;
@@ -368,9 +370,9 @@ namespace Semmle.Extraction
throw new InternalError("Unexpected TrapStackBehaviour"); throw new InternalError("Unexpected TrapStackBehaviour");
} }
var a = duplicationGuard && this.Create(entity.ReportingLocation) is NonGeneratedSourceLocation loc ? var a = duplicationGuard && this.Create(entity.ReportingLocation) is NonGeneratedSourceLocation loc
(Action)(() => WithDuplicationGuard(new Key(entity, loc), () => entity.Populate(TrapWriter.Writer))) : ? (Action)(() => WithDuplicationGuard(new Key(entity, loc), () => entity.Populate(TrapWriter.Writer)))
(Action)(() => this.Try(null, optionalSymbol, () => entity.Populate(TrapWriter.Writer))); : (Action)(() => this.Try(null, optionalSymbol, () => entity.Populate(TrapWriter.Writer)));
if (deferred) if (deferred)
populateQueue.Enqueue(a); populateQueue.Enqueue(a);
@@ -384,7 +386,7 @@ namespace Semmle.Extraction
/// </summary> /// </summary>
public void WithDuplicationGuard(Key key, Action a) public void WithDuplicationGuard(Key key, Action a)
{ {
if (scope is AssemblyScope) if (IsAssemblyScope)
{ {
// No need for a duplication guard when extracting assemblies, // No need for a duplication guard when extracting assemblies,
// and the duplication guard could lead to method bodies being missed // and the duplication guard could lead to method bodies being missed

View File

@@ -3,6 +3,7 @@
*/ */
import Element import Element
private import semmle.code.csharp.commons.Compilation
/** /**
* A preprocessor directive, such as `PragmaWarningDirective`, `PragmaChecksumDirective`, * A preprocessor directive, such as `PragmaWarningDirective`, `PragmaChecksumDirective`,
@@ -17,9 +18,10 @@ class PreprocessorDirective extends Element, @preprocessor_directive {
*/ */
predicate isActive() { preprocessor_directive_active(this, 1) } predicate isActive() { preprocessor_directive_active(this, 1) }
override Location getALocation() { override Location getALocation() { preprocessor_directive_location(this, result) }
preprocessor_directive_location(this, result) or preprocessor_directive_assembly(this, result)
} /** Gets the compilation this directive belongs to, if any. */
Compilation getCompilation() { preprocessor_directive_compilation(this, result) }
} }
/** /**

View File

@@ -424,9 +424,9 @@ preprocessor_directive_location(
unique int id: @preprocessor_directive ref, unique int id: @preprocessor_directive ref,
int loc: @location ref); int loc: @location ref);
preprocessor_directive_assembly( preprocessor_directive_compilation(
unique int id: @preprocessor_directive ref, unique int id: @preprocessor_directive ref,
int loc: @assembly ref); int compilation: @compilation ref);
preprocessor_directive_active( preprocessor_directive_active(
unique int id: @preprocessor_directive ref, unique int id: @preprocessor_directive ref,

View File

@@ -1,60 +1,62 @@
| trivia.cs:4:1:4:13 | #define ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active | directives
| trivia.cs:4:1:4:13 | #define ... | trivia.cs:4:1:4:13 | trivia.cs:4:1:4:13 | active | | trivia.cs:4:1:4:13 | #define ... | trivia.cs:4:1:4:13 | trivia.cs:4:1:4:13 | active |
| trivia.cs:6:1:6:12 | #undef ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:6:1:6:12 | #undef ... | trivia.cs:6:1:6:12 | trivia.cs:6:1:6:12 | active | | trivia.cs:6:1:6:12 | #undef ... | trivia.cs:6:1:6:12 | trivia.cs:6:1:6:12 | active |
| trivia.cs:12:1:12:35 | #pragma warning ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:12:1:12:35 | #pragma warning ... | trivia.cs:12:1:12:35 | trivia.cs:12:1:12:35 | active | | trivia.cs:12:1:12:35 | #pragma warning ... | trivia.cs:12:1:12:35 | trivia.cs:12:1:12:35 | active |
| trivia.cs:13:1:13:98 | #pragma checksum ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:13:1:13:98 | #pragma checksum ... | trivia.cs:13:1:13:98 | trivia.cs:13:1:13:98 | active | | trivia.cs:13:1:13:98 | #pragma checksum ... | trivia.cs:13:1:13:98 | trivia.cs:13:1:13:98 | active |
| trivia.cs:18:1:18:19 | #line ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:18:1:18:19 | #line ... | trivia.cs:18:1:18:19 | trivia.cs:18:1:18:19 | active | | trivia.cs:18:1:18:19 | #line ... | trivia.cs:18:1:18:19 | trivia.cs:18:1:18:19 | active |
| trivia.cs:21:1:21:13 | #line default | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:21:1:21:13 | #line default | trivia.cs:21:1:21:13 | trivia.cs:21:1:21:13 | active | | trivia.cs:21:1:21:13 | #line default | trivia.cs:21:1:21:13 | trivia.cs:21:1:21:13 | active |
| trivia.cs:23:1:23:23 | #pragma warning ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:23:1:23:23 | #pragma warning ... | trivia.cs:23:1:23:23 | trivia.cs:23:1:23:23 | active | | trivia.cs:23:1:23:23 | #pragma warning ... | trivia.cs:23:1:23:23 | trivia.cs:23:1:23:23 | active |
| trivia.cs:25:1:25:38 | #line hidden | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:25:1:25:38 | #line hidden | trivia.cs:25:1:25:38 | trivia.cs:25:1:25:38 | active | | trivia.cs:25:1:25:38 | #line hidden | trivia.cs:25:1:25:38 | trivia.cs:25:1:25:38 | active |
| trivia.cs:27:1:27:9 | #line ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:27:1:27:9 | #line ... | trivia.cs:27:1:27:9 | trivia.cs:27:1:27:9 | active | | trivia.cs:27:1:27:9 | #line ... | trivia.cs:27:1:27:9 | trivia.cs:27:1:27:9 | active |
| trivia.cs:36:9:36:22 | #region ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:36:9:36:22 | #region ... | trivia.cs:36:9:36:22 | trivia.cs:36:9:36:22 | active | | trivia.cs:36:9:36:22 | #region ... | trivia.cs:36:9:36:22 | trivia.cs:36:9:36:22 | active |
| trivia.cs:38:9:38:22 | #region ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:38:9:38:22 | #region ... | trivia.cs:38:9:38:22 | trivia.cs:38:9:38:22 | active | | trivia.cs:38:9:38:22 | #region ... | trivia.cs:38:9:38:22 | trivia.cs:38:9:38:22 | active |
| trivia.cs:40:9:40:18 | #endregion | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:40:9:40:18 | #endregion | trivia.cs:40:9:40:18 | trivia.cs:40:9:40:18 | active | | trivia.cs:40:9:40:18 | #endregion | trivia.cs:40:9:40:18 | trivia.cs:40:9:40:18 | active |
| trivia.cs:41:9:41:18 | #endregion | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:41:9:41:18 | #endregion | trivia.cs:41:9:41:18 | trivia.cs:41:9:41:18 | active | | trivia.cs:41:9:41:18 | #endregion | trivia.cs:41:9:41:18 | trivia.cs:41:9:41:18 | active |
| trivia.cs:49:1:49:82 | #nullable ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:49:1:49:82 | #nullable ... | trivia.cs:49:1:49:82 | trivia.cs:49:1:49:82 | active | | trivia.cs:49:1:49:82 | #nullable ... | trivia.cs:49:1:49:82 | trivia.cs:49:1:49:82 | active |
| trivia.cs:50:1:50:80 | #nullable ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:50:1:50:80 | #nullable ... | trivia.cs:50:1:50:80 | trivia.cs:50:1:50:80 | active | | trivia.cs:50:1:50:80 | #nullable ... | trivia.cs:50:1:50:80 | trivia.cs:50:1:50:80 | active |
| trivia.cs:51:1:51:94 | #nullable ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:51:1:51:94 | #nullable ... | trivia.cs:51:1:51:94 | trivia.cs:51:1:51:94 | active | | trivia.cs:51:1:51:94 | #nullable ... | trivia.cs:51:1:51:94 | trivia.cs:51:1:51:94 | active |
| trivia.cs:52:1:52:81 | #nullable ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:52:1:52:81 | #nullable ... | trivia.cs:52:1:52:81 | trivia.cs:52:1:52:81 | active | | trivia.cs:52:1:52:81 | #nullable ... | trivia.cs:52:1:52:81 | trivia.cs:52:1:52:81 | active |
| trivia.cs:53:1:53:79 | #nullable ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:53:1:53:79 | #nullable ... | trivia.cs:53:1:53:79 | trivia.cs:53:1:53:79 | active | | trivia.cs:53:1:53:79 | #nullable ... | trivia.cs:53:1:53:79 | trivia.cs:53:1:53:79 | active |
| trivia.cs:54:1:54:93 | #nullable ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:54:1:54:93 | #nullable ... | trivia.cs:54:1:54:93 | trivia.cs:54:1:54:93 | active | | trivia.cs:54:1:54:93 | #nullable ... | trivia.cs:54:1:54:93 | trivia.cs:54:1:54:93 | active |
| trivia.cs:55:1:55:75 | #nullable ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:55:1:55:75 | #nullable ... | trivia.cs:55:1:55:75 | trivia.cs:55:1:55:75 | active | | trivia.cs:55:1:55:75 | #nullable ... | trivia.cs:55:1:55:75 | trivia.cs:55:1:55:75 | active |
| trivia.cs:56:1:56:73 | #nullable ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:56:1:56:73 | #nullable ... | trivia.cs:56:1:56:73 | trivia.cs:56:1:56:73 | active | | trivia.cs:56:1:56:73 | #nullable ... | trivia.cs:56:1:56:73 | trivia.cs:56:1:56:73 | active |
| trivia.cs:57:1:57:87 | #nullable ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:57:1:57:87 | #nullable ... | trivia.cs:57:1:57:87 | trivia.cs:57:1:57:87 | active | | trivia.cs:57:1:57:87 | #nullable ... | trivia.cs:57:1:57:87 | trivia.cs:57:1:57:87 | active |
| trivia.cs:65:1:65:9 | #if ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:65:1:65:9 | #if ... | trivia.cs:65:1:65:9 | trivia.cs:65:1:65:9 | active | | trivia.cs:65:1:65:9 | #if ... | trivia.cs:65:1:65:9 | trivia.cs:65:1:65:9 | active |
| trivia.cs:66:1:66:23 | #error ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | inactive |
| trivia.cs:66:1:66:23 | #error ... | trivia.cs:66:1:66:23 | trivia.cs:66:1:66:23 | inactive | | trivia.cs:66:1:66:23 | #error ... | trivia.cs:66:1:66:23 | trivia.cs:66:1:66:23 | inactive |
| trivia.cs:68:1:68:10 | #if ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | inactive |
| trivia.cs:68:1:68:10 | #if ... | trivia.cs:68:1:68:10 | trivia.cs:68:1:68:10 | inactive | | trivia.cs:68:1:68:10 | #if ... | trivia.cs:68:1:68:10 | trivia.cs:68:1:68:10 | inactive |
| trivia.cs:70:1:70:6 | #endif | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | inactive |
| trivia.cs:70:1:70:6 | #endif | trivia.cs:70:1:70:6 | trivia.cs:70:1:70:6 | inactive | | trivia.cs:70:1:70:6 | #endif | trivia.cs:70:1:70:6 | trivia.cs:70:1:70:6 | inactive |
| trivia.cs:71:1:71:35 | #elif ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:71:1:71:35 | #elif ... | trivia.cs:71:1:71:35 | trivia.cs:71:1:71:35 | active | | trivia.cs:71:1:71:35 | #elif ... | trivia.cs:71:1:71:35 | trivia.cs:71:1:71:35 | active |
| trivia.cs:72:1:72:43 | #warning ... | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:72:1:72:43 | #warning ... | trivia.cs:72:1:72:43 | trivia.cs:72:1:72:43 | active | | trivia.cs:72:1:72:43 | #warning ... | trivia.cs:72:1:72:43 | trivia.cs:72:1:72:43 | active |
| trivia.cs:74:1:74:5 | #else | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:74:1:74:5 | #else | trivia.cs:74:1:74:5 | trivia.cs:74:1:74:5 | active | | trivia.cs:74:1:74:5 | #else | trivia.cs:74:1:74:5 | trivia.cs:74:1:74:5 | active |
| trivia.cs:76:1:76:6 | #endif | comments2.dll:0:0:0:0 | comments2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | active |
| trivia.cs:76:1:76:6 | #endif | trivia.cs:76:1:76:6 | trivia.cs:76:1:76:6 | active | | trivia.cs:76:1:76:6 | #endif | trivia.cs:76:1:76:6 | trivia.cs:76:1:76:6 | active |
comp
| trivia.cs:4:1:4:13 | #define ... | compilation |
| trivia.cs:6:1:6:12 | #undef ... | compilation |
| trivia.cs:12:1:12:35 | #pragma warning ... | compilation |
| trivia.cs:13:1:13:98 | #pragma checksum ... | compilation |
| trivia.cs:18:1:18:19 | #line ... | compilation |
| trivia.cs:21:1:21:13 | #line default | compilation |
| trivia.cs:23:1:23:23 | #pragma warning ... | compilation |
| trivia.cs:25:1:25:38 | #line hidden | compilation |
| trivia.cs:27:1:27:9 | #line ... | compilation |
| trivia.cs:36:9:36:22 | #region ... | compilation |
| trivia.cs:38:9:38:22 | #region ... | compilation |
| trivia.cs:40:9:40:18 | #endregion | compilation |
| trivia.cs:41:9:41:18 | #endregion | compilation |
| trivia.cs:49:1:49:82 | #nullable ... | compilation |
| trivia.cs:50:1:50:80 | #nullable ... | compilation |
| trivia.cs:51:1:51:94 | #nullable ... | compilation |
| trivia.cs:52:1:52:81 | #nullable ... | compilation |
| trivia.cs:53:1:53:79 | #nullable ... | compilation |
| trivia.cs:54:1:54:93 | #nullable ... | compilation |
| trivia.cs:55:1:55:75 | #nullable ... | compilation |
| trivia.cs:56:1:56:73 | #nullable ... | compilation |
| trivia.cs:57:1:57:87 | #nullable ... | compilation |
| trivia.cs:65:1:65:9 | #if ... | compilation |
| trivia.cs:66:1:66:23 | #error ... | compilation |
| trivia.cs:68:1:68:10 | #if ... | compilation |
| trivia.cs:70:1:70:6 | #endif | compilation |
| trivia.cs:71:1:71:35 | #elif ... | compilation |
| trivia.cs:72:1:72:43 | #warning ... | compilation |
| trivia.cs:74:1:74:5 | #else | compilation |
| trivia.cs:76:1:76:6 | #endif | compilation |

View File

@@ -1,6 +1,9 @@
import csharp import csharp
private import semmle.code.csharp.commons.Compilation
query predicate directives(PreprocessorDirective d, Location l, string isActive) { query predicate directives(PreprocessorDirective d, Location l, string isActive) {
d.getALocation() = l and d.getALocation() = l and
if d.isActive() then isActive = "active" else isActive = "inactive" if d.isActive() then isActive = "active" else isActive = "inactive"
} }
query predicate comp(PreprocessorDirective d, Compilation c) { d.getCompilation() = c }