mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-09 17:44:48 +09:00
Add support for primary constructors in LoggerMessageGenerator (#101660)
* Add support for primary constructors in LoggerMessageGenerator * Get the primary constructor parameters types from the constructor symbol instead of from the semantic model * Prioritize fields over primary constructor parameters and ignore shadowed parameters when finding a logger * Make checking for primary constructors non-conditional on Roslyn version and simplify project setup * Reintroduce Roslyn 4.8 test project * Add info-level diagnostic for logger primary constructor parameters that are shadowed by field * Update list of diagnostics with new logging message generator diagnostic * Only add non-logger field names to set of shadowed names * Add comment explaining the use of the set of shadowed names with an example
This commit is contained in:
parent
0005249901
commit
9daa4b41eb
26 changed files with 533 additions and 33 deletions
|
@ -145,7 +145,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
|
||||||
| __`SYSLIB1024`__ | Argument is using the unsupported out parameter modifier |
|
| __`SYSLIB1024`__ | Argument is using the unsupported out parameter modifier |
|
||||||
| __`SYSLIB1025`__ | Multiple logging methods cannot use the same event name within a class |
|
| __`SYSLIB1025`__ | Multiple logging methods cannot use the same event name within a class |
|
||||||
| __`SYSLIB1026`__ | C# language version not supported by the logging source generator. |
|
| __`SYSLIB1026`__ | C# language version not supported by the logging source generator. |
|
||||||
| __`SYSLIB1027`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ |
|
| __`SYSLIB1027`__ | Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field |
|
||||||
| __`SYSLIB1028`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ |
|
| __`SYSLIB1028`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ |
|
||||||
| __`SYSLIB1029`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ |
|
| __`SYSLIB1029`__ | _`SYSLIB1001`-`SYSLIB1029` reserved for logging._ |
|
||||||
| __`SYSLIB1030`__ | JsonSourceGenerator did not generate serialization metadata for type |
|
| __`SYSLIB1030`__ | JsonSourceGenerator did not generate serialization metadata for type |
|
||||||
|
|
|
@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Loggin
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Logging.Generators.Roslyn4.0.Tests", "tests\Microsoft.Extensions.Logging.Generators.Tests\Microsoft.Extensions.Logging.Generators.Roslyn4.0.Tests.csproj", "{1CB869A7-2EEC-4A53-9C33-DF9E0C75825B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Logging.Generators.Roslyn4.0.Tests", "tests\Microsoft.Extensions.Logging.Generators.Tests\Microsoft.Extensions.Logging.Generators.Roslyn4.0.Tests.csproj", "{1CB869A7-2EEC-4A53-9C33-DF9E0C75825B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Logging.Generators.Roslyn4.8.Tests", "tests\Microsoft.Extensions.Logging.Generators.Tests\Microsoft.Extensions.Logging.Generators.Roslyn4.8.Tests.csproj", "{D6167506-0671-46A3-94E5-7A98032DCEC6}"
|
||||||
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryImportGenerator", "..\System.Runtime.InteropServices\gen\LibraryImportGenerator\LibraryImportGenerator.csproj", "{852D4E16-58C3-47C2-A6BC-A5B12B37209F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryImportGenerator", "..\System.Runtime.InteropServices\gen\LibraryImportGenerator\LibraryImportGenerator.csproj", "{852D4E16-58C3-47C2-A6BC-A5B12B37209F}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.SourceGeneration", "..\System.Runtime.InteropServices\gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj", "{6645D0C4-83D1-4426-B9CD-67096CB7A60F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.SourceGeneration", "..\System.Runtime.InteropServices\gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj", "{6645D0C4-83D1-4426-B9CD-67096CB7A60F}"
|
||||||
|
@ -135,6 +137,10 @@ Global
|
||||||
{F3186815-B9A5-455F-B0DF-E39D4235C24F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{F3186815-B9A5-455F-B0DF-E39D4235C24F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{F3186815-B9A5-455F-B0DF-E39D4235C24F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{F3186815-B9A5-455F-B0DF-E39D4235C24F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{F3186815-B9A5-455F-B0DF-E39D4235C24F}.Release|Any CPU.Build.0 = Release|Any CPU
|
{F3186815-B9A5-455F-B0DF-E39D4235C24F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{D6167506-0671-46A3-94E5-7A98032DCEC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D6167506-0671-46A3-94E5-7A98032DCEC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D6167506-0671-46A3-94E5-7A98032DCEC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D6167506-0671-46A3-94E5-7A98032DCEC6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -162,6 +168,7 @@ Global
|
||||||
{8215F79E-510B-4CA1-B775-50C47BB58360} = {58760833-B4F5-429D-9ABD-15FDF83E25CD}
|
{8215F79E-510B-4CA1-B775-50C47BB58360} = {58760833-B4F5-429D-9ABD-15FDF83E25CD}
|
||||||
{F3186815-B9A5-455F-B0DF-E39D4235C24F} = {14DFA192-3C7E-4F10-B5FD-3953BC82A6B1}
|
{F3186815-B9A5-455F-B0DF-E39D4235C24F} = {14DFA192-3C7E-4F10-B5FD-3953BC82A6B1}
|
||||||
{14DFA192-3C7E-4F10-B5FD-3953BC82A6B1} = {58760833-B4F5-429D-9ABD-15FDF83E25CD}
|
{14DFA192-3C7E-4F10-B5FD-3953BC82A6B1} = {58760833-B4F5-429D-9ABD-15FDF83E25CD}
|
||||||
|
{D6167506-0671-46A3-94E5-7A98032DCEC6} = {4DE63935-DCA9-4D63-9C1F-AAE79C89CA8B}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {450DA749-CBDC-4BDC-950F-8A491CF59D49}
|
SolutionGuid = {450DA749-CBDC-4BDC-950F-8A491CF59D49}
|
||||||
|
|
|
@ -208,5 +208,13 @@ namespace Microsoft.Extensions.Logging.Generators
|
||||||
category: "LoggingGenerator",
|
category: "LoggingGenerator",
|
||||||
defaultSeverity: DiagnosticSeverity.Error,
|
defaultSeverity: DiagnosticSeverity.Error,
|
||||||
isEnabledByDefault: true);
|
isEnabledByDefault: true);
|
||||||
|
|
||||||
|
public static DiagnosticDescriptor PrimaryConstructorParameterLoggerHidden { get; } = DiagnosticDescriptorHelper.Create(
|
||||||
|
id: "SYSLIB1027",
|
||||||
|
title: new LocalizableResourceString(nameof(SR.PrimaryConstructorParameterLoggerHiddenTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Logging.Generators.SR)),
|
||||||
|
messageFormat: new LocalizableResourceString(nameof(SR.PrimaryConstructorParameterLoggerHiddenMessage), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Logging.Generators.SR)),
|
||||||
|
category: "LoggingGenerator",
|
||||||
|
DiagnosticSeverity.Info,
|
||||||
|
isEnabledByDefault: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -630,11 +630,23 @@ namespace Microsoft.Extensions.Logging.Generators
|
||||||
|
|
||||||
INamedTypeSymbol? classType = sm.GetDeclaredSymbol(classDec, _cancellationToken);
|
INamedTypeSymbol? classType = sm.GetDeclaredSymbol(classDec, _cancellationToken);
|
||||||
|
|
||||||
|
INamedTypeSymbol? currentClassType = classType;
|
||||||
bool onMostDerivedType = true;
|
bool onMostDerivedType = true;
|
||||||
|
|
||||||
while (classType is { SpecialType: not SpecialType.System_Object })
|
// We keep track of the names of all non-logger fields, since they prevent referring to logger
|
||||||
|
// primary constructor parameters with the same name. Example:
|
||||||
|
// partial class C(ILogger logger)
|
||||||
|
// {
|
||||||
|
// private readonly object logger = logger;
|
||||||
|
//
|
||||||
|
// [LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")]
|
||||||
|
// public partial void M1(); // The ILogger primary constructor parameter cannot be used here.
|
||||||
|
// }
|
||||||
|
HashSet<string> shadowedNames = new(StringComparer.Ordinal);
|
||||||
|
|
||||||
|
while (currentClassType is { SpecialType: not SpecialType.System_Object })
|
||||||
{
|
{
|
||||||
foreach (IFieldSymbol fs in classType.GetMembers().OfType<IFieldSymbol>())
|
foreach (IFieldSymbol fs in currentClassType.GetMembers().OfType<IFieldSymbol>())
|
||||||
{
|
{
|
||||||
if (!onMostDerivedType && fs.DeclaredAccessibility == Accessibility.Private)
|
if (!onMostDerivedType && fs.DeclaredAccessibility == Accessibility.Private)
|
||||||
{
|
{
|
||||||
|
@ -651,10 +663,52 @@ namespace Microsoft.Extensions.Logging.Generators
|
||||||
return (null, true);
|
return (null, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shadowedNames.Add(fs.Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMostDerivedType = false;
|
onMostDerivedType = false;
|
||||||
classType = classType.BaseType;
|
currentClassType = currentClassType.BaseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We prioritize fields over primary constructor parameters and avoid warnings if both exist.
|
||||||
|
if (loggerField is not null)
|
||||||
|
{
|
||||||
|
return (loggerField, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<IMethodSymbol> primaryConstructors = classType.InstanceConstructors
|
||||||
|
.Where(ic => ic.DeclaringSyntaxReferences
|
||||||
|
.Any(ds => ds.GetSyntax() is ClassDeclarationSyntax));
|
||||||
|
|
||||||
|
foreach (IMethodSymbol primaryConstructor in primaryConstructors)
|
||||||
|
{
|
||||||
|
foreach (IParameterSymbol parameter in primaryConstructor.Parameters)
|
||||||
|
{
|
||||||
|
if (IsBaseOrIdentity(parameter.Type, loggerSymbol))
|
||||||
|
{
|
||||||
|
if (shadowedNames.Contains(parameter.Name))
|
||||||
|
{
|
||||||
|
// Accessible fields always shadow primary constructor parameters,
|
||||||
|
// so we can't use the primary constructor parameter,
|
||||||
|
// even if the field is not a valid logger.
|
||||||
|
Diag(DiagnosticDescriptors.PrimaryConstructorParameterLoggerHidden, parameter.Locations[0], classDec.Identifier.Text);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loggerField == null)
|
||||||
|
{
|
||||||
|
loggerField = parameter.Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (null, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (loggerField, false);
|
return (loggerField, false);
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace Microsoft.Extensions.Logging.Generators
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<ClassDeclarationSyntax> distinctClasses = classes.Distinct();
|
ImmutableHashSet<ClassDeclarationSyntax> distinctClasses = classes.ToImmutableHashSet();
|
||||||
|
|
||||||
var p = new Parser(compilation, context.ReportDiagnostic, context.CancellationToken);
|
var p = new Parser(compilation, context.ReportDiagnostic, context.CancellationToken);
|
||||||
IReadOnlyList<LoggerClass> logClasses = p.GetLogClasses(distinctClasses);
|
IReadOnlyList<LoggerClass> logClasses = p.GetLogClasses(distinctClasses);
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
|
|
||||||
Version 2.0
|
Version 2.0
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
The primary goals of this format is to allow a simple XML format
|
||||||
that is mostly human readable. The generation and parsing of the
|
that is mostly human readable. The generation and parsing of the
|
||||||
various data types are done through the TypeConverter classes
|
various data types are done through the TypeConverter classes
|
||||||
associated with the data types.
|
associated with the data types.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
... ado.net/XML headers & schema ...
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
<resheader name="version">2.0</resheader>
|
<resheader name="version">2.0</resheader>
|
||||||
|
@ -26,36 +26,36 @@
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
<comment>This is a comment</comment>
|
<comment>This is a comment</comment>
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
There are any number of "resheader" rows that contain simple
|
||||||
name/value pairs.
|
name/value pairs.
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
Each data row contains a name, and value. The row also contains a
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
text/value conversion through the TypeConverter architecture.
|
text/value conversion through the TypeConverter architecture.
|
||||||
Classes that don't support this are serialized and stored with the
|
Classes that don't support this are serialized and stored with the
|
||||||
mimetype set.
|
mimetype set.
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
The mimetype is used for serialized objects, and tells the
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
read any of the formats listed below.
|
read any of the formats listed below.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
value : The object must be serialized into a byte array
|
value : The object must be serialized into a byte array
|
||||||
: using a System.ComponentModel.TypeConverter
|
: using a System.ComponentModel.TypeConverter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
-->
|
-->
|
||||||
|
@ -237,4 +237,12 @@
|
||||||
<data name="LoggingUnsupportedLanguageVersionMessageFormat" xml:space="preserve">
|
<data name="LoggingUnsupportedLanguageVersionMessageFormat" xml:space="preserve">
|
||||||
<value>The Logging source generator is not available in C# {0}. Please use language version {1} or greater.</value>
|
<value>The Logging source generator is not available in C# {0}. Please use language version {1} or greater.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="PrimaryConstructorParameterLoggerHiddenMessage" xml:space="preserve">
|
||||||
|
<value>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</value>
|
||||||
|
<comment>{Locked="Microsoft.Extensions.Logging.ILogger"}</comment>
|
||||||
|
</data>
|
||||||
|
<data name="PrimaryConstructorParameterLoggerHiddenTitle" xml:space="preserve">
|
||||||
|
<value>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</value>
|
||||||
|
<comment>{Locked="Microsoft.Extensions.Logging.ILogger"}</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Našlo se několik polí typu Microsoft.Extensions.Logging.ILogger</target>
|
<target state="translated">Našlo se několik polí typu Microsoft.Extensions.Logging.ILogger</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">Odeberte redundantní kvalifikátor (Informace:, Upozornění:, Chyba: atd.) ze zprávy o protokolování, protože je na zadané úrovni protokolu implicitní.</target>
|
<target state="translated">Odeberte redundantní kvalifikátor (Informace:, Upozornění:, Chyba: atd.) ze zprávy o protokolování, protože je na zadané úrovni protokolu implicitní.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Mehrere Felder vom Typ "Microsoft.Extensions.Logging.ILogger" gefunden</target>
|
<target state="translated">Mehrere Felder vom Typ "Microsoft.Extensions.Logging.ILogger" gefunden</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">Entfernen Sie den redundanten Qualifizierer (z. B. "Info:", "Warnung:" oder "Fehler:") aus der Protokollierungsmeldung, weil er auf der angegebenen Protokollebene implizit enthalten ist.</target>
|
<target state="translated">Entfernen Sie den redundanten Qualifizierer (z. B. "Info:", "Warnung:" oder "Fehler:") aus der Protokollierungsmeldung, weil er auf der angegebenen Protokollebene implizit enthalten ist.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Se encontraron varios campos de tipo Microsoft.Extensions.Logging.ILogger</target>
|
<target state="translated">Se encontraron varios campos de tipo Microsoft.Extensions.Logging.ILogger</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">Quitar calificadores redundantes (Información:, Advertencia:, Error:, etc.) del mensaje de registro, ya que está implícito en el nivel de registro especificado.</target>
|
<target state="translated">Quitar calificadores redundantes (Información:, Advertencia:, Error:, etc.) del mensaje de registro, ya que está implícito en el nivel de registro especificado.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Plusieurs champs de type Microsoft.Extensions.Logging.ILogger ont été trouvés</target>
|
<target state="translated">Plusieurs champs de type Microsoft.Extensions.Logging.ILogger ont été trouvés</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">Supprimez le qualificateur redondant (Info:, Warning:, Error:, etc.) du message de journalisation, car il est implicite dans le niveau de journalisation spécifié.</target>
|
<target state="translated">Supprimez le qualificateur redondant (Info:, Warning:, Error:, etc.) du message de journalisation, car il est implicite dans le niveau de journalisation spécifié.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Sono stati trovati più campi di tipo Microsoft.Extensions.Logging.ILogger</target>
|
<target state="translated">Sono stati trovati più campi di tipo Microsoft.Extensions.Logging.ILogger</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">Rimuovere il qualificatore ridondante (Informazioni:, Avviso:, Errore: e così via) dal messaggio di registrazione perché è implicito nel livello di log specificato.</target>
|
<target state="translated">Rimuovere il qualificatore ridondante (Informazioni:, Avviso:, Errore: e così via) dal messaggio di registrazione perché è implicito nel livello di log specificato.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Microsoft.Extensions.Logging.ILogger という種類の複数のフィールドが見つかりました</target>
|
<target state="translated">Microsoft.Extensions.Logging.ILogger という種類の複数のフィールドが見つかりました</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">指定されたログ レベルでは暗黙的であるため、冗長な修飾子 (Info:、Warning:、Error: など) をログ メッセージから削除します。</target>
|
<target state="translated">指定されたログ レベルでは暗黙的であるため、冗長な修飾子 (Info:、Warning:、Error: など) をログ メッセージから削除します。</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Microsoft.Extensions.Logging.ILogger 형식의 필드가 여러 개 있음</target>
|
<target state="translated">Microsoft.Extensions.Logging.ILogger 형식의 필드가 여러 개 있음</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">중복 한정자(정보:, 경고:, 오류: 등)가 지정된 로그 수준에서 암시적이기 때문에 로깅 메시지에서 제거합니다.</target>
|
<target state="translated">중복 한정자(정보:, 경고:, 오류: 등)가 지정된 로그 수준에서 암시적이기 때문에 로깅 메시지에서 제거합니다.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Znaleziono wiele pól typu Microsoft.Extensions.Logging.ILogger</target>
|
<target state="translated">Znaleziono wiele pól typu Microsoft.Extensions.Logging.ILogger</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">Usuń nadmiarowy kwalifikator (Info:, Warning:, Error: itp.) z komunikatu rejestrowania, ponieważ jest on domyślny na określonym poziomie dziennika.</target>
|
<target state="translated">Usuń nadmiarowy kwalifikator (Info:, Warning:, Error: itp.) z komunikatu rejestrowania, ponieważ jest on domyślny na określonym poziomie dziennika.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Múltiplos campos encontrados do tipo Microsoft.Extensions.Logging.ILogger</target>
|
<target state="translated">Múltiplos campos encontrados do tipo Microsoft.Extensions.Logging.ILogger</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">Remova o qualificador redundante (Info:, Aviso:, Erro:, etc) da mensagem de log, pois está implícito no nível de log especificado.</target>
|
<target state="translated">Remova o qualificador redundante (Info:, Aviso:, Erro:, etc) da mensagem de log, pois está implícito no nível de log especificado.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Обнаружено несколько полей типа Microsoft.Extensions.Logging.ILogger</target>
|
<target state="translated">Обнаружено несколько полей типа Microsoft.Extensions.Logging.ILogger</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">Удалите избыточный квалификатор (Info:, Warning:, Error:, и т. п.) из сообщения журнала, поскольку квалификатор подразумевается на указанном уровне ведения журнала.</target>
|
<target state="translated">Удалите избыточный квалификатор (Info:, Warning:, Error:, и т. п.) из сообщения журнала, поскольку квалификатор подразумевается на указанном уровне ведения журнала.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">Microsoft.Extensions.Logging.ILogger türünde birden çok alan bulundu</target>
|
<target state="translated">Microsoft.Extensions.Logging.ILogger türünde birden çok alan bulundu</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">Belirtilen günlük düzeyinde örtük olduğundan gereksiz niteleyiciyi (Bilgi:, Uyarı:, Hata: vb.) günlüğe kaydetme iletisinden kaldırın.</target>
|
<target state="translated">Belirtilen günlük düzeyinde örtük olduğundan gereksiz niteleyiciyi (Bilgi:, Uyarı:, Hata: vb.) günlüğe kaydetme iletisinden kaldırın.</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">找到 Microsoft.Extensions.Logging.ILogger 类型的多个字段</target>
|
<target state="translated">找到 Microsoft.Extensions.Logging.ILogger 类型的多个字段</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">从日志记录消息中删除冗余限定符(信息:、警告:、错误: 等),因为其在指定的日志级别中为隐式内容。</target>
|
<target state="translated">从日志记录消息中删除冗余限定符(信息:、警告:、错误: 等),因为其在指定的日志级别中为隐式内容。</target>
|
||||||
|
|
|
@ -132,6 +132,16 @@
|
||||||
<target state="translated">找到多個 Microsoft.Extensions.Logging.ILogger 類型的欄位</target>
|
<target state="translated">找到多個 Microsoft.Extensions.Logging.ILogger 類型的欄位</target>
|
||||||
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenMessage">
|
||||||
|
<source>Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</source>
|
||||||
|
<target state="new">Class '{0}' has a primary constructor parameter of type Microsoft.Extensions.Logging.ILogger that is hidden by a field in the class or a base class, preventing its use</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="PrimaryConstructorParameterLoggerHiddenTitle">
|
||||||
|
<source>Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</source>
|
||||||
|
<target state="new">Primary constructor parameter of type Microsoft.Extensions.Logging.ILogger is hidden by a field</target>
|
||||||
|
<note>{Locked="Microsoft.Extensions.Logging.ILogger"}</note>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="RedundantQualifierInMessageMessage">
|
<trans-unit id="RedundantQualifierInMessageMessage">
|
||||||
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
<source>Remove redundant qualifier (Info:, Warning:, Error:, etc) from the logging message since it is implicit in the specified log level.</source>
|
||||||
<target state="translated">從記錄訊息中移除備援限定詞 (資訊:、警告:、錯誤: 等等),因為它在指定的記錄層級中為隱含。</target>
|
<target state="translated">從記錄訊息中移除備援限定詞 (資訊:、警告:、錯誤: 等等),因為它在指定的記錄層級中為隱含。</target>
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
// <auto-generated/>
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
|
||||||
|
{
|
||||||
|
partial class TestWithLoggerFromPrimaryConstructor
|
||||||
|
{
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")]
|
||||||
|
private static readonly global::System.Action<global::Microsoft.Extensions.Logging.ILogger, global::System.Exception?> __M0Callback =
|
||||||
|
global::Microsoft.Extensions.Logging.LoggerMessage.Define(global::Microsoft.Extensions.Logging.LogLevel.Debug, new global::Microsoft.Extensions.Logging.EventId(0, nameof(M0)), "M0", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true });
|
||||||
|
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")]
|
||||||
|
public partial void M0()
|
||||||
|
{
|
||||||
|
if (logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Debug))
|
||||||
|
{
|
||||||
|
__M0Callback(logger, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// <auto-generated/>
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
|
||||||
|
{
|
||||||
|
partial class TestWithLoggerFromPrimaryConstructor
|
||||||
|
{
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")]
|
||||||
|
private static readonly global::System.Action<global::Microsoft.Extensions.Logging.ILogger, global::System.Exception?> __M0Callback =
|
||||||
|
global::Microsoft.Extensions.Logging.LoggerMessage.Define(global::Microsoft.Extensions.Logging.LogLevel.Debug, new global::Microsoft.Extensions.Logging.EventId(0, nameof(M0)), "M0", new global::Microsoft.Extensions.Logging.LogDefineOptions() { SkipEnabledCheck = true });
|
||||||
|
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Extensions.Logging.Generators", "%VERSION%")]
|
||||||
|
public partial void M0()
|
||||||
|
{
|
||||||
|
if (_logger.IsEnabled(global::Microsoft.Extensions.Logging.LogLevel.Debug))
|
||||||
|
{
|
||||||
|
__M0Callback(_logger, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void FindsLoggerFieldInAnotherParialClass()
|
public void FindsLoggerFieldInAnotherPartialClass()
|
||||||
{
|
{
|
||||||
var logger = new MockLogger();
|
var logger = new MockLogger();
|
||||||
|
|
||||||
|
@ -36,6 +36,41 @@ namespace Microsoft.Extensions.Logging.Generators.Tests
|
||||||
Assert.Equal("Test.", logger.LastFormattedString);
|
Assert.Equal("Test.", logger.LastFormattedString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ROSLYN4_8_OR_GREATER
|
||||||
|
[Fact]
|
||||||
|
public void FindsLoggerInPrimaryConstructorParameter()
|
||||||
|
{
|
||||||
|
var logger = new MockLogger();
|
||||||
|
|
||||||
|
logger.Reset();
|
||||||
|
|
||||||
|
new ClassWithPrimaryConstructor(logger).Test();
|
||||||
|
Assert.Equal("Test.", logger.LastFormattedString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FindsLoggerInPrimaryConstructorParameterInDifferentPartialDeclaration()
|
||||||
|
{
|
||||||
|
var logger = new MockLogger();
|
||||||
|
|
||||||
|
logger.Reset();
|
||||||
|
|
||||||
|
new ClassWithPrimaryConstructorInDifferentPartialDeclaration(logger).Test();
|
||||||
|
Assert.Equal("Test.", logger.LastFormattedString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void FindsLoggerInFieldInitializedFromPrimaryConstructorParameter()
|
||||||
|
{
|
||||||
|
var logger = new MockLogger();
|
||||||
|
|
||||||
|
logger.Reset();
|
||||||
|
|
||||||
|
new ClassWithPrimaryConstructor(logger).Test();
|
||||||
|
Assert.Equal("Test.", logger.LastFormattedString);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BasicTests()
|
public void BasicTests()
|
||||||
{
|
{
|
||||||
|
|
|
@ -187,6 +187,40 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
|
||||||
await VerifyAgainstBaselineUsingFile("TestWithNestedClassWithGenericTypesWithAttributes.generated.txt", testSourceCode);
|
await VerifyAgainstBaselineUsingFile("TestWithNestedClassWithGenericTypesWithAttributes.generated.txt", testSourceCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ROSLYN4_8_OR_GREATER
|
||||||
|
[Fact]
|
||||||
|
public async Task TestBaseline_TestWithLoggerFromPrimaryConstructor_Success()
|
||||||
|
{
|
||||||
|
string testSourceCode = @"
|
||||||
|
namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
|
||||||
|
{
|
||||||
|
internal partial class TestWithLoggerFromPrimaryConstructor(ILogger logger)
|
||||||
|
{
|
||||||
|
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M0"")]
|
||||||
|
public partial void M0();
|
||||||
|
}
|
||||||
|
}";
|
||||||
|
await VerifyAgainstBaselineUsingFile("TestWithLoggerFromPrimaryConstructor.generated.txt", testSourceCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task TestBaseline_TestWithLoggerInFieldAndFromPrimaryConstructor_UsesField()
|
||||||
|
{
|
||||||
|
string testSourceCode = @"
|
||||||
|
namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
|
||||||
|
{
|
||||||
|
internal partial class TestWithLoggerFromPrimaryConstructor(ILogger logger)
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
|
||||||
|
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M0"")]
|
||||||
|
public partial void M0();
|
||||||
|
}
|
||||||
|
}";
|
||||||
|
await VerifyAgainstBaselineUsingFile("TestWithLoggerInFieldAndFromPrimaryConstructor.generated.txt", testSourceCode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GenericTypeParameterAttributesAreRetained()
|
public void GenericTypeParameterAttributesAreRetained()
|
||||||
{
|
{
|
||||||
|
|
|
@ -417,6 +417,142 @@ namespace Microsoft.Extensions.Logging.Generators.Tests
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task FieldOnOtherPartialDeclarationOK()
|
||||||
|
{
|
||||||
|
IReadOnlyList<Diagnostic> diagnostics = await RunGenerator(@"
|
||||||
|
partial class C
|
||||||
|
{
|
||||||
|
private ILogger _logger;
|
||||||
|
|
||||||
|
public C(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
partial class C
|
||||||
|
{
|
||||||
|
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")]
|
||||||
|
public partial void M1();
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
Assert.Empty(diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ROSLYN4_8_OR_GREATER
|
||||||
|
[Fact]
|
||||||
|
public async Task PrimaryConstructorOK()
|
||||||
|
{
|
||||||
|
IReadOnlyList<Diagnostic> diagnostics = await RunGenerator(@"
|
||||||
|
partial class C(ILogger logger)
|
||||||
|
{
|
||||||
|
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")]
|
||||||
|
public partial void M1();
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
Assert.Empty(diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PrimaryConstructorOnOtherPartialDeclarationOK()
|
||||||
|
{
|
||||||
|
IReadOnlyList<Diagnostic> diagnostics = await RunGenerator(@"
|
||||||
|
partial class C(ILogger logger);
|
||||||
|
|
||||||
|
partial class C
|
||||||
|
{
|
||||||
|
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")]
|
||||||
|
public partial void M1();
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
Assert.Empty(diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PrimaryConstructorWithDifferentNameLoggerFieldOK()
|
||||||
|
{
|
||||||
|
IReadOnlyList<Diagnostic> diagnostics = await RunGenerator(@"
|
||||||
|
partial class C(ILogger logger)
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
|
||||||
|
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")]
|
||||||
|
public partial void M1();
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
Assert.Empty(diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PrimaryConstructorWithSameNameLoggerFieldOK()
|
||||||
|
{
|
||||||
|
IReadOnlyList<Diagnostic> diagnostics = await RunGenerator(@"
|
||||||
|
partial class C(ILogger logger)
|
||||||
|
{
|
||||||
|
private readonly ILogger logger = logger;
|
||||||
|
|
||||||
|
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")]
|
||||||
|
public partial void M1();
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
Assert.Empty(diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PrimaryConstructorLoggerShadowedByField()
|
||||||
|
{
|
||||||
|
IReadOnlyList<Diagnostic> diagnostics = await RunGenerator(@"
|
||||||
|
partial class C(ILogger logger)
|
||||||
|
{
|
||||||
|
private readonly object logger = logger;
|
||||||
|
|
||||||
|
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")]
|
||||||
|
public partial void M1();
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
Assert.Equal(2, diagnostics.Count);
|
||||||
|
|
||||||
|
Assert.Equal(DiagnosticDescriptors.PrimaryConstructorParameterLoggerHidden.Id, diagnostics[0].Id);
|
||||||
|
var lineSpan = diagnostics[0].Location.GetLineSpan();
|
||||||
|
Assert.Equal(4, lineSpan.StartLinePosition.Line);
|
||||||
|
Assert.Equal(40, lineSpan.StartLinePosition.Character);
|
||||||
|
|
||||||
|
Assert.Equal(DiagnosticDescriptors.MissingLoggerField.Id, diagnostics[1].Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PrimaryConstructorLoggerShadowedByBaseClass()
|
||||||
|
{
|
||||||
|
IReadOnlyList<Diagnostic> diagnostics = await RunGenerator(@"
|
||||||
|
class Base(object logger) {
|
||||||
|
protected readonly object logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
partial class Derived(ILogger logger) : Base(logger)
|
||||||
|
{
|
||||||
|
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = ""M1"")]
|
||||||
|
public partial void M1();
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
Assert.Equal(2, diagnostics.Count);
|
||||||
|
|
||||||
|
Assert.Equal(DiagnosticDescriptors.PrimaryConstructorParameterLoggerHidden.Id, diagnostics[0].Id);
|
||||||
|
var lineSpan = diagnostics[0].Location.GetLineSpan();
|
||||||
|
Assert.Equal(8, lineSpan.StartLinePosition.Line);
|
||||||
|
Assert.Equal(46, lineSpan.StartLinePosition.Character);
|
||||||
|
|
||||||
|
Assert.Equal(DiagnosticDescriptors.MissingLoggerField.Id, diagnostics[1].Id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("false")]
|
[InlineData("false")]
|
||||||
[InlineData("true")]
|
[InlineData("true")]
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<RoslynApiVersion>$(MicrosoftCodeAnalysisVersion_4_8)</RoslynApiVersion>
|
||||||
|
<DefineConstants>$(DefineConstants);ROSLYN4_0_OR_GREATER;ROSLYN4_8_OR_GREATER</DefineConstants>
|
||||||
|
<IsHighAotMemoryUsageTest>true</IsHighAotMemoryUsageTest>
|
||||||
|
<EmccLinkOptimizationFlag Condition="'$(ContinuousIntegrationBuild)' == 'true'">-O1</EmccLinkOptimizationFlag>
|
||||||
|
<!-- this Roslyn version brings in NS1.x dependencies -->
|
||||||
|
<FlagNetStandard1XDependencies>false</FlagNetStandard1XDependencies>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<HighAotMemoryUsageAssembly Include="Microsoft.CodeAnalysis.CSharp.dll" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Import Project="Microsoft.Extensions.Logging.Generators.targets" />
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\gen\Microsoft.Extensions.Logging.Generators.Roslyn4.4.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="true" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -57,6 +57,30 @@ public partial class PartialClassWithLoggerField
|
||||||
public partial void Test();
|
public partial void Test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ROSLYN4_8_OR_GREATER
|
||||||
|
public partial class ClassWithPrimaryConstructor(ILogger logger)
|
||||||
|
{
|
||||||
|
[LoggerMessage(0, LogLevel.Debug, "Test.")]
|
||||||
|
public partial void Test();
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class ClassWithPrimaryConstructorInDifferentPartialDeclaration(ILogger logger);
|
||||||
|
|
||||||
|
public partial class ClassWithPrimaryConstructorInDifferentPartialDeclaration
|
||||||
|
{
|
||||||
|
[LoggerMessage(0, LogLevel.Debug, "Test.")]
|
||||||
|
public partial void Test();
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class ClassWithPrimaryConstructorAndField(ILogger logger)
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger = logger;
|
||||||
|
|
||||||
|
[LoggerMessage(0, LogLevel.Debug, "Test.")]
|
||||||
|
public partial void Test();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Used to test use outside of a namespace
|
// Used to test use outside of a namespace
|
||||||
internal static partial class NoNamespace
|
internal static partial class NoNamespace
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue