Skip to content

Commit

Permalink
Enable CA1810 as a warning (#40384)
Browse files Browse the repository at this point in the history
Contributes to #24055
Contributes to #32087

* This updates most of the repo to use LoggerMessageAttributes. MvcCoreLoggerExtensions is the only standout but it is fairly involved since it mixes logging from several types, re-uses logger ids etc
  • Loading branch information
pranavkm authored Feb 25, 2022
1 parent f23cfb8 commit 1852bb7
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 459 deletions.
4 changes: 3 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ dotnet_diagnostic.CA1802.severity = warning
dotnet_diagnostic.CA1805.severity = warning

# CA1810: Do not initialize unnecessarily
dotnet_diagnostic.CA1810.severity = suggestion
dotnet_diagnostic.CA1810.severity = warning

# CA1821: Remove empty Finalizers
dotnet_diagnostic.CA1821.severity = warning
Expand Down Expand Up @@ -268,6 +268,8 @@ dotnet_diagnostic.CA1507.severity = suggestion
dotnet_diagnostic.CA1802.severity = suggestion
# CA1805: Do not initialize unnecessarily
dotnet_diagnostic.CA1805.severity = suggestion
# CA1810: Do not initialize unnecessarily
dotnet_diagnostic.CA1810.severity = suggestion
# CA1822: Make member static
dotnet_diagnostic.CA1822.severity = suggestion
# CA1823: Avoid zero-length array allocations
Expand Down
25 changes: 10 additions & 15 deletions src/Analyzers/Analyzers/src/StartupAnalyzer.Diagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,6 @@ public partial class StartupAnalyzer : DiagnosticAnalyzer
[System.Diagnostics.CodeAnalysis.SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008:Enable analyzer release tracking")]
internal static class Diagnostics
{
public static readonly ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics;

static Diagnostics()
{
SupportedDiagnostics = ImmutableArray.Create<DiagnosticDescriptor>(new[]
{
// ASP
BuildServiceProviderShouldNotCalledInConfigureServicesMethod,
IncorrectlyConfiguredAuthorizationMiddleware,

// MVC
UnsupportedUseMvcWithEndpointRouting,
});
}

internal static readonly DiagnosticDescriptor BuildServiceProviderShouldNotCalledInConfigureServicesMethod = new DiagnosticDescriptor(
"ASP0000",
"Do not call 'IServiceCollection.BuildServiceProvider' in 'ConfigureServices'",
Expand All @@ -53,5 +38,15 @@ static Diagnostics()
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
helpLinkUri: "https://aka.ms/AA64fv1");

public static readonly ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics = ImmutableArray.Create<DiagnosticDescriptor>(new[]
{
// ASP
BuildServiceProviderShouldNotCalledInConfigureServicesMethod,
IncorrectlyConfiguredAuthorizationMiddleware,

// MVC
UnsupportedUseMvcWithEndpointRouting,
});
}
}
92 changes: 15 additions & 77 deletions src/Identity/Core/src/LoggingExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,90 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

namespace Microsoft.Extensions.Logging;

internal static class LoggingExtensions
internal static partial class LoggingExtensions
{
private static readonly Action<ILogger, Exception> _invalidExpirationTime;
private static readonly Action<ILogger, Exception> _userIdsNotEquals;
private static readonly Action<ILogger, string, string, Exception> _purposeNotEquals;
private static readonly Action<ILogger, Exception> _unexpectedEndOfInput;
private static readonly Action<ILogger, Exception> _securityStampNotEquals;
private static readonly Action<ILogger, Exception> _securityStampIsNotEmpty;
private static readonly Action<ILogger, Exception> _unhandledException;

static LoggingExtensions()
{
_invalidExpirationTime = LoggerMessage.Define(
eventId: new EventId(0, "InvalidExpirationTime"),
logLevel: LogLevel.Debug,
formatString: "ValidateAsync failed: the expiration time is invalid.");

_userIdsNotEquals = LoggerMessage.Define(
eventId: new EventId(1, "UserIdsNotEquals"),
logLevel: LogLevel.Debug,
formatString: "ValidateAsync failed: did not find expected UserId.");

_purposeNotEquals = LoggerMessage.Define<string, string>(
eventId: new EventId(2, "PurposeNotEquals"),
logLevel: LogLevel.Debug,
formatString: "ValidateAsync failed: did not find expected purpose. '{ActualPurpose}' does not match the expected purpose '{ExpectedPurpose}'.");

_unexpectedEndOfInput = LoggerMessage.Define(
eventId: new EventId(3, "UnexpectedEndOfInput"),
logLevel: LogLevel.Debug,
formatString: "ValidateAsync failed: unexpected end of input.");

_securityStampNotEquals = LoggerMessage.Define(
eventId: new EventId(4, "SecurityStampNotEquals"),
logLevel: LogLevel.Debug,
formatString: "ValidateAsync failed: did not find expected security stamp.");

_securityStampIsNotEmpty = LoggerMessage.Define(
eventId: new EventId(5, "SecurityStampIsNotEmpty"),
logLevel: LogLevel.Debug,
formatString: "ValidateAsync failed: the expected stamp is not empty.");

_unhandledException = LoggerMessage.Define(
eventId: new EventId(6, "UnhandledException"),
logLevel: LogLevel.Debug,
formatString: "ValidateAsync failed: unhandled exception was thrown.");
}

public static void InvalidExpirationTime(this ILogger logger)
{
_invalidExpirationTime(logger, null);
}
[LoggerMessage(0, LogLevel.Debug, "ValidateAsync failed: the expiration time is invalid.", EventName = "InvalidExpirationTime")]
public static partial void InvalidExpirationTime(this ILogger logger);

public static void UserIdsNotEquals(this ILogger logger)
{
_userIdsNotEquals(logger, null);
}
[LoggerMessage(1, LogLevel.Debug, "ValidateAsync failed: did not find expected UserId.", EventName = "UserIdsNotEquals")]
public static partial void UserIdsNotEquals(this ILogger logger);

public static void PurposeNotEquals(this ILogger logger, string actualPurpose, string expectedPurpose)
{
_purposeNotEquals(logger, actualPurpose, expectedPurpose, null);
}
[LoggerMessage(2, LogLevel.Debug, "ValidateAsync failed: did not find expected purpose. '{ActualPurpose}' does not match the expected purpose '{ExpectedPurpose}'.", EventName = "PurposeNotEquals")]
public static partial void PurposeNotEquals(this ILogger logger, string actualPurpose, string expectedPurpose);

public static void UnexpectedEndOfInput(this ILogger logger)
{
_unexpectedEndOfInput(logger, null);
}
[LoggerMessage(3, LogLevel.Debug, "ValidateAsync failed: unexpected end of input.", EventName = "UnexpectedEndOfInput")]
public static partial void UnexpectedEndOfInput(this ILogger logger);

public static void SecurityStampNotEquals(this ILogger logger)
{
_securityStampNotEquals(logger, null);
}
[LoggerMessage(4, LogLevel.Debug, "ValidateAsync failed: did not find expected security stamp.", EventName = "SecurityStampNotEquals")]
public static partial void SecurityStampNotEquals(this ILogger logger);

public static void SecurityStampIsNotEmpty(this ILogger logger)
{
_securityStampIsNotEmpty(logger, null);
}
[LoggerMessage(5, LogLevel.Debug, "ValidateAsync failed: the expected stamp is not empty.", EventName = "SecurityStampIsNotEmpty")]
public static partial void SecurityStampIsNotEmpty(this ILogger logger);

public static void UnhandledException(this ILogger logger)
{
_unhandledException(logger, null);
}
[LoggerMessage(6, LogLevel.Debug, "ValidateAsync failed: unhandled exception was thrown.", EventName = "UnhandledException")]
public static partial void UnhandledException(this ILogger logger);
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Linq;
using System.Reflection;
using System.Resources;
using Microsoft.Extensions.Localization.Internal;
using Microsoft.Extensions.Logging;

namespace Microsoft.Extensions.Localization;
Expand All @@ -18,7 +17,7 @@ namespace Microsoft.Extensions.Localization;
/// <see cref="ResourceReader"/> to provide localized strings.
/// </summary>
/// <remarks>This type is thread-safe.</remarks>
public class ResourceManagerStringLocalizer : IStringLocalizer
public partial class ResourceManagerStringLocalizer : IStringLocalizer
{
private readonly ConcurrentDictionary<string, object?> _missingManifestCache = new ConcurrentDictionary<string, object?>();
private readonly IResourceNamesCache _resourceNamesCache;
Expand Down Expand Up @@ -193,7 +192,7 @@ protected IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures,

var cacheKey = $"name={name}&culture={keyCulture.Name}";

_logger.SearchedLocation(name, _resourceBaseName, keyCulture);
Log.SearchedLocation(_logger, name, _resourceBaseName, keyCulture);

if (_missingManifestCache.ContainsKey(cacheKey))
{
Expand Down Expand Up @@ -247,4 +246,10 @@ private IEnumerable<string> GetResourceNamesFromCultureHierarchy(CultureInfo sta

return resourceNames;
}

private static partial class Log
{
[LoggerMessage(1, LogLevel.Debug, $"{nameof(ResourceManagerStringLocalizer)} searched for '{{Key}}' in '{{LocationSearched}}' with culture '{{Culture}}'.", EventName = "SearchedLocation")]
public static partial void SearchedLocation(ILogger logger, string key, string locationSearched, CultureInfo culture);
}
}
1 change: 1 addition & 0 deletions src/Mvc/Mvc.Core/src/MvcCoreLoggerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable
#pragma warning disable CA1810 // Initialize all static fields inline.

using System.Collections;
using System.Globalization;
Expand Down
7 changes: 5 additions & 2 deletions src/Mvc/Mvc.Razor/src/Compilation/DefaultViewCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ public Task<CompiledViewDescriptor> CompileAsync(string relativePath)
// normalized and a cache entry exists.
if (_compiledViews.TryGetValue(relativePath, out var cachedResult))
{
_logger.ViewCompilerLocatedCompiledViewForPath(relativePath);
Log.ViewCompilerLocatedCompiledViewForPath(_logger, relativePath);
return cachedResult;
}

var normalizedPath = GetNormalizedPath(relativePath);
if (_compiledViews.TryGetValue(normalizedPath, out cachedResult))
{
_logger.ViewCompilerLocatedCompiledViewForPath(normalizedPath);
Log.ViewCompilerLocatedCompiledViewForPath(_logger, normalizedPath);
return cachedResult;
}

Expand Down Expand Up @@ -141,6 +141,9 @@ private static partial class Log
[LoggerMessage(4, LogLevel.Debug, "Initializing Razor view compiler with no compiled views.", EventName = "ViewCompilerNoCompiledViewsFound")]
public static partial void ViewCompilerNoCompiledViewsFound(ILogger logger);

[LoggerMessage(5, LogLevel.Trace, "Located compiled view for view at path '{Path}'.", EventName = "ViewCompilerLocatedCompiledViewForPath")]
public static partial void ViewCompilerLocatedCompiledViewForPath(ILogger logger, string path);

[LoggerMessage(7, LogLevel.Trace, "Could not find a file for view at path '{Path}'.", EventName = "ViewCompilerCouldNotFindFileAtPath")]
public static partial void ViewCompilerCouldNotFindFileAtPath(ILogger logger, string path);
}
Expand Down
Loading

0 comments on commit 1852bb7

Please sign in to comment.