C#: Do not skip extraction of already seen source files

This commit is contained in:
Tamas Vajk
2024-07-09 13:53:35 +02:00
parent 6f23819f60
commit a31d90897d
12 changed files with 110 additions and 30 deletions

View File

@@ -20,6 +20,7 @@ namespace Semmle.Extraction.CSharp.Entities
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.WriteSubId(Context.CreateLocation(ReportingLocation));
trapFile.WriteSubId(start);
trapFile.Write(Symbol.IsActive);
trapFile.Write(',');
trapFile.Write(Symbol.BranchTaken);

View File

@@ -18,6 +18,7 @@ namespace Semmle.Extraction.CSharp.Entities
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.WriteSubId(Context.CreateLocation(ReportingLocation));
trapFile.WriteSubId(start);
trapFile.Write(Symbol.IsActive);
trapFile.Write(',');
trapFile.Write(Symbol.BranchTaken);

View File

@@ -13,6 +13,14 @@ namespace Semmle.Extraction.CSharp.Entities
this.start = start;
}
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.WriteSubId(Context.CreateLocation(ReportingLocation));
trapFile.WriteSubId(start);
trapFile.Write(Symbol.IsActive);
trapFile.Write(";trivia");
}
protected override void PopulatePreprocessor(TextWriter trapFile)
{
trapFile.directive_endifs(this, start);

View File

@@ -190,37 +190,29 @@ namespace Semmle.Extraction.CSharp
var transformedSourcePath = PathTransformer.Transform(sourcePath);
var trapPath = transformedSourcePath.GetTrapPath(Logger, options.TrapCompression);
var upToDate = false;
// compilation.Clone() is used to allow symbols to be garbage collected.
using var trapWriter = transformedSourcePath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false);
upToDate = FileIsUpToDate(sourcePath, trapWriter.TrapFile);
var currentTaskId = IncrementTaskCount();
ReportProgressTaskStarted(currentTaskId, sourcePath);
if (!upToDate)
var cx = new Context(ExtractionContext, compilation, trapWriter, new SourceScope(tree), addAssemblyTrapPrefix);
// Ensure that the file itself is populated in case the source file is totally empty
var root = tree.GetRoot();
Entities.File.Create(cx, root.SyntaxTree.FilePath);
var csNode = (CSharpSyntaxNode)root;
var directiveVisitor = new DirectiveVisitor(cx);
csNode.Accept(directiveVisitor);
foreach (var branch in directiveVisitor.BranchesTaken)
{
var cx = new Context(ExtractionContext, compilation, trapWriter, new SourceScope(tree), addAssemblyTrapPrefix);
// Ensure that the file itself is populated in case the source file is totally empty
var root = tree.GetRoot();
Entities.File.Create(cx, root.SyntaxTree.FilePath);
var csNode = (CSharpSyntaxNode)root;
var directiveVisitor = new DirectiveVisitor(cx);
csNode.Accept(directiveVisitor);
foreach (var branch in directiveVisitor.BranchesTaken)
{
cx.TrapStackSuffix.Add(branch);
}
csNode.Accept(new CompilationUnitVisitor(cx));
cx.PopulateAll();
CommentPopulator.ExtractCommentBlocks(cx, cx.CommentGenerator);
cx.PopulateAll();
cx.TrapStackSuffix.Add(branch);
}
csNode.Accept(new CompilationUnitVisitor(cx));
cx.PopulateAll();
CommentPopulator.ExtractCommentBlocks(cx, cx.CommentGenerator);
cx.PopulateAll();
ReportProgressTaskDone(currentTaskId, sourcePath, trapPath, stopwatch.Elapsed, upToDate ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
ReportProgressTaskDone(currentTaskId, sourcePath, trapPath, stopwatch.Elapsed, AnalysisAction.Extracted);
}
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{

View File

@@ -194,8 +194,11 @@ namespace Semmle.Extraction
var hash = FileUtils.ComputeFileHash(tmpFile);
if (existingHash != hash)
{
var root = TrapFile.Substring(0, TrapFile.Length - 8); // Remove trailing ".trap.gz"
if (TryMove(tmpFile, $"{root}-{hash}.trap{TrapExtension(trapCompression)}"))
var extension = TrapExtension(trapCompression);
var root = TrapFile[..^extension.Length]; // Remove trailing ".trap", ".trap.gz", or ".trap.br"
var newTrapName = $"{root}-{hash}{extension}";
logger.LogInfo($"Identical trap file for {TrapFile} already exists, renaming to {newTrapName}");
if (TryMove(tmpFile, $"{newTrapName}"))
return;
}
logger.LogInfo($"Identical trap file for {TrapFile} already exists");
@@ -217,16 +220,16 @@ namespace Semmle.Extraction
{
switch (compression)
{
case CompressionMode.None: return "";
case CompressionMode.Gzip: return ".gz";
case CompressionMode.Brotli: return ".br";
case CompressionMode.None: return ".trap";
case CompressionMode.Gzip: return ".trap.gz";
case CompressionMode.Brotli: return ".trap.br";
default: throw new ArgumentOutOfRangeException(nameof(compression), compression, "Unsupported compression type");
}
}
public static string TrapPath(ILogger logger, string? folder, PathTransformer.ITransformedPath path, TrapWriter.CompressionMode trapCompression)
{
var filename = $"{path.Value}.trap{TrapExtension(trapCompression)}";
var filename = $"{path.Value}{TrapExtension(trapCompression)}";
if (string.IsNullOrEmpty(folder))
folder = Directory.GetCurrentDirectory();