mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
Merge pull request #15957 from tamasvajk/feature/limit-message-extraction
C#: Limit extracted compilation and extraction messages
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
@@ -8,6 +9,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class Compilation : CachedEntity<object>
|
||||
{
|
||||
internal readonly ConcurrentDictionary<string, int> messageCounts = new();
|
||||
|
||||
private static (string Cwd, string[] Args) settings;
|
||||
private static int hashCode;
|
||||
|
||||
@@ -78,10 +81,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
.ForEach((file, index) => trapFile.compilation_referencing_files(this, index, file));
|
||||
|
||||
// Diagnostics
|
||||
Context.Compilation
|
||||
.GetDiagnostics()
|
||||
.Select(d => new Diagnostic(Context, d))
|
||||
.ForEach((diag, index) => trapFile.diagnostic_for(diag, this, 0, index));
|
||||
var diags = Context.Compilation.GetDiagnostics();
|
||||
diags.ForEach((diag, index) => new CompilerDiagnostic(Context, diag, this, index));
|
||||
|
||||
var diagCounts = diags.GroupBy(diag => diag.Id).ToDictionary(group => group.Key, group => group.Count());
|
||||
diagCounts.ForEach(pair => trapFile.compilation_info(this, $"Compiler diagnostic count for {pair.Key}", pair.Value.ToString()));
|
||||
}
|
||||
|
||||
public void PopulatePerformance(PerformanceMetrics p)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.IO;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class CompilerDiagnostic : FreshEntity
|
||||
{
|
||||
private static readonly int limit = EnvironmentVariables.TryGetExtractorNumberOption<int>("COMPILER_DIAGNOSTIC_LIMIT") ?? 1000;
|
||||
|
||||
private readonly Microsoft.CodeAnalysis.Diagnostic diagnostic;
|
||||
private readonly Compilation compilation;
|
||||
private readonly int index;
|
||||
|
||||
public CompilerDiagnostic(Context cx, Microsoft.CodeAnalysis.Diagnostic diag, Compilation compilation, int index) : base(cx)
|
||||
{
|
||||
diagnostic = diag;
|
||||
this.compilation = compilation;
|
||||
this.index = index;
|
||||
TryPopulate();
|
||||
}
|
||||
|
||||
protected override void Populate(TextWriter trapFile)
|
||||
{
|
||||
// The below doesn't limit the extractor messages to the exact limit, but it's good enough.
|
||||
var key = diagnostic.Id;
|
||||
var messageCount = compilation.messageCounts.AddOrUpdate(key, 1, (_, c) => c + 1);
|
||||
if (messageCount > limit)
|
||||
{
|
||||
if (messageCount == limit + 1)
|
||||
{
|
||||
Context.Extractor.Logger.LogWarning($"Stopped logging {key} compiler diagnostics for the current compilation after reaching {limit}");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
trapFile.diagnostics(this, (int)diagnostic.Severity, key, diagnostic.Descriptor.Title.ToString(),
|
||||
diagnostic.GetMessage(), Context.CreateLocation(diagnostic.Location));
|
||||
|
||||
trapFile.diagnostic_for(this, compilation, 0, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class Diagnostic : FreshEntity
|
||||
{
|
||||
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(), Context.CreateLocation(diagnostic.Location));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,10 +122,10 @@ namespace Semmle.Extraction.CSharp
|
||||
internal static void destructors(this TextWriter trapFile, Destructor destructor, string name, Type containingType, Destructor original) =>
|
||||
trapFile.WriteTuple("destructors", destructor, name, containingType, original);
|
||||
|
||||
internal static void diagnostic_for(this TextWriter trapFile, Diagnostic diag, Compilation comp, int fileNo, int index) =>
|
||||
internal static void diagnostic_for(this TextWriter trapFile, CompilerDiagnostic diag, Compilation comp, int fileNo, int index) =>
|
||||
trapFile.WriteTuple("diagnostic_for", diag, comp, fileNo, index);
|
||||
|
||||
internal static void diagnostics(this TextWriter trapFile, Diagnostic diag, int severity, string errorTag, string errorMessage, string fullErrorMessage, Location location) =>
|
||||
internal static void diagnostics(this TextWriter trapFile, CompilerDiagnostic diag, int severity, string errorTag, string errorMessage, string fullErrorMessage, Location location) =>
|
||||
trapFile.WriteTuple("diagnostics", diag, severity, errorTag, errorMessage, fullErrorMessage, location);
|
||||
|
||||
internal static void dynamic_member_name(this TextWriter trapFile, Expression e, string name) =>
|
||||
|
||||
Reference in New Issue
Block a user