Skip to content

Commit 74db25d

Browse files
authored
C#: Enable nullability on Semmle.Extraction.CIL.Driver (#4114)
1 parent 722b1a2 commit 74db25d

File tree

4 files changed

+59
-43
lines changed

4 files changed

+59
-43
lines changed

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

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ static AssemblyName CreateAssemblyName(MetadataReader mdReader, AssemblyDefiniti
5050
return an;
5151
}
5252

53+
/// <summary>
54+
/// Initializes a new instance of the <see cref="AssemblyInfo"/> class.
55+
/// </summary>
56+
/// <param name="path">Path of the assembly.</param>
57+
/// <exception cref="Semmle.Extraction.CIL.Driver.InvalidAssemblyException">
58+
/// Thrown when the input file is not a valid assembly.
59+
/// </exception>
5360
public AssemblyInfo(string path)
5461
{
5562
filename = path;
@@ -60,13 +67,11 @@ public AssemblyInfo(string path)
6067
{
6168
try
6269
{
63-
isAssembly = peReader.HasMetadata;
64-
if (!isAssembly) return;
70+
if (!peReader.HasMetadata) throw new InvalidAssemblyException();
6571

6672
var mdReader = peReader.GetMetadataReader();
6773

68-
isAssembly = mdReader.IsAssembly;
69-
if (!mdReader.IsAssembly) return;
74+
if (!mdReader.IsAssembly) throw new InvalidAssemblyException();
7075

7176
// Get our own assembly name
7277
name = CreateAssemblyName(mdReader, mdReader.GetAssemblyDefinition());
@@ -81,15 +86,14 @@ public AssemblyInfo(string path)
8186
// This failed on one of the Roslyn tests that includes
8287
// a deliberately malformed assembly.
8388
// In this case, we just skip the extraction of this assembly.
84-
isAssembly = false;
89+
throw new InvalidAssemblyException();
8590
}
8691
}
8792
}
8893

8994
public readonly AssemblyName name;
9095
public readonly string filename;
9196
public bool extract;
92-
public readonly bool isAssembly;
9397
public readonly AssemblyName[] references;
9498
}
9599

@@ -102,11 +106,12 @@ class AssemblyList
102106
{
103107
class AssemblyNameComparer : IEqualityComparer<AssemblyName>
104108
{
105-
bool IEqualityComparer<AssemblyName>.Equals(AssemblyName x, AssemblyName y) =>
106-
x.Name == y.Name && x.Version == y.Version;
109+
bool IEqualityComparer<AssemblyName>.Equals(AssemblyName? x, AssemblyName? y) =>
110+
object.ReferenceEquals(x, y) ||
111+
x?.Name == y?.Name && x?.Version == y?.Version;
107112

108113
int IEqualityComparer<AssemblyName>.GetHashCode(AssemblyName obj) =>
109-
obj.Name.GetHashCode() + 7 * obj.Version.GetHashCode();
114+
(obj.Name, obj.Version).GetHashCode();
110115
}
111116

112117
readonly Dictionary<AssemblyName, AssemblyInfo> assembliesRead = new Dictionary<AssemblyName, AssemblyInfo>(new AssemblyNameComparer());
@@ -116,13 +121,15 @@ public void AddFile(string assemblyPath, bool extractAll)
116121
if (!filesAnalyzed.Contains(assemblyPath))
117122
{
118123
filesAnalyzed.Add(assemblyPath);
119-
var info = new AssemblyInfo(assemblyPath);
120-
if (info.isAssembly)
124+
try
121125
{
126+
var info = new AssemblyInfo(assemblyPath);
122127
info.extract = extractAll;
123128
if (!assembliesRead.ContainsKey(info.name))
124129
assembliesRead.Add(info.name, info);
125130
}
131+
catch (InvalidAssemblyException)
132+
{ }
126133
}
127134
}
128135

