C#: Code tidy. Rename variables, delete dead code, format whitespace, improve comments.

This commit is contained in:
Calum Grant
2019-08-23 14:31:30 +01:00
parent b3d5e405a6
commit 40f56ff4b3
29 changed files with 359 additions and 306 deletions

View File

@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CIL
globalNamespace = new Lazy<Entities.Namespace>(() => Populate(new Entities.Namespace(this, "", null)));
systemNamespace = new Lazy<Entities.Namespace>(() => Populate(new Entities.Namespace(this, "System")));
genericHandleFactory = new CachedFunction<GenericContext, Handle, ILabelledEntity>(CreateGenericHandle);
genericHandleFactory = new CachedFunction<GenericContext, Handle, IExtractedEntity>(CreateGenericHandle);
namespaceFactory = new CachedFunction<StringHandle, Entities.Namespace>(n => CreateNamespace(mdReader.GetString(n)));
namespaceDefinitionFactory = new CachedFunction<NamespaceDefinitionHandle, Entities.Namespace>(CreateNamespace);
sourceFiles = new CachedFunction<PDB.ISourceFile, Entities.PdbSourceFile>(path => new Entities.PdbSourceFile(this, path));

View File

@@ -7,7 +7,7 @@ namespace Semmle.Extraction.CIL.Entities
/// <summary>
/// An event.
/// </summary>
interface IEvent : ILabelledEntity
interface IEvent : IExtractedEntity
{
}

View File

@@ -13,7 +13,7 @@ namespace Semmle.Extraction.CIL.Entities
/// An entity represting a member.
/// Used to type tuples correctly.
/// </summary>
interface IMember : ILabelledEntity
interface IMember : IExtractedEntity
{
}

View File

