Skip to content

Commit

Permalink
Warnings config is tored by compound key instead of hash-with-collisi…
Browse files Browse the repository at this point in the history
…ons (#9162)
  • Loading branch information
rokonec authored Aug 24, 2023
1 parent 13deecf commit 415ba40
Showing 1 changed file with 18 additions and 19 deletions.
37 changes: 18 additions & 19 deletions src/Build/BackEnd/Components/Logging/LoggingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,17 +218,17 @@ internal partial class LoggingService : ILoggingService, INodePacketHandler, IBu
/// <summary>
/// A list of warnings to treat as errors for an associated <see cref="BuildEventContext"/>. If an empty set, all warnings are treated as errors.
/// </summary>
private IDictionary<int, ISet<string>> _warningsAsErrorsByProject;
private IDictionary<WarningsConfigKey, ISet<string>> _warningsAsErrorsByProject;

/// <summary>
/// A list of warnings to not to be promoted to errors for an associated <see cref="BuildEventContext"/>.
/// </summary>
private IDictionary<int, ISet<string>> _warningsNotAsErrorsByProject;
private IDictionary<WarningsConfigKey, ISet<string>> _warningsNotAsErrorsByProject;

/// <summary>
/// A list of warnings to treat as messages for an associated <see cref="BuildEventContext"/>.
/// </summary>
private IDictionary<int, ISet<string>> _warningsAsMessagesByProject;
private IDictionary<WarningsConfigKey, ISet<string>> _warningsAsMessagesByProject;

/// <summary>
/// The minimum message importance that must be logged because there is a possibility that a logger consumes it.
Expand Down Expand Up @@ -623,9 +623,9 @@ public ICollection<string> GetWarningsAsMessages(BuildEventContext context)
/// <param name="warningsByProject">A dictionary of all warnings to be treated special by for which projects.</param>
/// <param name="warnings">Warning codes we already know should be promoted, demoted, or not promoted as relevant.</param>
/// <returns></returns>
private ICollection<string> GetWarningsForProject(BuildEventContext context, IDictionary<int, ISet<string>> warningsByProject, ISet<string> warnings)
private ICollection<string> GetWarningsForProject(BuildEventContext context, IDictionary<WarningsConfigKey, ISet<string>> warningsByProject, ISet<string> warnings)
{
int key = GetWarningsAsErrorOrMessageKey(context);
WarningsConfigKey key = GetWarningsConfigKey(context);

if (warningsByProject != null && warningsByProject.TryGetValue(key, out ISet<string> newWarnings))
{
Expand Down Expand Up @@ -678,13 +678,13 @@ public void AddWarningsAsMessages(BuildEventContext buildEventContext, ISet<stri
/// <param name="warningsByProject">Dictionary with what warnings are currently known (by project) that we will add to.</param>
/// <param name="buildEventContext">Context for the project to be added</param>
/// <param name="codes">Codes to add</param>
private void AddWarningsAsMessagesOrErrors(ref IDictionary<int, ISet<string>> warningsByProject, BuildEventContext buildEventContext, ISet<string> codes)
private void AddWarningsAsMessagesOrErrors(ref IDictionary<WarningsConfigKey, ISet<string>> warningsByProject, BuildEventContext buildEventContext, ISet<string> codes)
{
lock (_lockObject)
{
int key = GetWarningsAsErrorOrMessageKey(buildEventContext);
WarningsConfigKey key = GetWarningsConfigKey(buildEventContext);

warningsByProject ??= new ConcurrentDictionary<int, ISet<string>>();
warningsByProject ??= new ConcurrentDictionary<WarningsConfigKey, ISet<string>>();

if (!warningsByProject.ContainsKey(key))
{
Expand Down Expand Up @@ -1294,19 +1294,18 @@ internal void InjectNonSerializedData(LogMessagePacket loggingPacket)
#endregion

#region Private Methods
private static int GetWarningsAsErrorOrMessageKey(BuildEventContext buildEventContext)
private static WarningsConfigKey GetWarningsConfigKey(BuildEventContext buildEventContext)
{
var hash = 17;
hash = (hash * 31) + buildEventContext.ProjectInstanceId;
hash = (hash * 31) + buildEventContext.ProjectContextId;
return hash;
return new WarningsConfigKey(buildEventContext.ProjectInstanceId, buildEventContext.ProjectContextId);
}

private static int GetWarningsAsErrorOrMessageKey(BuildEventArgs buildEventArgs)
private static WarningsConfigKey GetWarningsConfigKey(BuildEventArgs buildEventArgs)
{
return GetWarningsAsErrorOrMessageKey(buildEventArgs.BuildEventContext);
return GetWarningsConfigKey(buildEventArgs.BuildEventContext);
}

private readonly record struct WarningsConfigKey(int InstanceId, int ContextId);

/// <summary>
/// Create a logging thread to process the logging queue.
/// </summary>
Expand Down Expand Up @@ -1587,7 +1586,7 @@ private void RouteBuildEvent(object loggingEvent)

if (buildEventArgs is ProjectFinishedEventArgs projectFinishedEvent && projectFinishedEvent.BuildEventContext != null)
{
int key = GetWarningsAsErrorOrMessageKey(projectFinishedEvent);
WarningsConfigKey key = GetWarningsConfigKey(projectFinishedEvent);
_warningsAsErrorsByProject?.Remove(key);
_warningsNotAsErrorsByProject?.Remove(key);
_warningsAsMessagesByProject?.Remove(key);
Expand Down Expand Up @@ -1859,7 +1858,7 @@ private bool ShouldTreatWarningAsMessage(BuildWarningEventArgs warningEvent)
// This only applies if the user specified <MSBuildWarningsAsMessages /> and there is a valid ProjectInstanceId
if (_warningsAsMessagesByProject != null && warningEvent.BuildEventContext != null && warningEvent.BuildEventContext.ProjectInstanceId != BuildEventContext.InvalidProjectInstanceId)
{
if (_warningsAsMessagesByProject.TryGetValue(GetWarningsAsErrorOrMessageKey(warningEvent), out ISet<string> codesByProject))
if (_warningsAsMessagesByProject.TryGetValue(GetWarningsConfigKey(warningEvent), out ISet<string> codesByProject))
{
return codesByProject?.Contains(warningEvent.Code) == true;
}
Expand All @@ -1870,7 +1869,7 @@ private bool ShouldTreatWarningAsMessage(BuildWarningEventArgs warningEvent)

private bool WarningAsErrorNotOverriden(BuildWarningEventArgs warningEvent)
{
int key = GetWarningsAsErrorOrMessageKey(warningEvent);
WarningsConfigKey key = GetWarningsConfigKey(warningEvent);

return WarningsNotAsErrors?.Contains(warningEvent.Code) != true && !(_warningsNotAsErrorsByProject?.TryGetValue(key, out ISet<string> notToError) == true && notToError.Contains(warningEvent.Code));
}
Expand All @@ -1897,7 +1896,7 @@ private bool ShouldTreatWarningAsError(BuildWarningEventArgs warningEvent)
if (_warningsAsErrorsByProject != null && warningEvent.BuildEventContext != null && warningEvent.BuildEventContext.ProjectInstanceId != BuildEventContext.InvalidProjectInstanceId)
{
// Attempt to get the list of warnings to treat as errors for the current project
int key = GetWarningsAsErrorOrMessageKey(warningEvent);
WarningsConfigKey key = GetWarningsConfigKey(warningEvent);
if (_warningsAsErrorsByProject.TryGetValue(key, out ISet<string> codesByProject))
{
// We create an empty set if all warnings should be treated as errors so that should be checked first.
Expand Down

0 comments on commit 415ba40

Please sign in to comment.