@@ -137,8 +144,7 @@ public void ResolveReferences()
137144
while (assembliesToReference.Any())
138145
{
139146
var item = assembliesToReference.Pop();
140-
AssemblyInfo info;
141-
if (assembliesRead.TryGetValue(item, out info))
147+
if (assembliesRead.TryGetValue(item, out AssemblyInfo? info))
142148
{
143149
if (!info.extract)
144150
{
@@ -165,6 +171,21 @@ class ExtractorOptions
165171
{
166172
readonly AssemblyList assemblyList = new AssemblyList();
167173

174+
public ExtractorOptions(string[] args)
175+
{
176+
Verbosity = Verbosity.Info;
177+
Threads = System.Environment.ProcessorCount;
178+
PDB = true;
179+
TrapCompression = TrapWriter.CompressionMode.Gzip;
180+
181+
ParseArgs(args);
182+
183+
AddFrameworkDirectories(false);
184+
185+
assemblyList.ResolveReferences();
186+
AssembliesToExtract = assemblyList.AssembliesToExtract.ToArray();
187+
}
188+
168189
public void AddDirectory(string directory, bool extractAll)
169190
{
170191
foreach (var file in
@@ -192,21 +213,20 @@ void AddFileOrDirectory(string path)
192213
if (File.Exists(path))
193214
{
194215
assemblyList.AddFile(path, true);
195-
AddDirectory(Path.GetDirectoryName(path), false);
216+
string? directory = Path.GetDirectoryName(path);
217+
if (directory is null)
218+
{
219+
throw new InternalError($"Directory of path '{path}' is null");
220+
}
221+
AddDirectory(directory, false);
196222
}
197223
else if (Directory.Exists(path))
198224
{
199225
AddDirectory(path, true);
200226
}
201227
}
202228

203-
void ResolveReferences()
204-
{
205-
assemblyList.ResolveReferences();
206-
AssembliesToExtract = assemblyList.AssembliesToExtract.ToArray();
207-
}
208-
209-
public IEnumerable<AssemblyInfo> AssembliesToExtract { get; private set; }
229+
public IEnumerable<AssemblyInfo> AssembliesToExtract { get; }
210230

211231
/// <summary>
212232
/// Gets the assemblies that were referenced but were not available to be
@@ -215,55 +235,43 @@ void ResolveReferences()
215235
/// </summary>
216236
public IEnumerable<AssemblyName> MissingReferences => assemblyList.missingReferences;
217237

218-
public static ExtractorOptions ParseCommandLine(string[] args)
238+
private void ParseArgs(string[] args)
219239
{
220-
var options = new ExtractorOptions();
221-
options.Verbosity = Verbosity.Info;
222-
options.Threads = System.Environment.ProcessorCount;
223-
options.PDB = true;
224-
options.TrapCompression = TrapWriter.CompressionMode.Gzip;
225-
226240
foreach (var arg in args)
227241
{
228242
if (arg == "--verbose")
229243
{
230-
options.Verbosity = Verbosity.All;
244+
Verbosity = Verbosity.All;
231245
}
232246
else if (arg == "--silent")
233247
{
234-
options.Verbosity = Verbosity.Off;
248+
Verbosity = Verbosity.Off;
235249
}
236250
else if (arg.StartsWith("--verbosity:"))
237251
{
238-
options.Verbosity = (Verbosity)int.Parse(arg.Substring(12));
252+
Verbosity = (Verbosity)int.Parse(arg.Substring(12));
239253
}
240254
else if (arg == "--dotnet")
241255
{
242-
options.AddFrameworkDirectories(true);
256+
AddFrameworkDirectories(true);
243257
}
244258
else if (arg == "--nocache")
245259
{
246-
options.NoCache = true;
260+
NoCache = true;
247261
}
248262
else if (arg.StartsWith("--threads:"))
249263
{
250-
options.Threads = int.Parse(arg.Substring(10));
264+
Threads = int.Parse(arg.Substring(10));
251265
}
252266
else if (arg == "--no-pdb")
253267
{
254-
options.PDB = false;
268+
PDB = false;
255269
}
256270
else
257271
{
258-
options.AddFileOrDirectory(arg);
272+
AddFileOrDirectory(arg);
259273
}
260274
}
261-
262-
options.AddFrameworkDirectories(false);
263-
options.ResolveReferences();
264-
265-
return options;
266275
}
267-
268276
}
269277
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using System;
2+
3+
namespace Semmle.Extraction.CIL.Driver
4+
{
5+
class InvalidAssemblyException : Exception
6+
{ }
7+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static void Main(string[] args)
4040
return;
4141
}
4242

43-
var options = ExtractorOptions.ParseCommandLine(args);
43+
var options = new ExtractorOptions(args);
4444
var layout = new Layout();
4545
var logger = new ConsoleLogger(options.Verbosity);
4646

csharp/extractor/Semmle.Extraction.CIL.Driver/Semmle.Extraction.CIL.Driver.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<RootNamespace>Semmle.Extraction.CIL.Driver</RootNamespace>
88
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
99
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
10+
<Nullable>enable</Nullable>
1011
</PropertyGroup>
1112

1213
<ItemGroup>

0 commit comments

Comments
 (0)