mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
C#: Address review comments. Tidy up tuple generation, consolidating code and use run-time type information instead of FirstParam/NextParam.
This commit is contained in:
@@ -247,7 +247,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetPrimitiveTypeCode(out PrimitiveTypeCode code)
|
||||
private bool TryGetPrimitiveTypeCode(out PrimitiveTypeCode code)
|
||||
{
|
||||
if (ContainingType == null && Namespace.Name == cx.SystemNamespace.Name)
|
||||
{
|
||||
@@ -314,7 +314,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsPrimitiveType => TryGetPrimitiveTypeCode(out _);
|
||||
protected bool IsPrimitiveType => TryGetPrimitiveTypeCode(out _);
|
||||
|
||||
public static Type DecodeType(GenericContext gc, TypeSpecificationHandle handle) =>
|
||||
gc.cx.mdReader.GetTypeSpecification(handle).DecodeSignature(gc.cx.TypeSignatureDecoder, gc);
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Semmle.Extraction.CIL
|
||||
|
||||
public T Populate<T>(T e) where T : IExtractedEntity
|
||||
{
|
||||
if(e.Label.Valid)
|
||||
if (e.Label.Valid)
|
||||
{
|
||||
return e; // Already populated
|
||||
}
|
||||
@@ -72,7 +72,7 @@ namespace Semmle.Extraction.CIL
|
||||
{
|
||||
PrimitiveType e = primitiveTypes[(int)code];
|
||||
|
||||
if(e is null)
|
||||
if (e is null)
|
||||
{
|
||||
e = new PrimitiveType(this, code);
|
||||
e.Label = cx.GetNewLabel();
|
||||
@@ -157,7 +157,7 @@ namespace Semmle.Extraction.CIL
|
||||
/// <returns>The string.</returns>
|
||||
public string GetString(StringHandle h) => mdReader.GetString(h);
|
||||
|
||||
#region Namespaces
|
||||
#region Namespaces
|
||||
|
||||
readonly CachedFunction<StringHandle, Namespace> namespaceFactory;
|
||||
|
||||
@@ -197,9 +197,9 @@ namespace Semmle.Extraction.CIL
|
||||
NamespaceDefinition nd = mdReader.GetNamespaceDefinition(handle);
|
||||
return Populate(new Namespace(this, GetString(nd.Name), Create(nd.Parent)));
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Locations
|
||||
#region Locations
|
||||
readonly CachedFunction<PDB.ISourceFile, PdbSourceFile> sourceFiles;
|
||||
readonly CachedFunction<string, Folder> folders;
|
||||
readonly CachedFunction<PDB.Location, PdbSourceLocation> sourceLocations;
|
||||
@@ -225,7 +225,7 @@ namespace Semmle.Extraction.CIL
|
||||
/// <returns>A source location entity.</returns>
|
||||
public PdbSourceLocation CreateSourceLocation(PDB.Location loc) => sourceLocations[loc];
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
readonly CachedFunction<GenericContext, Handle, IExtractedEntity> genericHandleFactory;
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void accessors(this TextWriter trapFile, Accessor accessorKey, int kind, string name, Property propKey, Accessor unboundAccessor)
|
||||
{
|
||||
trapFile.BeginTuple("accessors").Param(accessorKey).Param(kind).Param(name).Param(propKey).Param(unboundAccessor).EndTuple();
|
||||
trapFile.WriteTuple("accessors", accessorKey, kind, name, propKey, unboundAccessor);
|
||||
}
|
||||
|
||||
internal static void array_element_type(this TextWriter trapFile, ArrayType array, int dimension, int rank, Type elementType)
|
||||
{
|
||||
trapFile.BeginTuple("array_element_type").Param(array).Param(dimension).Param(rank).Param(elementType).EndTuple();
|
||||
trapFile.WriteTuple("array_element_type", array, dimension, rank, elementType);
|
||||
}
|
||||
|
||||
internal static void attributes(this TextWriter trapFile, Attribute attribute, Type attributeType, IEntity entity)
|
||||
@@ -43,7 +43,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void catch_type(this TextWriter trapFile, Entities.Statements.Catch @catch, Type type, bool explicityCaught)
|
||||
{
|
||||
trapFile.BeginTuple("catch_type").Param(@catch).Param(type).Param(explicityCaught ? 1 : 2).EndTuple();
|
||||
trapFile.WriteTuple("catch_type", @catch, type, explicityCaught ? 1 : 2);
|
||||
}
|
||||
|
||||
internal static void commentblock(this TextWriter trapFile, CommentBlock k)
|
||||
@@ -53,12 +53,12 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void commentblock_binding(this TextWriter trapFile, CommentBlock commentBlock, Label entity, CommentBinding binding)
|
||||
{
|
||||
trapFile.BeginTuple("commentblock_binding").Param(commentBlock).Param(entity).Param((int)binding).EndTuple();
|
||||
trapFile.WriteTuple("commentblock_binding", commentBlock, entity, (int)binding);
|
||||
}
|
||||
|
||||
internal static void commentblock_child(this TextWriter trapFile, CommentBlock commentBlock, CommentLine commentLine, int child)
|
||||
{
|
||||
trapFile.BeginTuple("commentblock_child").Param(commentBlock).Param(commentLine).Param(child).EndTuple();
|
||||
trapFile.WriteTuple("commentblock_child", commentBlock, commentLine, child);
|
||||
}
|
||||
|
||||
internal static void commentblock_location(this TextWriter trapFile, CommentBlock k, Location l)
|
||||
@@ -68,7 +68,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void commentline(this TextWriter trapFile, CommentLine commentLine, CommentLineType type, string text, string rawtext)
|
||||
{
|
||||
trapFile.BeginTuple("commentline").Param(commentLine).Param((int)type).Param(text).Param(rawtext).EndTuple();
|
||||
trapFile.WriteTuple("commentline", commentLine, (int)type, text, rawtext);
|
||||
}
|
||||
|
||||
internal static void commentline_location(this TextWriter trapFile, CommentLine commentLine, Location location)
|
||||
@@ -78,32 +78,32 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void compilation_args(this TextWriter trapFile, Compilation compilation, int index, string arg)
|
||||
{
|
||||
trapFile.BeginTuple("compilation_args").Param(compilation).Param(index).Param(arg).EndTuple();
|
||||
trapFile.WriteTuple("compilation_args", compilation, index, arg);
|
||||
}
|
||||
|
||||
internal static void compilation_compiling_files(this TextWriter trapFile, Compilation compilation, int index, Extraction.Entities.File file)
|
||||
{
|
||||
trapFile.BeginTuple("compilation_compiling_files").Param(compilation).Param(index).Param(file).EndTuple();
|
||||
trapFile.WriteTuple("compilation_compiling_files", compilation, index, file);
|
||||
}
|
||||
|
||||
internal static void compilation_referencing_files(this TextWriter trapFile, Compilation compilation, int index, Extraction.Entities.File file)
|
||||
{
|
||||
trapFile.BeginTuple("compilation_referencing_files").Param(compilation).Param(index).Param(file).EndTuple();
|
||||
trapFile.WriteTuple("compilation_referencing_files", compilation, index, file);
|
||||
}
|
||||
|
||||
internal static void compilation_finished(this TextWriter trapFile, Compilation compilation, float cpuSeconds, float elapsedSeconds)
|
||||
{
|
||||
trapFile.BeginTuple("compilation_finished").Param(compilation).Param(cpuSeconds).Param(elapsedSeconds).EndTuple();
|
||||
trapFile.WriteTuple("compilation_finished", compilation, cpuSeconds, elapsedSeconds);
|
||||
}
|
||||
|
||||
internal static void compilation_time(this TextWriter trapFile, Compilation compilation, int num, int index, float metric)
|
||||
{
|
||||
trapFile.BeginTuple("compilation_time").Param(compilation).Param(num).Param(index).Param(metric).EndTuple();
|
||||
trapFile.WriteTuple("compilation_time", compilation, num, index, metric);
|
||||
}
|
||||
|
||||
internal static void compilations(this TextWriter trapFile, Compilation compilation, string cwd)
|
||||
{
|
||||
trapFile.BeginTuple("compilations").Param(compilation).Param(cwd).EndTuple();
|
||||
trapFile.WriteTuple("compilations", compilation, cwd);
|
||||
}
|
||||
|
||||
internal static void compiler_generated(this TextWriter trapFile, IEntity entity)
|
||||
@@ -118,7 +118,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void constant_value(this TextWriter trapFile, IEntity field, string value)
|
||||
{
|
||||
trapFile.BeginTuple("constant_value").Param(field).Param(value).EndTuple();
|
||||
trapFile.WriteTuple("constant_value", field, value);
|
||||
}
|
||||
|
||||
internal static void constructed_generic(this TextWriter trapFile, IEntity constructedTypeOrMethod, IEntity unboundTypeOrMethod)
|
||||
@@ -153,17 +153,17 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void diagnostic_for(this TextWriter trapFile, Diagnostic diag, Compilation comp, int fileNo, int index)
|
||||
{
|
||||
trapFile.BeginTuple("diagnostic_for").Param(diag).Param(comp).Param(fileNo).Param(index).EndTuple();
|
||||
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)
|
||||
{
|
||||
trapFile.BeginTuple("diagnostics").Param(diag).Param(severity).Param(errorTag).Param(errorMessage).Param(fullErrorMessage).Param(location).EndTuple();
|
||||
trapFile.WriteTuple("diagnostics", diag, severity, errorTag, errorMessage, fullErrorMessage, location);
|
||||
}
|
||||
|
||||
internal static void dynamic_member_name(this TextWriter trapFile, Expression e, string name)
|
||||
{
|
||||
trapFile.BeginTuple("dynamic_member_name").Param(e).Param(name).EndTuple();
|
||||
trapFile.WriteTuple("dynamic_member_name", e, name);
|
||||
}
|
||||
|
||||
internal static void enum_underlying_type(this TextWriter trapFile, Type @enum, Type type)
|
||||
@@ -178,7 +178,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void event_accessors(this TextWriter trapFile, EventAccessor accessorKey, int type, string name, Event eventKey, EventAccessor unboundAccessor)
|
||||
{
|
||||
trapFile.BeginTuple("event_accessors").Param(accessorKey).Param(type).Param(name).Param(eventKey).Param(unboundAccessor).EndTuple();
|
||||
trapFile.WriteTuple("event_accessors", accessorKey, type, name, eventKey, unboundAccessor);
|
||||
}
|
||||
|
||||
internal static void event_location(this TextWriter trapFile, Event eventKey, Location locationKey)
|
||||
@@ -268,7 +268,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void fields(this TextWriter trapFile, Field field, int @const, string name, Type declaringType, Type fieldType, Field unboundKey)
|
||||
{
|
||||
trapFile.BeginTuple("fields").Param(field).Param(@const).Param(name).Param(declaringType).Param(fieldType).Param(unboundKey).EndTuple();
|
||||
trapFile.WriteTuple("fields", field, @const, name, declaringType, fieldType, unboundKey);
|
||||
}
|
||||
|
||||
internal static void general_type_parameter_constraints(this TextWriter trapFile, TypeParameterConstraints constraints, int hasKind)
|
||||
@@ -328,7 +328,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void localvars(this TextWriter trapFile, LocalVariable key, int @const, string name, int @var, Type type, Expression expr)
|
||||
{
|
||||
trapFile.BeginTuple("localvars").Param(key).Param(@const).Param(name).Param(@var).Param(type).Param(expr).EndTuple();
|
||||
trapFile.WriteTuple("localvars", key, @const, name, @var, type, expr);
|
||||
}
|
||||
|
||||
public static void metadata_handle(this TextWriter trapFile, IEntity entity, Location assembly, int handleValue)
|
||||
@@ -348,7 +348,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void modifiers(this TextWriter trapFile, Label entity, string modifier)
|
||||
{
|
||||
trapFile.BeginTuple("modifiers").Param(entity).Param(modifier).EndTuple();
|
||||
trapFile.WriteTuple("modifiers", entity, modifier);
|
||||
}
|
||||
|
||||
internal static void mutator_invocation_mode(this TextWriter trapFile, Expression expr, int mode)
|
||||
@@ -383,7 +383,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void numlines(this TextWriter trapFile, IEntity label, LineCounts lineCounts)
|
||||
{
|
||||
trapFile.BeginTuple("numlines").Param(label).Param(lineCounts.Total).Param(lineCounts.Code).Param(lineCounts.Comment).EndTuple();
|
||||
trapFile.WriteTuple("numlines", label, lineCounts.Total, lineCounts.Code, lineCounts.Comment);
|
||||
}
|
||||
|
||||
internal static void operator_location(this TextWriter trapFile, UserOperator @operator, Location location)
|
||||
@@ -393,7 +393,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void operators(this TextWriter trapFile, UserOperator method, string methodName, string symbol, Type classKey, Type returnType, UserOperator originalDefinition)
|
||||
{
|
||||
trapFile.BeginTuple("operators").Param(method).Param(methodName).Param(symbol).Param(classKey).Param(returnType).Param(originalDefinition).EndTuple();
|
||||
trapFile.WriteTuple("operators", method, methodName, symbol, classKey, returnType, originalDefinition);
|
||||
}
|
||||
|
||||
internal static void overrides(this TextWriter trapFile, Method overriding, Method overridden)
|
||||
@@ -408,7 +408,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void @params(this TextWriter trapFile, Parameter param, string name, Type type, int child, Parameter.Kind mode, IEntity method, Parameter originalDefinition)
|
||||
{
|
||||
trapFile.BeginTuple("params").Param(param).Param(name).Param(type).Param(child).Param((int)mode).Param(method).Param(originalDefinition).EndTuple();
|
||||
trapFile.WriteTuple("params", param, name, type, child, (int)mode, method, originalDefinition);
|
||||
}
|
||||
|
||||
internal static void parent_namespace(this TextWriter trapFile, IEntity type, Namespace parent)
|
||||
@@ -513,7 +513,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void type_parameters(this TextWriter trapFile, TypeParameter param, int child, IEntity typeOrMethod)
|
||||
{
|
||||
trapFile.BeginTuple("type_parameters").Param(param).Param(child).Param(typeOrMethod).Param((int)param.Variance).EndTuple();
|
||||
trapFile.WriteTuple("type_parameters", param, child, typeOrMethod, (int)param.Variance);
|
||||
}
|
||||
|
||||
internal static void typeref_type(this TextWriter trapFile, NamedTypeRef typeref, Type type)
|
||||
@@ -528,7 +528,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void types(this TextWriter trapFile, Type type, TypeKind kind, string name)
|
||||
{
|
||||
trapFile.BeginTuple("types").Param(type).Param((int)kind).Param(name).EndTuple();
|
||||
trapFile.WriteTuple("types", type, (int)kind, name);
|
||||
}
|
||||
|
||||
internal static void using_namespace_directives(this TextWriter trapFile, UsingDirective @using, Namespace ns)
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace Semmle.Extraction.Tests
|
||||
Content = content;
|
||||
}
|
||||
|
||||
public void EmitToTrapBuilder(TextWriter trapFile)
|
||||
public void EmitTrap(TextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(Content);
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ namespace Semmle.Extraction
|
||||
Key = key;
|
||||
}
|
||||
|
||||
public void EmitToTrapBuilder(TextWriter trapFile)
|
||||
public void EmitTrap(TextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(".push ");
|
||||
Key.AppendTo(trapFile);
|
||||
@@ -342,7 +342,7 @@ namespace Semmle.Extraction
|
||||
|
||||
class PopEmitter : ITrapEmitter
|
||||
{
|
||||
public void EmitToTrapBuilder(TextWriter trapFile)
|
||||
public void EmitTrap(TextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteLine(".pop");
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Semmle.Extraction
|
||||
{
|
||||
public static class TrapBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Appends a [comma] separated list to a trap builder.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the list.</typeparam>
|
||||
/// <param name="trapFile">The trap builder to append to.</param>
|
||||
/// <param name="separator">The separator string (e.g. ",")</param>
|
||||
/// <param name="items">The list of items.</param>
|
||||
/// <returns>The original trap builder (fluent interface).</returns>
|
||||
public static TextWriter AppendList<T>(this TextWriter trapFile, string separator, IEnumerable<T> items) where T:IEntity
|
||||
{
|
||||
return trapFile.BuildList(separator, items, (x, tb0) => { tb0.WriteSubId(x); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a trap builder using a separator and an action for each item in the list.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items.</typeparam>
|
||||
/// <param name="trapFile">The trap builder to append to.</param>
|
||||
/// <param name="separator">The separator string (e.g. ",")</param>
|
||||
/// <param name="items">The list of items.</param>
|
||||
/// <param name="action">The action on each item.</param>
|
||||
/// <returns>The original trap builder (fluent interface).</returns>
|
||||
public static TextWriter BuildList<T>(this TextWriter trapFile, string separator, IEnumerable<T> items, Action<T, TextWriter> action)
|
||||
{
|
||||
bool first = true;
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (first) first = false; else trapFile.Write(separator);
|
||||
action(item, trapFile);
|
||||
}
|
||||
return trapFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Semmle.Extraction
|
||||
{
|
||||
@@ -27,85 +29,57 @@ namespace Semmle.Extraction
|
||||
if (index++ > 0) trapFile.Write(separator);
|
||||
}
|
||||
|
||||
public struct FirstParam
|
||||
|
||||
public static TextWriter WriteColumn(this TextWriter trapFile, int i)
|
||||
{
|
||||
private readonly TextWriter Writer;
|
||||
|
||||
public FirstParam(TextWriter trapFile)
|
||||
{
|
||||
Writer = trapFile;
|
||||
}
|
||||
|
||||
public NextParam Param(IEntity entity)
|
||||
{
|
||||
Writer.WriteLabel(entity.Label.Value);
|
||||
return new NextParam(Writer);
|
||||
}
|
||||
|
||||
public NextParam Param(Label label)
|
||||
{
|
||||
Writer.WriteLabel(label.Value);
|
||||
return new NextParam(Writer);
|
||||
}
|
||||
|
||||
public void EndTuple()
|
||||
{
|
||||
Writer.WriteLine(')');
|
||||
}
|
||||
trapFile.Write(i);
|
||||
return trapFile;
|
||||
}
|
||||
|
||||
public struct NextParam
|
||||
public static TextWriter WriteColumn(this TextWriter trapFile, string s)
|
||||
{
|
||||
private readonly TextWriter Writer;
|
||||
trapFile.WriteTrapString(s);
|
||||
return trapFile;
|
||||
}
|
||||
|
||||
public NextParam(TextWriter trapFile)
|
||||
{
|
||||
Writer = trapFile;
|
||||
}
|
||||
public static TextWriter WriteColumn(this TextWriter trapFile, IEntity entity)
|
||||
{
|
||||
trapFile.WriteLabel(entity.Label.Value);
|
||||
return trapFile;
|
||||
}
|
||||
|
||||
private void WriteComma()
|
||||
{
|
||||
Writer.Write(", ");
|
||||
}
|
||||
public static TextWriter WriteColumn(this TextWriter trapFile, Label label)
|
||||
{
|
||||
trapFile.WriteLabel(label.Value);
|
||||
return trapFile;
|
||||
}
|
||||
|
||||
public NextParam Param(string str)
|
||||
{
|
||||
WriteComma();
|
||||
Writer.WriteTrapString(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public NextParam Param(float f)
|
||||
{
|
||||
WriteComma();
|
||||
Writer.WriteTrapFloat(f);
|
||||
return this;
|
||||
}
|
||||
public static TextWriter WriteColumn(this TextWriter trapFile, float f)
|
||||
{
|
||||
trapFile.WriteTrapFloat(f);
|
||||
return trapFile;
|
||||
}
|
||||
|
||||
public NextParam Param(Label label)
|
||||
{
|
||||
WriteComma();
|
||||
Writer.WriteLabel(label.Value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public NextParam Param(int i)
|
||||
public static TextWriter WriteColumn(this TextWriter trapFile, object o)
|
||||
{
|
||||
switch (o)
|
||||
{
|
||||
WriteComma();
|
||||
Writer.Write(i);
|
||||
return this;
|
||||
}
|
||||
|
||||
public NextParam Param(IEntity e)
|
||||
{
|
||||
WriteComma();
|
||||
Writer.WriteLabel(e.Label.Value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void EndTuple()
|
||||
{
|
||||
Writer.WriteLine(')');
|
||||
case int i:
|
||||
return trapFile.WriteColumn(i);
|
||||
case float f:
|
||||
return trapFile.WriteColumn(f);
|
||||
case string s:
|
||||
return trapFile.WriteColumn(s);
|
||||
case IEntity e:
|
||||
return trapFile.WriteColumn(e);
|
||||
case Label l:
|
||||
return trapFile.WriteColumn(l);
|
||||
case Enum _:
|
||||
return trapFile.WriteColumn((int)o);
|
||||
default:
|
||||
throw new ArgumentException(nameof(o));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,66 +159,94 @@ namespace Semmle.Extraction
|
||||
trapFile.Write(f.ToString("0.#####e0")); // Trap importer won't accept ints
|
||||
}
|
||||
|
||||
public static FirstParam BeginTuple(this TextWriter trapFile, string name)
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, params object[] @params)
|
||||
{
|
||||
trapFile.Write(name);
|
||||
trapFile.Write('(');
|
||||
return new FirstParam(trapFile);
|
||||
int index = 0;
|
||||
foreach (var p in @params)
|
||||
{
|
||||
trapFile.WriteSeparator(",", ref index);
|
||||
trapFile.WriteColumn(p);
|
||||
}
|
||||
trapFile.WriteLine(')');
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).EndTuple();
|
||||
trapFile.Write(name);
|
||||
trapFile.Write('(');
|
||||
trapFile.WriteColumn(p1);
|
||||
trapFile.WriteLine(')');
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, IEntity p2)
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, object p2)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).EndTuple();
|
||||
trapFile.Write(name);
|
||||
trapFile.Write('(');
|
||||
trapFile.WriteColumn(p1);
|
||||
trapFile.Write(',');
|
||||
trapFile.WriteColumn(p2);
|
||||
trapFile.WriteLine(')');
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, string p2, IEntity p3, IEntity p4)
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, object p2, object p3)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).Param(p4).EndTuple();
|
||||
trapFile.Write(name);
|
||||
trapFile.Write('(');
|
||||
trapFile.WriteColumn(p1);
|
||||
trapFile.Write(',');
|
||||
trapFile.WriteColumn(p2);
|
||||
trapFile.Write(',');
|
||||
trapFile.WriteColumn(p3);
|
||||
trapFile.WriteLine(')');
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, string p2, IEntity p3)
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, object p2, object p3, object p4)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
|
||||
trapFile.Write(name);
|
||||
trapFile.Write('(');
|
||||
trapFile.WriteColumn(p1);
|
||||
trapFile.Write(',');
|
||||
trapFile.WriteColumn(p2);
|
||||
trapFile.Write(',');
|
||||
trapFile.WriteColumn(p3);
|
||||
trapFile.Write(',');
|
||||
trapFile.WriteColumn(p4);
|
||||
trapFile.WriteLine(')');
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, int p2, IEntity p3)
|
||||
/// <summary>
|
||||
/// Appends a [comma] separated list to a trap builder.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the list.</typeparam>
|
||||
/// <param name="trapFile">The trap builder to append to.</param>
|
||||
/// <param name="separator">The separator string (e.g. ",")</param>
|
||||
/// <param name="items">The list of items.</param>
|
||||
/// <returns>The original trap builder (fluent interface).</returns>
|
||||
public static TextWriter AppendList<T>(this TextWriter trapFile, string separator, IEnumerable<T> items) where T : IEntity
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
|
||||
return trapFile.BuildList(separator, items, (x, tb0) => { tb0.WriteSubId(x); });
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, int p2, int p3)
|
||||
/// <summary>
|
||||
/// Builds a trap builder using a separator and an action for each item in the list.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items.</typeparam>
|
||||
/// <param name="trapFile">The trap builder to append to.</param>
|
||||
/// <param name="separator">The separator string (e.g. ",")</param>
|
||||
/// <param name="items">The list of items.</param>
|
||||
/// <param name="action">The action on each item.</param>
|
||||
/// <returns>The original trap builder (fluent interface).</returns>
|
||||
public static TextWriter BuildList<T>(this TextWriter trapFile, string separator, IEnumerable<T> items, Action<T, TextWriter> action)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, IEntity p2, int p3)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, IEntity p2, IEntity p3)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, string p2, IEntity p3, IEntity p4, IEntity p5)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).Param(p4).Param(p5).EndTuple();
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, int p2)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).EndTuple();
|
||||
}
|
||||
|
||||
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, string p2)
|
||||
{
|
||||
trapFile.BeginTuple(name).Param(p1).Param(p2).EndTuple();
|
||||
bool first = true;
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (first) first = false; else trapFile.Write(separator);
|
||||
action(item, trapFile);
|
||||
}
|
||||
return trapFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Semmle.Extraction
|
||||
{
|
||||
public interface ITrapEmitter
|
||||
{
|
||||
void EmitToTrapBuilder(TextWriter trapFile);
|
||||
void EmitTrap(TextWriter trapFile);
|
||||
}
|
||||
|
||||
public sealed class TrapWriter : IDisposable
|
||||
@@ -202,7 +202,7 @@ namespace Semmle.Extraction
|
||||
|
||||
public void Emit(ITrapEmitter emitter)
|
||||
{
|
||||
emitter.EmitToTrapBuilder(Writer);
|
||||
emitter.EmitTrap(Writer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction
|
||||
{
|
||||
@@ -17,139 +16,13 @@ namespace Semmle.Extraction
|
||||
Args = args;
|
||||
}
|
||||
|
||||
const int maxStringBytes = 1<<20; // 1MB
|
||||
static readonly System.Text.Encoding encoding = System.Text.Encoding.UTF8;
|
||||
|
||||
private static bool NeedsTruncation(string s)
|
||||
{
|
||||
// Optimization: only count the actual number of bytes if there is the possibility
|
||||
// of the string exceeding maxStringBytes
|
||||
return encoding.GetMaxByteCount(s.Length) > maxStringBytes &&
|
||||
encoding.GetByteCount(s) > maxStringBytes;
|
||||
}
|
||||
|
||||
private static bool NeedsTruncation(string[] array)
|
||||
{
|
||||
// Optimization: only count the actual number of bytes if there is the possibility
|
||||
// of the strings exceeding maxStringBytes
|
||||
return encoding.GetMaxByteCount(array.Sum(s => s.Length)) > maxStringBytes &&
|
||||
array.Sum(encoding.GetByteCount) > maxStringBytes;
|
||||
}
|
||||
|
||||
private static void WriteString(TextWriter trapFile, string s) => trapFile.Write(EncodeString(s));
|
||||
|
||||
/// <summary>
|
||||
/// Truncates a string such that the output UTF8 does not exceed <paramref name="bytesRemaining"/> bytes.
|
||||
/// </summary>
|
||||
/// <param name="s">The input string to truncate.</param>
|
||||
/// <param name="bytesRemaining">The number of bytes available.</param>
|
||||
/// <returns>The truncated string.</returns>
|
||||
private static string TruncateString(string s, ref int bytesRemaining)
|
||||
{
|
||||
int outputLen = encoding.GetByteCount(s);
|
||||
if (outputLen > bytesRemaining)
|
||||
{
|
||||
outputLen = 0;
|
||||
int chars;
|
||||
for (chars = 0; chars < s.Length; ++chars)
|
||||
{
|
||||
var bytes = encoding.GetByteCount(s, chars, 1);
|
||||
if (outputLen + bytes <= bytesRemaining)
|
||||
outputLen += bytes;
|
||||
else
|
||||
break;
|
||||
}
|
||||
s = s.Substring(0, chars);
|
||||
}
|
||||
bytesRemaining -= outputLen;
|
||||
return s;
|
||||
}
|
||||
|
||||
private static string EncodeString(string s) => s.Replace("\"", "\"\"");
|
||||
|
||||
/// <summary>
|
||||
/// Output a string to the trap file, such that the encoded output does not exceed
|
||||
/// <paramref name="bytesRemaining"/> bytes.
|
||||
/// </summary>
|
||||
/// <param name="trapFile">The trapbuilder</param>
|
||||
/// <param name="s">The string to output.</param>
|
||||
/// <param name="bytesRemaining">The remaining bytes available to output.</param>
|
||||
private static void WriteTruncatedString(TextWriter trapFile, string s, ref int bytesRemaining)
|
||||
{
|
||||
WriteString(trapFile, TruncateString(s, ref bytesRemaining));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a unique string for this tuple.
|
||||
/// </summary>
|
||||
/// <param name="trapFile">The trap builder used to store the result.</param>
|
||||
public void EmitToTrapBuilder(TextWriter trapFile)
|
||||
/// <param name="trapFile">The trap file to write to.</param>
|
||||
public void EmitTrap(TextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(Name);
|
||||
trapFile.Write("(");
|
||||
|
||||
int column = 0;
|
||||
foreach (var a in Args)
|
||||
{
|
||||
trapFile.WriteSeparator(", ", ref column);
|
||||
switch(a)
|
||||
{
|
||||
case Label l:
|
||||
l.AppendTo(trapFile);
|
||||
break;
|
||||
case IEntity e:
|
||||
e.Label.AppendTo(trapFile);
|
||||
break;
|
||||
case string s:
|
||||
trapFile.Write("\"");
|
||||
if (NeedsTruncation(s))
|
||||
{
|
||||
// Slow path
|
||||
int remaining = maxStringBytes;
|
||||
WriteTruncatedString(trapFile, s, ref remaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fast path
|
||||
WriteString(trapFile, s);
|
||||
}
|
||||
trapFile.Write("\"");
|
||||
break;
|
||||
case System.Enum _:
|
||||
trapFile.Write((int)a);
|
||||
break;
|
||||
case int i:
|
||||
trapFile.Write(i);
|
||||
break;
|
||||
case float f:
|
||||
trapFile.Write(f.ToString("0.#####e0")); // Trap importer won't accept ints
|
||||
break;
|
||||
case string[] array:
|
||||
trapFile.Write('\"');
|
||||
if (NeedsTruncation(array))
|
||||
{
|
||||
// Slow path
|
||||
int remaining = maxStringBytes;
|
||||
foreach (var element in array)
|
||||
WriteTruncatedString(trapFile, element, ref remaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fast path
|
||||
foreach (var element in array)
|
||||
WriteString(trapFile, element);
|
||||
}
|
||||
trapFile.Write('\"');
|
||||
break;
|
||||
case null:
|
||||
throw new InternalError($"Attempt to write a null argument tuple {Name} at column {column}");
|
||||
default:
|
||||
throw new InternalError($"Attempt to write an invalid argument type {a.GetType()} in tuple {Name} at column {column}");
|
||||
}
|
||||
|
||||
++column;
|
||||
}
|
||||
trapFile.WriteLine(")");
|
||||
trapFile.WriteTuple(Name, Args);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@@ -157,7 +30,7 @@ namespace Semmle.Extraction
|
||||
// Only implemented for debugging purposes
|
||||
using (var writer = new StringWriter())
|
||||
{
|
||||
EmitToTrapBuilder(writer);
|
||||
EmitTrap(writer);
|
||||
return writer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,42 +10,42 @@ namespace Semmle.Extraction
|
||||
{
|
||||
public static void assemblies(this System.IO.TextWriter trapFile, Assembly assembly, File file, string identifier, string name, string version)
|
||||
{
|
||||
trapFile.BeginTuple("assemblies").Param(assembly).Param(file).Param(identifier).Param(name).Param(version).EndTuple();
|
||||
trapFile.WriteTuple("assemblies", assembly, file, identifier, name, version);
|
||||
}
|
||||
|
||||
public static void containerparent(this System.IO.TextWriter trapFile, Folder parent, IEntity child)
|
||||
{
|
||||
trapFile.BeginTuple("containerparent").Param(parent).Param(child).EndTuple();
|
||||
trapFile.WriteTuple("containerparent", parent, child);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
trapFile.BeginTuple("extractor_messages").Param(error).Param((int)severity).Param(origin).Param(errorMessage).Param(entityText).Param(location).Param(stackTrace).EndTuple();
|
||||
trapFile.WriteTuple("extractor_messages", error, (int)severity, origin, errorMessage, entityText, location, stackTrace);
|
||||
}
|
||||
|
||||
internal static void file_extraction_mode(this System.IO.TextWriter trapFile, Entities.File file, int mode)
|
||||
{
|
||||
trapFile.BeginTuple("file_extraction_mode").Param(file).Param(mode).EndTuple();
|
||||
trapFile.WriteTuple("file_extraction_mode", file, mode);
|
||||
}
|
||||
|
||||
public static void files(this System.IO.TextWriter trapFile, File file, string fullName, string name, string extension)
|
||||
{
|
||||
trapFile.BeginTuple("files").Param(file).Param(fullName).Param(name).Param(extension).Param(0).EndTuple();
|
||||
trapFile.WriteTuple("files", file, fullName, name, extension, 0);
|
||||
}
|
||||
|
||||
public static void folders(this System.IO.TextWriter trapFile, Folder folder, string path, string name)
|
||||
{
|
||||
trapFile.BeginTuple("folders").Param(folder).Param(path).Param(name).EndTuple();
|
||||
trapFile.WriteTuple("folders", folder, path, name);
|
||||
}
|
||||
|
||||
public static void locations_default(this System.IO.TextWriter trapFile, SourceLocation label, Entities.File file, int startLine, int startCol, int endLine, int endCol)
|
||||
{
|
||||
trapFile.BeginTuple("locations_default").Param(label).Param(file).Param(startLine).Param(startCol).Param(endLine).Param(endCol).EndTuple();
|
||||
trapFile.WriteTuple("locations_default", label, file, startLine, startCol, endLine, endCol);
|
||||
}
|
||||
|
||||
public static void numlines(this System.IO.TextWriter trapFile, IEntity label, LineCounts lineCounts)
|
||||
{
|
||||
trapFile.BeginTuple("numlines").Param(label).Param(lineCounts.Total).Param(lineCounts.Code).Param(lineCounts.Comment).EndTuple();
|
||||
trapFile.WriteTuple("numlines", label, lineCounts.Total, lineCounts.Code, lineCounts.Comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user