@@ -16,7 +16,6 @@ namespace Semmle.Extraction.CIL.Entities
this.path = path;
}
public override void WriteId(TextWriter trapFile)
{
trapFile.Write(Semmle.Extraction.Entities.File.PathAsDatabaseId(path));

View File

@@ -3,7 +3,7 @@ using System.IO;
namespace Semmle.Extraction.CIL.Entities
{
interface ILocal : ILabelledEntity
interface ILocal : IExtractedEntity
{
}

View File

@@ -64,7 +64,7 @@ namespace Semmle.Extraction.CIL.Entities
int index = 0;
foreach (var param in signature.ParameterTypes)
{
trapFile.WriteSeparator(",", index++);
trapFile.WriteSeparator(",", ref index);
param.WriteId(trapFile, this);
}
trapFile.Write(')');
@@ -503,7 +503,7 @@ namespace Semmle.Extraction.CIL.Entities
int index = 0;
foreach(var param in typeParams)
{
trapFile.WriteSeparator(",", index++);
trapFile.WriteSeparator(",", ref index);
trapFile.WriteSubId(param);
}
trapFile.Write('>');
@@ -516,10 +516,7 @@ namespace Semmle.Extraction.CIL.Entities
return obj is MethodSpecificationMethod method && handle.Equals(method.handle) && typeParams.SequenceEqual(method.typeParams);
}
public override int GetHashCode()
{
return handle.GetHashCode() * 11 + typeParams.SequenceHash();
}
public override int GetHashCode() => handle.GetHashCode() * 11 + typeParams.SequenceHash();
public override Method SourceDeclaration => unboundMethod;

View File

@@ -6,7 +6,7 @@ namespace Semmle.Extraction.CIL.Entities
/// <summary>
/// A parameter entity.
/// </summary>
interface IParameter : ILabelledEntity
interface IParameter : IExtractedEntity
{
}

View File

@@ -9,7 +9,7 @@ namespace Semmle.Extraction.CIL.Entities
/// <summary>
/// A property.
/// </summary>
interface IProperty : ILabelledEntity
interface IProperty : IExtractedEntity
{
}
@@ -42,11 +42,12 @@ namespace Semmle.Extraction.CIL.Entities
var signature = pd.DecodeSignature(new SignatureDecoder(), gc);
foreach (var param in signature.ParameterTypes)
{
trapFile.WriteSeparator(",", index++);
trapFile.WriteSeparator(",", ref index);
param.WriteId(trapFile, gc);
}
trapFile.Write(")");
}
public override bool Equals(object obj)
{
return obj is Property property && Equals(handle, property.handle);

View File

@@ -39,7 +39,7 @@ namespace Semmle.Extraction.CIL.Entities
/// <summary>
/// A type container (namespace/types/method).
/// </summary>
interface ITypeContainer : ILabelledEntity
interface ITypeContainer : IExtractedEntity
{
}
@@ -231,10 +231,9 @@ namespace Semmle.Extraction.CIL.Entities
/// <summary>
/// Gets the primitive type corresponding to this type, if possible.
/// </summary>
/// <param name="cx">Extraction context.</param>
/// <param name="t">The resulting primitive type.</param>
/// <param name="t">The resulting primitive type, or null.</param>
/// <returns>True if this type is a primitive type.</returns>
public bool TryGetPrimitiveType(Context cx, out PrimitiveType t)
public bool TryGetPrimitiveType(out PrimitiveType t)
{
if (TryGetPrimitiveTypeCode(out var code))
{
@@ -830,7 +829,7 @@ namespace Semmle.Extraction.CIL.Entities
int index = 0;
foreach (var t in thisTypeArguments)
{
trapFile.WriteSeparator(",", index++);
trapFile.WriteSeparator(",", ref index);
t.WriteId(trapFile);
}
trapFile.Write('>');
@@ -1253,7 +1252,7 @@ namespace Semmle.Extraction.CIL.Entities
int index = 0;
foreach(var arg in typeArguments)
{
trapFile.WriteSeparator(",", index++);
trapFile.WriteSeparator(",", ref index);
arg.WriteId(trapFile, gc);
}
trapFile.Write('>');

View File

@@ -12,7 +12,7 @@ namespace Semmle.Extraction.CIL
/// The extraction algorithm proceeds as follows:
/// - Construct entity
/// - Call Extract()
/// - ILabelledEntity check if already extracted
/// - IExtractedEntity check if already extracted
/// - Enumerate Contents to produce more extraction products
/// - Extract these until there is nothing left to extract
/// </remarks>
@@ -78,7 +78,7 @@ namespace Semmle.Extraction.CIL
/// An entity that needs to be populated during extraction.
/// This assigns a key and optionally extracts its contents.
/// </summary>
public abstract class LabelledEntity : ILabelledEntity
public abstract class LabelledEntity : IExtractedEntity
{
public abstract IEnumerable<IExtractionProduct> Contents { get; }
public Label Label { get; set; }
@@ -120,13 +120,6 @@ namespace Semmle.Extraction.CIL
TrapStackBehaviour IEntity.TrapStackBehaviour => TrapStackBehaviour.NoLabel;
}
/// <summary>
/// An entity with a defined ID.
/// </summary>
public interface ILabelledEntity : IExtractedEntity
{
}
/// <summary>
/// A tuple that is an extraction product.
/// </summary>

View File

@@ -13,7 +13,7 @@ namespace Semmle.Extraction.CIL
{
readonly Dictionary<object, Label> ids = new Dictionary<object, Label>();
public T Populate<T>(T e) where T : ILabelledEntity
public T Populate<T>(T e) where T : IExtractedEntity
{
if(e.Label.Valid)
{
@@ -41,7 +41,7 @@ namespace Semmle.Extraction.CIL
e.WriteId(writer);
var id = writer.ToString();
if (debugLabels.TryGetValue(id, out ILabelledEntity previousEntity))
if (debugLabels.TryGetValue(id, out IExtractedEntity previousEntity))
{
cx.Extractor.Message(new Message("Duplicate trap ID", id, null, severity: Util.Logging.Severity.Warning));
}
@@ -56,7 +56,7 @@ namespace Semmle.Extraction.CIL
}
#if DEBUG_LABELS
private readonly Dictionary<string, ILabelledEntity> debugLabels = new Dictionary<string, ILabelledEntity>();
private readonly Dictionary<string, IExtractedEntity> debugLabels = new Dictionary<string, IExtractedEntity>();
#endif
public IExtractedEntity Create(Handle h)
@@ -95,13 +95,13 @@ namespace Semmle.Extraction.CIL
/// <param name="h">The handle of the entity.</param>
/// <param name="genericContext">The generic context.</param>
/// <returns></returns>
public ILabelledEntity CreateGeneric(GenericContext genericContext, Handle h) => genericHandleFactory[genericContext, h];
public IExtractedEntity CreateGeneric(GenericContext genericContext, Handle h) => genericHandleFactory[genericContext, h];
readonly GenericContext defaultGenericContext;
ILabelledEntity CreateGenericHandle(GenericContext gc, Handle handle)
IExtractedEntity CreateGenericHandle(GenericContext gc, Handle handle)
{
ILabelledEntity entity;
IExtractedEntity entity;
switch (handle.Kind)
{
case HandleKind.MethodDefinition:
@@ -118,7 +118,8 @@ namespace Semmle.Extraction.CIL
break;
case HandleKind.TypeReference:
var tr = new TypeReferenceType(this, (TypeReferenceHandle)handle);
if (tr.TryGetPrimitiveType(gc.cx, out var pt))
if (tr.TryGetPrimitiveType(out var pt))
// Map special names like `System.Int32` to `int`
return pt;
entity = tr;
break;
@@ -135,7 +136,7 @@ namespace Semmle.Extraction.CIL
return entity;
}
ILabelledEntity Create(GenericContext gc, MemberReferenceHandle handle)
IExtractedEntity Create(GenericContext gc, MemberReferenceHandle handle)
{
var mr = mdReader.GetMemberReference(handle);
switch (mr.GetKind())
@@ -226,7 +227,7 @@ namespace Semmle.Extraction.CIL
#endregion
readonly CachedFunction<GenericContext, Handle, ILabelledEntity> genericHandleFactory;
readonly CachedFunction<GenericContext, Handle, IExtractedEntity> genericHandleFactory;
/// <summary>
/// Gets the short name of a member, without the preceding interface qualifier.

View File

@@ -22,10 +22,10 @@ namespace Semmle.Extraction.CSharp.Entities
public override bool NeedsPopulation => true;
public override void WriteId(TextWriter tw)
public override void WriteId(TextWriter trapFile)
{
tw.WriteSubId(Context.Create(symbol.Location));
tw.Write(";commentblock");
trapFile.WriteSubId(Context.Create(symbol.Location));
trapFile.Write(";commentblock");
}
public override Microsoft.CodeAnalysis.Location ReportingLocation => symbol.Location;

View File

@@ -123,10 +123,10 @@ namespace Semmle.Extraction.CSharp.Entities
public override bool NeedsPopulation => true;
public override void WriteId(TextWriter tw)
public override void WriteId(TextWriter trapFile)
{
tw.WriteSubId(Context.Create(Location));
tw.Write(";commentline");
trapFile.WriteSubId(Context.Create(Location));
trapFile.Write(";commentline");
}
static CommentLine Create(Context cx, Microsoft.CodeAnalysis.Location loc, CommentLineType type, string text, string raw) => CommentLineFactory.Instance.CreateEntity(cx, loc, type, text, raw);

View File

@@ -19,12 +19,12 @@ namespace Semmle.Extraction.CSharp.Entities
readonly bool IsVar;
readonly Extraction.Entities.Location DeclLocation;
public override void WriteId(TextWriter tw)
public override void WriteId(TextWriter trapFile)
{
tw.WriteSubId(Parent);
tw.Write('_');
tw.Write(symbol.Name);
tw.Write(";localvar");
trapFile.WriteSubId(Parent);
trapFile.Write('_');
trapFile.Write(symbol.Name);
trapFile.Write(";localvar");
}
public override void Populate(TextWriter trapFile)

View File

@@ -106,54 +106,54 @@ namespace Semmle.Extraction.CSharp.Entities
/// <summary>
/// Factored out to share logic between `Method` and `UserOperator`.
/// </summary>
protected static void BuildMethodId(Method m, TextWriter tw)
protected static void BuildMethodId(Method m, TextWriter trapFile)
{
tw.WriteSubId(m.ContainingType);
trapFile.WriteSubId(m.ContainingType);
AddExplicitInterfaceQualifierToId(m.Context, tw, m.symbol.ExplicitInterfaceImplementations);
AddExplicitInterfaceQualifierToId(m.Context, trapFile, m.symbol.ExplicitInterfaceImplementations);
tw.Write(".");
tw.Write(m.symbol.Name);
trapFile.Write(".");
trapFile.Write(m.symbol.Name);
if (m.symbol.IsGenericMethod)
{
if (Equals(m.symbol, m.symbol.OriginalDefinition))
{
tw.Write('`');
tw.Write(m.symbol.TypeParameters.Length);
trapFile.Write('`');
trapFile.Write(m.symbol.TypeParameters.Length);
}
else
{
tw.Write('<');
trapFile.Write('<');
// Encode the nullability of the type arguments in the label.
// Type arguments with different nullability can result in
// a constructed method with different nullability of its parameters and return type,
// so we need to create a distinct database entity for it.
tw.BuildList(",", m.symbol.GetAnnotatedTypeArguments(), (ta, tb0) => { AddSignatureTypeToId(m.Context, tb0, m.symbol, ta.Symbol); tw.Write((int)ta.Nullability); });
tw.Write('>');
trapFile.BuildList(",", m.symbol.GetAnnotatedTypeArguments(), (ta, tb0) => { AddSignatureTypeToId(m.Context, tb0, m.symbol, ta.Symbol); trapFile.Write((int)ta.Nullability); });
trapFile.Write('>');
}
}
AddParametersToId(m.Context, tw, m.symbol);
AddParametersToId(m.Context, trapFile, m.symbol);
switch (m.symbol.MethodKind)
{
case MethodKind.PropertyGet:
tw.Write(";getter");
trapFile.Write(";getter");
break;
case MethodKind.PropertySet:
tw.Write(";setter");
trapFile.Write(";setter");
break;
case MethodKind.EventAdd:
tw.Write(";adder");
trapFile.Write(";adder");
break;
case MethodKind.EventRaise:
tw.Write(";raiser");
trapFile.Write(";raiser");
break;
case MethodKind.EventRemove:
tw.Write(";remover");
trapFile.Write(";remover");
break;
default:
tw.Write(";method");
trapFile.Write(";method");
break;
}
}
@@ -164,7 +164,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
/// <summary>
/// Adds an appropriate label ID to the trap builder <paramref name="tb"/>
/// Adds an appropriate label ID to the trap builder <paramref name="trapFile"/>
/// for the type <paramref name="type"/> belonging to the signature of method
/// <paramref name="method"/>.
///
@@ -199,54 +199,54 @@ namespace Semmle.Extraction.CSharp.Entities
/// to make the reference to <code>#3</code> in the label definition <code>#4</code> for
/// <code>T</code> valid.
/// </summary>
protected static void AddSignatureTypeToId(Context cx, TextWriter tb, IMethodSymbol method, ITypeSymbol type)
protected static void AddSignatureTypeToId(Context cx, TextWriter trapFile, IMethodSymbol method, ITypeSymbol type)
{
if (type.ContainsTypeParameters(cx, method))
type.BuildTypeId(cx, tb, (cx0, tb0, type0) => AddSignatureTypeToId(cx, tb0, method, type0));
type.BuildTypeId(cx, trapFile, (cx0, tb0, type0) => AddSignatureTypeToId(cx, tb0, method, type0));
else
tb.WriteSubId(Type.Create(cx, type));
trapFile.WriteSubId(Type.Create(cx, type));
}
protected static void AddParametersToId(Context cx, TextWriter tb, IMethodSymbol method)
protected static void AddParametersToId(Context cx, TextWriter trapFile, IMethodSymbol method)
{
tb.Write('(');
trapFile.Write('(');
int index = 0;
if (method.MethodKind == MethodKind.ReducedExtension)
{
tb.WriteSeparator(",", index++);
AddSignatureTypeToId(cx, tb, method, method.ReceiverType);
trapFile.WriteSeparator(",", ref index);
AddSignatureTypeToId(cx, trapFile, method, method.ReceiverType);
}
foreach (var param in method.Parameters)
{
tb.WriteSeparator(",", index++);
AddSignatureTypeToId(cx, tb, method, param.Type);
trapFile.WriteSeparator(",", ref index);
AddSignatureTypeToId(cx, trapFile, method, param.Type);
switch (param.RefKind)
{
case RefKind.Out:
tb.Write(" out");
trapFile.Write(" out");
break;
case RefKind.Ref:
tb.Write(" ref");
trapFile.Write(" ref");
break;
}
}
if (method.IsVararg)
{
tb.WriteSeparator(",", index);
tb.Write("__arglist");
trapFile.WriteSeparator(",", ref index);
trapFile.Write("__arglist");
}
tb.Write(')');
trapFile.Write(')');
}
public static void AddExplicitInterfaceQualifierToId(Context cx, System.IO.TextWriter tw, IEnumerable<ISymbol> explicitInterfaceImplementations)
public static void AddExplicitInterfaceQualifierToId(Context cx, System.IO.TextWriter trapFile, IEnumerable<ISymbol> explicitInterfaceImplementations)
{
if (explicitInterfaceImplementations.Any())
{
tw.AppendList(",", explicitInterfaceImplementations.Select(impl => cx.CreateEntity(impl.ContainingType)));
trapFile.AppendList(",", explicitInterfaceImplementations.Select(impl => cx.CreateEntity(impl.ContainingType)));
}
}

View File

@@ -129,9 +129,9 @@ namespace Semmle.Extraction.CSharp
/// syntactic sub terms of this type (if any).
/// </summary>
/// <param name="cx">The extraction context.</param>
/// <param name="tw">The trap builder used to store the result.</param>
/// <param name="trapFile">The trap builder used to store the result.</param>
/// <param name="subTermAction">The action to apply to syntactic sub terms of this type.</param>
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter tw, Action<Context, TextWriter, ITypeSymbol> subTermAction)
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction)
{
if (type.SpecialType != SpecialType.None)
{
@@ -140,7 +140,7 @@ namespace Semmle.Extraction.CSharp
* This makes the IDs shorter and means that all built-in types map to
* the same entities (even when using multiple versions of mscorlib).
*/
tw.Write(type.ToDisplayString());
trapFile.Write(type.ToDisplayString());
return;
}
@@ -150,8 +150,8 @@ namespace Semmle.Extraction.CSharp
{
case TypeKind.Array:
var array = (IArrayTypeSymbol)type;
subTermAction(cx, tw, array.ElementType);
array.BuildArraySuffix(tw);
subTermAction(cx, trapFile, array.ElementType);
array.BuildArraySuffix(trapFile);
return;
case TypeKind.Class:
case TypeKind.Interface:
@@ -160,19 +160,19 @@ namespace Semmle.Extraction.CSharp
case TypeKind.Delegate:
case TypeKind.Error:
var named = (INamedTypeSymbol)type;
named.BuildNamedTypeId(cx, tw, subTermAction);
named.BuildNamedTypeId(cx, trapFile, subTermAction);
return;
case TypeKind.Pointer:
var ptr = (IPointerTypeSymbol)type;
subTermAction(cx, tw, ptr.PointedAtType);
tw.Write('*');
subTermAction(cx, trapFile, ptr.PointedAtType);
trapFile.Write('*');
return;
case TypeKind.TypeParameter:
var tp = (ITypeParameterSymbol)type;
tw.Write(tp.Name);
trapFile.Write(tp.Name);
return;
case TypeKind.Dynamic:
tw.Write("dynamic");
trapFile.Write("dynamic");
return;
default:
throw new InternalError(type, $"Unhandled type kind '{type.TypeKind}'");
@@ -184,66 +184,66 @@ namespace Semmle.Extraction.CSharp
/// <summary>
/// Constructs an array suffix string for this array type symbol.
/// </summary>
/// <param name="tb">The trap builder used to store the result.</param>
public static void BuildArraySuffix(this IArrayTypeSymbol array, TextWriter tb)
/// <param name="trapFile">The trap builder used to store the result.</param>
public static void BuildArraySuffix(this IArrayTypeSymbol array, TextWriter trapFile)
{
tb.Write('[');
trapFile.Write('[');
for (int i = 0; i < array.Rank - 1; i++)
tb.Write(',');
tb.Write(']');
trapFile.Write(',');
trapFile.Write(']');
}
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter tw, Action<Context, TextWriter, ITypeSymbol> subTermAction)
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction)
{
if (named.IsTupleType)
{
tw.Write('(');
tw.BuildList(",", named.TupleElements,
trapFile.Write('(');
trapFile.BuildList(",", named.TupleElements,
(f, tb0) =>
{
tw.Write(f.Name);
tw.Write(":");
trapFile.Write(f.Name);
trapFile.Write(":");
subTermAction(cx, tb0, f.Type);
}
);
tw.Write(")");
trapFile.Write(")");
return;
}
if (named.ContainingType != null)
{
subTermAction(cx, tw, named.ContainingType);
tw.Write('.');
subTermAction(cx, trapFile, named.ContainingType);
trapFile.Write('.');
}
else if (named.ContainingNamespace != null)
{
named.ContainingNamespace.BuildNamespace(cx, tw);
named.ContainingNamespace.BuildNamespace(cx, trapFile);
}
if (named.IsAnonymousType)
named.BuildAnonymousName(cx, tw, subTermAction, true);
named.BuildAnonymousName(cx, trapFile, subTermAction, true);
else if (named.TypeParameters.IsEmpty)
tw.Write(named.Name);
trapFile.Write(named.Name);
else if (IsReallyUnbound(named))
{
tw.Write(named.Name);
tw.Write("`");
tw.Write(named.TypeParameters.Length);
trapFile.Write(named.Name);
trapFile.Write("`");
trapFile.Write(named.TypeParameters.Length);
}
else
{
subTermAction(cx, tw, named.ConstructedFrom);
tw.Write('<');
subTermAction(cx, trapFile, named.ConstructedFrom);
trapFile.Write('<');
// Encode the nullability of the type arguments in the label.
// Type arguments with different nullability can result in
// a constructed type with different nullability of its members and methods,
// so we need to create a distinct database entity for it.
tw.BuildList(",", named.GetAnnotatedTypeArguments(), (ta, tb0) => { subTermAction(cx, tb0, ta.Symbol); tw.Write((int)ta.Nullability); });
tw.Write('>');
trapFile.BuildList(",", named.GetAnnotatedTypeArguments(), (ta, tb0) => { subTermAction(cx, tb0, ta.Symbol); trapFile.Write((int)ta.Nullability); });
trapFile.Write('>');
}
}
static void BuildNamespace(this INamespaceSymbol ns, Context cx, TextWriter tw)
static void BuildNamespace(this INamespaceSymbol ns, Context cx, TextWriter trapFile)
{
// Only include the assembly information in each type ID
// for normal extractions. This is because standalone extractions
@@ -255,44 +255,44 @@ namespace Semmle.Extraction.CSharp
// Note that we exclude the revision number as this has
// been observed to be unstable.
var assembly = ns.ContainingAssembly.Identity;
tw.Write(assembly.Name);
tw.Write('_');
tw.Write(assembly.Version.Major);
tw.Write('.');
tw.Write(assembly.Version.Minor);
tw.Write('.');
tw.Write(assembly.Version.Build);
tw.Write("::");
trapFile.Write(assembly.Name);
trapFile.Write('_');
trapFile.Write(assembly.Version.Major);
trapFile.Write('.');
trapFile.Write(assembly.Version.Minor);
trapFile.Write('.');
trapFile.Write(assembly.Version.Build);
trapFile.Write("::");
}
tw.WriteSubId(Namespace.Create(cx, ns));
tw.Write('.');
trapFile.WriteSubId(Namespace.Create(cx, ns));
trapFile.Write('.');
}
static void BuildAnonymousName(this ITypeSymbol type, Context cx, TextWriter tw, Action<Context, TextWriter, ITypeSymbol> subTermAction, bool includeParamName)
static void BuildAnonymousName(this ITypeSymbol type, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction, bool includeParamName)
{
var buildParam = includeParamName
? (prop, tb0) =>
{
tb0.Write(prop.Name);
tw.Write(' ');
trapFile.Write(' ');
subTermAction(cx, tb0, prop.Type);
}
: (Action<IPropertySymbol, TextWriter>)((prop, tb0) => subTermAction(cx, tb0, prop.Type));
int memberCount = type.GetMembers().OfType<IPropertySymbol>().Count();
int hackTypeNumber = memberCount == 1 ? 1 : 0;
tw.Write("<>__AnonType");
tw.Write(hackTypeNumber);
tw.Write('<');
tw.BuildList(",", type.GetMembers().OfType<IPropertySymbol>(), buildParam);
tw.Write('>');
trapFile.Write("<>__AnonType");
trapFile.Write(hackTypeNumber);
trapFile.Write('<');
trapFile.BuildList(",", type.GetMembers().OfType<IPropertySymbol>(), buildParam);
trapFile.Write('>');
}
/// <summary>
/// Constructs a display name string for this type symbol.
/// </summary>
/// <param name="tw">The trap builder used to store the result.</param>
public static void BuildDisplayName(this ITypeSymbol type, Context cx, TextWriter tw)
/// <param name="trapFile">The trap builder used to store the result.</param>
public static void BuildDisplayName(this ITypeSymbol type, Context cx, TextWriter trapFile)
{
using (cx.StackGuard)
{
@@ -303,11 +303,11 @@ namespace Semmle.Extraction.CSharp
var elementType = array.ElementType;
if (elementType.MetadataName.IndexOf("`") >= 0)
{
tw.Write(elementType.Name);
trapFile.Write(elementType.Name);
return;
}
elementType.BuildDisplayName(cx, tw);
array.BuildArraySuffix(tw);
elementType.BuildDisplayName(cx, trapFile);
array.BuildArraySuffix(trapFile);
return;
case TypeKind.Class:
case TypeKind.Interface:
@@ -316,18 +316,18 @@ namespace Semmle.Extraction.CSharp
case TypeKind.Delegate:
case TypeKind.Error:
var named = (INamedTypeSymbol)type;
named.BuildNamedTypeDisplayName(cx, tw);
named.BuildNamedTypeDisplayName(cx, trapFile);
return;
case TypeKind.Pointer:
var ptr = (IPointerTypeSymbol)type;
ptr.PointedAtType.BuildDisplayName(cx, tw);
tw.Write('*');
ptr.PointedAtType.BuildDisplayName(cx, trapFile);
trapFile.Write('*');
return;
case TypeKind.TypeParameter:
tw.Write(type.Name);
trapFile.Write(type.Name);
return;
case TypeKind.Dynamic:
tw.Write("dynamic");
trapFile.Write("dynamic");
return;
default:
throw new InternalError(type, $"Unhandled type kind '{type.TypeKind}'");
@@ -335,34 +335,34 @@ namespace Semmle.Extraction.CSharp
}
}
public static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter tw)
public static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter trapFile)
{
if (namedType.IsTupleType)
{
tw.Write('(');
tw.BuildList(",", namedType.TupleElements.Select(f => f.Type),
trapFile.Write('(');
trapFile.BuildList(",", namedType.TupleElements.Select(f => f.Type),
(t, tb0) => t.BuildDisplayName(cx, tb0)
);
tw.Write(")");
trapFile.Write(")");
return;
}
if (namedType.IsAnonymousType)
{
namedType.BuildAnonymousName(cx, tw, (cx0, tb0, sub) => sub.BuildDisplayName(cx0, tb0), false);
namedType.BuildAnonymousName(cx, trapFile, (cx0, tb0, sub) => sub.BuildDisplayName(cx0, tb0), false);
}
tw.Write(namedType.Name);
trapFile.Write(namedType.Name);
if (namedType.IsGenericType && namedType.TypeKind != TypeKind.Error && namedType.TypeArguments.Any())
{
tw.Write('<');
tw.BuildList(",", namedType.TypeArguments, (p, tb0) =>
trapFile.Write('<');
trapFile.BuildList(",", namedType.TypeArguments, (p, tb0) =>
{
if (IsReallyBound(namedType))
p.BuildDisplayName(cx, tb0);
});
tw.Write('>');
trapFile.Write('>');
}
}

View File

@@ -18,7 +18,7 @@ namespace Semmle.Extraction.CSharp
{
internal static void accessor_location(this TextWriter trapFile, Accessor accessorKey, Location location)
{
trapFile.BeginTuple("accessor_location").Param(accessorKey).Param(location).EndTuple();
trapFile.WriteTuple("accessor_location", accessorKey, location);
}
internal static void accessors(this TextWriter trapFile, Accessor accessorKey, int kind, string name, Property propKey, Accessor unboundAccessor)
@@ -33,12 +33,12 @@ namespace Semmle.Extraction.CSharp
internal static void attributes(this TextWriter trapFile, Attribute attribute, Type attributeType, IEntity entity)
{
trapFile.BeginTuple("attributes").Param(attribute).Param(attributeType).Param(entity).EndTuple();
trapFile.WriteTuple("attributes", attribute, attributeType, entity);
}
internal static void attribute_location(this TextWriter trapFile, Attribute attribute, Location location)
{
trapFile.BeginTuple("attribute_location").Param(attribute).Param(location).EndTuple();
trapFile.WriteTuple("attribute_location", attribute, location);
}
internal static void catch_type(this TextWriter trapFile, Entities.Statements.Catch @catch, Type type, bool explicityCaught)
@@ -48,7 +48,7 @@ namespace Semmle.Extraction.CSharp
internal static void commentblock(this TextWriter trapFile, CommentBlock k)
{
trapFile.BeginTuple("commentblock").Param(k).EndTuple();
trapFile.WriteTuple("commentblock", k);
}
internal static void commentblock_binding(this TextWriter trapFile, CommentBlock commentBlock, Label entity, CommentBinding binding)
@@ -63,7 +63,7 @@ namespace Semmle.Extraction.CSharp
internal static void commentblock_location(this TextWriter trapFile, CommentBlock k, Location l)
{
trapFile.BeginTuple("commentblock_location").Param(k).Param(l).EndTuple();
trapFile.WriteTuple("commentblock_location", k, l);
}
internal static void commentline(this TextWriter trapFile, CommentLine commentLine, CommentLineType type, string text, string rawtext)
@@ -73,7 +73,7 @@ namespace Semmle.Extraction.CSharp
internal static void commentline_location(this TextWriter trapFile, CommentLine commentLine, Location location)
{
trapFile.BeginTuple("commentline_location").Param(commentLine).Param(location).EndTuple();
trapFile.WriteTuple("commentline_location", commentLine, location);
}
internal static void compilation_args(this TextWriter trapFile, Compilation compilation, int index, string arg)
@@ -108,12 +108,12 @@ namespace Semmle.Extraction.CSharp
internal static void compiler_generated(this TextWriter trapFile, IEntity entity)
{
trapFile.BeginTuple("compiler_generated").Param(entity).EndTuple();
trapFile.WriteTuple("compiler_generated", entity);
}
internal static void conditional_access(this TextWriter trapFile, Expression access)
{
trapFile.BeginTuple("conditional_access").Param(access).EndTuple();
trapFile.WriteTuple("conditional_access", access);
}
internal static void constant_value(this TextWriter trapFile, IEntity field, string value)
@@ -146,7 +146,6 @@ namespace Semmle.Extraction.CSharp
trapFile.WriteTuple("destructor_location", destructor, location);
}
internal static void destructors(this TextWriter trapFile, Destructor destructor, string name, Type containingType, Destructor original)
{
trapFile.WriteTuple("destructors", destructor, name, containingType, original);
@@ -162,148 +161,186 @@ namespace Semmle.Extraction.CSharp
trapFile.BeginTuple("diagnostics").Param(diag).Param(severity).Param(errorTag).Param(errorMessage).Param(fullErrorMessage).Param(location).EndTuple();
}
internal static void dynamic_member_name(this TextWriter trapFile, Expression e, string name) { trapFile.BeginTuple("dynamic_member_name").Param(e).Param(name).EndTuple(); }
internal static void dynamic_member_name(this TextWriter trapFile, Expression e, string name)
{
trapFile.BeginTuple("dynamic_member_name").Param(e).Param(name).EndTuple();
}
internal static void enum_underlying_type(this TextWriter trapFile, Type @enum, Type type) { trapFile.WriteTuple("enum_underlying_type", @enum, type); }
internal static void enum_underlying_type(this TextWriter trapFile, Type @enum, Type type)
{
trapFile.WriteTuple("enum_underlying_type", @enum, type);
}
internal static void event_accessor_location(this TextWriter trapFile, EventAccessor accessor, Location location) { trapFile.WriteTuple("event_accessor_location", accessor, location); }
internal static void event_accessor_location(this TextWriter trapFile, EventAccessor accessor, Location location)
{
trapFile.WriteTuple("event_accessor_location", accessor, location);
}
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();
}
internal static void event_location(this TextWriter trapFile, Event eventKey, Location locationKey)
{
trapFile.WriteTuple("event_location", eventKey, locationKey);
}
internal static void events(this TextWriter trapFile, Event eventKey, string name, Type declaringType, Type memberType, Event originalDefinition)
{
trapFile.WriteTuple("events", eventKey, name, declaringType, memberType, originalDefinition);
}
internal static void explicitly_implements(this TextWriter trapFile, IEntity member, Type @interface)
{
trapFile.WriteTuple("explicitly_implements", member, @interface);
}
internal static void explicitly_sized_array_creation(this TextWriter trapFile, Expression array)
{
trapFile.WriteTuple("explicitly_sized_array_creation", array);
}
internal static void expr_compiler_generated(this TextWriter trapFile, Expression expr)
{
trapFile.WriteTuple("expr_compiler_generated", expr);
}
internal static void expr_location(this TextWriter trapFile, Expression exprKey, Location location)
{
trapFile.WriteTuple("expr_location", exprKey, location);
}
internal static void expr_access(this TextWriter trapFile, Expression expr, IEntity access)
{
trapFile.WriteTuple("expr_access", expr, access);
}
internal static void expr_argument(this TextWriter trapFile, Expression expr, int mode)
{
trapFile.WriteTuple("expr_argument", expr, mode);
}
internal static void expr_argument_name(this TextWriter trapFile, Expression expr, string name)
{
trapFile.WriteTuple("expr_argument_name", expr, name);
}
internal static void expr_call(this TextWriter trapFile, Expression expr, Method target)
{
trapFile.WriteTuple("expr_call", expr, target);
}
internal static void expr_parent(this TextWriter trapFile, Expression exprKey, int child, IExpressionParentEntity parent)
{
trapFile.WriteTuple("expr_parent", exprKey, child, parent);
}
internal static void expr_parent_top_level(this TextWriter trapFile, Expression exprKey, int child, IExpressionParentEntity parent)
{
trapFile.WriteTuple("expr_parent_top_level", exprKey, child, parent);
}
internal static void expr_value(this TextWriter trapFile, Expression exprKey, string value)
{
trapFile.WriteTuple("expr_value", exprKey, value);
}
internal static void expressions(this TextWriter trapFile, Expression expr, ExprKind kind, Type exprType)
{
trapFile.WriteTuple("expressions", expr, (int)kind, exprType);
}
internal static void exprorstmt_name(this TextWriter trapFile, IEntity expr, string name)
{
trapFile.WriteTuple("exprorstmt_name", expr, name);
}
internal static void extend(this TextWriter trapFile, Type type, Type super)
{
trapFile.WriteTuple("extend", type, super);
}
internal static void field_location(this TextWriter trapFile, Field field, Location location)
{
trapFile.WriteTuple("field_location", field, location);
}
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();
}
internal static void general_type_parameter_constraints(this TextWriter trapFile, TypeParameterConstraints constraints, int hasKind)
{
trapFile.WriteTuple("general_type_parameter_constraints", constraints, hasKind);
}
internal static void has_modifiers(this TextWriter trapFile, IEntity entity, Modifier modifier)
{
trapFile.WriteTuple("has_modifiers", entity, modifier);
}
internal static void implement(this TextWriter trapFile, Type type, Type @interface)
{
trapFile.WriteTuple("implement", type, @interface);
}
internal static void implicitly_typed_array_creation(this TextWriter trapFile, Expression array)
{
trapFile.WriteTuple("implicitly_typed_array_creation", array);
}
internal static void indexer_location(this TextWriter trapFile, Indexer indexer, Location location)
{
trapFile.WriteTuple("indexer_location", indexer, location);
}
internal static void indexers(this TextWriter trapFile, Indexer propKey, string name, Type declaringType, Type memberType, Indexer unboundProperty)
{
trapFile.WriteTuple("indexers", propKey, name, declaringType, memberType, unboundProperty);
}
internal static void is_constructed(this TextWriter trapFile, IEntity typeOrMethod)
{
trapFile.WriteTuple("is_constructed", typeOrMethod);
}
internal static void is_generic(this TextWriter trapFile, IEntity typeOrMethod)
{
trapFile.WriteTuple("is_generic", typeOrMethod);
}
internal static void jump_step(this TextWriter trapFile, IEntity origin, IEntity src, Statement dest)
{
trapFile.WriteTuple("jump_step", origin, src, dest);
}
internal static void local_function_stmts(this TextWriter trapFile, Entities.Statements.LocalFunction fnStmt, LocalFunction fn)
{
trapFile.WriteTuple("local_function_stmts", fnStmt, fn);
}
internal static void local_functions(this TextWriter trapFile, LocalFunction fn, string name, Type returnType, LocalFunction unboundFn)
{
trapFile.WriteTuple("local_functions", fn, name, returnType, unboundFn);
}
internal static void localvar_location(this TextWriter trapFile, LocalVariable var, Location location)
{
trapFile.WriteTuple("localvar_location", var, location);
}
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();
}
public static void metadata_handle(this TextWriter trapFile, IEntity entity, Location assembly, int handleValue)
{
trapFile.WriteTuple("metadata_handle", entity, assembly, handleValue);
}
internal static void method_location(this TextWriter trapFile, Method method, Location location)
{
trapFile.WriteTuple("method_location", method, location);
}
internal static void methods(this TextWriter trapFile, Method method, string name, Type declType, Type retType, Method originalDefinition)
{
trapFile.WriteTuple("methods", method, name, declType, retType, originalDefinition);
@@ -318,102 +355,122 @@ namespace Semmle.Extraction.CSharp
{
trapFile.WriteTuple("mutator_invocation_mode", expr, mode);
}
internal static void namespace_declaration_location(this TextWriter trapFile, NamespaceDeclaration decl, Location location)
{
trapFile.WriteTuple("namespace_declaration_location", decl, location);
}
internal static void namespace_declarations(this TextWriter trapFile, NamespaceDeclaration decl, Namespace ns)
{
trapFile.WriteTuple("namespace_declarations", decl, ns);
}
internal static void namespaces(this TextWriter trapFile, Namespace ns, string name)
{
trapFile.WriteTuple("namespaces", ns, name);
}
internal static void nested_types(this TextWriter trapFile, Type typeKey, Type declaringTypeKey, Type unboundTypeKey)
{
trapFile.WriteTuple("nested_types", typeKey, declaringTypeKey, unboundTypeKey);
}
internal static void nullable_underlying_type(this TextWriter trapFile, Type nullableType, Type underlyingType)
{
trapFile.WriteTuple("nullable_underlying_type", nullableType, underlyingType);
}
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();
}
internal static void operator_location(this TextWriter trapFile, UserOperator @operator, Location location)
{
trapFile.WriteTuple("operator_location", @operator, location);
}
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();
}
internal static void overrides(this TextWriter trapFile, Method overriding, Method overridden)
{
trapFile.WriteTuple("overrides", overriding, overridden);
}
internal static void param_location(this TextWriter trapFile, Parameter param, Location location)
{
trapFile.WriteTuple("param_location", param, location);
}
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();
}
internal static void parent_namespace(this TextWriter trapFile, IEntity type, Namespace parent)
{
trapFile.WriteTuple("parent_namespace", type, parent);
}
internal static void parent_namespace_declaration(this TextWriter trapFile, IEntity item, NamespaceDeclaration parent)
{
trapFile.WriteTuple("parent_namespace_declaration", item, parent);
}
internal static void pointer_referent_type(this TextWriter trapFile, PointerType pointerType, Type referentType)
{
trapFile.WriteTuple("pointer_referent_type", pointerType, referentType);
}
internal static void property_location(this TextWriter trapFile, Property property, Location location)
{
trapFile.WriteTuple("property_location", property, location);
}
internal static void properties(this TextWriter trapFile, Property propKey, string name, Type declaringType, Type memberType, Property unboundProperty)
{
trapFile.WriteTuple("properties", propKey, name, declaringType, memberType, unboundProperty);
}
internal static void statements(this TextWriter trapFile, Statement stmt, StmtKind kind)
{
trapFile.WriteTuple("statements", stmt, (int)kind);
}
internal static void specific_type_parameter_constraints(this TextWriter trapFile, TypeParameterConstraints constraints, Type baseType)
{
trapFile.WriteTuple("specific_type_parameter_constraints", constraints, baseType);
}
internal static void specific_type_parameter_annotation(this TextWriter trapFile, TypeParameterConstraints constraints, Type baseType, TypeAnnotation annotation)
{
trapFile.WriteTuple("specific_type_parameter_annotation", constraints, baseType, (int)annotation);
}
internal static void successors(this TextWriter trapFile, IEntity from, IEntity to)
{
trapFile.WriteTuple("successors", from, to);
}
internal static void stmt_location(this TextWriter trapFile, Statement stmt, Location location)
{
trapFile.WriteTuple("stmt_location", stmt, location);
}
internal static void stmt_parent(this TextWriter trapFile, Statement stmt, int child, IStatementParentEntity parent)
{
trapFile.WriteTuple("stmt_parent", stmt, child, parent);
}
internal static void stmt_parent_top_level(this TextWriter trapFile, Statement stmt, int child, IStatementParentEntity parent)
{
trapFile.WriteTuple("stmt_parent_top_level", stmt, child, parent);
}
internal static void tuple_element(this TextWriter trapFile, TupleType type, int index, Field field)
{
trapFile.WriteTuple("tuple_element", type, index, field);
}
internal static void tuple_underlying_type(this TextWriter trapFile, TupleType type, NamedType underlying)
{
trapFile.WriteTuple("tuple_underlying_type", type, underlying);
@@ -423,54 +480,67 @@ namespace Semmle.Extraction.CSharp
{
trapFile.WriteTuple("type_annotation", element, (int)annotation);
}
internal static void type_argument_annotation(this TextWriter trapFile, IEntity element, int index, Kinds.TypeAnnotation annotation)
{
trapFile.WriteTuple("type_argument_annotation", element, index, (int)annotation);
}
internal static void type_mention(this TextWriter trapFile, TypeMention ta, Type type, IEntity parent)
{
trapFile.WriteTuple("type_mention", ta, type, parent);
}
internal static void type_mention_location(this TextWriter trapFile, TypeMention ta, Location loc)
{
trapFile.WriteTuple("type_mention_location", ta, loc);
}
internal static void type_arguments(this TextWriter trapFile, Type arg, int n, IEntity typeOrMethod)
{
trapFile.WriteTuple("type_arguments", arg, n, typeOrMethod);
}
internal static void type_location(this TextWriter trapFile, Type type, Location location)
{
trapFile.WriteTuple("type_location", type, location);
}
internal static void type_parameter_constraints(this TextWriter trapFile, TypeParameterConstraints constraints, TypeParameter typeParam)
{
trapFile.WriteTuple("type_parameter_constraints", constraints, typeParam);
}
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();
}
internal static void typeref_type(this TextWriter trapFile, NamedTypeRef typeref, Type type)
{
trapFile.WriteTuple("typeref_type", typeref, type);
}
internal static void typerefs(this TextWriter trapFile, NamedTypeRef type, string name)
{
trapFile.WriteTuple("typerefs", type, name);
}
internal static void types(this TextWriter trapFile, Type type, TypeKind kind, string name)
{
trapFile.BeginTuple("types").Param(type).Param((int)kind).Param(name).EndTuple();
}
internal static void using_namespace_directives(this TextWriter trapFile, UsingDirective @using, Namespace ns)
{
trapFile.WriteTuple("using_namespace_directives", @using, ns);
}
internal static void using_directive_location(this TextWriter trapFile, UsingDirective @using, Location location)
{
trapFile.WriteTuple("using_directive_location", @using, location);
}
internal static void using_static_directives(this TextWriter trapFile, UsingDirective @using, Type type)
{
trapFile.WriteTuple("using_static_directives", @using, type);

View File

@@ -178,9 +178,9 @@ namespace Semmle.Extraction.Tests
static class TrapWriterTestExtensions
{
public static void Emit(this TrapWriter tw, string s)
public static void Emit(this TrapWriter trapFile, string s)
{
tw.Emit(new StringTrapEmitter(s));
trapFile.Emit(new StringTrapEmitter(s));
}
class StringTrapEmitter : ITrapEmitter
@@ -191,9 +191,9 @@ namespace Semmle.Extraction.Tests
Content = content;
}
public void EmitToTrapBuilder(TextWriter tb)
public void EmitToTrapBuilder(TextWriter trapFile)
{
tb.Write(Content);
trapFile.Write(Content);
}
}
}

