Skip to content

Commit 3e716bf

Browse files
authored
Merge pull request #1749 from calumgrant/cs/extractor-tidy
C#: Refactor extractor trap generation code
2 parents a2841b4 + 0129b42 commit 3e716bf

File tree

155 files changed

+3264
-2377
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+3264
-2377
lines changed

csharp/extractor/Semmle.Extraction.CIL.Driver/ExtractorOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ void AddFrameworkDirectories(bool extractAll)
184184
public bool NoCache { get; private set; }
185185
public int Threads { get; private set; }
186186
public bool PDB { get; private set; }
187+
public TrapWriter.CompressionMode TrapCompression { get; private set; }
187188

188189
void AddFileOrDirectory(string path)
189190
{
@@ -220,6 +221,7 @@ public static ExtractorOptions ParseCommandLine(string[] args)
220221
options.Verbosity = Verbosity.Info;
221222
options.Threads = System.Environment.ProcessorCount;
222223
options.PDB = true;
224+
options.TrapCompression = TrapWriter.CompressionMode.Gzip;
223225

224226
foreach (var arg in args)
225227
{

csharp/extractor/Semmle.Extraction.CIL.Driver/Program.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ static void DisplayHelp()
2121
Console.WriteLine(" path A directory/dll/exe to analyze");
2222
}
2323

24-
static void ExtractAssembly(Layout layout, string assemblyPath, ILogger logger, bool nocache, bool extractPdbs)
24+
static void ExtractAssembly(Layout layout, string assemblyPath, ILogger logger, bool nocache, bool extractPdbs, TrapWriter.CompressionMode trapCompression)
2525
{
2626
string trapFile;
2727
bool extracted;
2828
var sw = new Stopwatch();
2929
sw.Start();
30-
Entities.Assembly.ExtractCIL(layout, assemblyPath, logger, nocache, extractPdbs, out trapFile, out extracted);
30+
Entities.Assembly.ExtractCIL(layout, assemblyPath, logger, nocache, extractPdbs, trapCompression, out trapFile, out extracted);
3131
sw.Stop();
3232
logger.Log(Severity.Info, " {0} ({1})", assemblyPath, sw.Elapsed);
3333
}
@@ -46,7 +46,7 @@ static void Main(string[] args)
4646

4747
var actions = options.
4848
AssembliesToExtract.Select(asm => asm.filename).
49-
Select<string, Action>(filename => () => ExtractAssembly(layout, filename, logger, options.NoCache, options.PDB)).
49+
Select<string, Action>(filename => () => ExtractAssembly(layout, filename, logger, options.NoCache, options.PDB, options.TrapCompression)).
5050
ToArray();
5151

5252
foreach (var missingRef in options.MissingReferences)

csharp/extractor/Semmle.Extraction.CIL/Context.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ public Context(Extraction.Context cx, string assemblyPath, bool extractPdbs)
3131
mdReader = peReader.GetMetadataReader();
3232
TypeSignatureDecoder = new Entities.TypeSignatureDecoder(this);
3333

34-
globalNamespace = new Lazy<Entities.Namespace>(() => Populate(new Entities.Namespace(this, GetId(""), null)));
34+
globalNamespace = new Lazy<Entities.Namespace>(() => Populate(new Entities.Namespace(this, "", null)));
3535
systemNamespace = new Lazy<Entities.Namespace>(() => Populate(new Entities.Namespace(this, "System")));
36-
genericHandleFactory = new CachedFunction<GenericContext, Handle, ILabelledEntity>(CreateGenericHandle);
36+
genericHandleFactory = new CachedFunction<GenericContext, Handle, IExtractedEntity>(CreateGenericHandle);
3737
namespaceFactory = new CachedFunction<StringHandle, Entities.Namespace>(n => CreateNamespace(mdReader.GetString(n)));
3838
namespaceDefinitionFactory = new CachedFunction<NamespaceDefinitionHandle, Entities.Namespace>(CreateNamespace);
3939
sourceFiles = new CachedFunction<PDB.ISourceFile, Entities.PdbSourceFile>(path => new Entities.PdbSourceFile(this, path));
@@ -42,9 +42,6 @@ public Context(Extraction.Context cx, string assemblyPath, bool extractPdbs)
4242

4343
defaultGenericContext = new EmptyContext(this);
4444

45-
var def = mdReader.GetAssemblyDefinition();
46-
AssemblyPrefix = GetId(def.Name) + "_" + def.Version.ToString() + "::";
47-
4845
if (extractPdbs)
4946
{
5047
pdb = PDB.PdbReader.Create(assemblyPath, peReader);
@@ -75,7 +72,14 @@ public void Extract(IExtractedEntity entity)
7572
}
7673
}
7774

