C#: Refactoring expression and statement population.

This commit is contained in:
Calum Grant
2019-08-09 16:52:53 +01:00
parent e41e8d6547
commit 486c192dda
110 changed files with 602 additions and 437 deletions

View File

@@ -387,8 +387,8 @@ namespace Semmle.Extraction
}
var a = duplicationGuard ?
(Action)(() => WithDuplicationGuard(new Key(entity, this.Create(entity.ReportingLocation)), entity.Populate)) :
(Action)(() => this.Try(null, optionalSymbol, entity.Populate));
(Action)(() => WithDuplicationGuard(new Key(entity, this.Create(entity.ReportingLocation)), () => entity.Populate(TrapWriter.Writer))) :
(Action)(() => this.Try(null, optionalSymbol, () => entity.Populate(TrapWriter.Writer)));
if (deferred)
populateQueue.Enqueue(a);

View File

@@ -1,4 +1,5 @@
using Microsoft.CodeAnalysis;
using System.IO;
namespace Semmle.Extraction.Entities
{
@@ -25,11 +26,11 @@ namespace Semmle.Extraction.Entities
}
}
public override void Populate()
public override void Populate(TextWriter trapFile)
{
if (assemblyPath != null)
{
Context.TrapWriter.assemblies(this, File.Create(Context, assemblyPath), assembly.ToString(),
trapFile.assemblies(this, File.Create(Context, assemblyPath), assembly.ToString(),
assembly.Identity.Name, assembly.Identity.Version.ToString());
}
}

View File

@@ -1,10 +1,20 @@
namespace Semmle.Extraction.Entities
using System.IO;
namespace Semmle.Extraction.Entities
{
class ExtractionMessage : FreshEntity
{
readonly Message msg;
public ExtractionMessage(Context cx, Message msg) : base(cx)
{
cx.TrapWriter.extractor_messages(this, msg.Severity, "C# extractor", msg.Text, msg.EntityText, msg.Location, msg.StackTrace);
this.msg = msg;
TryPopulate();
}
protected override void Populate(TextWriter trapFile)
{
trapFile.extractor_messages(this, msg.Severity, "C# extractor", msg.Text, msg.EntityText, msg.Location, msg.StackTrace);
}
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;

View File

@@ -23,11 +23,11 @@ namespace Semmle.Extraction.Entities
public override bool NeedsPopulation => Context.DefinesFile(Path) || Path == Context.Extractor.OutputPath;
public override void Populate()
public override void Populate(TextWriter trapFile)
{
if (Path == null)
{
Context.TrapWriter.files(this, "", "", "");
trapFile.files(this, "", "", "");
}
else
{
@@ -41,9 +41,9 @@ namespace Semmle.Extraction.Entities
// remove the dot from the extension
if (extension.Length > 0)
extension = extension.Substring(1);
Context.TrapWriter.files(this, PathAsDatabaseString(Path), name, extension);
trapFile.files(this, PathAsDatabaseString(Path), name, extension);
Context.TrapWriter.containerparent(Folder.Create(Context, fi.Directory), this);
trapFile.containerparent(Folder.Create(Context, fi.Directory), this);
if (fromSource == 1)
{
foreach (var text in Context.Compilation.SyntaxTrees.
@@ -54,12 +54,12 @@ namespace Semmle.Extraction.Entities
var lineCounts = LineCounter.ComputeLineCounts(rawText);
if (rawText.Length > 0 && rawText[rawText.Length - 1] != '\n') lineCounts.Total++;
Context.TrapWriter.numlines(this, lineCounts);
trapFile.numlines(this, lineCounts);
Context.TrapWriter.Archive(fi.FullName, text.Encoding);
}
}
Context.TrapWriter.file_extraction_mode(this, Context.Extractor.Standalone ? 1 : 0);
trapFile.file_extraction_mode(this, Context.Extractor.Standalone ? 1 : 0);
}
}
@@ -100,9 +100,9 @@ namespace Semmle.Extraction.Entities
public override bool NeedsPopulation => true;
public override void Populate()
public override void Populate(TextWriter trapFile)
{
Context.TrapWriter.files(this, "", "", "");
trapFile.files(this, "", "", "");
}
public override void WriteId(TextWriter trapFile)

View File

@@ -18,7 +18,7 @@ namespace Semmle.Extraction.Entities
public string DatabasePath => File.PathAsDatabaseId(Path);
public override void Populate()
public override void Populate(TextWriter trapFile)
{
// Ensure that the name of the root directory is consistent
// with the XmlTrapWriter.
@@ -27,10 +27,10 @@ namespace Semmle.Extraction.Entities
// On Windows: System.IO.DirectoryInfo.Name returns "L:\"
string shortName = symbol.Parent == null ? "" : symbol.Name;
Context.TrapWriter.folders(this, File.PathAsDatabaseString(Path), shortName);
trapFile.folders(this, File.PathAsDatabaseString(Path), shortName);
if (symbol.Parent != null)
{
Context.TrapWriter.containerparent(Create(Context, symbol.Parent), this);
trapFile.containerparent(Create(Context, symbol.Parent), this);
}
}

View File

@@ -12,9 +12,9 @@ namespace Semmle.Extraction.Entities
GeneratedFile = File.CreateGenerated(cx);
}
public override void Populate()
public override void Populate(TextWriter trapFile)
{
Context.TrapWriter.locations_default(this, GeneratedFile, 0, 0, 0, 0);
trapFile.locations_default(this, GeneratedFile, 0, 0, 0, 0);
}
public override void WriteId(TextWriter trapFile)

View File

@@ -10,11 +10,11 @@ namespace Semmle.Extraction.Entities
public new static Location Create(Context cx, Microsoft.CodeAnalysis.Location loc) => SourceLocationFactory.Instance.CreateEntity(cx, loc);
public override void Populate()
public override void Populate(TextWriter trapFile)
{
Position = symbol.GetLineSpan();
FileEntity = File.Create(Context, Position.Path);
Context.TrapWriter.locations_default(this, FileEntity, Position.Span.Start.Line + 1, Position.Span.Start.Character + 1,
trapFile.locations_default(this, FileEntity, Position.Span.Start.Line + 1, Position.Span.Start.Character + 1,
Position.Span.End.Line + 1, Position.Span.End.Character);
}

View File

@@ -87,7 +87,7 @@ namespace Semmle.Extraction
/// as required. Is only called when <see cref="NeedsPopulation"/> returns
/// <code>true</code> and the entity has not already been populated.
/// </summary>
void Populate();
void Populate(TextWriter trapFile);
bool NeedsPopulation { get; }

View File

@@ -1,4 +1,5 @@
using Semmle.Extraction.Entities;
using System;
using System.IO;
namespace Semmle.Extraction
@@ -31,9 +32,24 @@ namespace Semmle.Extraction
WriteId(writer);
}
public override string ToString() => Label.ToString();
protected abstract void Populate(TextWriter trapFile);
public IId Id => FreshId.Instance;
protected void TryPopulate()
{
cx.Try(null, null, () => Populate(cx.TrapWriter.Writer));
}
public string DebugTuples
{
get
{
var writer = new StringWriter();
Populate(writer);
return writer.ToString();
}
}
public override string ToString() => Label.ToString();
public virtual Microsoft.CodeAnalysis.Location ReportingLocation => null;

View File

@@ -20,7 +20,17 @@ namespace Semmle.Extraction
public override string ToString() => Label.ToString();
public abstract void Populate();
public abstract void Populate(TextWriter trapFile);
public string DebugTrapContents
{
get
{
var trap = new StringWriter();
Populate(trap);
return trap.ToString();
}
}
public Context Context
{

View File

@@ -8,44 +8,44 @@ namespace Semmle.Extraction
/// </summary>
static class Tuples
{
public static void assemblies(this TrapWriter writer, Assembly assembly, File file, string identifier, string name, string version)
public static void assemblies(this System.IO.TextWriter trapFile, Assembly assembly, File file, string identifier, string name, string version)
{
writer.Writer.BeginTuple("assemblies").Param(assembly).Param(file).Param(identifier).Param(name).Param(version).EndTuple();
trapFile.BeginTuple("assemblies").Param(assembly).Param(file).Param(identifier).Param(name).Param(version).EndTuple();
}
public static void containerparent(this TrapWriter writer, Folder parent, IEntity child)
public static void containerparent(this System.IO.TextWriter trapFile, Folder parent, IEntity child)
{
writer.Writer.BeginTuple("containerparent").Param(parent).Param(child).EndTuple();
trapFile.BeginTuple("containerparent").Param(parent).Param(child).EndTuple();
}
public static void extractor_messages(this TrapWriter writer, ExtractionMessage error, Semmle.Util.Logging.Severity severity, string origin, string errorMessage, string entityText, Location location, string stackTrace)
public static void extractor_messages(this System.IO.TextWriter trapFile, ExtractionMessage error, Semmle.Util.Logging.Severity severity, string origin, string errorMessage, string entityText, Location location, string stackTrace)
{
writer.Writer.BeginTuple("extractor_messages").Param(error).Param((int)severity).Param(origin).Param(errorMessage).Param(entityText).Param(location).Param(stackTrace).EndTuple();
trapFile.BeginTuple("extractor_messages").Param(error).Param((int)severity).Param(origin).Param(errorMessage).Param(entityText).Param(location).Param(stackTrace).EndTuple();
}
internal static void file_extraction_mode(this TrapWriter writer, Entities.File file, int mode)
internal static void file_extraction_mode(this System.IO.TextWriter trapFile, Entities.File file, int mode)
{
writer.Writer.BeginTuple("file_extraction_mode").Param(file).Param(mode).EndTuple();
trapFile.BeginTuple("file_extraction_mode").Param(file).Param(mode).EndTuple();
}
public static void files(this TrapWriter writer, Entities.File file, string fullName, string name, string extension)
public static void files(this System.IO.TextWriter trapFile, File file, string fullName, string name, string extension)
{
writer.Writer.BeginTuple("files").Param(file).Param(fullName).Param(name).Param(extension).Param(0).EndTuple();
trapFile.BeginTuple("files").Param(file).Param(fullName).Param(name).Param(extension).Param(0).EndTuple();
}
public static void folders(this TrapWriter writer, Folder folder, string path, string name)
public static void folders(this System.IO.TextWriter trapFile, Folder folder, string path, string name)
{
writer.Writer.BeginTuple("folders").Param(folder).Param(path).Param(name).EndTuple();
trapFile.BeginTuple("folders").Param(folder).Param(path).Param(name).EndTuple();
}
public static void locations_default(this TrapWriter writer, SourceLocation label, Entities.File file, int startLine, int startCol, int endLine, int endCol)
public static void locations_default(this System.IO.TextWriter trapFile, SourceLocation label, Entities.File file, int startLine, int startCol, int endLine, int endCol)
{
writer.Writer.BeginTuple("locations_default").Param(label).Param(file).Param(startLine).Param(startCol).Param(endLine).Param(endCol).EndTuple();
trapFile.BeginTuple("locations_default").Param(label).Param(file).Param(startLine).Param(startCol).Param(endLine).Param(endCol).EndTuple();
}
public static void numlines(this TrapWriter writer, IEntity label, LineCounts lineCounts)
public static void numlines(this System.IO.TextWriter trapFile, IEntity label, LineCounts lineCounts)
{
writer.Writer.BeginTuple("numlines").Param(label).Param(lineCounts.Total).Param(lineCounts.Code).Param(lineCounts.Comment).EndTuple();
trapFile.BeginTuple("numlines").Param(label).Param(lineCounts.Total).Param(lineCounts.Code).Param(lineCounts.Comment).EndTuple();
}
}
}