View File

@@ -54,24 +54,26 @@ namespace Semmle.Extraction
return init == null ? CreateEntity2(factory, init) : CreateNonNullEntity(factory, init);
}
bool DefiningLabel = false;
// A recursion guard against writing to the trap file whilst writing an id to the trap file.
bool WritingLabel = false;
public void DefineLabel(IEntity entity, TextWriter trapFile)
{
if (DefiningLabel)
if (WritingLabel)
{
// Don't define a label whilst writing a label.
PopulateLater(() => DefineLabel(entity, trapFile));
}
else
{
try
{
DefiningLabel = true;
WritingLabel = true;
entity.DefineLabel(trapFile);
}
finally
{
DefiningLabel = false;
WritingLabel = false;
}
}
}
@@ -330,19 +332,19 @@ namespace Semmle.Extraction
Key = key;
}
public void EmitToTrapBuilder(TextWriter tw)
public void EmitToTrapBuilder(TextWriter trapFile)
{
tw.Write(".push ");
Key.AppendTo(tw);
tw.WriteLine();
trapFile.Write(".push ");
Key.AppendTo(trapFile);
trapFile.WriteLine();
}
}
class PopEmitter : ITrapEmitter
{
public void EmitToTrapBuilder(TextWriter tw)
public void EmitToTrapBuilder(TextWriter trapFile)
{
tw.WriteLine(".pop");
trapFile.WriteLine(".pop");
}
}
@@ -356,7 +358,7 @@ namespace Semmle.Extraction
/// <exception cref="InternalError">Thrown on invalid trap stack behaviour.</exception>
public void Populate(ISymbol optionalSymbol, ICachedEntity entity)
{
if (DefiningLabel)
if (WritingLabel)
{
// Don't write tuples etc if we're currently defining a label
PopulateLater(() => Populate(optionalSymbol, entity));

View File

@@ -28,15 +28,15 @@ namespace Semmle.Extraction
/// <summary>
/// Writes the unique identifier of this entitiy to a trap file.
/// </summary>
/// <param name="writer"></param>
void WriteId(TextWriter writer);
/// <param name="trapFile">The trapfile to write to.</param>
void WriteId(TextWriter writrapFileter);
/// <summary>
/// Writes the quoted identifier of this entity,
/// which could be @"..." or *
/// </summary>
/// <param name="writer"></param>
void WriteQuotedId(TextWriter writer);
/// <param name="trapFile">The trapfile to write to.</param>
void WriteQuotedId(TextWriter trapFile);
/// <summary>
/// The location for reporting purposes.

View File

@@ -39,7 +39,10 @@ namespace Semmle.Extraction
cx.Try(null, null, () => Populate(cx.TrapWriter.Writer));
}
public string DebugTuples
/// <summary>
/// For debugging.
/// </summary>
public string DebugContents
{
get
{

View File

@@ -17,7 +17,7 @@ namespace Semmle.Extraction
/// <summary>
/// Appends this ID to the supplied trap builder.
/// </summary>
void AppendTo(TextWriter tw);
void AppendTo(TextWriter trapFile);
}
/// <summary>
@@ -38,9 +38,9 @@ namespace Semmle.Extraction
public override int GetHashCode() => 0;
public void AppendTo(System.IO.TextWriter tw)
public void AppendTo(TextWriter trapFile)
{
tw.Write('*');
trapFile.Write('*');
}
}
@@ -97,11 +97,11 @@ namespace Semmle.Extraction
public override int GetHashCode() => TrapBuilder.ToString().GetHashCode();
public void AppendTo(TextWriter tb)
public void AppendTo(TextWriter trapFile)
{
tb.Write("@\"");
tb.Write(TrapBuilder.ToString());
tb.Write("\"");
trapFile.Write("@\"");
trapFile.Write(TrapBuilder.ToString());
trapFile.Write("\"");
}
}
@@ -143,14 +143,14 @@ namespace Semmle.Extraction
/// <summary>
/// Constructs a unique string for this label.
/// </summary>
/// <param name="tb">The trap builder used to store the result.</param>
public void AppendTo(System.IO.TextWriter tw)
/// <param name="trapFile">The trap builder used to store the result.</param>
public void AppendTo(System.IO.TextWriter trapFile)
{
if (!Valid)
throw new NullReferenceException("Attempt to use an invalid label");
tw.Write('#');
tw.Write(Value);
trapFile.Write('#');
trapFile.Write(Value);
}
}
}

