Skip to content

Commit 4bcf9e5

Browse files
committed
C#: Address review comments.
1 parent df4f2a3 commit 4bcf9e5

File tree

4 files changed

+48
-50
lines changed

4 files changed

+48
-50
lines changed

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Assets.cs

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using Newtonsoft.Json.Linq;
6+
using Semmle.Util;
67

78
namespace Semmle.Extraction.CSharp.DependencyFetching
89
{
@@ -29,21 +30,15 @@ internal Assets(ProgressMonitor progressMonitor)
2930
/// <summary>
3031
/// Class needed for deserializing parts of an assets file.
3132
/// It holds information about a reference.
33+
///
34+
/// Type carries the type of the reference.
35+
/// We are only interested in package references.
36+
///
37+
/// Compile holds information about the files needed for compilation.
38+
/// However, if it is a .NET framework reference we assume that all files in the
39+
/// package are needed for compilation.
3240
/// </summary>
33-
private class ReferenceInfo
34-
{
35-
/// <summary>
36-
/// This carries the type of the reference.
37-
/// We are only interested in package references.
38-
/// </summary>
39-
public string Type { get; set; } = "";
40-
41-
/// <summary>
42-
/// If not a .NET framework reference we assume that only the files mentioned
43-
/// in the compile section are needed for compilation.
44-
/// </summary>
45-
public Dictionary<string, object> Compile { get; set; } = new();
46-
}
41+
private record class ReferenceInfo(string? Type, Dictionary<string, object>? Compile);
4742

4843
/// <summary>
4944
/// Add the package dependencies from the assets file to dependencies.
@@ -74,7 +69,7 @@ private class ReferenceInfo
7469
/// }
7570
///
7671
/// Returns dependencies
77-
/// Required = {
72+
/// RequiredPaths = {
7873
/// "castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll",
7974
/// "json.net/1.0.33/lib/netstandard2.0/Json.Net.dll"
8075
/// }
@@ -83,7 +78,7 @@ private class ReferenceInfo
8378
/// "json.net"
8479
/// }
8580
/// </summary>
86-
private Dependencies AddPackageDependencies(JObject json, Dependencies dependencies)
81+
private DependencyContainer AddPackageDependencies(JObject json, DependencyContainer dependencies)
8782
{
8883
// If there are more than one framework we need to pick just one.
8984
// To ensure stability we pick one based on the lexicographic order of
@@ -103,31 +98,37 @@ private Dependencies AddPackageDependencies(JObject json, Dependencies dependenc
10398

10499
// Find all the compile dependencies for each reference and
105100
// create the relative path to the dependency.
106-
return references
107-
.Aggregate(dependencies, (deps, r) =>
101+
references
102+
.ForEach(r =>
108103
{
109104
var info = r.Value;
110105
var name = r.Key.ToLowerInvariant();
111106
if (info.Type != "package")
112107
{
113-
return deps;
108+
return;
114109
}
115110

116111
// If this is a .NET framework reference then include everything.
117-
return netFrameworks.Any(framework => name.StartsWith(framework))
118-
? deps.Add(name, "")
119-
: info
120-
.Compile
121-
.Aggregate(deps, (d, p) => d.Add(name, p.Key));
112+
if (netFrameworks.Any(framework => name.StartsWith(framework)))
113+
{
114+
dependencies.Add(name);
115+
}
116+
else
117+
{
118+
info.Compile?
119+
.ForEach(r => dependencies.Add(name, r.Key));
120+
}
122121
});
122+
123+
return dependencies;
123124
}
124125

125126
/// <summary>
126127
/// Parse `json` as project.assets.json content and add relative paths to the dependencies
127128
/// (together with used package information) required for compilation.
128129
/// </summary>
129130
/// <returns>True if parsing succeeds, otherwise false.</returns>
130-
public bool TryParse(string json, Dependencies dependencies)
131+
public bool TryParse(string json, DependencyContainer dependencies)
131132
{
132133
try
133134
{
@@ -142,15 +143,16 @@ public bool TryParse(string json, Dependencies dependencies)
142143
}
143144
}
144145

145-
public static Dependencies GetCompilationDependencies(ProgressMonitor progressMonitor, IEnumerable<string> assets)
146+
public static DependencyContainer GetCompilationDependencies(ProgressMonitor progressMonitor, IEnumerable<string> assets)
146147
{
147148
var parser = new Assets(progressMonitor);
148-
return assets.Aggregate(new Dependencies(), (dependencies, asset) =>
149+
var dependencies = new DependencyContainer();
150+
assets.ForEach(asset =>
149151
{
150152
var json = File.ReadAllText(asset);
151153
parser.TryParse(json, dependencies);
152-
return dependencies;
153154
});
155+
return dependencies;
154156
}
155157
}
156158

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Dependencies.cs renamed to csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyContainer.cs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
77
/// <summary>
88
/// Container class for dependencies found in the assets file.
99
/// </summary>
10-
internal class Dependencies
10+
internal class DependencyContainer
1111
{
12-
private readonly List<string> required = new();
12+
private readonly List<string> requiredPaths = new();
1313
private readonly HashSet<string> usedPackages = new();
1414

1515
/// <summary>
@@ -33,9 +33,9 @@ private static string GetPackageName(string package) =>
3333
.First();
3434

3535
/// <summary>
36-
/// Dependencies required for Compilation.
36+
/// Paths to dependencies required for compilation.
3737
/// </summary>
38-
public IEnumerable<string> Required => required;
38+
public IEnumerable<string> RequiredPaths => requiredPaths;
3939

4040
/// <summary>
4141
/// Packages that are used as a part of the required dependencies.
@@ -45,29 +45,25 @@ private static string GetPackageName(string package) =>
4545
/// <summary>
4646
/// Add a dependency inside a package.
4747
/// </summary>
48-
public Dependencies Add(string package, string dependency)
48+
public void Add(string package, string dependency)
4949
{
5050
var p = package.Replace('/', Path.DirectorySeparatorChar);
5151
var d = dependency.Replace('/', Path.DirectorySeparatorChar);
5252

5353
var path = Path.Combine(p, ParseFilePath(d));
54-
required.Add(path);
54+
requiredPaths.Add(path);
5555
usedPackages.Add(GetPackageName(p));
56-
57-
return this;
5856
}
5957

6058
/// <summary>
6159
/// Add a dependency to an entire package
6260
/// </summary>
63-
public Dependencies Add(string package)
61+
public void Add(string package)
6462
{
6563
var p = package.Replace('/', Path.DirectorySeparatorChar);
6664

67-
required.Add(p);
65+
requiredPaths.Add(p);
6866
usedPackages.Add(GetPackageName(p));
69-
70-
return this;
7167
}
7268
}
7369
}

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public DependencyManager(string srcDir, IDependencyOptions options, ILogger logg
104104
var dependencies = Assets.GetCompilationDependencies(progressMonitor, assets1.Union(assets2));
105105

106106
var paths = dependencies
107-
.Required
107+
.RequiredPaths
108108
.Select(d => Path.Combine(packageDirectory.DirInfo.FullName, d))
109109
.ToList();
110110
dllPaths.AddRange(paths);
@@ -303,7 +303,7 @@ private IEnumerable<string> GetAllPackageDirectories()
303303
.Select(d => d.FullName);
304304
}
305305

306-
private void LogAllUnusedPackages(Dependencies dependencies) =>
306+
private void LogAllUnusedPackages(DependencyContainer dependencies) =>
307307
GetAllPackageDirectories()
308308
.Where(package => !dependencies.UsedPackages.Contains(package))
309309
.ForEach(package => progressMonitor.LogInfo($"Unused package: {package}"));

csharp/extractor/Semmle.Extraction.Tests/Assets.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ public void TestAssets1()
1414
// Setup
1515
var assets = new Assets(new ProgressMonitor(new LoggerStub()));
1616
var json = assetsJson1;
17-
var dependencies = new Dependencies();
17+
var dependencies = new DependencyContainer();
1818

1919
// Execute
2020
var success = assets.TryParse(json, dependencies);
2121

2222
// Verify
2323
Assert.True(success);
24-
Assert.Equal(5, dependencies.Required.Count());
24+
Assert.Equal(5, dependencies.RequiredPaths.Count());
2525
Assert.Equal(4, dependencies.UsedPackages.Count());
2626

27-
var normalizedPaths = dependencies.Required.Select(FixExpectedPathOnWindows);
27+
var normalizedPaths = dependencies.RequiredPaths.Select(FixExpectedPathOnWindows);
2828
// Required references
2929
Assert.Contains("castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll", normalizedPaths);
3030
Assert.Contains("castle.core/4.4.1/lib/netstandard1.5/Castle.Core2.dll", normalizedPaths);
@@ -44,16 +44,16 @@ public void TestAssets2()
4444
// Setup
4545
var assets = new Assets(new ProgressMonitor(new LoggerStub()));
4646
var json = assetsJson2;
47-
var dependencies = new Dependencies();
47+
var dependencies = new DependencyContainer();
4848

4949
// Execute
5050
var success = assets.TryParse(json, dependencies);
5151

5252
// Verify
5353
Assert.True(success);
54-
Assert.Equal(2, dependencies.Required.Count());
54+
Assert.Equal(2, dependencies.RequiredPaths.Count());
5555

56-
var normalizedPaths = dependencies.Required.Select(FixExpectedPathOnWindows);
56+
var normalizedPaths = dependencies.RequiredPaths.Select(FixExpectedPathOnWindows);
5757
// Required references
5858
Assert.Contains("microsoft.netframework.referenceassemblies/1.0.3", normalizedPaths);
5959
Assert.Contains("microsoft.netframework.referenceassemblies.net48/1.0.3", normalizedPaths);
@@ -68,14 +68,14 @@ public void TestAssets3()
6868
// Setup
6969
var assets = new Assets(new ProgressMonitor(new LoggerStub()));
7070
var json = "garbage data";
71-
var dependencies = new Dependencies();
71+
var dependencies = new DependencyContainer();
7272

7373
// Execute
7474
var success = assets.TryParse(json, dependencies);
7575

7676
// Verify
7777
Assert.False(success);
78-
Assert.Empty(dependencies.Required);
78+
Assert.Empty(dependencies.RequiredPaths);
7979
}
8080

8181
private readonly string assetsJson1 = """

0 commit comments

Comments
 (0)