78-
public readonly Id AssemblyPrefix;
75+
public void WriteAssemblyPrefix(TextWriter trapFile)
76+
{
77+
var def = mdReader.GetAssemblyDefinition();
78+
trapFile.Write(GetString(def.Name));
79+
trapFile.Write('_');
80+
trapFile.Write(def.Version.ToString());
81+
trapFile.Write("::");
82+
}
7983

8084
public readonly Entities.TypeSignatureDecoder TypeSignatureDecoder;
8185

csharp/extractor/Semmle.Extraction.CIL/Entities/Assembly.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Semmle.Util.Logging;
55
using System;
66
using Semmle.Extraction.Entities;
7+
using System.IO;
78

89
namespace Semmle.Extraction.CIL.Entities
910
{
@@ -20,8 +21,6 @@ interface IAssembly : ILocation
2021
/// </summary>
2122
public class Assembly : LabelledEntity, IAssembly
2223
{
23-
public override Id IdSuffix => suffix;
24-
2524
readonly File file;
2625
readonly AssemblyName assemblyName;
2726

@@ -38,12 +37,24 @@ public Assembly(Context cx) : base(cx)
3837
if (!def.PublicKey.IsNil)
3938
assemblyName.SetPublicKey(cx.mdReader.GetBlobBytes(def.PublicKey));
4039

41-
ShortId = cx.GetId(FullName) + "#file:///" + cx.assemblyPath.Replace("\\", "/");
42-
4340
file = new File(cx, cx.assemblyPath);
4441
}
4542

46-
static readonly Id suffix = new StringId(";assembly");
43+
public override void WriteId(TextWriter trapFile)
44+
{
45+
trapFile.Write(FullName);
46+
trapFile.Write("#file:///");
47+
trapFile.Write(cx.assemblyPath.Replace("\\", "/"));
48+
}
49+
50+
public override bool Equals(object obj)
51+
{
52+
return GetType() == obj.GetType() && Equals(file, ((Assembly)obj).file);
53+
}
54+
55+
public override int GetHashCode() => 7 * file.GetHashCode();
56+
57+
public override string IdSuffix => ";assembly";
4758

4859
string FullName => assemblyName.GetPublicKey() is null ? assemblyName.FullName + ", PublicKeyToken=null" : assemblyName.FullName;
4960

@@ -117,15 +128,15 @@ static void ExtractCIL(Extraction.Context cx, string assemblyPath, bool extractP
117128
/// <param name="extractPdbs">Whether to extract PDBs.</param>
118129
/// <param name="trapFile">The path of the trap file.</param>
119130
/// <param name="extracted">Whether the file was extracted (false=cached).</param>
120-
public static void ExtractCIL(Layout layout, string assemblyPath, ILogger logger, bool nocache, bool extractPdbs, out string trapFile, out bool extracted)
131+
public static void ExtractCIL(Layout layout, string assemblyPath, ILogger logger, bool nocache, bool extractPdbs, TrapWriter.CompressionMode trapCompression, out string trapFile, out bool extracted)
121132
{
122133
trapFile = "";
123134
extracted = false;
124135
try
125136
{
126137
var extractor = new Extractor(false, assemblyPath, logger);
127138
var project = layout.LookupProjectOrDefault(assemblyPath);
128-
using (var trapWriter = project.CreateTrapWriter(logger, assemblyPath + ".cil", true))
139+
using (var trapWriter = project.CreateTrapWriter(logger, assemblyPath + ".cil", true, trapCompression))
129140
{
130141
trapFile = trapWriter.TrapFile;
131142
if (nocache || !System.IO.File.Exists(trapFile))

csharp/extractor/Semmle.Extraction.CIL/Entities/Attribute.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ interface IAttribute : IExtractedEntity
1414
/// <summary>
1515
/// Entity representing a CIL attribute.
1616
/// </summary>
17-
class Attribute : UnlabelledEntity, IAttribute
17+
sealed class Attribute : UnlabelledEntity, IAttribute
1818
{
19+
readonly CustomAttributeHandle handle;
1920
readonly CustomAttribute attrib;
2021
readonly IEntity @object;
2122

@@ -25,6 +26,13 @@ public Attribute(Context cx, IEntity @object, CustomAttributeHandle handle) : ba
2526
this.@object = @object;
2627
}
2728

29+
public override bool Equals(object obj)
30+
{
31+
return obj is Attribute attribute && handle.Equals(attribute.handle);
32+
}
33+
34+
public override int GetHashCode() => handle.GetHashCode();
35+
2836
public override IEnumerable<IExtractionProduct> Contents
2937
{
3038
get
@@ -78,7 +86,7 @@ class CustomAttributeDecoder : ICustomAttributeTypeProvider<Type>
7886
readonly Context cx;
7987
public CustomAttributeDecoder(Context cx) { this.cx = cx; }
8088

81-
public Type GetPrimitiveType(PrimitiveTypeCode typeCode) => cx.Populate(new PrimitiveType(cx, typeCode));
89+
public Type GetPrimitiveType(PrimitiveTypeCode typeCode) => cx.Create(typeCode);
8290

8391
public Type GetSystemType() => throw new NotImplementedException();
8492

csharp/extractor/Semmle.Extraction.CIL/Entities/Event.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,48 @@
11
using System.Collections.Generic;
2+
using System.IO;
23
using System.Reflection.Metadata;
34

45
namespace Semmle.Extraction.CIL.Entities
56
{
67
/// <summary>
78
/// An event.
89
/// </summary>
9-
interface IEvent : ILabelledEntity
10+
interface IEvent : IExtractedEntity
1011
{
1112
}
1213

1314
/// <summary>
1415
/// An event entity.
1516
/// </summary>
16-
class Event : LabelledEntity, IEvent
17+
sealed class Event : LabelledEntity, IEvent
1718
{
19+
readonly EventDefinitionHandle handle;
1820
readonly Type parent;
1921
readonly EventDefinition ed;
20-
static readonly Id suffix = CIL.Id.Create(";cil-event");
2122

2223
public Event(Context cx, Type parent, EventDefinitionHandle handle) : base(cx)
2324
{
25+
this.handle = handle;
2426
this.parent = parent;
2527
ed = cx.mdReader.GetEventDefinition(handle);
26-
ShortId = parent.ShortId + cx.Dot + cx.ShortName(ed.Name) + suffix;
2728
}
2829

30+
public override void WriteId(TextWriter trapFile)
31+
{
32+
parent.WriteId(trapFile);
33+
trapFile.Write('.');
34+
trapFile.Write(cx.ShortName(ed.Name));
35+
}
36+
37+
public override string IdSuffix => ";cil-event";
38+
39+
public override bool Equals(object obj)
40+
{
41+
return obj is Event e && handle.Equals(e.handle);
42+
}
43+
44+
public override int GetHashCode() => handle.GetHashCode();
45+
2946
public override IEnumerable<IExtractionProduct> Contents
3047
{
3148
get
@@ -61,7 +78,5 @@ public override IEnumerable<IExtractionProduct> Contents
6178
yield return c;
6279
}
6380
}
64-
65-
public override Id IdSuffix => suffix;
6681
}
6782
}

csharp/extractor/Semmle.Extraction.CIL/Entities/Field.cs

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
using System.Reflection.Metadata;
66
using System.Reflection;
77
using System.Reflection.Metadata.Ecma335;
8+
using System.IO;
89

910
namespace Semmle.Extraction.CIL.Entities
1011
{
1112
/// <summary>
1213
/// An entity represting a member.
1314
/// Used to type tuples correctly.
1415
/// </summary>
15-
interface IMember : ILabelledEntity
16+
interface IMember : IExtractedEntity
1617
{
1718
}
1819

@@ -36,18 +37,24 @@ protected Field(Context cx) : base(cx)
3637

3738
public Label Label { get; set; }
3839

39-
public IId Id => ShortId + IdSuffix;
40-
41-
public Id IdSuffix => fieldSuffix;
42-
43-
static readonly StringId fieldSuffix = new StringId(";cil-field");
40+
public void WriteId(TextWriter trapFile)
41+
{
42+
trapFile.WriteSubId(DeclaringType);
43+
trapFile.Write('.');
44+
trapFile.Write(Name);
45+
}
4446

45-
public Id ShortId
47+
public void WriteQuotedId(TextWriter trapFile)
4648
{
47-
get; set;
49+
trapFile.Write("@\"");
50+
WriteId(trapFile);
51+
trapFile.Write(IdSuffix);
52+
trapFile.Write('\"');
4853
}
4954

50-
public abstract Id Name { get; }
55+
public string IdSuffix => ";cil-field";
56+
57+
public abstract string Name { get; }
5158

5259
public abstract Type DeclaringType { get; }
5360

@@ -59,7 +66,7 @@ public virtual IEnumerable<IExtractionProduct> Contents
5966
{
6067
get
6168
{
62-
yield return Tuples.cil_field(this, DeclaringType, Name.Value, Type);
69+
yield return Tuples.cil_field(this, DeclaringType, Name, Type);
6370
}
6471
}
6572

@@ -82,9 +89,15 @@ public DefinitionField(GenericContext gc, FieldDefinitionHandle handle) : base(g
8289
this.handle = handle;
8390
this.gc = gc;
8491
fd = cx.mdReader.GetFieldDefinition(handle);
85-
ShortId = DeclaringType.ShortId + cx.Dot + Name;
8692
}
8793

94+
public override bool Equals(object obj)
95+
{
96+
return obj is DefinitionField field && handle.Equals(field.handle);
97+
}
98+
99+
public override int GetHashCode() => handle.GetHashCode();
100+
88101
public override IEnumerable<IExtractionProduct> Contents
89102
{
90103
get
@@ -114,7 +127,7 @@ public override IEnumerable<IExtractionProduct> Contents
114127
}
115128
}
116129

117-
public override Id Name => cx.GetId(fd.Name);
130+
public override string Name => cx.GetString(fd.Name);
118131

119132
public override Type DeclaringType => (Type)cx.Create(fd.GetDeclaringType());
120133

@@ -127,19 +140,30 @@ public override IEnumerable<IExtractionProduct> Contents
127140

128141
sealed class MemberReferenceField : Field
129142
{
143+
readonly MemberReferenceHandle Handle;
130144
readonly MemberReference mr;
131145
readonly GenericContext gc;
132146
readonly Type declType;
133147

134148
public MemberReferenceField(GenericContext gc, MemberReferenceHandle handle) : base(gc.cx)
135149
{
150+
Handle = handle;
136151
this.gc = gc;
137152
mr = cx.mdReader.GetMemberReference(handle);
138153
declType = (Type)cx.CreateGeneric(gc, mr.Parent);
139-
ShortId = declType.ShortId + cx.Dot + Name;
140154
}
141155

142-
public override Id Name => cx.GetId(mr.Name);
156+
public override bool Equals(object obj)
157+
{
158+
return obj is MemberReferenceField field && Handle.Equals(field.Handle);
159+
}
160+
161+
public override int GetHashCode()
162+
{
163+
return Handle.GetHashCode();
164+
}
165+
166+
public override string Name => cx.GetString(mr.Name);
143167

144168
public override Type DeclaringType => declType;
145169

csharp/extractor/Semmle.Extraction.CIL/Entities/File.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.IO;
23

34
namespace Semmle.Extraction.CIL.Entities
45
{
@@ -17,9 +18,20 @@ public class File : LabelledEntity, IFile
1718
public File(Context cx, string path) : base(cx)
1819
{
1920
this.path = Semmle.Extraction.Entities.File.PathAsDatabaseString(path);
20-
ShortId = new StringId(Semmle.Extraction.Entities.File.PathAsDatabaseId(path));
2121
}
2222

23+
public override void WriteId(TextWriter trapFile)
24+
{
25+
trapFile.Write(Semmle.Extraction.Entities.File.PathAsDatabaseId(path));
26+
}
27+
28+
public override bool Equals(object obj)
29+
{
30+
return GetType() == obj.GetType() && path == ((File)obj).path;
31+
}
32+
33+
public override int GetHashCode() => 11 * path.GetHashCode();
34+
2335
public override IEnumerable<IExtractionProduct> Contents
2436
{
2537
get
@@ -31,9 +43,7 @@ public override IEnumerable<IExtractionProduct> Contents
3143
}
3244
}
3345

34-
public override Id IdSuffix => suffix;
35-
36-
static readonly Id suffix = new StringId(";sourcefile");
46+
public override string IdSuffix => ";sourcefile";
3747
}
3848

3949
public class PdbSourceFile : File

0 commit comments

Comments
 (0)