View File

@@ -25,7 +25,7 @@ namespace Semmle.Extraction
}
/// <summary>
/// Whether one Location ends before another starts.
/// Whether one Location ends before another starts.
/// </summary>
/// <param name="before">The Location coming before</param>
/// <param name="after">The Location coming after</param>

View File

@@ -22,7 +22,10 @@ namespace Semmle.Extraction
public abstract void Populate(TextWriter trapFile);
public string DebugTrapContents
/// <summary>
/// For debugging.
/// </summary>
public string DebugContents
{
get
{

View File

@@ -11,33 +11,33 @@ namespace Semmle.Extraction
/// Appends a [comma] separated list to a trap builder.
/// </summary>
/// <typeparam name="T">The type of the list.</typeparam>
/// <param name="tb">The trap builder to append to.</param>
/// <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 tb, string separator, IEnumerable<T> items) where T:IEntity
public static TextWriter AppendList<T>(this TextWriter trapFile, string separator, IEnumerable<T> items) where T:IEntity
{
return tb.BuildList(separator, items, (x, tb0) => { tb0.WriteSubId(x); });
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="tb">The trap builder to append to.</param>
/// <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 tb, string separator, IEnumerable<T> items, Action<T, TextWriter> action)
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 tb.Write(separator);
action(item, tb);
if (first) first = false; else trapFile.Write(separator);
action(item, trapFile);
}
return tb;
return trapFile;
}
}
}

