C#: Extract ID writing logic to separate class

This commit is contained in:
Tamas Vajk
2020-12-03 15:20:57 +01:00
parent fc5f6c5203
commit d270aa2281
5 changed files with 95 additions and 104 deletions

View File

@@ -18,31 +18,11 @@ namespace Semmle.Extraction.CIL.Entities
private readonly Type[]? thisTypeArguments;
private readonly Type? containingType;
public override IEnumerable<Type> ThisTypeArguments => thisTypeArguments.EnumerateNull();
public override IEnumerable<Type> ThisGenericArguments => thisTypeArguments.EnumerateNull();
public override IEnumerable<IExtractionProduct> Contents
{
get
{
foreach (var c in base.Contents)
yield return c;
var i = 0;
foreach (var type in ThisTypeArguments)
{
yield return type;
yield return Tuples.cil_type_argument(this, i++, type);
}
}
}
public override Type SourceDeclaration => unboundGenericType;
private readonly NamedTypeIdWriter idWriter;
public ConstructedType(Context cx, Type unboundType, IEnumerable<Type> typeArguments) : base(cx)
{
idWriter = new NamedTypeIdWriter(this);
var suppliedArgs = typeArguments.Count();
if (suppliedArgs != unboundType.TotalTypeParametersCount)
throw new InternalError("Unexpected number of type arguments in ConstructedType");
@@ -90,6 +70,28 @@ namespace Semmle.Extraction.CIL.Entities
return h;
}
public override IEnumerable<Type> ThisTypeArguments => thisTypeArguments.EnumerateNull();
public override IEnumerable<Type> ThisGenericArguments => thisTypeArguments.EnumerateNull();
public override IEnumerable<IExtractionProduct> Contents
{
get
{
foreach (var c in base.Contents)
yield return c;
var i = 0;
foreach (var type in ThisTypeArguments)
{
yield return type;
yield return Tuples.cil_type_argument(this, i++, type);
}
}
}
public override Type SourceDeclaration => unboundGenericType;
public override Type? ContainingType => containingType;
public override string Name => unboundGenericType.Name;
@@ -107,34 +109,7 @@ namespace Semmle.Extraction.CIL.Entities
public override void WriteId(TextWriter trapFile, bool inContext)
{
if (ContainingType != null)
{
ContainingType.GetId(trapFile, inContext);
trapFile.Write('.');
}
else
{
WriteAssemblyPrefix(trapFile);
if (!ContainingNamespace.IsGlobalNamespace)
{
ContainingNamespace.WriteId(trapFile);
trapFile.Write('.');
}
}
trapFile.Write(unboundGenericType.Name);
if (thisTypeArguments != null && thisTypeArguments.Any())
{
trapFile.Write('<');
var index = 0;
foreach (var t in thisTypeArguments)
{
trapFile.WriteSeparator(",", ref index);
t.WriteId(trapFile);
}
trapFile.Write('>');
}
idWriter.WriteId(trapFile, inContext);
}
public override void WriteAssemblyPrefix(TextWriter trapFile) => unboundGenericType.WriteAssemblyPrefix(trapFile);

View File

@@ -0,0 +1,63 @@
using Microsoft.CodeAnalysis;
using System.Linq;
using System.IO;
namespace Semmle.Extraction.CIL.Entities
{
internal class NamedTypeIdWriter
{
private readonly Type type;
public NamedTypeIdWriter(Type type)
{
this.type = type;
}
public void WriteId(TextWriter trapFile, bool inContext)
{
if (type.IsPrimitiveType)
{
Type.WritePrimitiveTypeId(trapFile, type.Name);
return;
}
var ct = type.ContainingType;
if (ct != null)
{
ct.GetId(trapFile, inContext);
trapFile.Write('.');
}
else
{
type.WriteAssemblyPrefix(trapFile);
var ns = type.ContainingNamespace!;
if (!ns.IsGlobalNamespace)
{
ns.WriteId(trapFile);
trapFile.Write('.');
}
}
trapFile.Write(type.Name);
var thisTypeArguments = type.ThisTypeArguments;
if (thisTypeArguments != null && thisTypeArguments.Any())
{
trapFile.Write('<');
var index = 0;
foreach (var t in thisTypeArguments)
{
trapFile.WriteSeparator(",", ref index);
t.WriteId(trapFile);
}
trapFile.Write('>');
}
else if (type.ThisTypeParameterCount > 0)
{
trapFile.Write('`');
trapFile.Write(type.ThisTypeParameterCount);
}
}
}
}

View File

@@ -193,7 +193,7 @@ namespace Semmle.Extraction.CIL.Entities
return false;
}
protected bool IsPrimitiveType => TryGetPrimitiveTypeCode(out _);
protected internal bool IsPrimitiveType => TryGetPrimitiveTypeCode(out _);
public sealed override IEnumerable<Type> MethodParameters => Enumerable.Empty<Type>();

View File

@@ -19,9 +19,11 @@ namespace Semmle.Extraction.CIL.Entities
private readonly TypeDefinition td;
private readonly Lazy<IEnumerable<TypeTypeParameter>> typeParams;
private readonly Type? declType;
private readonly NamedTypeIdWriter idWriter;
public TypeDefinitionType(Context cx, TypeDefinitionHandle handle) : base(cx)
{
idWriter = new NamedTypeIdWriter(this);
td = cx.MdReader.GetTypeDefinition(handle);
this.handle = handle;
@@ -42,32 +44,7 @@ namespace Semmle.Extraction.CIL.Entities
public override void WriteId(TextWriter trapFile, bool inContext)
{
if (IsPrimitiveType)
{
WritePrimitiveTypeId(trapFile, Name);
return;
}
var name = Cx.GetString(td.Name);
if (ContainingType != null)
{
ContainingType.GetId(trapFile, inContext);
trapFile.Write('.');
}
else
{
WriteAssemblyPrefix(trapFile);
var ns = ContainingNamespace;
if (!ns.IsGlobalNamespace)
{
ns.WriteId(trapFile);
trapFile.Write('.');
}
}
trapFile.Write(name);
idWriter.WriteId(trapFile, inContext);
}
public override string Name

View File

@@ -16,9 +16,11 @@ namespace Semmle.Extraction.CIL.Entities
private readonly TypeReferenceHandle handle;
private readonly TypeReference tr;
private readonly Lazy<TypeTypeParameter[]> typeParams;
private readonly NamedTypeIdWriter idWriter;
public TypeReferenceType(Context cx, TypeReferenceHandle handle) : base(cx)
{
this.idWriter = new NamedTypeIdWriter(this);
this.typeParams = new Lazy<TypeTypeParameter[]>(MakeTypeParameters);
this.handle = handle;
this.tr = cx.MdReader.GetTypeReference(handle);
@@ -124,33 +126,7 @@ namespace Semmle.Extraction.CIL.Entities
public override void WriteId(TextWriter trapFile, bool inContext)
{
if (IsPrimitiveType)
{
WritePrimitiveTypeId(trapFile, Name);
return;
}
var ct = ContainingType;
if (ct != null)
{
ct.GetId(trapFile, inContext);
trapFile.Write('.');
}
else
{
if (tr.ResolutionScope.Kind == HandleKind.AssemblyReference)
{
WriteAssemblyPrefix(trapFile);
}
if (!ContainingNamespace.IsGlobalNamespace)
{
ContainingNamespace.WriteId(trapFile);
trapFile.Write('.');
}
}
trapFile.Write(Cx.GetString(tr.Name));
idWriter.WriteId(trapFile, inContext);
}
public override Type Construct(IEnumerable<Type> typeArguments)