Skip to content

C#: Improve log messages in buildless mode + some cleanup/refactoring #15424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Semmle.Util.Logging;

namespace Semmle.Extraction.CSharp.DependencyFetching
{
Expand All @@ -18,25 +19,26 @@ internal class AssemblyCache
/// Paths to search. Directories are searched recursively. Files are added directly to the
/// assembly cache.
/// </param>
/// <param name="progressMonitor">Callback for progress.</param>
public AssemblyCache(IEnumerable<string> paths, IEnumerable<string> frameworkPaths, ProgressMonitor progressMonitor)
/// <param name="logger">Callback for progress.</param>
public AssemblyCache(IEnumerable<string> paths, IEnumerable<string> frameworkPaths, ILogger logger)
{
this.logger = logger;
foreach (var path in paths)
{
if (File.Exists(path))
{
pendingDllsToIndex.Enqueue(path);
dllsToIndex.Add(path);
continue;
}

if (Directory.Exists(path))
{
progressMonitor.FindingFiles(path);
logger.LogInfo($"Finding reference DLLs in {path}...");
AddReferenceDirectory(path);
}
else
{
progressMonitor.LogInfo("AssemblyCache: Path not found: " + path);
logger.LogInfo("AssemblyCache: Path not found: " + path);
}
}
IndexReferences(frameworkPaths);
Expand All @@ -52,7 +54,7 @@ private void AddReferenceDirectory(string dir)
{
foreach (var dll in new DirectoryInfo(dir).EnumerateFiles("*.dll", SearchOption.AllDirectories))
{
pendingDllsToIndex.Enqueue(dll.FullName);
dllsToIndex.Add(dll.FullName);
}
}

Expand All @@ -62,12 +64,16 @@ private void AddReferenceDirectory(string dir)
/// </summary>
private void IndexReferences(IEnumerable<string> frameworkPaths)
{
logger.LogInfo($"Indexing {dllsToIndex.Count} assemblies...");

// Read all of the files
foreach (var filename in pendingDllsToIndex)
foreach (var filename in dllsToIndex)
{
IndexReference(filename);
}

logger.LogInfo($"Read {assemblyInfoByFileName.Count} assembly infos");

foreach (var info in assemblyInfoByFileName.Values
.OrderBy(info => info.Name)
.OrderAssemblyInfosByPreference(frameworkPaths))
Expand All @@ -83,25 +89,16 @@ private void IndexReference(string filename)
{
try
{
logger.LogDebug($"Reading assembly info from {filename}");
var info = AssemblyInfo.ReadFromFile(filename);
assemblyInfoByFileName[filename] = info;
}
catch (AssemblyLoadException)
{
failedAssemblyInfoFileNames.Add(filename);
logger.LogInfo($"Couldn't read assembly info from {filename}");
}
}

/// <summary>
/// The number of DLLs which are assemblies.
/// </summary>
public int AssemblyCount => assemblyInfoByFileName.Count;

/// <summary>
/// The number of DLLs which weren't assemblies. (E.g. C++).
/// </summary>
public int NonAssemblyCount => failedAssemblyInfoFileNames.Count;

/// <summary>
/// Given an assembly id, determine its full info.
/// </summary>
Expand All @@ -113,8 +110,7 @@ public AssemblyInfo ResolveReference(string id)
if (failedAssemblyInfoIds.Contains(id))
throw new AssemblyLoadException();

string assemblyName;
(id, assemblyName) = AssemblyInfo.ComputeSanitizedAssemblyInfo(id);
(id, var assemblyName) = AssemblyInfo.ComputeSanitizedAssemblyInfo(id);

// Look up the id in our references map.
if (assemblyInfoById.TryGetValue(id, out var result))
Expand Down Expand Up @@ -164,17 +160,15 @@ public AssemblyInfo GetAssemblyInfo(string filepath)
throw new AssemblyLoadException();
}

private readonly Queue<string> pendingDllsToIndex = new Queue<string>();
private readonly List<string> dllsToIndex = new List<string>();

private readonly Dictionary<string, AssemblyInfo> assemblyInfoByFileName = new Dictionary<string, AssemblyInfo>();

// List of DLLs which are not assemblies.
// We probably don't need to keep this
private readonly List<string> failedAssemblyInfoFileNames = new List<string>();

// Map from assembly id (in various formats) to the full info.
private readonly Dictionary<string, AssemblyInfo> assemblyInfoById = new Dictionary<string, AssemblyInfo>();

private readonly HashSet<string> failedAssemblyInfoIds = new HashSet<string>();

private readonly ILogger logger;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,21 +120,6 @@ private AssemblyInfo(string filename, string name, Version version, string cultu
NetCoreVersion = netCoreVersion;
}

/// <summary>
/// Get AssemblyInfo from a loaded Assembly.
/// </summary>
/// <param name="assembly">The assembly.</param>
/// <returns>Info about the assembly.</returns>
public static AssemblyInfo MakeFromAssembly(Assembly assembly)
{
if (assembly.FullName is null)
{
throw new InvalidOperationException("Assembly with empty full name is not expected.");
}

return new AssemblyInfo(assembly.FullName, assembly.Location);
}

/// <summary>
/// Returns the id and name of the assembly that would be created from the received id.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using Newtonsoft.Json.Linq;
using Semmle.Util;
using Semmle.Util.Logging;

namespace Semmle.Extraction.CSharp.DependencyFetching
{
Expand All @@ -13,11 +14,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
internal class Assets
{
private readonly ProgressMonitor progressMonitor;
private readonly ILogger logger;

internal Assets(ProgressMonitor progressMonitor)
internal Assets(ILogger logger)
{
this.progressMonitor = progressMonitor;
this.logger = logger;
}

/// <summary>
Expand All @@ -35,7 +36,7 @@ private record class ReferenceInfo(string? Type, Dictionary<string, object>? Com

/// <summary>
/// Add the package dependencies from the assets file to dependencies.
///
///
/// Parse a part of the JSon assets file and add the paths
/// to the dependencies required for compilation (and collect
/// information about used packages).
Expand All @@ -60,7 +61,7 @@ private record class ReferenceInfo(string? Type, Dictionary<string, object>? Com
/// }
/// }
/// }
///
///
/// Adds the following dependencies
/// Paths: {
/// "castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll",
Expand All @@ -85,7 +86,7 @@ private void AddPackageDependencies(JObject json, DependencyContainer dependenci

if (references is null)
{
progressMonitor.LogDebug("No references found in the targets section in the assets file.");
logger.LogDebug("No references found in the targets section in the assets file.");
return;
}

Expand Down Expand Up @@ -157,7 +158,7 @@ private void AddFrameworkDependencies(JObject json, DependencyContainer dependen

if (frameworks is null)
{
progressMonitor.LogDebug("No framework section in assets.json.");
logger.LogDebug("No framework section in assets.json.");
return;
}

Expand All @@ -171,7 +172,7 @@ private void AddFrameworkDependencies(JObject json, DependencyContainer dependen

if (references is null)
{
progressMonitor.LogDebug("No framework references in assets.json.");
logger.LogDebug("No framework references in assets.json.");
return;
}

Expand All @@ -196,12 +197,12 @@ public bool TryParse(string json, DependencyContainer dependencies)
}
catch (Exception e)
{
progressMonitor.LogDebug($"Failed to parse assets file (unexpected error): {e.Message}");
logger.LogDebug($"Failed to parse assets file (unexpected error): {e.Message}");
return false;
}
}

private static bool TryReadAllText(string path, ProgressMonitor progressMonitor, [NotNullWhen(returnValue: true)] out string? content)
private static bool TryReadAllText(string path, ILogger logger, [NotNullWhen(returnValue: true)] out string? content)
{
try
{
Expand All @@ -210,19 +211,19 @@ private static bool TryReadAllText(string path, ProgressMonitor progressMonitor,
}
catch (Exception e)
{
progressMonitor.LogInfo($"Failed to read assets file '{path}': {e.Message}");
logger.LogInfo($"Failed to read assets file '{path}': {e.Message}");
content = null;
return false;
}
}

public static DependencyContainer GetCompilationDependencies(ProgressMonitor progressMonitor, IEnumerable<string> assets)
public static DependencyContainer GetCompilationDependencies(ILogger logger, IEnumerable<string> assets)
{
var parser = new Assets(progressMonitor);
var parser = new Assets(logger);
var dependencies = new DependencyContainer();
assets.ForEach(asset =>
{
if (TryReadAllText(asset, progressMonitor, out var json))
if (TryReadAllText(asset, logger, out var json))
{
parser.TryParse(json, dependencies);
}
Expand Down
Loading