View File

@@ -4,42 +4,36 @@ namespace Semmle.Extraction
{
public static class TrapExtensions
{
public static void WriteLabel(this TextWriter writer, int value)
public static void WriteLabel(this TextWriter trapFile, int value)
{
writer.Write('#');
writer.Write(value);
trapFile.Write('#');
trapFile.Write(value);
}
public static void WriteLabel(this TextWriter writer, IEntity entity)
public static void WriteLabel(this TextWriter trapFile, IEntity entity)
{
writer.WriteLabel(entity.Label.Value);
trapFile.WriteLabel(entity.Label.Value);
}
public static void WriteSubId(this TextWriter writer, IEntity entity)
public static void WriteSubId(this TextWriter trapFile, IEntity entity)
{
writer.Write('{');
writer.WriteLabel(entity);
writer.Write('}');
trapFile.Write('{');
trapFile.WriteLabel(entity);
trapFile.Write('}');
}
public static void WriteSeparator(this TextWriter writer, string separator, int index)
public static void WriteSeparator(this TextWriter trapFile, string separator, ref int index)
{
if (index > 0) writer.Write(separator);
}
// This is temporary and we can get rid of IId entirely
public static void WriteIId(this TextWriter writer, IId iid)
{
iid.AppendTo(writer);
if (index++ > 0) trapFile.Write(separator);
}
public struct FirstParam
{
private readonly TextWriter Writer;
public FirstParam(TextWriter writer)
public FirstParam(TextWriter trapFile)
{
Writer = writer;
Writer = trapFile;
}
public NextParam Param(IEntity entity)
@@ -64,9 +58,9 @@ namespace Semmle.Extraction
{
private readonly TextWriter Writer;
public NextParam(TextWriter writer)
public NextParam(TextWriter trapFile)
{
Writer = writer;
Writer = trapFile;
}
private void WriteComma()
@@ -126,7 +120,7 @@ namespace Semmle.Extraction
encoding.GetByteCount(s) > maxStringBytes;
}
private static void WriteString(TextWriter writer, string s) => writer.Write(EncodeString(s));
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.
@@ -161,104 +155,96 @@ namespace Semmle.Extraction
/// Output a string to the trap file, such that the encoded output does not exceed
/// <paramref name="bytesRemaining"/> bytes.
/// </summary>
/// <param name="writer">The trapbuilder</param>
/// <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 writer, string s, ref int bytesRemaining)
private static void WriteTruncatedString(TextWriter trapFile, string s, ref int bytesRemaining)
{
WriteString(writer, TruncateString(s, ref bytesRemaining));
WriteString(trapFile, TruncateString(s, ref bytesRemaining));
}
public static void WriteTrapString(this TextWriter writer, string s)
public static void WriteTrapString(this TextWriter trapFile, string s)
{
writer.Write('\"');
trapFile.Write('\"');
if (NeedsTruncation(s))
{
// Slow path
int remaining = maxStringBytes;
WriteTruncatedString(writer, s, ref remaining);
WriteTruncatedString(trapFile, s, ref remaining);
}
else
{
// Fast path
WriteString(writer, s);
WriteString(trapFile, s);
}
writer.Write('\"');
trapFile.Write('\"');
}
public static void WriteTrapFloat(this TextWriter writer, float f)
public static void WriteTrapFloat(this TextWriter trapFile, float f)
{
writer.Write(f.ToString("0.#####e0")); // Trap importer won't accept ints
trapFile.Write(f.ToString("0.#####e0")); // Trap importer won't accept ints
}
public static FirstParam BeginTuple(this TextWriter writer, string name)
public static FirstParam BeginTuple(this TextWriter trapFile, string name)
{
writer.Write(name);
writer.Write('(');
return new FirstParam(writer);
trapFile.Write(name);
trapFile.Write('(');
return new FirstParam(trapFile);
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1)
{
writer.BeginTuple(name).Param(p1).EndTuple();
trapFile.BeginTuple(name).Param(p1).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, IEntity p2)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, IEntity p2)
{
writer.BeginTuple(name).Param(p1).Param(p2).EndTuple();
trapFile.BeginTuple(name).Param(p1).Param(p2).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, string p2, IEntity p3, IEntity p4)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, string p2, IEntity p3, IEntity p4)
{
writer.BeginTuple(name).Param(p1).Param(p2).Param(p3).Param(p4).EndTuple();
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).Param(p4).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, string p2, IEntity p3)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, string p2, IEntity p3)
{
writer.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, int p2, IEntity p3)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, int p2, IEntity p3)
{
writer.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, int p2, int p3)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, int p2, int p3)
{
writer.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, IEntity p2, int p3)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, IEntity p2, int p3)
{
writer.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, IEntity p2, IEntity p3)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, IEntity p2, IEntity p3)
{
writer.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, string p2, IEntity p3, IEntity p4, IEntity p5)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, string p2, IEntity p3, IEntity p4, IEntity p5)
{
writer.BeginTuple(name).Param(p1).Param(p2).Param(p3).Param(p4).Param(p5).EndTuple();
trapFile.BeginTuple(name).Param(p1).Param(p2).Param(p3).Param(p4).Param(p5).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, int p2)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, int p2)
{
writer.BeginTuple(name).Param(p1).Param(p2).EndTuple();
trapFile.BeginTuple(name).Param(p1).Param(p2).EndTuple();
}
public static void WriteTuple(this TextWriter writer, string name, IEntity p1, string p2)
public static void WriteTuple(this TextWriter trapFile, string name, IEntity p1, string p2)
{
writer.BeginTuple(name).Param(p1).Param(p2).EndTuple();
}
// DELETEME
public static void Emit(this TextWriter writer, Tuple t)
{
t.EmitToTrapBuilder(writer);
trapFile.BeginTuple(name).Param(p1).Param(p2).EndTuple();
}
}
}

View File

@@ -10,7 +10,7 @@ namespace Semmle.Extraction
{
public interface ITrapEmitter
{
void EmitToTrapBuilder(TextWriter tw);
void EmitToTrapBuilder(TextWriter trapFile);
}
public sealed class TrapWriter : IDisposable
@@ -88,7 +88,6 @@ namespace Semmle.Extraction
compressionStream = fileStream;
break;
default:
// Dead code
throw new ArgumentException(nameof(trapCompression));
}

View File

@@ -36,7 +36,7 @@ namespace Semmle.Extraction
array.Sum(encoding.GetByteCount) > maxStringBytes;
}
private static void WriteString(TextWriter tb, string s) => tb.Write(EncodeString(s));
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.
@@ -71,75 +71,75 @@ namespace Semmle.Extraction
/// Output a string to the trap file, such that the encoded output does not exceed
/// <paramref name="bytesRemaining"/> bytes.
/// </summary>
/// <param name="tb">The trapbuilder</param>
/// <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 tb, string s, ref int bytesRemaining)
private static void WriteTruncatedString(TextWriter trapFile, string s, ref int bytesRemaining)
{
WriteString(tb, TruncateString(s, ref bytesRemaining));
WriteString(trapFile, TruncateString(s, ref bytesRemaining));
}
/// <summary>
/// Constructs a unique string for this tuple.
/// </summary>
/// <param name="tw">The trap builder used to store the result.</param>
public void EmitToTrapBuilder(TextWriter tw)
/// <param name="trapFile">The trap builder used to store the result.</param>
public void EmitToTrapBuilder(TextWriter trapFile)
{
tw.Write(Name);
tw.Write("(");
trapFile.Write(Name);
trapFile.Write("(");
int column = 0;
foreach (var a in Args)
{
tw.WriteSeparator(", ", column++);
trapFile.WriteSeparator(", ", ref column);
switch(a)
{
case Label l:
l.AppendTo(tw);
l.AppendTo(trapFile);
break;
case IEntity e:
e.Label.AppendTo(tw);
e.Label.AppendTo(trapFile);
break;
case string s:
tw.Write("\"");
trapFile.Write("\"");
if (NeedsTruncation(s))
{
// Slow path
int remaining = maxStringBytes;
WriteTruncatedString(tw, s, ref remaining);
WriteTruncatedString(trapFile, s, ref remaining);
}
else
{
// Fast path
WriteString(tw, s);
WriteString(trapFile, s);
}
tw.Write("\"");
trapFile.Write("\"");
break;
case System.Enum _:
tw.Write((int)a);
trapFile.Write((int)a);
break;
case int i:
tw.Write(i);
trapFile.Write(i);
break;
case float f:
tw.Write(f.ToString("0.#####e0")); // Trap importer won't accept ints
trapFile.Write(f.ToString("0.#####e0")); // Trap importer won't accept ints
break;
case string[] array:
tw.Write('\"');
trapFile.Write('\"');
if (NeedsTruncation(array))
{
// Slow path
int remaining = maxStringBytes;
foreach (var element in array)
WriteTruncatedString(tw, element, ref remaining);
WriteTruncatedString(trapFile, element, ref remaining);
}
else
{
// Fast path
foreach (var element in array)
WriteString(tw, element);
WriteString(trapFile, element);
}
tw.Write('\"');
trapFile.Write('\"');
break;
case null:
throw new InternalError($"Attempt to write a null argument tuple {Name} at column {column}");
@@ -149,7 +149,7 @@ namespace Semmle.Extraction
++column;
}
tw.WriteLine(")");
trapFile.WriteLine(")");
}
public override string ToString()

View File

@@ -520,7 +520,7 @@ class KindViolation extends TypeViolation {
}
override string getMessage() {
result = "Incorrect class/interface on type: " + concat(typeKind(this.getType()), " ")
result = "Invalid kinds on type: " + concat(typeKind(this.getType()), " ")
}
}